Upgrade to softfloat3e.

This should solve licensing problems as well.
This commit is contained in:
TC1995
2024-06-09 23:08:46 +02:00
parent 4b77ef6823
commit 0f29bcddf1
271 changed files with 25882 additions and 10441 deletions

View File

@@ -0,0 +1,56 @@
#
# 86Box A hypervisor and IBM PC system emulator that specializes in
# running old operating systems and software designed for IBM
# PC systems and compatibles from 1981 through fairly recent
# system designs based on the PCI bus.
#
# This file is part of the 86Box distribution.
#
# CMake build script.
#
# Authors: David Hrdlička, <hrdlickadavid@outlook.com>
#
# Copyright 2020-2021 David Hrdlička.
#
add_library(softfloat3e OBJECT extF80_addsub.cc extF80_class.cc extF80_compare.cc
extF80_div.cc extF80_extract.cc extF80_mul.cc extF80_rem.cc extF80_roundToInt.cc
extF80_scale.cc extF80_sqrt.cc extF80_to_f16.cc extF80_to_f32.cc extF80_to_f64.cc
extF80_to_f128.cc extF80_to_i32.cc extF80_to_i32_r_minMag.cc extF80_to_i64.cc
extF80_to_i64_r_minMag.cc extF80_to_ui32.cc extF80_to_ui32_r_minMag.cc extF80_to_ui64.cc
extF80_to_ui64_r_minMag.cc f16_addsub.c f16_class.c f16_compare.c f16_div.c f16_getExp.c
f16_getMant.c f16_minmax.c f16_mul.c f16_mulAdd.c f16_range.c f16_roundToInt.c
f16_sqrt.c f16_to_extF80.cc f16_to_f32.c f16_to_f64.c f16_to_i32.c f16_to_i32_r_minMag.c
f16_to_i64.c f16_to_i64_r_minMag.c f16_to_ui32.c f16_to_ui32_r_minMag.c f16_to_ui64.c
f16_to_ui64_r_minMag.c f32_addsub.c f32_class.c f32_compare.c f32_div.c f32_frc.c
f32_getExp.c f32_getMant.c f32_minmax.c f32_mul.c f32_mulAdd.c f32_range.c
f32_roundToInt.c f32_scalef.c f32_sqrt.c f32_to_extF80.cc f32_to_f16.c f32_to_f64.c
f32_to_f128.cc f32_to_i32.c f32_to_i32_r_minMag.c f32_to_i64.c f32_to_i64_r_minMag.c
f32_to_ui32.c f32_to_ui32_r_minMag.c f32_to_ui64.c f32_to_ui64_r_minMag.c f64_addsub.c
f64_class.c f64_compare.c f64_div.c f64_frc.c f64_getExp.c f64_getMant.c f64_minmax.c
f64_mul.c f64_mulAdd.c f64_range.c f64_roundToInt.c f64_scalef.c f64_sqrt.c f64_to_extF80.cc
f64_to_f16.c f64_to_f32.c f64_to_f128.cc f64_to_i32.c f64_to_i32_r_minMag.c f64_to_i64.c
f64_to_i64_r_minMag.c f64_to_ui32.c f64_to_ui32_r_minMag.c f64_to_ui64.c f64_to_ui64_r_minMag.c
f128_addsub.cc f128_div.cc f128_mul.cc f128_mulAdd.cc f128_roundToInt.cc f128_to_extF80.cc
f128_to_f32.cc f128_to_f64.cc f128_to_i32.cc f128_to_i32_r_minMag.cc f128_to_i64.cc
f128_to_i64_r_minMag.cc f128_to_ui32.cc f128_to_ui32_r_minMag.cc f128_to_ui64.cc
f128_to_ui64_r_minMag.cc i32_to_extF80.cc i32_to_f16.c i32_to_f32.c i32_to_f64.c
i32_to_f128.cc i64_to_extF80.cc i64_to_f16.c i64_to_f32.c i64_to_f64.c i64_to_f128.cc
isNaN.cc isSignalingNaN.cc s_add128.cc s_add256M.c s_addMagsExtF80.cc s_addMagsF16.c
s_addMagsF32.c s_addMagsF64.c s_addMagsF128.cc s_approxRecip_1Ks.c s_approxRecipSqrt_1Ks.c
s_approxRecipSqrt32_1.c s_commonNaNToExtF80UI.cc s_commonNaNToF16UI.c s_commonNaNToF32UI.c
s_commonNaNToF64UI.c s_commonNaNToF128UI.cc s_countLeadingZeros8.c s_countLeadingZeros16.c
s_countLeadingZeros32.c s_countLeadingZeros64.c s_eq128.c s_le128.c s_lt128.c
s_mul64ByShifted32To128.cc s_mul64To128.cc s_mul128By32.cc s_mul128To256M.cc
s_normRoundPackToExtF80.cc s_normRoundPackToF16.c s_normRoundPackToF32.c s_normRoundPackToF64.c
s_normRoundPackToF128.cc s_normSubnormalExtF80Sig.cc s_normSubnormalF16Sig.c
s_normSubnormalF32Sig.c s_normSubnormalF64Sig.c s_normSubnormalF128Sig.cc s_packToExtF80.cc
s_propagateNaNExtF80UI.cc s_propagateNaNF16UI.c s_propagateNaNF32UI.c s_propagateNaNF64UI.c
s_propagateNaNF128UI.cc s_roundPackToExtF80.cc s_roundPackToF16.c s_roundPackToF32.c
s_roundPackToF64.c s_roundPackToF128.cc s_roundToI32.c s_roundToI64.c s_roundToUI32.c
s_roundToUI64.c s_shiftRightJam32.c s_shiftRightJam64.c s_shiftRightJam64Extra.c
s_shiftRightJam256M.c s_shortShiftLeft128.cc s_shortShiftRight128.cc s_shortShiftRightJam64.c
s_shortShiftRightJam64Extra.c s_sub128.cc s_sub256M.c s_subMagsExtF80.cc s_subMagsF16.c
s_subMagsF32.c s_subMagsF64.c s_subMagsF128.cc ui32_to_extF80.cc ui32_to_f16.c ui32_to_f32.c
ui32_to_f64.c ui32_to_f128.cc ui64_to_extF80.cc ui64_to_f16.c ui64_to_f32.c ui64_to_f64.c
ui64_to_f128.cc f2xm1.cc fpatan.cc fprem.cc fsincos.cc fyl2x.cc poly.cc consts.cc)

View File

@@ -0,0 +1,37 @@
License for Berkeley SoftFloat Release 3e
John R. Hauser
2018 January 20
The following applies to the whole of SoftFloat Release 3e as well as to
each source file individually.
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the
University of California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions, and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -0,0 +1,49 @@
<HTML>
<HEAD>
<TITLE>Berkeley SoftFloat Package Overview</TITLE>
</HEAD>
<BODY>
<H1>Package Overview for Berkeley SoftFloat Release 3e</H1>
<P>
John R. Hauser<BR>
2018 January 20<BR>
</P>
<P>
Berkeley SoftFloat is a software implementation of binary floating-point that
conforms to the IEEE Standard for Floating-Point Arithmetic.
SoftFloat is distributed in the form of C source code.
Building the SoftFloat sources generates a library file (typically
<CODE>softfloat.a</CODE> or <CODE>libsoftfloat.a</CODE>) containing the
floating-point subroutines.
</P>
<P>
The SoftFloat package is documented in the following files in the
<CODE>doc</CODE> subdirectory:
<BLOCKQUOTE>
<TABLE>
<TR>
<TD><A HREF="doc/SoftFloat.html"><NOBR><CODE>SoftFloat.html</CODE></NOBR></A></TD>
<TD>Documentation for using the SoftFloat functions.</TD>
</TR>
<TR>
<TD><A HREF="doc/SoftFloat-source.html"><NOBR><CODE>SoftFloat-source.html</CODE></NOBR></A></TD>
<TD>Documentation for building SoftFloat.</TD>
</TR>
<TR>
<TD><A HREF="doc/SoftFloat-history.html"><NOBR><CODE>SoftFloat-history.html</CODE></A><CODE>&nbsp;&nbsp;&nbsp;</CODE></NOBR></TD>
<TD>History of the major changes to SoftFloat.</TD>
</TR>
</TABLE>
</BLOCKQUOTE>
Other files in the package comprise the source code for SoftFloat.
</P>
</BODY>

View File

@@ -0,0 +1,21 @@
Package Overview for Berkeley SoftFloat Release 3e
John R. Hauser
2018 January 20
Berkeley SoftFloat is a software implementation of binary floating-point
that conforms to the IEEE Standard for Floating-Point Arithmetic. SoftFloat
is distributed in the form of C source code. Building the SoftFloat sources
generates a library file (typically "softfloat.a" or "libsoftfloat.a")
containing the floating-point subroutines.
The SoftFloat package is documented in the following files in the "doc"
subdirectory:
SoftFloat.html Documentation for using the SoftFloat functions.
SoftFloat-source.html Documentation for building SoftFloat.
SoftFloat-history.html History of the major changes to SoftFloat.
Other files in the package comprise the source code for SoftFloat.

View File

@@ -0,0 +1,14 @@
#ifndef EMU_SF_CONFIG_H
#define EMU_SF_CONFIG_H
/*----------------------------------------------------------------------------
| The `LIT64' macro takes as its argument a textual integer literal and
| if necessary ``marks'' the literal as having a 64-bit integer type.
| For example, the GNU C Compiler (`gcc') requires that 64-bit literals be
| appended with the letters `LL' standing for `long long', which is `gcc's
| name for the 64-bit integer type. Some compilers may allow `LIT64' to be
| defined as the identity macro: `#define LIT64( a ) a'.
*----------------------------------------------------------------------------*/
#define BX_CONST64(a) a##LL
#endif /*EMU_SF_CONFIG_H*/

View File

@@ -0,0 +1,51 @@
/*============================================================================
This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdio.h>
#include <stdint.h>
#include <86box/86box.h>
#include "../cpu.h"
#include "softfloat-specialize.h"
const floatx80 Const_QNaN = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
const floatx80 Const_Z = packFloatx80(0, 0x0000, 0);
const floatx80 Const_1 = packFloatx80(0, 0x3fff, BX_CONST64(0x8000000000000000));
const floatx80 Const_L2T = packFloatx80(0, 0x4000, BX_CONST64(0xd49a784bcd1b8afe));
const floatx80 Const_L2E = packFloatx80(0, 0x3fff, BX_CONST64(0xb8aa3b295c17f0bc));
const floatx80 Const_PI = packFloatx80(0, 0x4000, BX_CONST64(0xc90fdaa22168c235));
const floatx80 Const_LG2 = packFloatx80(0, 0x3ffd, BX_CONST64(0x9a209a84fbcff799));
const floatx80 Const_LN2 = packFloatx80(0, 0x3ffe, BX_CONST64(0xb17217f7d1cf79ac));
const floatx80 Const_INF = packFloatx80(0, 0x7fff, BX_CONST64(0x8000000000000000));

View File

@@ -0,0 +1,258 @@
<HTML>
<HEAD>
<TITLE>Berkeley SoftFloat History</TITLE>
</HEAD>
<BODY>
<H1>History of Berkeley SoftFloat, to Release 3e</H1>
<P>
John R. Hauser<BR>
2018 January 20<BR>
</P>
<H3>Release 3e (2018 January)</H3>
<UL>
<LI>
Changed the default numeric code for optional rounding mode <CODE>odd</CODE>
(round to odd, also known as <EM>jamming</EM>) from 5 to 6.
<LI>
Modified the behavior of rounding mode <CODE>odd</CODE> when rounding to an
integer value (either conversion to an integer format or a
&lsquo;<CODE>roundToInt</CODE>&rsquo; function).
Previously, for those cases only, rounding mode <CODE>odd</CODE> acted the same
as rounding to minimum magnitude.
Now all operations are rounded consistently.
<LI>
Fixed some errors in the specialization code modeling Intel x86 floating-point,
specifically the integers returned on invalid operations and the propagation of
NaN payloads in a few rare cases.
<LI>
Added specialization code modeling ARM floating-point, conforming to VFPv2 or
later.
<LI>
Added an example target for ARM processors.
<LI>
Fixed a minor bug whereby function <CODE>f16_to_ui64</CODE> might return a
different integer than expected in the case that the floating-point operand is
negative.
<LI>
Added example target-specific optimization for GCC, employing GCC instrinsics
and support for <NOBR>128-bit</NOBR> integer arithmetic.
<LI>
Made other minor improvements.
</UL>
<H3>Release 3d (2017 August)</H3>
<UL>
<LI>
Fixed bugs in the square root functions for <NOBR>64-bit</NOBR>
double-precision, <NOBR>80-bit</NOBR> double-extended-precision, and
<NOBR>128-bit</NOBR> quadruple-precision.
For <NOBR>64-bit</NOBR> double-precision (<CODE>f64_sqrt</CODE>), the result
could sometimes be off by <NOBR>1 unit</NOBR> in the last place
(<NOBR>1 ulp</NOBR>) from what it should be.
For the larger formats, the square root could be wrong in a large portion of
the less-significant bits.
(A bug in <CODE>f128_sqrt</CODE> was first reported by Alexei Sibidanov.)
</UL>
<H3>Release 3c (2017 February)</H3>
<UL>
<LI>
Added optional rounding mode <CODE>odd</CODE> (round to odd, also known as
<EM>jamming</EM>).
<LI>
Corrected the documentation concerning non-canonical representations in
<NOBR>80-bit</NOBR> double-extended-precision.
</UL>
<H3>Release 3b (2016 July)</H3>
<UL>
<LI>
Implemented the common <NOBR>16-bit</NOBR> &ldquo;half-precision&rdquo;
floating-point format (<CODE>float16_t</CODE>).
<LI>
Made the integer values returned on invalid conversions to integer formats
be determined by the port-specific specialization instead of being the same for
all ports.
<LI>
Added preprocessor macro <CODE>THREAD_LOCAL</CODE> to allow the floating-point
state (modes and exception flags) to be made per-thread.
<LI>
Modified the provided Makefiles to allow some options to be overridden from the
<CODE>make</CODE> command.
<LI>
Made other minor improvements.
</UL>
<H3>Release 3a (2015 October)</H3>
<UL>
<LI>
Replaced the license text supplied by the University of California, Berkeley.
</UL>
<H3>Release 3 (2015 February)</H3>
<UL>
<LI>
Complete rewrite, funded by the University of California, Berkeley, and
consequently having a different use license than earlier releases.
Major changes included renaming most types and functions, upgrading some
algorithms, restructuring the source files, and making SoftFloat into a true
library.
<LI>
Added functions to convert between floating-point and unsigned integers, both
<NOBR>32-bit</NOBR> and <NOBR>64-bit</NOBR> (<CODE>uint32_t</CODE> and
<CODE>uint64_t</CODE>).
<LI>
Added functions for fused multiply-add, for all supported floating-point
formats except <NOBR>80-bit</NOBR> double-extended-precision.
<LI>
Added support for a fifth rounding mode, <CODE>near_maxMag</CODE> (round to
nearest, with ties to maximum magnitude, away from zero).
<LI>
Dropped the <CODE>timesoftfloat</CODE> program (now part of the Berkeley
TestFloat package).
</UL>
<H3>Release 2c (2015 January)</H3>
<UL>
<LI>
Fixed mistakes affecting some <NOBR>64-bit</NOBR> processors.
<LI>
Further improved the documentation and the wording for the legal restrictions
on using SoftFloat releases <NOBR>through 2c</NOBR> (not applicable to
<NOBR>Release 3</NOBR> or later).
</UL>
<H3>Release 2b (2002 May)</H3>
<UL>
<LI>
Made minor updates to the documentation, including improved wording for the
legal restrictions on using SoftFloat.
</UL>
<H3>Release 2a (1998 December)</H3>
<UL>
<LI>
Added functions to convert between <NOBR>64-bit</NOBR> integers
(<CODE>int64</CODE>) and all supported floating-point formats.
<LI>
Fixed a bug in all <NOBR>64-bit</NOBR>-version square root functions except
<CODE>float32_sqrt</CODE> that caused the result sometimes to be off by
<NOBR>1 unit</NOBR> in the last place (<NOBR>1 ulp</NOBR>) from what it should
be.
(Bug discovered by Paul Donahue.)
<LI>
Improved the Makefiles.
</UL>
<H3>Release 2 (1997 June)</H3>
<UL>
<LI>
Created the <NOBR>64-bit</NOBR> (<CODE>bits64</CODE>) version, adding the
<CODE>floatx80</CODE> and <CODE>float128</CODE> formats.
<LI>
Changed the source directory structure, splitting the sources into a
<CODE>bits32</CODE> and a <CODE>bits64</CODE> version.
Renamed <CODE>environment.h</CODE> to <CODE>milieu.h</CODE> to avoid confusion
with environment variables.
<LI>
Fixed a small error that caused <CODE>float64_round_to_int</CODE> often to
round the wrong way in nearest/even mode when the operand was between
2<SUP>20</SUP> and 2<SUP>21</SUP> and halfway between two integers.
</UL>
<H3>Release 1a (1996 July)</H3>
<UL>
<LI>
Corrected a mistake that caused borderline underflow cases not to raise the
underflow flag when they should have.
(Problem reported by Doug Priest.)
<LI>
Added the <CODE>float_detect_tininess</CODE> variable to control whether
tininess is detected before or after rounding.
</UL>
<H3>Release 1 (1996 July)</H3>
<UL>
<LI>
Original release, based on work done for the International Computer Science
Institute (ICSI) in Berkeley, California.
</UL>
</BODY>

View File

@@ -0,0 +1,686 @@
<HTML>
<HEAD>
<TITLE>Berkeley SoftFloat Source Documentation</TITLE>
</HEAD>
<BODY>
<H1>Berkeley SoftFloat Release 3e: Source Documentation</H1>
<P>
John R. Hauser<BR>
2018 January 20<BR>
</P>
<H2>Contents</H2>
<BLOCKQUOTE>
<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0>
<COL WIDTH=25>
<COL WIDTH=*>
<TR><TD COLSPAN=2>1. Introduction</TD></TR>
<TR><TD COLSPAN=2>2. Limitations</TD></TR>
<TR><TD COLSPAN=2>3. Acknowledgments and License</TD></TR>
<TR><TD COLSPAN=2>4. SoftFloat Package Directory Structure</TD></TR>
<TR><TD COLSPAN=2>5. Issues for Porting SoftFloat to a New Target</TD></TR>
<TR>
<TD></TD>
<TD>5.1. Standard Headers <CODE>&lt;stdbool.h&gt;</CODE> and
<CODE>&lt;stdint.h&gt;</CODE></TD>
</TR>
<TR><TD></TD><TD>5.2. Specializing Floating-Point Behavior</TD></TR>
<TR><TD></TD><TD>5.3. Macros for Build Options</TD></TR>
<TR><TD></TD><TD>5.4. Adapting a Template Target Directory</TD></TR>
<TR>
<TD></TD><TD>5.5. Target-Specific Optimization of Primitive Functions</TD>
</TR>
<TR><TD COLSPAN=2>6. Testing SoftFloat</TD></TR>
<TR>
<TD COLSPAN=2>7. Providing SoftFloat as a Common Library for Applications</TD>
</TR>
<TR><TD COLSPAN=2>8. Contact Information</TD></TR>
</TABLE>
</BLOCKQUOTE>
<H2>1. Introduction</H2>
<P>
This document gives information needed for compiling and/or porting Berkeley
SoftFloat, a library of C functions implementing binary floating-point
conforming to the IEEE Standard for Floating-Point Arithmetic.
For basic documentation about SoftFloat refer to
<A HREF="SoftFloat.html"><NOBR><CODE>SoftFloat.html</CODE></NOBR></A>.
</P>
<P>
The source code for SoftFloat is intended to be relatively machine-independent
and should be compilable with any ISO-Standard C compiler that also supports
<NOBR>64-bit</NOBR> integers.
SoftFloat has been successfully compiled with the GNU C Compiler
(<CODE>gcc</CODE>) for several platforms.
</P>
<P>
<NOBR>Release 3</NOBR> of SoftFloat was a complete rewrite relative to
<NOBR>Release 2</NOBR> or earlier.
Changes to the interface of SoftFloat functions are documented in
<A HREF="SoftFloat.html"><NOBR><CODE>SoftFloat.html</CODE></NOBR></A>.
The current version of SoftFloat is <NOBR>Release 3e</NOBR>.
</P>
<H2>2. Limitations</H2>
<P>
SoftFloat assumes the computer has an addressable byte size of either 8 or
<NOBR>16 bits</NOBR>.
(Nearly all computers in use today have <NOBR>8-bit</NOBR> bytes.)
</P>
<P>
SoftFloat is written in C and is designed to work with other C code.
The C compiler used must conform at a minimum to the 1989 ANSI standard for the
C language (same as the 1990 ISO standard) and must in addition support basic
arithmetic on <NOBR>64-bit</NOBR> integers.
Earlier releases of SoftFloat included implementations of <NOBR>32-bit</NOBR>
single-precision and <NOBR>64-bit</NOBR> double-precision floating-point that
did not require <NOBR>64-bit</NOBR> integers, but this option is not supported
starting with <NOBR>Release 3</NOBR>.
Since 1999, ISO standards for C have mandated compiler support for
<NOBR>64-bit</NOBR> integers.
A compiler conforming to the 1999 C Standard or later is recommended but not
strictly required.
</P>
<P>
<NOBR>C Standard</NOBR> header files <CODE>&lt;stdbool.h&gt;</CODE> and
<CODE>&lt;stdint.h&gt;</CODE> are required for defining standard Boolean and
integer types.
If these headers are not supplied with the C compiler, minimal substitutes must
be provided.
SoftFloat&rsquo;s dependence on these headers is detailed later in
<NOBR>section 5.1</NOBR>, <I>Standard Headers <CODE>&lt;stdbool.h&gt;</CODE>
and <CODE>&lt;stdint.h&gt;</CODE></I>.
</P>
<H2>3. Acknowledgments and License</H2>
<P>
The SoftFloat package was written by me, <NOBR>John R.</NOBR> Hauser.
<NOBR>Release 3</NOBR> of SoftFloat was a completely new implementation
supplanting earlier releases.
The project to create <NOBR>Release 3</NOBR> (now <NOBR>through 3e</NOBR>) was
done in the employ of the University of California, Berkeley, within the
Department of Electrical Engineering and Computer Sciences, first for the
Parallel Computing Laboratory (Par Lab) and then for the ASPIRE Lab.
The work was officially overseen by Prof. Krste Asanovic, with funding provided
by these sources:
<BLOCKQUOTE>
<TABLE>
<COL>
<COL WIDTH=10>
<COL>
<TR>
<TD VALIGN=TOP><NOBR>Par Lab:</NOBR></TD>
<TD></TD>
<TD>
Microsoft (Award #024263), Intel (Award #024894), and U.C. Discovery
(Award #DIG07-10227), with additional support from Par Lab affiliates Nokia,
NVIDIA, Oracle, and Samsung.
</TD>
</TR>
<TR>
<TD VALIGN=TOP><NOBR>ASPIRE Lab:</NOBR></TD>
<TD></TD>
<TD>
DARPA PERFECT program (Award #HR0011-12-2-0016), with additional support from
ASPIRE industrial sponsor Intel and ASPIRE affiliates Google, Nokia, NVIDIA,
Oracle, and Samsung.
</TD>
</TR>
</TABLE>
</BLOCKQUOTE>
</P>
<P>
The following applies to the whole of SoftFloat <NOBR>Release 3e</NOBR> as well
as to each source file individually.
</P>
<P>
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the
University of California.
All rights reserved.
</P>
<P>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
<OL>
<LI>
<P>
Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.
</P>
<LI>
<P>
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions, and the following disclaimer in the documentation and/or
other materials provided with the distribution.
</P>
<LI>
<P>
Neither the name of the University nor the names of its contributors may be
used to endorse or promote products derived from this software without specific
prior written permission.
</P>
</OL>
</P>
<P>
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS &ldquo;AS IS&rdquo;,
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED.
IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</P>
<H2>4. SoftFloat Package Directory Structure</H2>
<P>
Because SoftFloat is targeted to multiple platforms, its source code is
slightly scattered between target-specific and target-independent directories
and files.
The supplied directory structure is as follows:
<BLOCKQUOTE>
<PRE>
doc
source
include
8086
8086-SSE
ARM-VFPv2
ARM-VFPv2-defaultNaN
build
template-FAST_INT64
template-not-FAST_INT64
Linux-386-GCC
Linux-386-SSE2-GCC
Linux-x86_64-GCC
Linux-ARM-VFPv2-GCC
Win32-MinGW
Win32-SSE2-MinGW
Win64-MinGW-w64
</PRE>
</BLOCKQUOTE>
The majority of the SoftFloat sources are provided in the <CODE>source</CODE>
directory.
The <CODE>include</CODE> subdirectory contains several header files
(unsurprisingly), while the other subdirectories of <CODE>source</CODE> contain
source files that specialize the floating-point behavior to match particular
processor families:
<BLOCKQUOTE>
<DL>
<DT><CODE>8086</CODE></DT>
<DD>
Intel&rsquo;s older, 8087-derived floating-point, extended to all supported
floating-point types
</DD>
<DT><CODE>8086-SSE</CODE></DT>
<DD>
Intel&rsquo;s x86 processors with Streaming SIMD Extensions (SSE) and later
compatible extensions, having 8087 behavior for <NOBR>80-bit</NOBR>
double-extended-precision (<CODE>extFloat80_t</CODE>) and SSE behavior for
other floating-point types
</DD>
<DT><CODE>ARM-VFPv2</CODE></DT>
<DD>
ARM&rsquo;s VFPv2 or later floating-point, with NaN payload propagation
</DD>
<DT><CODE>ARM-VFPv2-defaultNaN</CODE></DT>
<DD>
ARM&rsquo;s VFPv2 or later floating-point, with the &ldquo;default NaN&rdquo;
option
</DD>
</DL>
</BLOCKQUOTE>
If other specializations are attempted, these would be expected to be other
subdirectories of <CODE>source</CODE> alongside the ones listed above.
Specialization is covered later, in <NOBR>section 5.2</NOBR>, <I>Specializing
Floating-Point Behavior</I>.
</P>
<P>
The <CODE>build</CODE> directory is intended to contain a subdirectory for each
target platform for which a build of the SoftFloat library may be created.
For each build target, the target&rsquo;s subdirectory is where all derived
object files and the completed SoftFloat library (typically
<CODE>softfloat.a</CODE> or <CODE>libsoftfloat.a</CODE>) are created.
The two <CODE>template</CODE> subdirectories are not actual build targets but
contain sample files for creating new target directories.
(The meaning of <CODE>FAST_INT64</CODE> will be explained later.)
</P>
<P>
Ignoring the <CODE>template</CODE> directories, the supplied target directories
are intended to follow a naming system of
<NOBR><CODE>&lt;<I>execution-environment</I>&gt;-&lt;<I>compiler</I>&gt;</CODE></NOBR>.
For the example targets,
<NOBR><CODE>&lt;<I>execution-environment</I>&gt;</CODE></NOBR> is
<NOBR><CODE>Linux-386</CODE></NOBR>, <NOBR><CODE>Linux-386-SSE2</CODE></NOBR>,
<NOBR><CODE>Linux-x86_64</CODE></NOBR>,
<NOBR><CODE>Linux-ARM-VFPv2</CODE></NOBR>, <CODE>Win32</CODE>,
<NOBR><CODE>Win32-SSE2</CODE></NOBR>, or <CODE>Win64</CODE>, and
<NOBR><CODE>&lt;<I>compiler</I>&gt;</CODE></NOBR> is <CODE>GCC</CODE>,
<CODE>MinGW</CODE>, or <NOBR><CODE>MinGW-w64</CODE></NOBR>.
</P>
<P>
All of the supplied target directories are merely examples that may or may not
be correct for compiling on any particular system.
Despite requests, there are currently no plans to include and maintain in the
SoftFloat package the build files needed for a great many users&rsquo;
compilation environments, which can span a huge range of operating systems,
compilers, and other tools.
</P>
<P>
As supplied, each target directory contains two files:
<BLOCKQUOTE>
<PRE>
Makefile
platform.h
</PRE>
</BLOCKQUOTE>
The provided <CODE>Makefile</CODE> is written for GNU <CODE>make</CODE>.
A build of SoftFloat for the specific target is begun by executing the
<CODE>make</CODE> command with the target directory as the current directory.
A completely different build tool can be used if an appropriate
<CODE>Makefile</CODE> equivalent is created.
</P>
<P>
The <CODE>platform.h</CODE> header file exists to provide a location for
additional C declarations specific to the build target.
Every C source file of SoftFloat contains a <CODE>#include</CODE> for
<CODE>platform.h</CODE>.
In many cases, the contents of <CODE>platform.h</CODE> can be as simple as one
or two lines of code.
At the other extreme, to get maximal performance from SoftFloat, it may be
desirable to include in header <CODE>platform.h</CODE> (directly or via
<CODE>#include</CODE>) declarations for numerous target-specific optimizations.
Such possibilities are discussed in the next section, <I>Issues for Porting
SoftFloat to a New Target</I>.
If the target&rsquo;s compiler or library has bugs or other shortcomings,
workarounds for these issues may also be possible with target-specific
declarations in <CODE>platform.h</CODE>, avoiding the need to modify the main
SoftFloat sources.
</P>
<H2>5. Issues for Porting SoftFloat to a New Target</H2>
<H3>5.1. Standard Headers <CODE>&lt;stdbool.h&gt;</CODE> and <CODE>&lt;stdint.h&gt;</CODE></H3>
<P>
The SoftFloat sources make use of standard headers
<CODE>&lt;stdbool.h&gt;</CODE> and <CODE>&lt;stdint.h&gt;</CODE>, which have
been part of the ISO C Standard Library since 1999.
With any recent compiler, these standard headers are likely to be supported,
even if the compiler does not claim complete conformance to the latest ISO C
Standard.
For older or nonstandard compilers, substitutes for
<CODE>&lt;stdbool.h&gt;</CODE> and <CODE>&lt;stdint.h&gt;</CODE> may need to be
created.
SoftFloat depends on these names from <CODE>&lt;stdbool.h&gt;</CODE>:
<BLOCKQUOTE>
<PRE>
bool
true
false
</PRE>
</BLOCKQUOTE>
and on these names from <CODE>&lt;stdint.h&gt;</CODE>:
<BLOCKQUOTE>
<PRE>
uint16_t
uint32_t
uint64_t
int32_t
int64_t
UINT64_C
INT64_C
uint_least8_t
uint_fast8_t
uint_fast16_t
uint_fast32_t
uint_fast64_t
int_fast8_t
int_fast16_t
int_fast32_t
int_fast64_t
</PRE>
</BLOCKQUOTE>
</P>
<H3>5.2. Specializing Floating-Point Behavior</H3>
<P>
The IEEE Floating-Point Standard allows for some flexibility in a conforming
implementation, particularly concerning NaNs.
The SoftFloat <CODE>source</CODE> directory is supplied with some
<I>specialization</I> subdirectories containing possible definitions for this
implementation-specific behavior.
For example, the <CODE>8086</CODE> and <NOBR><CODE>8086-SSE</CODE></NOBR>
subdirectories have source files that specialize SoftFloat&rsquo;s behavior to
match that of Intel&rsquo;s x86 line of processors.
The files in a specialization subdirectory must determine:
<UL>
<LI>
whether tininess for underflow is detected before or after rounding by default;
<LI>
how signaling NaNs are distinguished from quiet NaNs;
<LI>
what (if anything) special happens when exceptions are raised;
<LI>
the default generated quiet NaNs;
<LI>
how NaNs are propagated from function inputs to output; and
<LI>
the integer results returned when conversions to integer type raise the
<I>invalid</I> exception.
</UL>
</P>
<P>
As provided, the build process for a target expects to involve exactly
<EM>one</EM> specialization directory that defines <EM>all</EM> of these
implementation-specific details for the target.
A specialization directory such as <CODE>8086</CODE> is expected to contain a
header file called <CODE>specialize.h</CODE>, together with whatever other
source files are needed to complete the specialization.
</P>
<P>
A new build target may use an existing specialization, such as the ones
provided by the <CODE>8086</CODE> and <NOBR><CODE>8086-SSE</CODE></NOBR>
subdirectories.
If a build target needs a new specialization, different from any existing ones,
it is recommended that a new specialization directory be created for this
purpose.
The <CODE>specialize.h</CODE> header file from any of the provided
specialization subdirectories can be used as a model for what definitions are
needed.
</P>
<H3>5.3. Macros for Build Options</H3>
<P>
The SoftFloat source files adapt the floating-point implementation according to
several C preprocessor macros:
<BLOCKQUOTE>
<DL>
<DT><CODE>LITTLEENDIAN</CODE>
<DD>
Must be defined for little-endian machines; must not be defined for big-endian
machines.
<DT><CODE>INLINE</CODE>
<DD>
Specifies the sequence of tokens used to indicate that a C function should be
inlined.
If macro <CODE>INLINE_LEVEL</CODE> is defined with a value of 1 or higher, this
macro must be defined; otherwise, this macro is ignored and need not be
defined.
For compilers that conform to the C Standard&rsquo;s rules for inline
functions, this macro can be defined as the single keyword <CODE>inline</CODE>.
For other compilers that follow a convention pre-dating the standardization of
<CODE>inline</CODE>, this macro may need to be defined to <CODE>extern</CODE>
<CODE>inline</CODE>.
<DT><CODE>THREAD_LOCAL</CODE>
<DD>
Can be defined to a sequence of tokens that, when appearing at the start of a
variable declaration, indicates to the C compiler that the variable is
<I>per-thread</I>, meaning that each execution thread gets its own separate
instance of the variable.
This macro is used in header <CODE>softfloat.h</CODE> in the declarations of
variables <CODE>softfloat_roundingMode</CODE>,
<CODE>softfloat_detectTininess</CODE>, <CODE>extF80_roundingPrecision</CODE>,
and <CODE>softfloat_exceptionFlags</CODE>.
If macro <CODE>THREAD_LOCAL</CODE> is left undefined, these variables will
default to being ordinary global variables.
Depending on the compiler, possible valid definitions of this macro include
<CODE>_Thread_local</CODE> and <CODE>__thread</CODE>.
</DL>
<DL>
<DT><CODE>SOFTFLOAT_ROUND_ODD</CODE>
<DD>
Can be defined to enable support for optional rounding mode
<CODE>softfloat_round_odd</CODE>.
</DL>
<DL>
<DT><CODE>INLINE_LEVEL</CODE>
<DD>
Can be defined to an integer to determine the degree of inlining requested of
the compiler.
Larger numbers request that more inlining be done.
If this macro is not defined or is defined to a value less <NOBR>than 1</NOBR>
(zero or negative), no inlining is requested.
The maximum effective value is no higher <NOBR>than 5</NOBR>.
Defining this macro to a value greater than 5 is the same as defining it
<NOBR>to 5</NOBR>.
<DT><CODE>SOFTFLOAT_FAST_INT64</CODE>
<DD>
Can be defined to indicate that the build target&rsquo;s implementation of
<NOBR>64-bit</NOBR> arithmetic is efficient.
For newer <NOBR>64-bit</NOBR> processors, this macro should usually be defined.
For very small microprocessors whose buses and registers are <NOBR>8-bit</NOBR>
or <NOBR>16-bit</NOBR> in size, this macro should usually not be defined.
Whether this macro should be defined for a <NOBR>32-bit</NOBR> processor may
depend on the target machine and the applications that will use SoftFloat.
<DT><CODE>SOFTFLOAT_FAST_DIV32TO16</CODE>
<DD>
Can be defined to indicate that the target&rsquo;s division operator
<NOBR>in C</NOBR> (written as <CODE>/</CODE>) is reasonably efficient for
dividing a <NOBR>32-bit</NOBR> unsigned integer by a <NOBR>16-bit</NOBR>
unsigned integer.
Setting this macro may affect the performance of function <CODE>f16_div</CODE>.
<DT><CODE>SOFTFLOAT_FAST_DIV64TO32</CODE>
<DD>
Can be defined to indicate that the target&rsquo;s division operator
<NOBR>in C</NOBR> (written as <CODE>/</CODE>) is reasonably efficient for
dividing a <NOBR>64-bit</NOBR> unsigned integer by a <NOBR>32-bit</NOBR>
unsigned integer.
Setting this macro may affect the performance of division, remainder, and
square root operations other than <CODE>f16_div</CODE>.
</DL>
</BLOCKQUOTE>
</P>
<P>
Following the usual custom <NOBR>for C</NOBR>, for most of these macros (all
except <CODE>INLINE</CODE>, <CODE>THREAD_LOCAL</CODE>, and
<CODE>INLINE_LEVEL</CODE>), the content of any definition is irrelevant;
what matters is a macro&rsquo;s effect on <CODE>#ifdef</CODE> directives.
</P>
<P>
It is recommended that any definitions of macros <CODE>LITTLEENDIAN</CODE>,
<CODE>INLINE</CODE>, and <CODE>THREAD_LOCAL</CODE> be made in a build
target&rsquo;s <CODE>platform.h</CODE> header file, because these macros are
expected to be determined inflexibly by the target machine and compiler.
The other five macros select options and control optimization, and thus might
be better located in the target&rsquo;s Makefile (or its equivalent).
</P>
<H3>5.4. Adapting a Template Target Directory</H3>
<P>
In the <CODE>build</CODE> directory, two <CODE>template</CODE> subdirectories
provide models for new target directories.
Two different templates exist because different functions are needed in the
SoftFloat library depending on whether macro <CODE>SOFTFLOAT_FAST_INT64</CODE>
is defined.
If macro <CODE>SOFTFLOAT_FAST_INT64</CODE> will be defined,
<NOBR><CODE>template-FAST_INT64</CODE></NOBR> is the template to use;
otherwise, <NOBR><CODE>template-not-FAST_INT64</CODE></NOBR> is the appropriate
template.
A new target directory can be created by copying the correct template directory
and editing the files inside.
To avoid confusion, it would be wise to refrain from editing the files within a
template directory directly.
</P>
<H3>5.5. Target-Specific Optimization of Primitive Functions</H3>
<P>
Header file <CODE>primitives.h</CODE> (in directory
<CODE>source/include</CODE>) declares macros and functions for numerous
underlying arithmetic operations upon which many of SoftFloat&rsquo;s
floating-point functions are ultimately built.
The SoftFloat sources include implementations of all of these functions/macros,
written as standard C code, so a complete and correct SoftFloat library can be
created using only the supplied code for all functions.
However, for many targets, SoftFloat&rsquo;s performance can be improved by
substituting target-specific implementations of some of the functions/macros
declared in <CODE>primitives.h</CODE>.
</P>
<P>
For example, <CODE>primitives.h</CODE> declares a function called
<CODE>softfloat_countLeadingZeros32</CODE> that takes an unsigned
<NOBR>32-bit</NOBR> integer as an argument and returns the number of the
integer&rsquo;s most-significant bits that are zeros.
While the SoftFloat sources include an implementation of this function written
in <NOBR>standard C</NOBR>, many processors can perform this same function
directly in only one or two machine instructions.
An alternative, target-specific implementation that maps to those instructions
is likely to be more efficient than the generic C code from the SoftFloat
package.
</P>
<P>
A build target can replace the supplied version of any function or macro of
<CODE>primitives.h</CODE> by defining a macro with the same name in the
target&rsquo;s <CODE>platform.h</CODE> header file.
For this purpose, it may be helpful for <CODE>platform.h</CODE> to
<CODE>#include</CODE> header file <CODE>primitiveTypes.h</CODE>, which defines
types used for arguments and results of functions declared in
<CODE>primitives.h</CODE>.
When a desired replacement implementation is a function, not a macro, it is
sufficient for <CODE>platform.h</CODE> to include the line
<BLOCKQUOTE>
<PRE>
#define &lt;<I>function-name</I>&gt; &lt;<I>function-name</I>&gt;
</PRE>
</BLOCKQUOTE>
where <NOBR><CODE>&lt;<I>function-name</I>&gt;</CODE></NOBR> is the name of the
function.
This technically defines <NOBR><CODE>&lt;<I>function-name</I>&gt;</CODE></NOBR>
as a macro, but one that resolves to the same name, which may then be a
function.
(A preprocessor that conforms to the C Standard is required to limit recursive
macro expansion from being applied more than once.)
</P>
<P>
The supplied header file <CODE>opts-GCC.h</CODE> (in directory
<CODE>source/include</CODE>) provides an example of target-specific
optimization for the GCC compiler.
Each GCC target example in the <CODE>build</CODE> directory has
<BLOCKQUOTE>
<CODE>#include "opts-GCC.h"</CODE>
</BLOCKQUOTE>
in its <CODE>platform.h</CODE> header file.
Before <CODE>opts-GCC.h</CODE> is included, the following macros must be
defined (or not) to control which features are invoked:
<BLOCKQUOTE>
<DL>
<DT><CODE>SOFTFLOAT_BUILTIN_CLZ</CODE></DT>
<DD>
If defined, SoftFloat&rsquo;s internal
&lsquo;<CODE>countLeadingZeros</CODE>&rsquo; functions use intrinsics
<CODE>__builtin_clz</CODE> and <CODE>__builtin_clzll</CODE>.
</DD>
<DT><CODE>SOFTFLOAT_INTRINSIC_INT128</CODE></DT>
<DD>
If defined, SoftFloat makes use of GCC&rsquo;s nonstandard <NOBR>128-bit</NOBR>
integer type <CODE>__int128</CODE>.
</DD>
</DL>
</BLOCKQUOTE>
On some machines, these improvements are observed to increase the speeds of
<CODE>f64_mul</CODE> and <CODE>f128_mul</CODE> by around 20 to 25%, although
other functions receive less dramatic boosts, or none at all.
Results can vary greatly across different platforms.
</P>
<H2>6. Testing SoftFloat</H2>
<P>
SoftFloat can be tested using the <CODE>testsoftfloat</CODE> program by the
same author.
This program is part of the Berkeley TestFloat package available at the Web
page
<A HREF="http://www.jhauser.us/arithmetic/TestFloat.html"><NOBR><CODE>http://www.jhauser.us/arithmetic/TestFloat.html</CODE></NOBR></A>.
The TestFloat package also has a program called <CODE>timesoftfloat</CODE> that
measures the speed of SoftFloat&rsquo;s floating-point functions.
</P>
<H2>7. Providing SoftFloat as a Common Library for Applications</H2>
<P>
Header file <CODE>softfloat.h</CODE> defines the SoftFloat interface as seen by
clients.
If the SoftFloat library will be made a common library for programs on a
system, the supplied <CODE>softfloat.h</CODE> has a couple of deficiencies for
this purpose:
<UL>
<LI>
As supplied, <CODE>softfloat.h</CODE> depends on another header,
<CODE>softfloat_types.h</CODE>, that is not intended for public use but which
must also be visible to the programmer&rsquo;s compiler.
<LI>
More troubling, at the time <CODE>softfloat.h</CODE> is included in a C source
file, macros <CODE>SOFTFLOAT_FAST_INT64</CODE> and <CODE>THREAD_LOCAL</CODE>
must be defined, or not defined, consistent with how these macro were defined
when the SoftFloat library was built.
</UL>
In the situation that new programs may regularly <CODE>#include</CODE> header
file <CODE>softfloat.h</CODE>, it is recommended that a custom, self-contained
version of this header file be created that eliminates these issues.
</P>
<H2>8. Contact Information</H2>
<P>
At the time of this writing, the most up-to-date information about SoftFloat
and the latest release can be found at the Web page
<A HREF="http://www.jhauser.us/arithmetic/SoftFloat.html"><NOBR><CODE>http://www.jhauser.us/arithmetic/SoftFloat.html</CODE></NOBR></A>.
</P>
</BODY>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,106 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
extern extFloat80_t softfloat_addMagsExtF80(uint16_t, uint64_t, uint16_t, uint64_t, bool, struct softfloat_status_t *);
extern extFloat80_t softfloat_subMagsExtF80(uint16_t, uint64_t, uint16_t, uint64_t, bool, struct softfloat_status_t *);
extFloat80_t extF80_add(extFloat80_t a, extFloat80_t b, struct softfloat_status_t *status)
{
uint16_t uiA64;
uint64_t uiA0;
bool signA;
uint16_t uiB64;
uint64_t uiB0;
bool signB;
// handle unsupported extended double-precision floating encodings
if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
a.signExp = defaultNaNExtF80UI64;
a.signif = defaultNaNExtF80UI0;
return a;
}
uiA64 = a.signExp;
uiA0 = a.signif;
signA = signExtF80UI64(uiA64);
uiB64 = b.signExp;
uiB0 = b.signif;
signB = signExtF80UI64(uiB64);
if (signA == signB) {
return softfloat_addMagsExtF80(uiA64, uiA0, uiB64, uiB0, signA, status);
} else {
return softfloat_subMagsExtF80(uiA64, uiA0, uiB64, uiB0, signA, status);
}
}
extFloat80_t extF80_sub(extFloat80_t a, extFloat80_t b, struct softfloat_status_t *status)
{
uint16_t uiA64;
uint64_t uiA0;
bool signA;
uint16_t uiB64;
uint64_t uiB0;
bool signB;
// handle unsupported extended double-precision floating encodings
if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
a.signExp = defaultNaNExtF80UI64;
a.signif = defaultNaNExtF80UI0;
return a;
}
uiA64 = a.signExp;
uiA0 = a.signif;
signA = signExtF80UI64(uiA64);
uiB64 = b.signExp;
uiB0 = b.signif;
signB = signExtF80UI64(uiB64);
if (signA == signB) {
return softfloat_subMagsExtF80(uiA64, uiA0, uiB64, uiB0, signA, status);
} else {
return softfloat_addMagsExtF80(uiA64, uiA0, uiB64, uiB0, signA, status);
}
}

View File

@@ -0,0 +1,71 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdint.h>
#include "internals.h"
#include "softfloat.h"
softfloat_class_t extF80_class(extFloat80_t a)
{
uint16_t uiA64;
uint64_t uiA0;
bool signA;
int32_t expA;
uint64_t sigA;
uiA64 = a.signExp;
uiA0 = a.signif;
signA = signExtF80UI64(uiA64);
expA = expExtF80UI64(uiA64);
sigA = uiA0;
if (! expA) {
if (! sigA) return softfloat_zero;
return softfloat_denormal; /* denormal or pseudo-denormal */
}
/* valid numbers have the MS bit set */
if (!(sigA & UINT64_C(0x8000000000000000)))
return softfloat_SNaN; /* report unsupported as SNaNs */
if (expA == 0x7FFF) {
if ((sigA<<1) == 0)
return (signA) ? softfloat_negative_inf : softfloat_positive_inf;
return (sigA & UINT64_C(0x4000000000000000)) ? softfloat_QNaN : softfloat_SNaN;
}
return softfloat_normalized;
}

View File

@@ -0,0 +1,147 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdio.h>
#include <stdint.h>
#include <86box/86box.h>
#include "../cpu.h"
#include "internals.h"
#include "softfloat.h"
/*----------------------------------------------------------------------------
| Compare between two extended precision floating point numbers. Returns
| 'float_relation_equal' if the operands are equal, 'float_relation_less' if
| the value 'a' is less than the corresponding value `b',
| 'float_relation_greater' if the value 'a' is greater than the corresponding
| value `b', or 'float_relation_unordered' otherwise.
*----------------------------------------------------------------------------*/
int extF80_compare(extFloat80_t a, extFloat80_t b, int quiet, struct softfloat_status_t *status)
{
uint16_t uiA64;
uint64_t uiA0;
bool signA;
int32_t expA;
uint64_t sigA;
uint16_t uiB64;
uint64_t uiB0;
bool signB;
int32_t expB;
uint64_t sigB;
struct exp32_sig64 normExpSig;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
softfloat_class_t aClass = extF80_class(a);
softfloat_class_t bClass = extF80_class(b);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (fpu_type < FPU_287XL) {
if ((aClass == softfloat_positive_inf) && (bClass == softfloat_negative_inf))
{
return softfloat_relation_equal;
}
if ((aClass == softfloat_negative_inf) && (bClass == softfloat_positive_inf))
{
return softfloat_relation_equal;
}
}
if (aClass == softfloat_SNaN || bClass == softfloat_SNaN)
{
/* unsupported reported as SNaN */
softfloat_raiseFlags(status, softfloat_flag_invalid);
return softfloat_relation_unordered;
}
if (aClass == softfloat_QNaN || bClass == softfloat_QNaN) {
if (! quiet) softfloat_raiseFlags(status, softfloat_flag_invalid);
return softfloat_relation_unordered;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (aClass == softfloat_denormal || bClass == softfloat_denormal) {
softfloat_raiseFlags(status, softfloat_flag_denormal);
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiA64 = a.signExp;
uiA0 = a.signif;
signA = signExtF80UI64(uiA64);
expA = expExtF80UI64(uiA64);
sigA = uiA0;
uiB64 = b.signExp;
uiB0 = b.signif;
signB = signExtF80UI64(uiB64);
expB = expExtF80UI64(uiB64);
sigB = uiB0;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (aClass == softfloat_zero) {
if (bClass == softfloat_zero) return softfloat_relation_equal;
return signB ? softfloat_relation_greater : softfloat_relation_less;
}
if (bClass == softfloat_zero || signA != signB) {
return signA ? softfloat_relation_less : softfloat_relation_greater;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (aClass == softfloat_denormal) {
normExpSig = softfloat_normSubnormalExtF80Sig(sigA);
expA += normExpSig.exp + 1;
sigA = normExpSig.sig;
}
if (bClass == softfloat_denormal) {
normExpSig = softfloat_normSubnormalExtF80Sig(sigB);
expB += normExpSig.exp + 1;
sigB = normExpSig.sig;
}
if (expA == expB && sigA == sigB)
return softfloat_relation_equal;
int less_than =
signA ? ((expB < expA) || ((expB == expA) && (sigB < sigA)))
: ((expA < expB) || ((expA == expB) && (sigA < sigB)));
if (less_than) return softfloat_relation_less;
return softfloat_relation_greater;
}

View File

@@ -0,0 +1,188 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdint.h>
#include "internals.h"
#include "primitives.h"
#include "specialize.h"
#include "softfloat.h"
extFloat80_t extF80_div(extFloat80_t a, extFloat80_t b, struct softfloat_status_t *status)
{
uint16_t uiA64;
uint64_t uiA0;
bool signA;
int32_t expA;
uint64_t sigA;
uint16_t uiB64;
uint64_t uiB0;
bool signB;
int32_t expB;
uint64_t sigB;
bool signZ;
struct exp32_sig64 normExpSig;
int32_t expZ;
struct uint128 rem;
uint32_t recip32;
uint64_t sigZ;
int ix;
uint64_t q64;
uint32_t q;
struct uint128 term;
uint64_t sigZExtra;
// handle unsupported extended double-precision floating encodings
if (extF80_isUnsupported(a) || extF80_isUnsupported(b))
goto invalid;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiA64 = a.signExp;
uiA0 = a.signif;
signA = signExtF80UI64(uiA64);
expA = expExtF80UI64(uiA64);
sigA = uiA0;
uiB64 = b.signExp;
uiB0 = b.signif;
signB = signExtF80UI64(uiB64);
expB = expExtF80UI64(uiB64);
sigB = uiB0;
signZ = signA ^ signB;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (expA == 0x7FFF) {
if (sigA & UINT64_C(0x7FFFFFFFFFFFFFFF)) goto propagateNaN;
if (expB == 0x7FFF) {
if (sigB & UINT64_C(0x7FFFFFFFFFFFFFFF)) goto propagateNaN;
goto invalid;
}
if (! expB && sigB)
softfloat_raiseFlags(status, softfloat_flag_denormal);
return packToExtF80(signZ, 0x7FFF, UINT64_C(0x8000000000000000));
}
if (expB == 0x7FFF) {
if (sigB & UINT64_C(0x7FFFFFFFFFFFFFFF)) goto propagateNaN;
if (! expA && sigA)
softfloat_raiseFlags(status, softfloat_flag_denormal);
return packToExtF80(signZ, 0, 0);
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (! expB) {
expB = 1;
if (sigB)
softfloat_raiseFlags(status, softfloat_flag_denormal);
}
if (! (sigB & UINT64_C(0x8000000000000000))) {
if (! sigB) {
if (! sigA) goto invalid;
softfloat_raiseFlags(status, softfloat_flag_infinite);
return packToExtF80(signZ, 0x7FFF, UINT64_C(0x8000000000000000));
}
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalExtF80Sig(sigB);
expB += normExpSig.exp;
sigB = normExpSig.sig;
}
if (! expA) {
expA = 1;
if (sigA)
softfloat_raiseFlags(status, softfloat_flag_denormal);
}
if (! (sigA & UINT64_C(0x8000000000000000))) {
if (! sigA) return packToExtF80(signZ, 0, 0);
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalExtF80Sig(sigA);
expA += normExpSig.exp;
sigA = normExpSig.sig;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
expZ = expA - expB + 0x3FFF;
if (sigA < sigB) {
--expZ;
rem = softfloat_shortShiftLeft128(0, sigA, 32);
} else {
rem = softfloat_shortShiftLeft128(0, sigA, 31);
}
recip32 = softfloat_approxRecip32_1(sigB>>32);
sigZ = 0;
ix = 2;
for (;;) {
q64 = (uint64_t) (uint32_t) (rem.v64>>2) * recip32;
q = (q64 + 0x80000000)>>32;
--ix;
if (ix < 0) break;
rem = softfloat_shortShiftLeft128(rem.v64, rem.v0, 29);
term = softfloat_mul64ByShifted32To128(sigB, q);
rem = softfloat_sub128(rem.v64, rem.v0, term.v64, term.v0);
if (rem.v64 & UINT64_C(0x8000000000000000)) {
--q;
rem = softfloat_add128(rem.v64, rem.v0, sigB>>32, sigB<<32);
}
sigZ = (sigZ<<29) + q;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (((q + 1) & 0x3FFFFF) < 2) {
rem = softfloat_shortShiftLeft128(rem.v64, rem.v0, 29);
term = softfloat_mul64ByShifted32To128(sigB, q);
rem = softfloat_sub128(rem.v64, rem.v0, term.v64, term.v0);
term = softfloat_shortShiftLeft128(0, sigB, 32);
if (rem.v64 & UINT64_C(0x8000000000000000)) {
--q;
rem = softfloat_add128(rem.v64, rem.v0, term.v64, term.v0);
} else if (softfloat_le128(term.v64, term.v0, rem.v64, rem.v0)) {
++q;
rem = softfloat_sub128(rem.v64, rem.v0, term.v64, term.v0);
}
if (rem.v64 | rem.v0) q |= 1;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sigZ = (sigZ<<6) + (q>>23);
sigZExtra = (uint64_t) ((uint64_t) q<<41);
return
softfloat_roundPackToExtF80(signZ, expZ, sigZ, sigZExtra, softfloat_extF80_roundingPrecision(status), status);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
propagateNaN:
return softfloat_propagateNaNExtF80UI(uiA64, uiA0, uiB64, uiB0, status);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
invalid:
softfloat_raiseFlags(status, softfloat_flag_invalid);
return packToExtF80_twoargs(defaultNaNExtF80UI64, defaultNaNExtF80UI0);
}

View File

@@ -0,0 +1,97 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
/*----------------------------------------------------------------------------
| Separate the source extended double-precision floating point value `a'
| into its exponent and significand, store the significant back to the
| 'a' and return the exponent. The operation performed is a superset of
| the IEC/IEEE recommended logb(x) function.
*----------------------------------------------------------------------------*/
extFloat80_t extF80_extract(extFloat80_t *a, struct softfloat_status_t *status)
{
uint16_t uiA64;
uint64_t uiA0;
bool signA;
int32_t expA;
uint64_t sigA;
struct exp32_sig64 normExpSig;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
// handle unsupported extended double-precision floating encodings
if (extF80_isUnsupported(*a)) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
*a = packToExtF80_twoargs(defaultNaNExtF80UI64, defaultNaNExtF80UI0);
return *a;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiA64 = a->signExp;
uiA0 = a->signif;
signA = signExtF80UI64(uiA64);
expA = expExtF80UI64(uiA64);
sigA = uiA0;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (expA == 0x7FFF) {
if (sigA<<1) {
*a = softfloat_propagateNaNExtF80UI(uiA64, uiA0, 0, 0, status);
return *a;
}
return packToExtF80(0, 0x7FFF, BX_CONST64(0x8000000000000000));
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (! expA) {
if (! sigA) {
softfloat_raiseFlags(status, softfloat_flag_divbyzero);
*a = packToExtF80(signA, 0, 0);
return packToExtF80(1, 0x7FFF, BX_CONST64(0x8000000000000000));
}
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalExtF80Sig(sigA);
expA = normExpSig.exp + 1;
sigA = normExpSig.sig;
}
*a = packToExtF80(signA, 0x3FFF, sigA);
return i32_to_extF80(expA - 0x3FFF);
}

View File

@@ -0,0 +1,153 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdint.h>
#include "internals.h"
#include "primitives.h"
#include "specialize.h"
#include "softfloat.h"
extFloat80_t extF80_mul(extFloat80_t a, extFloat80_t b, struct softfloat_status_t *status)
{
uint16_t uiA64;
uint64_t uiA0;
bool signA;
int32_t expA;
uint64_t sigA;
uint16_t uiB64;
uint64_t uiB0;
bool signB;
int32_t expB;
uint64_t sigB;
bool signZ;
uint64_t magBits;
struct exp32_sig64 normExpSig;
int32_t expZ;
struct uint128 sig128Z;
uint16_t uiZ64;
uint64_t uiZ0;
// handle unsupported extended double-precision floating encodings
if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return packToExtF80_twoargs(defaultNaNExtF80UI64, defaultNaNExtF80UI0);
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiA64 = a.signExp;
uiA0 = a.signif;
signA = signExtF80UI64(uiA64);
expA = expExtF80UI64(uiA64);
sigA = uiA0;
uiB64 = b.signExp;
uiB0 = b.signif;
signB = signExtF80UI64(uiB64);
expB = expExtF80UI64(uiB64);
sigB = uiB0;
signZ = signA ^ signB;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (expA == 0x7FFF) {
if ((sigA & UINT64_C(0x7FFFFFFFFFFFFFFF)) || ((expB == 0x7FFF) && (sigB & UINT64_C(0x7FFFFFFFFFFFFFFF)))) {
goto propagateNaN;
}
magBits = expB | sigB;
goto infArg;
}
if (expB == 0x7FFF) {
if (sigB & UINT64_C(0x7FFFFFFFFFFFFFFF)) goto propagateNaN;
magBits = expA | sigA;
goto infArg;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (! expA) {
expA = 1;
if (sigA)
softfloat_raiseFlags(status, softfloat_flag_denormal);
}
if (! (sigA & UINT64_C(0x8000000000000000))) {
if (! sigA) {
if (! expB && sigB)
softfloat_raiseFlags(status, softfloat_flag_denormal);
return packToExtF80(signZ, 0, 0);
}
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalExtF80Sig(sigA);
expA += normExpSig.exp;
sigA = normExpSig.sig;
}
if (! expB) {
expB = 1;
if (sigB)
softfloat_raiseFlags(status, softfloat_flag_denormal);
}
if (! (sigB & UINT64_C(0x8000000000000000))) {
if (! sigB) return packToExtF80(signZ, 0, 0);
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalExtF80Sig(sigB);
expB += normExpSig.exp;
sigB = normExpSig.sig;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
expZ = expA + expB - 0x3FFE;
sig128Z = softfloat_mul64To128(sigA, sigB);
if (sig128Z.v64 < UINT64_C(0x8000000000000000)) {
--expZ;
sig128Z = softfloat_add128(sig128Z.v64, sig128Z.v0, sig128Z.v64, sig128Z.v0);
}
return
softfloat_roundPackToExtF80(signZ, expZ, sig128Z.v64, sig128Z.v0, softfloat_extF80_roundingPrecision(status), status);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
propagateNaN:
return softfloat_propagateNaNExtF80UI(uiA64, uiA0, uiB64, uiB0, status);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
infArg:
if (! magBits) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
uiZ64 = defaultNaNExtF80UI64;
uiZ0 = defaultNaNExtF80UI0;
} else {
if ((! expA && sigA) || (! expB && sigB))
softfloat_raiseFlags(status, softfloat_flag_denormal);
uiZ64 = packToExtF80UI64(signZ, 0x7FFF);
uiZ0 = UINT64_C(0x8000000000000000);
}
return packToExtF80_twoargs(uiZ64, uiZ0);
}

View File

@@ -0,0 +1,199 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
University of California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdint.h>
#include "internals.h"
#include "primitives.h"
#include "specialize.h"
#include "softfloat.h"
extFloat80_t extF80_rem(extFloat80_t a, extFloat80_t b, struct softfloat_status_t *status)
{
uint16_t uiA64;
uint64_t uiA0;
bool signA;
int32_t expA;
uint64_t sigA;
uint16_t uiB64;
uint64_t uiB0;
int32_t expB;
uint64_t sigB;
struct exp32_sig64 normExpSig;
int32_t expDiff;
struct uint128 rem, shiftedSigB;
uint32_t q, recip32;
uint64_t q64;
struct uint128 term, altRem, meanRem;
bool signRem;
// handle unsupported extended double-precision floating encodings
if (extF80_isUnsupported(a) || extF80_isUnsupported(b))
goto invalid;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiA64 = a.signExp;
uiA0 = a.signif;
signA = signExtF80UI64(uiA64);
expA = expExtF80UI64(uiA64);
sigA = uiA0;
uiB64 = b.signExp;
uiB0 = b.signif;
expB = expExtF80UI64(uiB64);
sigB = uiB0;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (expA == 0x7FFF) {
if ((sigA & UINT64_C(0x7FFFFFFFFFFFFFFF)) || ((expB == 0x7FFF) && (sigB & UINT64_C(0x7FFFFFFFFFFFFFFF)))) {
goto propagateNaN;
}
goto invalid;
}
if (expB == 0x7FFF) {
if (sigB & UINT64_C(0x7FFFFFFFFFFFFFFF)) goto propagateNaN;
/*--------------------------------------------------------------------
| Argument b is an infinity. Doubling `expB' is an easy way to ensure
| that `expDiff' later is less than -1, which will result in returning
| a canonicalized version of argument a.
*--------------------------------------------------------------------*/
expB += expB;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (! expB) {
expB = 1;
if (sigB)
softfloat_raiseFlags(status, softfloat_flag_denormal);
}
if (! (sigB & UINT64_C(0x8000000000000000))) {
if (! sigB) goto invalid;
normExpSig = softfloat_normSubnormalExtF80Sig(sigB);
expB += normExpSig.exp;
sigB = normExpSig.sig;
}
if (! expA) {
expA = 1;
if (sigA)
softfloat_raiseFlags(status, softfloat_flag_denormal);
}
if (! (sigA & UINT64_C(0x8000000000000000))) {
if (! sigA) {
expA = 0;
goto copyA;
}
normExpSig = softfloat_normSubnormalExtF80Sig(sigA);
expA += normExpSig.exp;
sigA = normExpSig.sig;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
expDiff = expA - expB;
if (expDiff < -1) goto copyA;
rem = softfloat_shortShiftLeft128(0, sigA, 32);
shiftedSigB = softfloat_shortShiftLeft128(0, sigB, 32);
if (expDiff < 1) {
if (expDiff) {
--expB;
shiftedSigB = softfloat_shortShiftLeft128(0, sigB, 33);
q = 0;
} else {
q = (sigB <= sigA);
if (q) {
rem = softfloat_sub128(rem.v64, rem.v0, shiftedSigB.v64, shiftedSigB.v0);
}
}
} else {
recip32 = softfloat_approxRecip32_1(sigB>>32);
expDiff -= 30;
for (;;) {
q64 = (uint64_t) (uint32_t) (rem.v64>>2) * recip32;
if (expDiff < 0) break;
q = (q64 + 0x80000000)>>32;
rem = softfloat_shortShiftLeft128(rem.v64, rem.v0, 29);
term = softfloat_mul64ByShifted32To128(sigB, q);
rem = softfloat_sub128(rem.v64, rem.v0, term.v64, term.v0);
if (rem.v64 & UINT64_C(0x8000000000000000)) {
rem = softfloat_add128(rem.v64, rem.v0, shiftedSigB.v64, shiftedSigB.v0);
}
expDiff -= 29;
}
/*--------------------------------------------------------------------
| (`expDiff' cannot be less than -29 here.)
*--------------------------------------------------------------------*/
q = (uint32_t) (q64>>32)>>(~expDiff & 31);
rem = softfloat_shortShiftLeft128(rem.v64, rem.v0, expDiff + 30);
term = softfloat_mul64ByShifted32To128(sigB, q);
rem = softfloat_sub128(rem.v64, rem.v0, term.v64, term.v0);
if (rem.v64 & UINT64_C(0x8000000000000000)) {
altRem = softfloat_add128(rem.v64, rem.v0, shiftedSigB.v64, shiftedSigB.v0);
goto selectRem;
}
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
do {
altRem = rem;
++q;
rem = softfloat_sub128(rem.v64, rem.v0, shiftedSigB.v64, shiftedSigB.v0);
} while (! (rem.v64 & UINT64_C(0x8000000000000000)));
selectRem:
meanRem = softfloat_add128(rem.v64, rem.v0, altRem.v64, altRem.v0);
if ((meanRem.v64 & UINT64_C(0x8000000000000000)) || (! (meanRem.v64 | meanRem.v0) && (q & 1))) {
rem = altRem;
}
signRem = signA;
if (rem.v64 & UINT64_C(0x8000000000000000)) {
signRem = ! signRem;
rem = softfloat_sub128(0, 0, rem.v64, rem.v0);
}
return softfloat_normRoundPackToExtF80(signRem, rem.v64 | rem.v0 ? expB + 32 : 0, rem.v64, rem.v0, 80, status);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
propagateNaN:
return softfloat_propagateNaNExtF80UI(uiA64, uiA0, uiB64, uiB0, status);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
invalid:
softfloat_raiseFlags(status, softfloat_flag_invalid);
return packToExtF80_twoargs(defaultNaNExtF80UI64, defaultNaNExtF80UI0);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
copyA:
if (expA < 1) {
sigA >>= 1 - expA;
expA = 0;
}
return packToExtF80(signA, expA, sigA);
}

View File

@@ -0,0 +1,123 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
extFloat80_t
extF80_roundToInt(extFloat80_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
{
uint16_t uiA64, signUI64;
int32_t exp;
uint64_t sigA;
uint16_t uiZ64;
uint64_t sigZ;
uint64_t lastBitMask, roundBitsMask;
// handle unsupported extended double-precision floating encodings
if (extF80_isUnsupported(a)) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return packToExtF80_twoargs(defaultNaNExtF80UI64, defaultNaNExtF80UI0);
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiA64 = a.signExp;
signUI64 = uiA64 & packToExtF80UI64(1, 0);
exp = expExtF80UI64(uiA64);
sigA = a.signif;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (0x403E <= exp) {
if ((exp == 0x7FFF) && (uint64_t) (sigA<<1)) {
return softfloat_propagateNaNExtF80UI(uiA64, sigA, 0, 0, status);
}
return a;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (exp <= 0x3FFE) {
if (! exp) {
if ((sigA<<1) == 0) return a;
softfloat_raiseFlags(status, softfloat_flag_denormal);
}
if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact);
switch (roundingMode) {
case softfloat_round_near_even:
if (!(sigA & UINT64_C(0x7FFFFFFFFFFFFFFF))) break;
case softfloat_round_near_maxMag:
if (exp == 0x3FFE) goto mag1;
break;
case softfloat_round_min:
if (signUI64) goto mag1;
break;
case softfloat_round_max:
if (!signUI64) goto mag1;
break;
}
return packToExtF80(signUI64, 0, 0);
mag1:
softfloat_setRoundingUp(status);
return packToExtF80(signUI64, 0x3FFF, UINT64_C(0x8000000000000000));
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiZ64 = signUI64 | exp;
lastBitMask = (uint64_t) 1<<(0x403E - exp);
roundBitsMask = lastBitMask - 1;
sigZ = sigA;
if (roundingMode == softfloat_round_near_maxMag) {
sigZ += lastBitMask>>1;
} else if (roundingMode == softfloat_round_near_even) {
sigZ += lastBitMask>>1;
if (!(sigZ & roundBitsMask)) sigZ &= ~lastBitMask;
} else if (roundingMode == (signUI64 ? softfloat_round_min : softfloat_round_max)) {
sigZ += roundBitsMask;
}
sigZ &= ~roundBitsMask;
if (!sigZ) {
++uiZ64;
sigZ = UINT64_C(0x8000000000000000);
softfloat_setRoundingUp(status);
}
if (sigZ != sigA) {
if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact);
if (sigZ > sigA)
softfloat_setRoundingUp(status);
}
return packToExtF80_twoargs(uiZ64, sigZ);
}

View File

@@ -0,0 +1,136 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
/*----------------------------------------------------------------------------
| Scales extended double-precision floating-point value in operand `a' by
| value `b'. The function truncates the value in the second operand 'b' to
| an integral value and adds that value to the exponent of the operand 'a'.
| The operation performed according to the IEC/IEEE Standard for Binary
| Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
extFloat80_t extF80_scale(extFloat80_t a, extFloat80_t b, struct softfloat_status_t *status)
{
uint16_t uiA64;
uint64_t uiA0;
bool signA;
int32_t expA;
uint64_t sigA;
uint16_t uiB64;
uint64_t uiB0;
bool signB;
int32_t expB;
uint64_t sigB;
struct exp32_sig64 normExpSig;
// handle unsupported extended double-precision floating encodings
if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) {
invalid:
softfloat_raiseFlags(status, softfloat_flag_invalid);
return packToExtF80_twoargs(defaultNaNExtF80UI64, defaultNaNExtF80UI0);
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiA64 = a.signExp;
uiA0 = a.signif;
signA = signExtF80UI64(uiA64);
expA = expExtF80UI64(uiA64);
sigA = uiA0;
uiB64 = b.signExp;
uiB0 = b.signif;
signB = signExtF80UI64(uiB64);
expB = expExtF80UI64(uiB64);
sigB = uiB0;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (expA == 0x7FFF) {
if ((sigA<<1) || ((expB == 0x7FFF) && (sigB<<1))) {
return softfloat_propagateNaNExtF80UI(uiA64, uiA0, uiB64, uiB0, status);
}
if ((expB == 0x7FFF) && signB) goto invalid;
if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal);
return a;
}
if (expB == 0x7FFF) {
if (sigB<<1) {
return softfloat_propagateNaNExtF80UI(uiA64, uiA0, uiB64, uiB0, status);
}
if ((expA | sigA) == 0) {
if (! signB) goto invalid;
return a;
}
if (sigA && !expA) softfloat_raiseFlags(status, softfloat_flag_denormal);
if (signB) return packToExtF80(signA, 0, 0);
return packToExtF80(signA, 0x7FFF, BX_CONST64(0x8000000000000000));
}
if (! expA) {
if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal);
if (! sigA) return a;
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalExtF80Sig(sigA);
expA = normExpSig.exp + 1;
sigA = normExpSig.sig;
if (expB < 0x3FFF)
return softfloat_normRoundPackToExtF80(signA, expA, sigA, 0, 80, status);
}
if (!expB) {
if (!sigB) return a;
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalExtF80Sig(sigB);
expB = normExpSig.exp + 1;
sigB = normExpSig.sig;
}
if (expB > 0x400E) {
/* generate appropriate overflow/underflow */
return softfloat_roundPackToExtF80(signA, signB ? -0x3FFF : 0x7FFF, sigA, 0, 80, status);
}
if (expB < 0x3FFF) return a;
int shiftCount = 0x403E - expB;
sigB >>= shiftCount;
int32_t scale = (int32_t) sigB;
if (signB) scale = -scale; /* -32768..32767 */
return softfloat_roundPackToExtF80(signA, expA + scale, sigA, 0, 80, status);
}

View File

@@ -0,0 +1,159 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
University of California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdint.h>
#include "internals.h"
#include "primitives.h"
#include "specialize.h"
#include "softfloat.h"
extFloat80_t extF80_sqrt(extFloat80_t a, struct softfloat_status_t *status)
{
uint16_t uiA64;
uint64_t uiA0;
bool signA;
int32_t expA;
uint64_t sigA;
struct exp32_sig64 normExpSig;
int32_t expZ;
uint32_t sig32A, recipSqrt32, sig32Z;
struct uint128 rem;
uint64_t q, x64, sigZ;
struct uint128 y, term;
uint64_t sigZExtra;
// handle unsupported extended double-precision floating encodings
if (extF80_isUnsupported(a))
goto invalid;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiA64 = a.signExp;
uiA0 = a.signif;
signA = signExtF80UI64(uiA64);
expA = expExtF80UI64(uiA64);
sigA = uiA0;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (expA == 0x7FFF) {
if (sigA & UINT64_C(0x7FFFFFFFFFFFFFFF)) {
return softfloat_propagateNaNExtF80UI(uiA64, uiA0, 0, 0, status);
}
if (! signA) return a;
goto invalid;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (signA) {
if ((expA | sigA) == 0) return packToExtF80(signA, 0, 0);
goto invalid;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (! expA) {
expA = 1;
if (sigA)
softfloat_raiseFlags(status, softfloat_flag_denormal);
}
if (! (sigA & UINT64_C(0x8000000000000000))) {
if (! sigA) return packToExtF80(signA, 0, 0);
normExpSig = softfloat_normSubnormalExtF80Sig(sigA);
expA += normExpSig.exp;
sigA = normExpSig.sig;
}
/*------------------------------------------------------------------------
| (`sig32Z' is guaranteed to be a lower bound on the square root of
| `sig32A', which makes `sig32Z' also a lower bound on the square root of
| `sigA'.)
*------------------------------------------------------------------------*/
expZ = ((expA - 0x3FFF)>>1) + 0x3FFF;
expA &= 1;
sig32A = sigA>>32;
recipSqrt32 = softfloat_approxRecipSqrt32_1(expA, sig32A);
sig32Z = ((uint64_t) sig32A * recipSqrt32)>>32;
if (expA) {
sig32Z >>= 1;
rem = softfloat_shortShiftLeft128(0, sigA, 61);
} else {
rem = softfloat_shortShiftLeft128(0, sigA, 62);
}
rem.v64 -= (uint64_t) sig32Z * sig32Z;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
q = ((uint32_t) (rem.v64>>2) * (uint64_t) recipSqrt32)>>32;
x64 = (uint64_t) sig32Z<<32;
sigZ = x64 + (q<<3);
y = softfloat_shortShiftLeft128(rem.v64, rem.v0, 29);
/*------------------------------------------------------------------------
| (Repeating this loop is a rare occurrence.)
*------------------------------------------------------------------------*/
for (;;) {
term = softfloat_mul64ByShifted32To128(x64 + sigZ, q);
rem = softfloat_sub128(y.v64, y.v0, term.v64, term.v0);
if (! (rem.v64 & UINT64_C(0x8000000000000000))) break;
--q;
sigZ -= 1<<3;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
q = (((rem.v64>>2) * recipSqrt32)>>32) + 2;
x64 = sigZ;
sigZ = (sigZ<<1) + (q>>25);
sigZExtra = (uint64_t) (q<<39);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if ((q & 0xFFFFFF) <= 2) {
q &= ~(uint64_t) 0xFFFF;
sigZExtra = (uint64_t) (q<<39);
term = softfloat_mul64ByShifted32To128(x64 + (q>>27), q);
x64 = (uint32_t) (q<<5) * (uint64_t) (uint32_t) q;
term = softfloat_add128(term.v64, term.v0, 0, x64);
rem = softfloat_shortShiftLeft128(rem.v64, rem.v0, 28);
rem = softfloat_sub128(rem.v64, rem.v0, term.v64, term.v0);
if (rem.v64 & UINT64_C(0x8000000000000000)) {
if (! sigZExtra) --sigZ;
--sigZExtra;
} else {
if (rem.v64 | rem.v0) sigZExtra |= 1;
}
}
return
softfloat_roundPackToExtF80(0, expZ, sigZ, sigZExtra, softfloat_extF80_roundingPrecision(status), status);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
invalid:
softfloat_raiseFlags(status, softfloat_flag_invalid);
return packToExtF80_twoargs(defaultNaNExtF80UI64, defaultNaNExtF80UI0);
}

View File

@@ -0,0 +1,75 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdint.h>
#include "internals.h"
#include "primitives.h"
#include "specialize.h"
#include "softfloat.h"
float128_t extF80_to_f128(extFloat80_t a, struct softfloat_status_t *status)
{
uint16_t uiA64;
uint64_t uiA0;
uint16_t exp;
uint64_t frac;
struct commonNaN commonNaN;
struct uint128 uiZ;
bool sign;
struct uint128 frac128;
// handle unsupported extended double-precision floating encodings
if (extF80_isUnsupported(a)) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
uiZ.v64 = defaultNaNF128UI64;
uiZ.v0 = defaultNaNF128UI0;
return uiZ;
}
uiA64 = a.signExp;
uiA0 = a.signif;
exp = expExtF80UI64(uiA64);
frac = uiA0 & UINT64_C(0x7FFFFFFFFFFFFFFF);
if ((exp == 0x7FFF) && frac) {
softfloat_extF80UIToCommonNaN(uiA64, uiA0, &commonNaN, status);
uiZ = softfloat_commonNaNToF128UI(&commonNaN);
} else {
sign = signExtF80UI64(uiA64);
frac128 = softfloat_shortShiftLeft128(0, frac, 49);
uiZ.v64 = packToF128UI64(sign, exp, frac128.v64);
uiZ.v0 = frac128.v0;
}
return uiZ;
}

View File

@@ -0,0 +1,89 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdint.h>
#include "internals.h"
#include "primitives.h"
#include "specialize.h"
#include "softfloat.h"
float16 extF80_to_f16(extFloat80_t a, struct softfloat_status_t *status)
{
uint16_t uiA64;
uint64_t uiA0;
bool sign;
int32_t exp;
uint64_t sig;
struct commonNaN commonNaN;
uint16_t uiZ, sig16;
// handle unsupported extended double-precision floating encodings
if (extF80_isUnsupported(a)) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return defaultNaNF16UI;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiA64 = a.signExp;
uiA0 = a.signif;
sign = signExtF80UI64(uiA64);
exp = expExtF80UI64(uiA64);
sig = uiA0;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (exp == 0x7FFF) {
if (sig & UINT64_C(0x7FFFFFFFFFFFFFFF)) {
softfloat_extF80UIToCommonNaN(uiA64, uiA0, &commonNaN, status);
uiZ = softfloat_commonNaNToF16UI(&commonNaN);
} else {
uiZ = packToF16UI(sign, 0x1F, 0);
}
return uiZ;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sig16 = softfloat_shortShiftRightJam64(sig, 49);
if (! (exp | sig16)) {
return packToF16UI(sign, 0, 0);
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
exp -= 0x3FF1;
if (sizeof (int16_t) < sizeof (int32_t)) {
if (exp < -0x40) exp = -0x40;
}
return softfloat_roundPackToF16(sign, exp, sig16, status);
}

View File

@@ -0,0 +1,89 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdint.h>
#include "internals.h"
#include "primitives.h"
#include "specialize.h"
#include "softfloat.h"
float32 extF80_to_f32(extFloat80_t a, struct softfloat_status_t *status)
{
uint16_t uiA64;
uint64_t uiA0;
bool sign;
int32_t exp;
uint64_t sig;
struct commonNaN commonNaN;
uint32_t uiZ, sig32;
// handle unsupported extended double-precision floating encodings
if (extF80_isUnsupported(a)) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return defaultNaNF32UI;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiA64 = a.signExp;
uiA0 = a.signif;
sign = signExtF80UI64(uiA64);
exp = expExtF80UI64(uiA64);
sig = uiA0;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (exp == 0x7FFF) {
if (sig & UINT64_C(0x7FFFFFFFFFFFFFFF)) {
softfloat_extF80UIToCommonNaN(uiA64, uiA0, &commonNaN, status);
uiZ = softfloat_commonNaNToF32UI(&commonNaN);
} else {
uiZ = packToF32UI(sign, 0xFF, 0);
}
return uiZ;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sig32 = softfloat_shortShiftRightJam64(sig, 33);
if (! (exp | sig32)) {
return packToF32UI(sign, 0, 0);
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
exp -= 0x3F81;
if (sizeof (int16_t) < sizeof (int32_t)) {
if (exp < -0x1000) exp = -0x1000;
}
return softfloat_roundPackToF32(sign, exp, sig32, status);
}

View File

@@ -0,0 +1,89 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdint.h>
#include "internals.h"
#include "primitives.h"
#include "specialize.h"
#include "softfloat.h"
float64 extF80_to_f64(extFloat80_t a, struct softfloat_status_t *status)
{
uint16_t uiA64;
uint64_t uiA0;
bool sign;
int32_t exp;
uint64_t sig;
struct commonNaN commonNaN;
uint64_t uiZ;
// handle unsupported extended double-precision floating encodings
if (extF80_isUnsupported(a)) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return defaultNaNF64UI;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiA64 = a.signExp;
uiA0 = a.signif;
sign = signExtF80UI64(uiA64);
exp = expExtF80UI64(uiA64);
sig = uiA0;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (! (exp | sig)) {
return packToF64UI(sign, 0, 0);
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (exp == 0x7FFF) {
if (sig & UINT64_C(0x7FFFFFFFFFFFFFFF)) {
softfloat_extF80UIToCommonNaN(uiA64, uiA0, &commonNaN, status);
uiZ = softfloat_commonNaNToF64UI(&commonNaN);
} else {
uiZ = packToF64UI(sign, 0x7FF, 0);
}
return uiZ;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sig = softfloat_shortShiftRightJam64(sig, 1);
exp -= 0x3C01;
if (sizeof (int16_t) < sizeof (int32_t)) {
if (exp < -0x1000) exp = -0x1000;
}
return softfloat_roundPackToF64(sign, exp, sig, status);
}

View File

@@ -0,0 +1,82 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
University of California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdint.h>
#include "internals.h"
#include "primitives.h"
#include "specialize.h"
#include "softfloat.h"
int32_t extF80_to_i32(extFloat80_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
{
uint16_t uiA64;
bool sign;
int32_t exp;
uint64_t sig;
int32_t shiftDist;
// handle unsupported extended double-precision floating encodings
if (extF80_isUnsupported(a)) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return i32_fromNaN;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiA64 = a.signExp;
sign = signExtF80UI64(uiA64);
exp = expExtF80UI64(uiA64);
sig = a.signif;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
#if (i32_fromNaN != i32_fromPosOverflow) || (i32_fromNaN != i32_fromNegOverflow)
if ((exp == 0x7FFF) && (sig & UINT64_C(0x7FFFFFFFFFFFFFFF))) {
#if (i32_fromNaN == i32_fromPosOverflow)
sign = 0;
#elif (i32_fromNaN == i32_fromNegOverflow)
sign = 1;
#else
softfloat_raiseFlags(status, softfloat_flag_invalid);
return i32_fromNaN;
#endif
}
#endif
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
shiftDist = 0x4032 - exp;
if (shiftDist <= 0) shiftDist = 1;
sig = softfloat_shiftRightJam64(sig, shiftDist);
return softfloat_roundToI32(sign, sig, roundingMode, exact, status);
}

View File

@@ -0,0 +1,93 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
int32_t extF80_to_i32_r_minMag(extFloat80_t a, bool exact, struct softfloat_status_t *status)
{
uint16_t uiA64;
int32_t exp;
uint64_t sig;
int32_t shiftDist;
bool sign;
int32_t absZ;
// handle unsupported extended double-precision floating encodings
if (extF80_isUnsupported(a)) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return i32_fromNaN;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiA64 = a.signExp;
exp = expExtF80UI64(uiA64);
sig = a.signif;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
shiftDist = 0x403E - exp;
if (64 <= shiftDist) {
if (exact && (exp | sig)) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
return 0;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sign = signExtF80UI64(uiA64);
if (shiftDist < 33) {
if ((uiA64 == packToExtF80UI64(1, 0x401E)) && (sig < UINT64_C(0x8000000100000000))) {
if (exact && (sig & UINT64_C(0x00000000FFFFFFFF))) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
return -0x7FFFFFFF - 1;
}
softfloat_raiseFlags(status, softfloat_flag_invalid);
return
(exp == 0x7FFF) && (sig & UINT64_C(0x7FFFFFFFFFFFFFFF))
? i32_fromNaN
: sign ? i32_fromNegOverflow : i32_fromPosOverflow;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
absZ = sig>>shiftDist;
if (exact && ((uint64_t) (uint32_t) absZ<<shiftDist != sig)) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
return sign ? -absZ : absZ;
}

View File

@@ -0,0 +1,88 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
University of California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdint.h>
#include "internals.h"
#include "primitives.h"
#include "specialize.h"
#include "softfloat.h"
int64_t extF80_to_i64(extFloat80_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
{
uint16_t uiA64;
bool sign;
int32_t exp;
uint64_t sig;
int32_t shiftDist;
uint64_t sigExtra;
struct uint64_extra sig64Extra;
// handle unsupported extended double-precision floating encodings
if (extF80_isUnsupported(a)) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return i64_fromNaN;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiA64 = a.signExp;
sign = signExtF80UI64(uiA64);
exp = expExtF80UI64(uiA64);
sig = a.signif;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
shiftDist = 0x403E - exp;
if (shiftDist <= 0) {
/*--------------------------------------------------------------------
*--------------------------------------------------------------------*/
if (shiftDist) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return
(exp == 0x7FFF) && (sig & UINT64_C(0x7FFFFFFFFFFFFFFF))
? i64_fromNaN
: sign ? i64_fromNegOverflow : i64_fromPosOverflow;
}
/*--------------------------------------------------------------------
*--------------------------------------------------------------------*/
sigExtra = 0;
} else {
/*--------------------------------------------------------------------
*--------------------------------------------------------------------*/
sig64Extra = softfloat_shiftRightJam64Extra(sig, 0, shiftDist);
sig = sig64Extra.v;
sigExtra = sig64Extra.extra;
}
return softfloat_roundToI64(sign, sig, sigExtra, roundingMode, exact, status);
}

View File

@@ -0,0 +1,90 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
int64_t extF80_to_i64_r_minMag(extFloat80_t a, bool exact, struct softfloat_status_t *status)
{
uint16_t uiA64;
int32_t exp;
uint64_t sig;
int32_t shiftDist;
bool sign;
int64_t absZ;
// handle unsupported extended double-precision floating encodings
if (extF80_isUnsupported(a)) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return i64_fromNaN;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiA64 = a.signExp;
exp = expExtF80UI64(uiA64);
sig = a.signif;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
shiftDist = 0x403E - exp;
if (64 <= shiftDist) {
if (exact && (exp | sig)) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
return 0;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sign = signExtF80UI64(uiA64);
if (shiftDist <= 0) {
if ((uiA64 == packToExtF80UI64(1, 0x403E)) && (sig == UINT64_C(0x8000000000000000))) {
return -INT64_C(0x7FFFFFFFFFFFFFFF) - 1;
}
softfloat_raiseFlags(status, softfloat_flag_invalid);
return
(exp == 0x7FFF) && (sig & UINT64_C(0x7FFFFFFFFFFFFFFF))
? i64_fromNaN
: sign ? i64_fromNegOverflow : i64_fromPosOverflow;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
absZ = sig>>shiftDist;
if (exact && (uint64_t) (sig<<(-shiftDist & 63))) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
return sign ? -absZ : absZ;
}

View File

@@ -0,0 +1,83 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
University of California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdint.h>
#include "internals.h"
#include "primitives.h"
#include "specialize.h"
#include "softfloat.h"
uint32_t
extF80_to_ui32(extFloat80_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
{
uint16_t uiA64;
bool sign;
int32_t exp;
uint64_t sig;
int32_t shiftDist;
// handle unsupported extended double-precision floating encodings
if (extF80_isUnsupported(a)) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return ui32_fromNaN;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiA64 = a.signExp;
sign = signExtF80UI64(uiA64);
exp = expExtF80UI64(uiA64);
sig = a.signif;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
#if (ui32_fromNaN != ui32_fromPosOverflow) || (ui32_fromNaN != ui32_fromNegOverflow)
if ((exp == 0x7FFF) && (sig & UINT64_C(0x7FFFFFFFFFFFFFFF))) {
#if (ui32_fromNaN == ui32_fromPosOverflow)
sign = 0;
#elif (ui32_fromNaN == ui32_fromNegOverflow)
sign = 1;
#else
softfloat_raiseFlags(status, softfloat_flag_invalid);
return ui32_fromNaN;
#endif
}
#endif
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
shiftDist = 0x4032 - exp;
if (shiftDist <= 0) shiftDist = 1;
sig = softfloat_shiftRightJam64(sig, shiftDist);
return softfloat_roundToUI32(sign, sig, roundingMode, exact, status);
}

View File

@@ -0,0 +1,87 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
uint32_t extF80_to_ui32_r_minMag(extFloat80_t a, bool exact, struct softfloat_status_t *status)
{
uint16_t uiA64;
int32_t exp;
uint64_t sig;
int32_t shiftDist;
bool sign;
uint32_t z;
// handle unsupported extended double-precision floating encodings
if (extF80_isUnsupported(a)) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return ui32_fromNaN;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiA64 = a.signExp;
exp = expExtF80UI64(uiA64);
sig = a.signif;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
shiftDist = 0x403E - exp;
if (64 <= shiftDist) {
if (exact && (exp | sig)) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
return 0;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sign = signExtF80UI64(uiA64);
if (sign || (shiftDist < 32)) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return
(exp == 0x7FFF) && (sig & UINT64_C(0x7FFFFFFFFFFFFFFF))
? ui32_fromNaN
: sign ? ui32_fromNegOverflow : ui32_fromPosOverflow;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
z = sig>>shiftDist;
if (exact && ((uint64_t) z<<shiftDist != sig)) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
return z;
}

View File

@@ -0,0 +1,83 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
University of California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdint.h>
#include "internals.h"
#include "primitives.h"
#include "specialize.h"
#include "softfloat.h"
uint64_t extF80_to_ui64(extFloat80_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
{
uint16_t uiA64;
bool sign;
int32_t exp;
uint64_t sig;
int32_t shiftDist;
uint64_t sigExtra;
struct uint64_extra sig64Extra;
// handle unsupported extended double-precision floating encodings
if (extF80_isUnsupported(a)) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return ui64_fromNaN;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiA64 = a.signExp;
sign = signExtF80UI64(uiA64);
exp = expExtF80UI64(uiA64);
sig = a.signif;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
shiftDist = 0x403E - exp;
if (shiftDist < 0) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return
(exp == 0x7FFF) && (sig & UINT64_C(0x7FFFFFFFFFFFFFFF))
? ui64_fromNaN
: sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sigExtra = 0;
if (shiftDist) {
sig64Extra = softfloat_shiftRightJam64Extra(sig, 0, shiftDist);
sig = sig64Extra.v;
sigExtra = sig64Extra.extra;
}
return softfloat_roundToUI64(sign, sig, sigExtra, roundingMode, exact, status);
}

View File

@@ -0,0 +1,87 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
uint64_t extF80_to_ui64_r_minMag(extFloat80_t a, bool exact, struct softfloat_status_t *status)
{
uint16_t uiA64;
int32_t exp;
uint64_t sig;
int32_t shiftDist;
bool sign;
uint64_t z;
// handle unsupported extended double-precision floating encodings
if (extF80_isUnsupported(a)) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return ui64_fromNaN;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiA64 = a.signExp;
exp = expExtF80UI64(uiA64);
sig = a.signif;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
shiftDist = 0x403E - exp;
if (64 <= shiftDist) {
if (exact && (exp | sig)) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
return 0;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sign = signExtF80UI64(uiA64);
if (sign || (shiftDist < 0)) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return
(exp == 0x7FFF) && (sig & UINT64_C(0x7FFFFFFFFFFFFFFF))
? ui64_fromNaN
: sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
z = sig>>shiftDist;
if (exact && (z<<shiftDist != sig)) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
return z;
}

View File

@@ -0,0 +1,88 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "softfloat.h"
extern float128_t
softfloat_addMagsF128(uint64_t, uint64_t, uint64_t, uint64_t, bool, struct softfloat_status_t *);
extern float128_t
softfloat_subMagsF128(uint64_t, uint64_t, uint64_t, uint64_t, bool, struct softfloat_status_t *);
float128_t f128_add(float128_t a, float128_t b, struct softfloat_status_t *status)
{
uint64_t uiA64, uiA0;
bool signA;
uint64_t uiB64, uiB0;
bool signB;
uiA64 = a.v64;
uiA0 = a.v0;
signA = signF128UI64(uiA64);
uiB64 = b.v64;
uiB0 = b.v0;
signB = signF128UI64(uiB64);
if (signA == signB) {
return softfloat_addMagsF128(uiA64, uiA0, uiB64, uiB0, signA, status);
} else {
return softfloat_subMagsF128(uiA64, uiA0, uiB64, uiB0, signA, status);
}
}
float128_t f128_sub(float128_t a, float128_t b, struct softfloat_status_t *status)
{
uint64_t uiA64, uiA0;
bool signA;
uint64_t uiB64, uiB0;
bool signB;
uiA64 = a.v64;
uiA0 = a.v0;
signA = signF128UI64(uiA64);
uiB64 = b.v64;
uiB0 = b.v0;
signB = signF128UI64(uiB64);
if (signA == signB) {
return softfloat_subMagsF128(uiA64, uiA0, uiB64, uiB0, signA, status);
} else {
return softfloat_addMagsF128(uiA64, uiA0, uiB64, uiB0, signA, status);
}
}

View File

@@ -0,0 +1,187 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "primitives.h"
#include "specialize.h"
#include "softfloat.h"
float128_t f128_div(float128_t a, float128_t b, struct softfloat_status_t *status)
{
uint64_t uiA64, uiA0;
bool signA;
int32_t expA;
struct uint128 sigA;
uint64_t uiB64, uiB0;
bool signB;
int32_t expB;
struct uint128 sigB;
bool signZ;
struct exp32_sig128 normExpSig;
int32_t expZ;
struct uint128 rem;
uint32_t recip32;
int ix;
uint64_t q64;
uint32_t q;
struct uint128 term;
uint32_t qs[3];
uint64_t sigZExtra;
struct uint128 sigZ, uiZ;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiA64 = a.v64;
uiA0 = a.v0;
signA = signF128UI64(uiA64);
expA = expF128UI64(uiA64);
sigA.v64 = fracF128UI64(uiA64);
sigA.v0 = uiA0;
uiB64 = b.v64;
uiB0 = b.v0;
signB = signF128UI64(uiB64);
expB = expF128UI64(uiB64);
sigB.v64 = fracF128UI64(uiB64);
sigB.v0 = uiB0;
signZ = signA ^ signB;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (expA == 0x7FFF) {
if (sigA.v64 | sigA.v0) goto propagateNaN;
if (expB == 0x7FFF) {
if (sigB.v64 | sigB.v0) goto propagateNaN;
goto invalid;
}
goto infinity;
}
if (expB == 0x7FFF) {
if (sigB.v64 | sigB.v0) goto propagateNaN;
goto zero;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (! expB) {
if (! (sigB.v64 | sigB.v0)) {
if (! (expA | sigA.v64 | sigA.v0)) goto invalid;
softfloat_raiseFlags(status, softfloat_flag_infinite);
goto infinity;
}
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalF128Sig(sigB.v64, sigB.v0);
expB = normExpSig.exp;
sigB = normExpSig.sig;
}
if (! expA) {
if (! (sigA.v64 | sigA.v0)) goto zero;
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalF128Sig(sigA.v64, sigA.v0);
expA = normExpSig.exp;
sigA = normExpSig.sig;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
expZ = expA - expB + 0x3FFE;
sigA.v64 |= UINT64_C(0x0001000000000000);
sigB.v64 |= UINT64_C(0x0001000000000000);
rem = sigA;
if (softfloat_lt128(sigA.v64, sigA.v0, sigB.v64, sigB.v0)) {
--expZ;
rem = softfloat_add128(sigA.v64, sigA.v0, sigA.v64, sigA.v0);
}
recip32 = softfloat_approxRecip32_1(sigB.v64>>17);
ix = 3;
for (;;) {
q64 = (uint64_t) (uint32_t) (rem.v64>>19) * recip32;
q = (q64 + 0x80000000)>>32;
--ix;
if (ix < 0) break;
rem = softfloat_shortShiftLeft128(rem.v64, rem.v0, 29);
term = softfloat_mul128By32(sigB.v64, sigB.v0, q);
rem = softfloat_sub128(rem.v64, rem.v0, term.v64, term.v0);
if (rem.v64 & UINT64_C(0x8000000000000000)) {
--q;
rem = softfloat_add128(rem.v64, rem.v0, sigB.v64, sigB.v0);
}
qs[ix] = q;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (((q + 1) & 7) < 2) {
rem = softfloat_shortShiftLeft128(rem.v64, rem.v0, 29);
term = softfloat_mul128By32(sigB.v64, sigB.v0, q);
rem = softfloat_sub128(rem.v64, rem.v0, term.v64, term.v0);
if (rem.v64 & UINT64_C(0x8000000000000000)) {
--q;
rem = softfloat_add128(rem.v64, rem.v0, sigB.v64, sigB.v0);
} else if (softfloat_le128(sigB.v64, sigB.v0, rem.v64, rem.v0)) {
++q;
rem = softfloat_sub128(rem.v64, rem.v0, sigB.v64, sigB.v0);
}
if (rem.v64 | rem.v0) q |= 1;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sigZExtra = (uint64_t) ((uint64_t) q<<60);
term = softfloat_shortShiftLeft128(0, qs[1], 54);
sigZ = softfloat_add128((uint64_t) qs[2]<<19, ((uint64_t) qs[0]<<25) + (q>>4), term.v64, term.v0);
return
softfloat_roundPackToF128(signZ, expZ, sigZ.v64, sigZ.v0, sigZExtra, status);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
propagateNaN:
uiZ = softfloat_propagateNaNF128UI(uiA64, uiA0, uiB64, uiB0, status);
return uiZ;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
invalid:
softfloat_raiseFlags(status, softfloat_flag_invalid);
uiZ.v64 = defaultNaNF128UI64;
uiZ.v0 = defaultNaNF128UI0;
return uiZ;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
infinity:
uiZ.v64 = packToF128UI64(signZ, 0x7FFF, 0);
uiZ.v0 = 0;
return uiZ;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
zero:
uiZ.v64 = packToF128UI64(signZ, 0, 0);
uiZ.v0 = 0;
return uiZ;
}

View File

@@ -0,0 +1,148 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "primitives.h"
#include "primitiveTypes.h"
#include "specialize.h"
#include "softfloat.h"
float128_t f128_mul(float128_t a, float128_t b, struct softfloat_status_t *status)
{
uint64_t uiA64, uiA0;
bool signA;
int32_t expA;
struct uint128 sigA;
uint64_t uiB64, uiB0;
bool signB;
int32_t expB;
struct uint128 sigB;
bool signZ;
uint64_t magBits;
struct exp32_sig128 normExpSig;
int32_t expZ;
uint64_t sig256Z[4];
uint64_t sigZExtra;
struct uint128 sigZ;
struct uint128_extra sig128Extra;
struct uint128 uiZ;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiA64 = a.v64;
uiA0 = a.v0;
signA = signF128UI64(uiA64);
expA = expF128UI64(uiA64);
sigA.v64 = fracF128UI64(uiA64);
sigA.v0 = uiA0;
uiB64 = b.v64;
uiB0 = b.v0;
signB = signF128UI64(uiB64);
expB = expF128UI64(uiB64);
sigB.v64 = fracF128UI64(uiB64);
sigB.v0 = uiB0;
signZ = signA ^ signB;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (expA == 0x7FFF) {
if ((sigA.v64 | sigA.v0) || ((expB == 0x7FFF) && (sigB.v64 | sigB.v0))) {
goto propagateNaN;
}
magBits = expB | sigB.v64 | sigB.v0;
goto infArg;
}
if (expB == 0x7FFF) {
if (sigB.v64 | sigB.v0) goto propagateNaN;
magBits = expA | sigA.v64 | sigA.v0;
goto infArg;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (! expA) {
if (! (sigA.v64 | sigA.v0)) goto zero;
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalF128Sig(sigA.v64, sigA.v0);
expA = normExpSig.exp;
sigA = normExpSig.sig;
}
if (! expB) {
if (! (sigB.v64 | sigB.v0)) goto zero;
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalF128Sig(sigB.v64, sigB.v0);
expB = normExpSig.exp;
sigB = normExpSig.sig;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
expZ = expA + expB - 0x4000;
sigA.v64 |= UINT64_C(0x0001000000000000);
sigB = softfloat_shortShiftLeft128(sigB.v64, sigB.v0, 16);
softfloat_mul128To256M(sigA.v64, sigA.v0, sigB.v64, sigB.v0, sig256Z);
sigZExtra = sig256Z[indexWord(4, 1)] | (sig256Z[indexWord(4, 0)] != 0);
sigZ = softfloat_add128(sig256Z[indexWord(4, 3)], sig256Z[indexWord(4, 2)], sigA.v64, sigA.v0);
if (UINT64_C(0x0002000000000000) <= sigZ.v64) {
++expZ;
sig128Extra = softfloat_shortShiftRightJam128Extra(sigZ.v64, sigZ.v0, sigZExtra, 1);
sigZ = sig128Extra.v;
sigZExtra = sig128Extra.extra;
}
return
softfloat_roundPackToF128(signZ, expZ, sigZ.v64, sigZ.v0, sigZExtra, status);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
propagateNaN:
uiZ = softfloat_propagateNaNF128UI(uiA64, uiA0, uiB64, uiB0, status);
return uiZ;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
infArg:
if (! magBits) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
uiZ.v64 = defaultNaNF128UI64;
uiZ.v0 = defaultNaNF128UI0;
return uiZ;
}
uiZ.v64 = packToF128UI64(signZ, 0x7FFF, 0);
uiZ.v0 = 0;
return uiZ;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
zero:
uiZ.v64 = packToF128UI64(signZ, 0, 0);
uiZ.v0 = 0;
return uiZ;
}

View File

@@ -0,0 +1,332 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdint.h>
#include "internals.h"
#include "primitives.h"
#include "primitiveTypes.h"
#include "softfloat.h"
#include "specialize.h"
float128_t f128_mulAdd(float128_t a, float128_t b, float128_t c, uint8_t op, struct softfloat_status_t *status)
{
bool signA;
int32_t expA;
struct uint128 sigA;
bool signB;
int32_t expB;
struct uint128 sigB;
bool signC;
int32_t expC;
struct uint128 sigC;
bool signZ;
uint64_t magBits;
struct uint128 uiZ;
struct exp32_sig128 normExpSig;
int32_t expZ;
uint64_t sig256Z[4];
struct uint128 sigZ;
int32_t shiftDist, expDiff;
struct uint128 x128;
uint64_t sig256C[4];
static uint64_t zero256[4] = INIT_UINTM4(0, 0, 0, 0);
uint64_t sigZExtra, sig256Z0;
uint64_t uiA64, uiA0;
uint64_t uiB64, uiB0;
uint64_t uiC64, uiC0;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiA64 = a.v64;
uiA0 = a.v0;
uiB64 = b.v64;
uiB0 = b.v0;
uiC64 = c.v64;
uiC0 = c.v0;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
signA = signF128UI64(uiA64);
expA = expF128UI64(uiA64);
sigA.v64 = fracF128UI64(uiA64);
sigA.v0 = uiA0;
signB = signF128UI64(uiB64);
expB = expF128UI64(uiB64);
sigB.v64 = fracF128UI64(uiB64);
sigB.v0 = uiB0;
signC = signF128UI64(uiC64) ^ ((op & softfloat_mulAdd_subC) != 0);
expC = expF128UI64(uiC64);
sigC.v64 = fracF128UI64(uiC64);
sigC.v0 = uiC0;
signZ = signA ^ signB ^ ((op & softfloat_mulAdd_subProd) != 0);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (expA == 0x7FFF) {
if ((sigA.v64 | sigA.v0) || ((expB == 0x7FFF) && (sigB.v64 | sigB.v0))) {
goto propagateNaN_ABC;
}
magBits = expB | sigB.v64 | sigB.v0;
goto infProdArg;
}
if (expB == 0x7FFF) {
if (sigB.v64 | sigB.v0) goto propagateNaN_ABC;
magBits = expA | sigA.v64 | sigA.v0;
goto infProdArg;
}
if (expC == 0x7FFF) {
if (sigC.v64 | sigC.v0) {
uiZ.v64 = 0;
uiZ.v0 = 0;
goto propagateNaN_ZC;
}
uiZ.v64 = uiC64;
uiZ.v0 = uiC0;
return uiZ;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (! expA) {
if (! (sigA.v64 | sigA.v0)) goto zeroProd;
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalF128Sig(sigA.v64, sigA.v0);
expA = normExpSig.exp;
sigA = normExpSig.sig;
}
if (! expB) {
if (! (sigB.v64 | sigB.v0)) goto zeroProd;
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalF128Sig(sigB.v64, sigB.v0);
expB = normExpSig.exp;
sigB = normExpSig.sig;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
expZ = expA + expB - 0x3FFE;
sigA.v64 |= UINT64_C(0x0001000000000000);
sigB.v64 |= UINT64_C(0x0001000000000000);
sigA = softfloat_shortShiftLeft128(sigA.v64, sigA.v0, 8);
sigB = softfloat_shortShiftLeft128(sigB.v64, sigB.v0, 15);
softfloat_mul128To256M(sigA.v64, sigA.v0, sigB.v64, sigB.v0, sig256Z);
sigZ.v64 = sig256Z[indexWord(4, 3)];
sigZ.v0 = sig256Z[indexWord(4, 2)];
shiftDist = 0;
if (! (sigZ.v64 & UINT64_C(0x0100000000000000))) {
--expZ;
shiftDist = -1;
}
if (! expC) {
if (! (sigC.v64 | sigC.v0)) {
shiftDist += 8;
goto sigZ;
}
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalF128Sig(sigC.v64, sigC.v0);
expC = normExpSig.exp;
sigC = normExpSig.sig;
}
sigC.v64 |= UINT64_C(0x0001000000000000);
sigC = softfloat_shortShiftLeft128(sigC.v64, sigC.v0, 8);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
expDiff = expZ - expC;
if (expDiff < 0) {
expZ = expC;
if ((signZ == signC) || (expDiff < -1)) {
shiftDist -= expDiff;
if (shiftDist) {
sigZ = softfloat_shiftRightJam128(sigZ.v64, sigZ.v0, shiftDist);
}
} else {
if (! shiftDist) {
x128 = softfloat_shortShiftRight128(sig256Z[indexWord(4, 1)], sig256Z[indexWord(4, 0)], 1);
sig256Z[indexWord(4, 1)] = (sigZ.v0<<63) | x128.v64;
sig256Z[indexWord(4, 0)] = x128.v0;
sigZ = softfloat_shortShiftRight128(sigZ.v64, sigZ.v0, 1);
sig256Z[indexWord(4, 3)] = sigZ.v64;
sig256Z[indexWord(4, 2)] = sigZ.v0;
}
}
} else {
if (shiftDist) softfloat_add256M(sig256Z, sig256Z, sig256Z);
if (! expDiff) {
sigZ.v64 = sig256Z[indexWord(4, 3)];
sigZ.v0 = sig256Z[indexWord(4, 2)];
} else {
sig256C[indexWord(4, 3)] = sigC.v64;
sig256C[indexWord(4, 2)] = sigC.v0;
sig256C[indexWord(4, 1)] = 0;
sig256C[indexWord(4, 0)] = 0;
softfloat_shiftRightJam256M(sig256C, expDiff, sig256C);
}
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
shiftDist = 8;
if (signZ == signC) {
/*--------------------------------------------------------------------
*--------------------------------------------------------------------*/
if (expDiff <= 0) {
sigZ = softfloat_add128(sigC.v64, sigC.v0, sigZ.v64, sigZ.v0);
} else {
softfloat_add256M(sig256Z, sig256C, sig256Z);
sigZ.v64 = sig256Z[indexWord(4, 3)];
sigZ.v0 = sig256Z[indexWord(4, 2)];
}
if (sigZ.v64 & UINT64_C(0x0200000000000000)) {
++expZ;
shiftDist = 9;
}
} else {
/*--------------------------------------------------------------------
*--------------------------------------------------------------------*/
if (expDiff < 0) {
signZ = signC;
if (expDiff < -1) {
sigZ = softfloat_sub128(sigC.v64, sigC.v0, sigZ.v64, sigZ.v0);
sigZExtra = sig256Z[indexWord(4, 1)] | sig256Z[indexWord(4, 0)];
if (sigZExtra) {
sigZ = softfloat_sub128(sigZ.v64, sigZ.v0, 0, 1);
}
if (! (sigZ.v64 & UINT64_C(0x0100000000000000))) {
--expZ;
shiftDist = 7;
}
goto shiftRightRoundPack;
} else {
sig256C[indexWord(4, 3)] = sigC.v64;
sig256C[indexWord(4, 2)] = sigC.v0;
sig256C[indexWord(4, 1)] = 0;
sig256C[indexWord(4, 0)] = 0;
softfloat_sub256M(sig256C, sig256Z, sig256Z);
}
} else if (! expDiff) {
sigZ = softfloat_sub128(sigZ.v64, sigZ.v0, sigC.v64, sigC.v0);
if (! (sigZ.v64 | sigZ.v0) && ! sig256Z[indexWord(4, 1)] && ! sig256Z[indexWord(4, 0)]) {
goto completeCancellation;
}
sig256Z[indexWord(4, 3)] = sigZ.v64;
sig256Z[indexWord(4, 2)] = sigZ.v0;
if (sigZ.v64 & UINT64_C(0x8000000000000000)) {
signZ = ! signZ;
softfloat_sub256M(zero256, sig256Z, sig256Z);
}
} else {
softfloat_sub256M(sig256Z, sig256C, sig256Z);
if (1 < expDiff) {
sigZ.v64 = sig256Z[indexWord(4, 3)];
sigZ.v0 = sig256Z[indexWord(4, 2)];
if (! (sigZ.v64 & UINT64_C(0x0100000000000000))) {
--expZ;
shiftDist = 7;
}
goto sigZ;
}
}
/*--------------------------------------------------------------------
*--------------------------------------------------------------------*/
sigZ.v64 = sig256Z[indexWord(4, 3)];
sigZ.v0 = sig256Z[indexWord(4, 2)];
sigZExtra = sig256Z[indexWord(4, 1)];
sig256Z0 = sig256Z[indexWord(4, 0)];
if (sigZ.v64) {
if (sig256Z0) sigZExtra |= 1;
} else {
expZ -= 64;
sigZ.v64 = sigZ.v0;
sigZ.v0 = sigZExtra;
sigZExtra = sig256Z0;
if (! sigZ.v64) {
expZ -= 64;
sigZ.v64 = sigZ.v0;
sigZ.v0 = sigZExtra;
sigZExtra = 0;
if (! sigZ.v64) {
expZ -= 64;
sigZ.v64 = sigZ.v0;
sigZ.v0 = 0;
}
}
}
shiftDist = softfloat_countLeadingZeros64(sigZ.v64);
expZ += 7 - shiftDist;
shiftDist = 15 - shiftDist;
if (0 < shiftDist) goto shiftRightRoundPack;
if (shiftDist) {
shiftDist = -shiftDist;
sigZ = softfloat_shortShiftLeft128(sigZ.v64, sigZ.v0, shiftDist);
x128 = softfloat_shortShiftLeft128(0, sigZExtra, shiftDist);
sigZ.v0 |= x128.v64;
sigZExtra = x128.v0;
}
goto roundPack;
}
sigZ:
sigZExtra = sig256Z[indexWord(4, 1)] | sig256Z[indexWord(4, 0)];
shiftRightRoundPack:
sigZExtra = (uint64_t) (sigZ.v0<<(64 - shiftDist)) | (sigZExtra != 0);
sigZ = softfloat_shortShiftRight128(sigZ.v64, sigZ.v0, shiftDist);
roundPack:
return softfloat_roundPackToF128(signZ, expZ - 1, sigZ.v64, sigZ.v0, sigZExtra, status);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
propagateNaN_ABC:
uiZ = softfloat_propagateNaNF128UI(uiA64, uiA0, uiB64, uiB0, status);
goto propagateNaN_ZC;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
infProdArg:
if ((sigC.v64 | sigC.v0) && expC == 0x7FFF) goto propagateNaN_ZC;
if (magBits) {
uiZ.v64 = packToF128UI64(signZ, 0x7FFF, 0);
uiZ.v0 = 0;
if (expC != 0x7FFF) return uiZ;
if (signZ == signC) return uiZ;
}
softfloat_raiseFlags(status, softfloat_flag_invalid);
uiZ.v64 = defaultNaNF128UI64;
uiZ.v0 = defaultNaNF128UI0;
propagateNaN_ZC:
uiZ = softfloat_propagateNaNF128UI(uiZ.v64, uiZ.v0, uiC64, uiC0, status);
return uiZ;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
zeroProd:
uiZ.v64 = uiC64;
uiZ.v0 = uiC0;
if (! (expC | sigC.v64 | sigC.v0) && (signZ != signC)) {
completeCancellation:
uiZ.v64 = packToF128UI64((softfloat_getRoundingMode(status) == softfloat_round_min), 0, 0);
uiZ.v0 = 0;
}
return uiZ;
}

View File

@@ -0,0 +1,142 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "primitives.h"
#include "specialize.h"
#include "softfloat.h"
float128_t
f128_roundToInt(float128_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
{
uint64_t uiA64, uiA0;
int32_t exp;
struct uint128 uiZ;
uint64_t lastBitMask0, roundBitsMask;
bool roundNearEven;
uint64_t lastBitMask64;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiA64 = a.v64;
uiA0 = a.v0;
exp = expF128UI64(uiA64);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (0x402F <= exp) {
/*--------------------------------------------------------------------
*--------------------------------------------------------------------*/
if (0x406F <= exp) {
if ((exp == 0x7FFF) && (fracF128UI64(uiA64) | uiA0)) {
uiZ = softfloat_propagateNaNF128UI(uiA64, uiA0, 0, 0, status);
return uiZ;
}
return a;
}
/*--------------------------------------------------------------------
*--------------------------------------------------------------------*/
lastBitMask0 = (uint64_t) 2<<(0x406E - exp);
roundBitsMask = lastBitMask0 - 1;
uiZ.v64 = uiA64;
uiZ.v0 = uiA0;
roundNearEven = (roundingMode == softfloat_round_near_even);
if (roundNearEven || (roundingMode == softfloat_round_near_maxMag)) {
if (exp == 0x402F) {
if (UINT64_C(0x8000000000000000) <= uiZ.v0) {
++uiZ.v64;
if (roundNearEven && (uiZ.v0 == UINT64_C(0x8000000000000000))) {
uiZ.v64 &= ~1;
}
}
} else {
uiZ = softfloat_add128(uiZ.v64, uiZ.v0, 0, lastBitMask0>>1);
if (roundNearEven && !(uiZ.v0 & roundBitsMask)) {
uiZ.v0 &= ~lastBitMask0;
}
}
} else if (roundingMode == (signF128UI64(uiZ.v64) ? softfloat_round_min : softfloat_round_max)) {
uiZ = softfloat_add128(uiZ.v64, uiZ.v0, 0, roundBitsMask);
}
uiZ.v0 &= ~roundBitsMask;
lastBitMask64 = !lastBitMask0;
} else {
/*--------------------------------------------------------------------
*--------------------------------------------------------------------*/
if (exp < 0x3FFF) {
if (!((uiA64 & UINT64_C(0x7FFFFFFFFFFFFFFF)) | uiA0)) return a;
if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact);
uiZ.v64 = uiA64 & packToF128UI64(1, 0, 0);
uiZ.v0 = 0;
switch (roundingMode) {
case softfloat_round_near_even:
if (!(fracF128UI64(uiA64) | uiA0)) break;
case softfloat_round_near_maxMag:
if (exp == 0x3FFE) uiZ.v64 |= packToF128UI64(0, 0x3FFF, 0);
break;
case softfloat_round_min:
if (uiZ.v64) uiZ.v64 = packToF128UI64(1, 0x3FFF, 0);
break;
case softfloat_round_max:
if (!uiZ.v64) uiZ.v64 = packToF128UI64(0, 0x3FFF, 0);
break;
}
return uiZ;
}
/*--------------------------------------------------------------------
*--------------------------------------------------------------------*/
uiZ.v64 = uiA64;
uiZ.v0 = 0;
lastBitMask64 = (uint64_t) 1<<(0x402F - exp);
roundBitsMask = lastBitMask64 - 1;
if (roundingMode == softfloat_round_near_maxMag) {
uiZ.v64 += lastBitMask64>>1;
} else if (roundingMode == softfloat_round_near_even) {
uiZ.v64 += lastBitMask64>>1;
if (!((uiZ.v64 & roundBitsMask) | uiA0)) {
uiZ.v64 &= ~lastBitMask64;
}
} else if (roundingMode == (signF128UI64(uiZ.v64) ? softfloat_round_min : softfloat_round_max)) {
uiZ.v64 = (uiZ.v64 | (uiA0 != 0)) + roundBitsMask;
}
uiZ.v64 &= ~roundBitsMask;
lastBitMask0 = 0;
}
if ((uiZ.v64 != uiA64) || (uiZ.v0 != uiA0)) {
if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact);
}
return uiZ;
}

View File

@@ -0,0 +1,94 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "primitives.h"
#include "specialize.h"
#include "softfloat.h"
extFloat80_t f128_to_extF80(float128_t a, struct softfloat_status_t *status)
{
uint64_t uiA64, uiA0;
bool sign;
int32_t exp;
uint64_t frac64, frac0;
struct commonNaN commonNaN;
struct uint128 uiZ;
uint16_t uiZ64;
uint64_t uiZ0;
struct exp32_sig128 normExpSig;
struct uint128 sig128;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiA64 = a.v64;
uiA0 = a.v0;
sign = signF128UI64(uiA64);
exp = expF128UI64(uiA64);
frac64 = fracF128UI64(uiA64);
frac0 = uiA0;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (exp == 0x7FFF) {
if (frac64 | frac0) {
softfloat_f128UIToCommonNaN(uiA64, uiA0, &commonNaN, status);
uiZ = softfloat_commonNaNToExtF80UI(&commonNaN);
uiZ64 = uiZ.v64;
uiZ0 = uiZ.v0;
} else {
uiZ64 = packToExtF80UI64(sign, 0x7FFF);
uiZ0 = UINT64_C(0x8000000000000000);
}
return packToExtF80_twoargs(uiZ64, uiZ0);
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (! exp) {
if (! (frac64 | frac0)) {
return packToExtF80(sign, 0, 0);
}
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalF128Sig(frac64, frac0);
exp = normExpSig.exp;
frac64 = normExpSig.sig.v64;
frac0 = normExpSig.sig.v0;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sig128 = softfloat_shortShiftLeft128(frac64 | UINT64_C(0x0001000000000000), frac0, 15);
return softfloat_roundPackToExtF80(sign, exp, sig128.v64, sig128.v0, 80, status);
}

View File

@@ -0,0 +1,83 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "primitives.h"
#include "specialize.h"
#include "softfloat.h"
float32 f128_to_f32(float128_t a, struct softfloat_status_t *status)
{
uint64_t uiA64, uiA0;
bool sign;
int32_t exp;
uint64_t frac64;
struct commonNaN commonNaN;
uint32_t uiZ, frac32;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiA64 = a.v64;
uiA0 = a.v0;
sign = signF128UI64(uiA64);
exp = expF128UI64(uiA64);
frac64 = fracF128UI64(uiA64) | (uiA0 != 0);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (exp == 0x7FFF) {
if (frac64) {
softfloat_f128UIToCommonNaN(uiA64, uiA0, &commonNaN, status);
uiZ = softfloat_commonNaNToF32UI(&commonNaN);
} else {
uiZ = packToF32UI(sign, 0xFF, 0);
}
return uiZ;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
frac32 = softfloat_shortShiftRightJam64(frac64, 18);
if (! (exp | frac32)) {
return packToF32UI(sign, 0, 0);
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
exp -= 0x3F81;
if (sizeof (int16_t) < sizeof (int32_t)) {
if (exp < -0x1000) exp = -0x1000;
}
return softfloat_roundPackToF32(sign, exp, frac32 | 0x40000000, status);
}

View File

@@ -0,0 +1,87 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "primitives.h"
#include "specialize.h"
#include "softfloat.h"
float64 f128_to_f64(float128_t a, struct softfloat_status_t *status)
{
uint64_t uiA64, uiA0;
bool sign;
int32_t exp;
uint64_t frac64, frac0;
struct commonNaN commonNaN;
uint64_t uiZ;
struct uint128 frac128;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiA64 = a.v64;
uiA0 = a.v0;
sign = signF128UI64(uiA64);
exp = expF128UI64(uiA64);
frac64 = fracF128UI64(uiA64);
frac0 = uiA0;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (exp == 0x7FFF) {
if (frac64 | frac0) {
softfloat_f128UIToCommonNaN(uiA64, uiA0, &commonNaN, status);
uiZ = softfloat_commonNaNToF64UI(&commonNaN);
} else {
uiZ = packToF64UI(sign, 0x7FF, 0);
}
return uiZ;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
frac128 = softfloat_shortShiftLeft128(frac64, frac0, 14);
frac64 = frac128.v64 | (frac128.v0 != 0);
if (! (exp | frac64)) {
return packToF64UI(sign, 0, 0);
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
exp -= 0x3C01;
if (sizeof (int16_t) < sizeof (int32_t)) {
if (exp < -0x1000) exp = -0x1000;
}
return
softfloat_roundPackToF64(sign, exp, frac64 | UINT64_C(0x4000000000000000), status);
}

View File

@@ -0,0 +1,80 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
University of California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "primitives.h"
#include "specialize.h"
#include "softfloat.h"
int32_t f128_to_i32(float128_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
{
uint64_t uiA64, uiA0;
bool sign;
int32_t exp;
uint64_t sig64, sig0;
int32_t shiftDist;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiA64 = a.v64;
uiA0 = a.v0;
sign = signF128UI64(uiA64);
exp = expF128UI64(uiA64);
sig64 = fracF128UI64(uiA64);
sig0 = uiA0;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
#if (i32_fromNaN != i32_fromPosOverflow) || (i32_fromNaN != i32_fromNegOverflow)
if ((exp == 0x7FFF) && (sig64 | sig0)) {
#if (i32_fromNaN == i32_fromPosOverflow)
sign = 0;
#elif (i32_fromNaN == i32_fromNegOverflow)
sign = 1;
#else
softfloat_raiseFlags(status, softfloat_flag_invalid);
return i32_fromNaN;
#endif
}
#endif
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (exp) sig64 |= UINT64_C(0x0001000000000000);
sig64 |= (sig0 != 0);
shiftDist = 0x4023 - exp;
if (0 < shiftDist) sig64 = softfloat_shiftRightJam64(sig64, shiftDist);
return softfloat_roundToI32(sign, sig64, roundingMode, exact, status);
}

View File

@@ -0,0 +1,89 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
int32_t f128_to_i32_r_minMag(float128_t a, bool exact, struct softfloat_status_t *status)
{
uint64_t uiA64, uiA0;
int32_t exp;
uint64_t sig64;
int32_t shiftDist;
bool sign;
int32_t absZ;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiA64 = a.v64;
uiA0 = a.v0;
exp = expF128UI64(uiA64);
sig64 = fracF128UI64(uiA64) | (uiA0 != 0);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
shiftDist = 0x402F - exp;
if (49 <= shiftDist) {
if (exact && (exp | sig64)) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
return 0;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sign = signF128UI64(uiA64);
if (shiftDist < 18) {
if (sign && (shiftDist == 17) && (sig64 < UINT64_C(0x0000000000020000))) {
if (exact && sig64) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
return -0x7FFFFFFF - 1;
}
softfloat_raiseFlags(status, softfloat_flag_invalid);
return
(exp == 0x7FFF) && sig64 ? i32_fromNaN
: sign ? i32_fromNegOverflow : i32_fromPosOverflow;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sig64 |= UINT64_C(0x0001000000000000);
absZ = sig64>>shiftDist;
if (exact && ((uint64_t) (uint32_t) absZ<<shiftDist != sig64)) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
return sign ? -absZ : absZ;
}

View File

@@ -0,0 +1,90 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
University of California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "primitives.h"
#include "specialize.h"
#include "softfloat.h"
int64_t f128_to_i64(float128_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
{
uint64_t uiA64, uiA0;
bool sign;
int32_t exp;
uint64_t sig64, sig0;
int32_t shiftDist;
struct uint128 sig128;
struct uint64_extra sigExtra;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiA64 = a.v64;
uiA0 = a.v0;
sign = signF128UI64(uiA64);
exp = expF128UI64(uiA64);
sig64 = fracF128UI64(uiA64);
sig0 = uiA0;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
shiftDist = 0x402F - exp;
if (shiftDist <= 0) {
/*--------------------------------------------------------------------
*--------------------------------------------------------------------*/
if (shiftDist < -15) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return
(exp == 0x7FFF) && (sig64 | sig0) ? i64_fromNaN
: sign ? i64_fromNegOverflow : i64_fromPosOverflow;
}
/*--------------------------------------------------------------------
*--------------------------------------------------------------------*/
sig64 |= UINT64_C(0x0001000000000000);
if (shiftDist) {
sig128 = softfloat_shortShiftLeft128(sig64, sig0, -shiftDist);
sig64 = sig128.v64;
sig0 = sig128.v0;
}
} else {
/*--------------------------------------------------------------------
*--------------------------------------------------------------------*/
if (exp) sig64 |= UINT64_C(0x0001000000000000);
sigExtra = softfloat_shiftRightJam64Extra(sig64, sig0, shiftDist);
sig64 = sigExtra.v;
sig0 = sigExtra.extra;
}
return softfloat_roundToI64(sign, sig64, sig0, roundingMode, exact, status);
}

View File

@@ -0,0 +1,104 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
int64_t f128_to_i64_r_minMag(float128_t a, bool exact, struct softfloat_status_t *status)
{
uint64_t uiA64, uiA0;
bool sign;
int32_t exp;
uint64_t sig64, sig0;
int32_t shiftDist;
int8_t negShiftDist;
uint64_t absZ;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiA64 = a.v64;
uiA0 = a.v0;
sign = signF128UI64(uiA64);
exp = expF128UI64(uiA64);
sig64 = fracF128UI64(uiA64);
sig0 = uiA0;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
shiftDist = 0x402F - exp;
if (shiftDist < 0) {
/*--------------------------------------------------------------------
*--------------------------------------------------------------------*/
if (shiftDist < -14) {
if ((uiA64 == UINT64_C(0xC03E000000000000)) && (sig0 < UINT64_C(0x0002000000000000))) {
if (exact && sig0) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
return -INT64_C(0x7FFFFFFFFFFFFFFF) - 1;
}
softfloat_raiseFlags(status, softfloat_flag_invalid);
return (exp == 0x7FFF) && (sig64 | sig0)
? i64_fromNaN
: sign ? i64_fromNegOverflow : i64_fromPosOverflow;
}
/*--------------------------------------------------------------------
*--------------------------------------------------------------------*/
sig64 |= UINT64_C(0x0001000000000000);
negShiftDist = -shiftDist;
absZ = sig64<<negShiftDist | sig0>>(shiftDist & 63);
if (exact && (uint64_t) (sig0<<negShiftDist)) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
} else {
/*--------------------------------------------------------------------
*--------------------------------------------------------------------*/
if (49 <= shiftDist) {
if (exact && (exp | sig64 | sig0)) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
return 0;
}
/*--------------------------------------------------------------------
*--------------------------------------------------------------------*/
sig64 |= UINT64_C(0x0001000000000000);
absZ = sig64>>shiftDist;
if (exact && (sig0 || (absZ<<shiftDist != sig64))) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
}
return sign ? -absZ : absZ;
}

View File

@@ -0,0 +1,81 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
University of California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "primitives.h"
#include "specialize.h"
#include "softfloat.h"
uint32_t f128_to_ui32(float128_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
{
uint64_t uiA64, uiA0;
bool sign;
int32_t exp;
uint64_t sig64;
int32_t shiftDist;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiA64 = a.v64;
uiA0 = a.v0;
sign = signF128UI64(uiA64);
exp = expF128UI64(uiA64);
sig64 = fracF128UI64(uiA64) | (uiA0 != 0);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
#if (ui32_fromNaN != ui32_fromPosOverflow) || (ui32_fromNaN != ui32_fromNegOverflow)
if ((exp == 0x7FFF) && sig64) {
#if (ui32_fromNaN == ui32_fromPosOverflow)
sign = 0;
#elif (ui32_fromNaN == ui32_fromNegOverflow)
sign = 1;
#else
softfloat_raiseFlags(status, softfloat_flag_invalid);
return ui32_fromNaN;
#endif
}
#endif
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (exp) sig64 |= UINT64_C(0x0001000000000000);
shiftDist = 0x4023 - exp;
if (0 < shiftDist) {
sig64 = softfloat_shiftRightJam64(sig64, shiftDist);
}
return softfloat_roundToUI32(sign, sig64, roundingMode, exact, status);
}

View File

@@ -0,0 +1,83 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
uint32_t f128_to_ui32_r_minMag(float128_t a, bool exact, struct softfloat_status_t *status)
{
uint64_t uiA64, uiA0;
int32_t exp;
uint64_t sig64;
int32_t shiftDist;
bool sign;
uint32_t z;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiA64 = a.v64;
uiA0 = a.v0;
exp = expF128UI64(uiA64);
sig64 = fracF128UI64(uiA64) | (uiA0 != 0);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
shiftDist = 0x402F - exp;
if (49 <= shiftDist) {
if (exact && (exp | sig64)) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
return 0;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sign = signF128UI64(uiA64);
if (sign || (shiftDist < 17)) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return
(exp == 0x7FFF) && sig64 ? ui32_fromNaN
: sign ? ui32_fromNegOverflow : ui32_fromPosOverflow;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sig64 |= UINT64_C(0x0001000000000000);
z = sig64>>shiftDist;
if (exact && ((uint64_t) z<<shiftDist != sig64)) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
return z;
}

View File

@@ -0,0 +1,90 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
University of California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "primitives.h"
#include "specialize.h"
#include "softfloat.h"
uint64_t f128_to_ui64(float128_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
{
uint64_t uiA64, uiA0;
bool sign;
int32_t exp;
uint64_t sig64, sig0;
int32_t shiftDist;
struct uint128 sig128;
struct uint64_extra sigExtra;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiA64 = a.v64;
uiA0 = a.v0;
sign = signF128UI64(uiA64);
exp = expF128UI64(uiA64);
sig64 = fracF128UI64(uiA64);
sig0 = uiA0;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
shiftDist = 0x402F - exp;
if (shiftDist <= 0) {
/*--------------------------------------------------------------------
*--------------------------------------------------------------------*/
if (shiftDist < -15) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return
(exp == 0x7FFF) && (sig64 | sig0) ? ui64_fromNaN
: sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;
}
/*--------------------------------------------------------------------
*--------------------------------------------------------------------*/
sig64 |= UINT64_C(0x0001000000000000);
if (shiftDist) {
sig128 = softfloat_shortShiftLeft128(sig64, sig0, -shiftDist);
sig64 = sig128.v64;
sig0 = sig128.v0;
}
} else {
/*--------------------------------------------------------------------
*--------------------------------------------------------------------*/
if (exp) sig64 |= UINT64_C(0x0001000000000000);
sigExtra = softfloat_shiftRightJam64Extra(sig64, sig0, shiftDist);
sig64 = sigExtra.v;
sig0 = sigExtra.extra;
}
return softfloat_roundToUI64(sign, sig64, sig0, roundingMode, exact, status);
}

View File

@@ -0,0 +1,99 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
uint64_t f128_to_ui64_r_minMag(float128_t a, bool exact, struct softfloat_status_t *status)
{
uint64_t uiA64, uiA0;
bool sign;
int32_t exp;
uint64_t sig64, sig0;
int32_t shiftDist;
int8_t negShiftDist;
uint64_t z;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiA64 = a.v64;
uiA0 = a.v0;
sign = signF128UI64(uiA64);
exp = expF128UI64(uiA64);
sig64 = fracF128UI64(uiA64);
sig0 = uiA0;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
shiftDist = 0x402F - exp;
if (shiftDist < 0) {
/*--------------------------------------------------------------------
*--------------------------------------------------------------------*/
if (sign || (shiftDist < -15)) goto invalid;
sig64 |= UINT64_C(0x0001000000000000);
negShiftDist = -shiftDist;
z = sig64<<negShiftDist | sig0>>(shiftDist & 63);
if (exact && (uint64_t) (sig0<<negShiftDist)) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
} else {
/*--------------------------------------------------------------------
*--------------------------------------------------------------------*/
if (49 <= shiftDist) {
if (exact && (exp | sig64 | sig0)) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
return 0;
}
/*--------------------------------------------------------------------
*--------------------------------------------------------------------*/
if (sign) goto invalid;
sig64 |= UINT64_C(0x0001000000000000);
z = sig64>>shiftDist;
if (exact && (sig0 || (z<<shiftDist != sig64))) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
}
return z;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
invalid:
softfloat_raiseFlags(status, softfloat_flag_invalid);
return
(exp == 0x7FFF) && (sig64 | sig0) ? ui64_fromNaN
: sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;
}

View File

@@ -0,0 +1,60 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "softfloat.h"
extern float16 softfloat_addMagsF16(uint16_t, uint16_t, struct softfloat_status_t *);
extern float16 softfloat_subMagsF16(uint16_t, uint16_t, struct softfloat_status_t *);
float16 f16_add(float16 a, float16 b, struct softfloat_status_t *status)
{
if (signF16UI((uint16_t) a ^ (uint16_t) b)) {
return softfloat_subMagsF16(a, b, status);
} else {
return softfloat_addMagsF16(a, b, status);
}
}
float16 f16_sub(float16 a, float16 b, struct softfloat_status_t *status)
{
if (signF16UI((uint16_t) a ^ (uint16_t) b)) {
return softfloat_addMagsF16(a, b, status);
} else {
return softfloat_subMagsF16(a, b, status);
}
}

View File

@@ -0,0 +1,64 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "softfloat.h"
softfloat_class_t f16_class(float16 a)
{
bool signA;
int8_t expA;
uint16_t sigA;
signA = signF16UI(a);
expA = expF16UI(a);
sigA = fracF16UI(a);
if (expA == 0x1F) {
if (sigA == 0)
return (signA) ? softfloat_negative_inf : softfloat_positive_inf;
return (sigA & 0x200) ? softfloat_QNaN : softfloat_SNaN;
}
if (expA == 0) {
if (sigA == 0) return softfloat_zero;
return softfloat_denormal;
}
return softfloat_normalized;
}

View File

@@ -0,0 +1,92 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "softfloat.h"
/*----------------------------------------------------------------------------
| Compare between two half precision floating point numbers. Returns
| 'float_relation_equal' if the operands are equal, 'float_relation_less' if
| the value 'a' is less than the corresponding value `b',
| 'float_relation_greater' if the value 'a' is greater than the corresponding
| value `b', or 'float_relation_unordered' otherwise.
*----------------------------------------------------------------------------*/
int f16_compare(float16 a, float16 b, bool quiet, struct softfloat_status_t *status)
{
softfloat_class_t aClass;
softfloat_class_t bClass;
bool signA;
bool signB;
aClass = f16_class(a);
bClass = f16_class(b);
if (aClass == softfloat_SNaN || bClass == softfloat_SNaN) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return softfloat_relation_unordered;
}
if (aClass == softfloat_QNaN || bClass == softfloat_QNaN) {
if (! quiet) softfloat_raiseFlags(status, softfloat_flag_invalid);
return softfloat_relation_unordered;
}
if (aClass == softfloat_denormal) {
if (softfloat_denormalsAreZeros(status))
a = a & 0x8000;
else
softfloat_raiseFlags(status, softfloat_flag_denormal);
}
if (bClass == softfloat_denormal) {
if (softfloat_denormalsAreZeros(status))
b = b & 0x8000;
else
softfloat_raiseFlags(status, softfloat_flag_denormal);
}
if ((a == b) || ((uint16_t) ((a | b)<<1) == 0)) return softfloat_relation_equal;
signA = signF16UI(a);
signB = signF16UI(b);
if (signA != signB)
return (signA) ? softfloat_relation_less : softfloat_relation_greater;
if (signA ^ (a < b)) return softfloat_relation_less;
return softfloat_relation_greater;
}

View File

@@ -0,0 +1,149 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
#define SOFTFLOAT_FAST_DIV32TO16 1
extern const uint16_t softfloat_approxRecip_1k0s[];
extern const uint16_t softfloat_approxRecip_1k1s[];
float16 f16_div(float16 a, float16 b, struct softfloat_status_t *status)
{
bool signA;
int8_t expA;
uint16_t sigA;
bool signB;
int8_t expB;
uint16_t sigB;
bool signZ;
struct exp8_sig16 normExpSig;
int8_t expZ;
#ifdef SOFTFLOAT_FAST_DIV32TO16
uint32_t sig32A;
uint16_t sigZ;
#endif
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
signA = signF16UI(a);
expA = expF16UI(a);
sigA = fracF16UI(a);
signB = signF16UI(b);
expB = expF16UI(b);
sigB = fracF16UI(b);
signZ = signA ^ signB;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (softfloat_denormalsAreZeros(status)) {
if (!expA) sigA = 0;
if (!expB) sigB = 0;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (expA == 0x1F) {
if (sigA) goto propagateNaN;
if (expB == 0x1F) {
if (sigB) goto propagateNaN;
goto invalid;
}
if (sigB && !expB)
softfloat_raiseFlags(status, softfloat_flag_denormal);
goto infinity;
}
if (expB == 0x1F) {
if (sigB) goto propagateNaN;
if (sigA && !expA)
softfloat_raiseFlags(status, softfloat_flag_denormal);
goto zero;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (! expB) {
if (! sigB) {
if (! (expA | sigA)) goto invalid;
softfloat_raiseFlags(status, softfloat_flag_infinite);
goto infinity;
}
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalF16Sig(sigB);
expB = normExpSig.exp;
sigB = normExpSig.sig;
}
if (! expA) {
if (! sigA) goto zero;
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalF16Sig(sigA);
expA = normExpSig.exp;
sigA = normExpSig.sig;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
expZ = expA - expB + 0xE;
sigA |= 0x0400;
sigB |= 0x0400;
#ifdef SOFTFLOAT_FAST_DIV32TO16
if (sigA < sigB) {
--expZ;
sig32A = (uint32_t) sigA<<15;
} else {
sig32A = (uint32_t) sigA<<14;
}
sigZ = sig32A / sigB;
if (! (sigZ & 7)) sigZ |= ((uint32_t) sigB * sigZ != sig32A);
#endif
return softfloat_roundPackToF16(signZ, expZ, sigZ, status);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
propagateNaN:
return softfloat_propagateNaNF16UI(a, b, status);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
invalid:
softfloat_raiseFlags(status, softfloat_flag_invalid);
return defaultNaNF16UI;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
infinity:
return packToF16UI(signZ, 0x1F, 0);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
zero:
return packToF16UI(signZ, 0, 0);
}

View File

@@ -0,0 +1,73 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
/*----------------------------------------------------------------------------
| Extracts the exponent portion of half-precision floating-point value 'a',
| and returns the result as a half-precision floating-point value
| representing unbiased integer exponent. The operation is performed according
| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
float16 f16_getExp(float16 a, struct softfloat_status_t *status)
{
int8_t expA;
uint16_t sigA;
struct exp8_sig16 normExpSig;
expA = expF16UI(a);
sigA = fracF16UI(a);
if (expA == 0x1F) {
if (sigA) return softfloat_propagateNaNF16UI(a, 0, status);
return (float16)packToF32UI(0, 0x1F, 0);
}
if (! expA) {
if (! sigA || softfloat_denormalsAreZeros(status))
return (float16)packToF32UI(1, 0x1F, 0);
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalF16Sig(sigA);
expA = normExpSig.exp;
}
return i32_to_f16((int32_t)(expA) - 0xF, status);
}

View File

@@ -0,0 +1,108 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
/*----------------------------------------------------------------------------
| Extracts the mantissa of half-precision floating-point value 'a' and
| returns the result as a half-precision floating-point after applying
| the mantissa interval normalization and sign control. The operation is
| performed according to the IEC/IEEE Standard for Binary Floating-Point
| Arithmetic.
*----------------------------------------------------------------------------*/
float16 f16_getMant(float16 a, struct softfloat_status_t *status, int sign_ctrl, int interv)
{
bool signA;
int8_t expA;
uint16_t sigA;
struct exp8_sig16 normExpSig;
signA = signF16UI(a);
expA = expF16UI(a);
sigA = fracF16UI(a);
if (expA == 0x1F) {
if (sigA) return softfloat_propagateNaNF16UI(a, 0, status);
if (signA) {
if (sign_ctrl & 0x2) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return defaultNaNF16UI;
}
}
return packToF16UI(~sign_ctrl & signA, 0x1F, 0);
}
if (! expA && (! sigA || softfloat_denormalsAreZeros(status))) {
return packToF16UI(~sign_ctrl & signA, 0x1F, 0);
}
if (signA) {
if (sign_ctrl & 0x2) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return defaultNaNF16UI;
}
}
if (expA == 0) {
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalF16Sig(sigA);
expA = normExpSig.exp;
sigA = normExpSig.sig;
sigA &= 0x3ff;
}
switch(interv) {
case 0x0: // interval [1,2)
expA = 0xF;
break;
case 0x1: // interval [1/2,2)
expA -= 0xF;
expA = 0xF - (expA & 0x1);
break;
case 0x2: // interval [1/2,1)
expA = 0xE;
break;
case 0x3: // interval [3/4,3/2)
expA = 0xF - ((sigA >> 9) & 0x1);
break;
}
return packToF16UI(~sign_ctrl & signA, expA, sigA);
}

View File

@@ -0,0 +1,69 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "softfloat.h"
/*----------------------------------------------------------------------------
| Compare between two half precision floating point numbers and return the
| smaller of them.
*----------------------------------------------------------------------------*/
float16 f16_min(float16 a, float16 b, struct softfloat_status_t *status)
{
if (softfloat_denormalsAreZeros(status)) {
a = f16_denormal_to_zero(a);
b = f16_denormal_to_zero(b);
}
return (f16_compare_normal(a, b, status) == softfloat_relation_less) ? a : b;
}
/*----------------------------------------------------------------------------
| Compare between two half precision floating point numbers and return the
| larger of them.
*----------------------------------------------------------------------------*/
float16 f16_max(float16 a, float16 b, struct softfloat_status_t *status)
{
if (softfloat_denormalsAreZeros(status)) {
a = f16_denormal_to_zero(a);
b = f16_denormal_to_zero(b);
}
return (f16_compare_normal(a, b, status) == softfloat_relation_greater) ? a : b;
}

View File

@@ -0,0 +1,139 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
float16 f16_mul(float16 a, float16 b, struct softfloat_status_t *status)
{
bool signA;
int8_t expA;
uint16_t sigA;
bool signB;
int8_t expB;
uint16_t sigB;
bool signZ;
uint16_t magBits;
struct exp8_sig16 normExpSig;
int8_t expZ;
uint32_t sig32Z;
uint16_t sigZ, uiZ;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
signA = signF16UI(a);
expA = expF16UI(a);
sigA = fracF16UI(a);
signB = signF16UI(b);
expB = expF16UI(b);
sigB = fracF16UI(b);
signZ = signA ^ signB;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (softfloat_denormalsAreZeros(status)) {
if (!expA) sigA = 0;
if (!expB) sigB = 0;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (expA == 0x1F) {
if (sigA || ((expB == 0x1F) && sigB)) goto propagateNaN;
magBits = expB | sigB;
if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal);
goto infArg;
}
if (expB == 0x1F) {
if (sigB) goto propagateNaN;
magBits = expA | sigA;
if (sigA && !expA) softfloat_raiseFlags(status, softfloat_flag_denormal);
goto infArg;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (! expA) {
if (! sigA) {
if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal);
goto zero;
}
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalF16Sig(sigA);
expA = normExpSig.exp;
sigA = normExpSig.sig;
}
if (! expB) {
if (! sigB) {
if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal);
goto zero;
}
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalF16Sig(sigB);
expB = normExpSig.exp;
sigB = normExpSig.sig;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
expZ = expA + expB - 0xF;
sigA = (sigA | 0x0400)<<4;
sigB = (sigB | 0x0400)<<5;
sig32Z = (uint32_t) sigA * sigB;
sigZ = sig32Z>>16;
if (sig32Z & 0xFFFF) sigZ |= 1;
if (sigZ < 0x4000) {
--expZ;
sigZ <<= 1;
}
return softfloat_roundPackToF16(signZ, expZ, sigZ, status);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
propagateNaN:
return softfloat_propagateNaNF16UI(a, b, status);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
infArg:
if (! magBits) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
uiZ = defaultNaNF16UI;
} else {
uiZ = packToF16UI(signZ, 0x1F, 0);
}
return uiZ;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
zero:
return packToF16UI(signZ, 0, 0);
}

View File

@@ -0,0 +1,232 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdint.h>
#include "internals.h"
#include "primitives.h"
#include "softfloat.h"
#include "specialize.h"
float16 f16_mulAdd(float16 a, float16 b, float16 c, uint8_t op, struct softfloat_status_t *status)
{
bool signA;
int8_t expA;
uint16_t sigA;
bool signB;
int8_t expB;
uint16_t sigB;
bool signC;
int8_t expC;
uint16_t sigC;
bool signProd;
uint16_t magBits, uiA, uiB, uiC, uiZ;
struct exp8_sig16 normExpSig;
int8_t expProd;
uint32_t sigProd;
bool signZ;
int8_t expZ;
uint16_t sigZ;
int8_t expDiff;
uint32_t sig32Z, sig32C;
int8_t shiftDist;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiA = a;
uiB = b;
uiC = c;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
signA = signF16UI(uiA);
expA = expF16UI(uiA);
sigA = fracF16UI(uiA);
signB = signF16UI(uiB);
expB = expF16UI(uiB);
sigB = fracF16UI(uiB);
signC = signF16UI(uiC) ^ ((op & softfloat_mulAdd_subC) != 0);
expC = expF16UI(uiC);
sigC = fracF16UI(uiC);
signProd = signA ^ signB ^ ((op & softfloat_mulAdd_subProd) != 0);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
bool aisNaN = (expA == 0x1F) && sigA;
bool bisNaN = (expB == 0x1F) && sigB;
bool cisNaN = (expC == 0x1F) && sigC;
if (aisNaN | bisNaN | cisNaN) {
uiZ = (aisNaN | bisNaN) ? softfloat_propagateNaNF16UI(uiA, uiB, status) : 0;
return softfloat_propagateNaNF16UI(uiZ, uiC, status);
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (softfloat_denormalsAreZeros(status)) {
if (!expA) sigA = 0;
if (!expB) sigB = 0;
if (!expC) sigC = 0;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (expA == 0x1F) {
magBits = expB | sigB;
goto infProdArg;
}
if (expB == 0x1F) {
magBits = expA | sigA;
goto infProdArg;
}
if (expC == 0x1F) {
if ((sigA && !expA) || (sigB && !expB)) {
softfloat_raiseFlags(status, softfloat_flag_denormal);
}
return packToF16UI(signC, 0x1F, 0);
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (! expA) {
if (! sigA) goto zeroProd;
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalF16Sig(sigA);
expA = normExpSig.exp;
sigA = normExpSig.sig;
}
if (! expB) {
if (! sigB) goto zeroProd;
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalF16Sig(sigB);
expB = normExpSig.exp;
sigB = normExpSig.sig;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
expProd = expA + expB - 0xE;
sigA = (sigA | 0x0400)<<4;
sigB = (sigB | 0x0400)<<4;
sigProd = (uint32_t) sigA * sigB;
if (sigProd < 0x20000000) {
--expProd;
sigProd <<= 1;
}
signZ = signProd;
if (! expC) {
if (! sigC) {
expZ = expProd - 1;
sigZ = sigProd>>15 | ((sigProd & 0x7FFF) != 0);
goto roundPack;
}
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalF16Sig(sigC);
expC = normExpSig.exp;
sigC = normExpSig.sig;
}
sigC = (sigC | 0x0400)<<3;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
expDiff = expProd - expC;
if (signProd == signC) {
/*--------------------------------------------------------------------
*--------------------------------------------------------------------*/
if (expDiff <= 0) {
expZ = expC;
sigZ = sigC + softfloat_shiftRightJam32(sigProd, 16 - expDiff);
} else {
expZ = expProd;
sig32Z = sigProd + softfloat_shiftRightJam32((uint32_t) sigC<<16, expDiff);
sigZ = sig32Z>>16 | ((sig32Z & 0xFFFF) != 0);
}
if (sigZ < 0x4000) {
--expZ;
sigZ <<= 1;
}
} else {
/*--------------------------------------------------------------------
*--------------------------------------------------------------------*/
sig32C = (uint32_t) sigC<<16;
if (expDiff < 0) {
signZ = signC;
expZ = expC;
sig32Z = sig32C - softfloat_shiftRightJam32(sigProd, -expDiff);
} else if (! expDiff) {
expZ = expProd;
sig32Z = sigProd - sig32C;
if (! sig32Z) goto completeCancellation;
if (sig32Z & 0x80000000) {
signZ = ! signZ;
sig32Z = -sig32Z;
}
} else {
expZ = expProd;
sig32Z = sigProd - softfloat_shiftRightJam32(sig32C, expDiff);
}
shiftDist = softfloat_countLeadingZeros32(sig32Z) - 1;
expZ -= shiftDist;
shiftDist -= 16;
if (shiftDist < 0) {
sigZ = sig32Z>>(-shiftDist) | ((uint32_t) (sig32Z<<(shiftDist & 31)) != 0);
} else {
sigZ = (uint16_t) sig32Z<<shiftDist;
}
}
roundPack:
return softfloat_roundPackToF16(signZ, expZ, sigZ, status);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
infProdArg:
if (magBits) {
uiZ = packToF16UI(signProd, 0x1F, 0);
if (signProd == signC || expC != 0x1F) {
if ((sigA && !expA) || (sigB && !expB) || (sigC && !expC))
softfloat_raiseFlags(status, softfloat_flag_denormal);
return uiZ;
}
}
softfloat_raiseFlags(status, softfloat_flag_invalid);
uiZ = defaultNaNF16UI;
return softfloat_propagateNaNF16UI(uiZ, uiC, status);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
zeroProd:
uiZ = packToF16UI(signC, expC, sigC);
if (!expC && sigC) {
/* Exact zero plus a denormal */
softfloat_raiseFlags(status, softfloat_flag_denormal);
if (softfloat_flushUnderflowToZero(status)) {
softfloat_raiseFlags(status, softfloat_flag_underflow | softfloat_flag_inexact);
return packToF16UI(signC, 0, 0);
}
}
if (! (expC | sigC) && (signProd != signC)) {
completeCancellation:
uiZ = packToF16UI((softfloat_getRoundingMode(status) == softfloat_round_min), 0, 0);
}
return uiZ;
}

View File

@@ -0,0 +1,135 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
float16 f16_range(float16 a, float16 b, bool is_max, bool is_abs, int sign_ctrl, struct softfloat_status_t *status)
{
bool signA;
int8_t expA;
uint16_t sigA;
bool signB;
int8_t expB;
uint16_t sigB;
bool aIsNaN, bIsNaN;
uint16_t z;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
signA = signF16UI(a);
expA = expF16UI(a);
sigA = fracF16UI(a);
signB = signF16UI(b);
expB = expF16UI(b);
sigB = fracF16UI(b);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (softfloat_isSigNaNF16UI(a)) {
return softfloat_propagateNaNF16UI(a, 0, status);
}
if (softfloat_isSigNaNF16UI(b)) {
return softfloat_propagateNaNF16UI(b, 0, status);
}
aIsNaN = isNaNF16UI(a);
bIsNaN = isNaNF16UI(b);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (! expA && sigA) {
if (softfloat_denormalsAreZeros(status)) {
a = packToF16UI(signA, 0, 0);
}
else if (! bIsNaN) {
softfloat_raiseFlags(status, softfloat_flag_denormal);
}
}
if (! expB && sigB) {
if (softfloat_denormalsAreZeros(status)) {
b = packToF16UI(signB, 0, 0);
}
else if (! aIsNaN) {
softfloat_raiseFlags(status, softfloat_flag_denormal);
}
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (bIsNaN) {
z = a;
}
else if (aIsNaN) {
z = b;
}
else if (signA != signB && ! is_abs) {
if (! is_max) {
z = signA ? a : b;
} else {
z = signA ? b : a;
}
} else {
float16 tmp_a = a, tmp_b = b;
if (is_abs) {
tmp_a = tmp_a & ~0x8000; // clear the sign bit
tmp_b = tmp_b & ~0x8000;
signA = 0;
}
if (! is_max) {
z = (signA ^ (tmp_a < tmp_b)) ? a : b;
} else {
z = (signA ^ (tmp_a < tmp_b)) ? b : a;
}
}
switch(sign_ctrl) {
case 0:
z = (z & ~0x8000) | (a & 0x8000); // keep sign of a
break;
case 1:
break; // preserve sign of compare result
case 2:
z = z & ~0x8000; // zero out the sign bit
break;
case 3:
z = z | 0x8000; // set the sign bit
break;
}
return z;
}

View File

@@ -0,0 +1,112 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
float16 f16_roundToInt(float16 a, uint8_t scale, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
{
int8_t exp;
uint16_t frac;
bool sign;
uint16_t uiZ, lastBitMask, roundBitsMask;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
scale &= 0xF;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
exp = expF16UI(a);
frac = fracF16UI(a);
sign = signF16UI(a);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (0x19 <= (exp + scale)) {
if ((exp == 0x1F) && frac) {
return softfloat_propagateNaNF16UI(a, 0, status);
}
return a;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (softfloat_denormalsAreZeros(status)) {
if (!exp) {
frac = 0;
a = packToF16UI(sign, 0, 0);
}
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if ((exp + scale) <= 0xE) {
if (!(exp | frac)) return a;
if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact);
uiZ = packToF16UI(sign, 0, 0);
switch (roundingMode) {
case softfloat_round_near_even:
if (!frac) break;
case softfloat_round_near_maxMag:
if ((exp + scale) == 0xE) uiZ |= packToF16UI(0, 0xF - scale, 0);
break;
case softfloat_round_min:
if (uiZ) uiZ = packToF16UI(1, 0xF - scale, 0);
break;
case softfloat_round_max:
if (!uiZ) uiZ = packToF16UI(0, 0xF - scale, 0);
break;
}
return uiZ;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiZ = a;
lastBitMask = (uint16_t) 1<<(0x19 - exp - scale);
roundBitsMask = lastBitMask - 1;
if (roundingMode == softfloat_round_near_maxMag) {
uiZ += lastBitMask>>1;
} else if (roundingMode == softfloat_round_near_even) {
uiZ += lastBitMask>>1;
if (!(uiZ & roundBitsMask)) uiZ &= ~lastBitMask;
} else if (roundingMode == (signF16UI(uiZ) ? softfloat_round_min : softfloat_round_max)) {
uiZ += roundBitsMask;
}
uiZ &= ~roundBitsMask;
if (uiZ != a) {
if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact);
}
return uiZ;
}

View File

@@ -0,0 +1,130 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
extern const uint16_t softfloat_approxRecipSqrt_1k0s[];
extern const uint16_t softfloat_approxRecipSqrt_1k1s[];
float16 f16_sqrt(float16 a, struct softfloat_status_t *status)
{
bool signA;
int8_t expA;
uint16_t sigA;
struct exp8_sig16 normExpSig;
int8_t expZ;
int index;
uint16_t r0;
uint32_t ESqrR0;
uint16_t sigma0;
uint16_t recipSqrt16, sigZ, shiftedSigZ;
uint16_t negRem;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
signA = signF16UI(a);
expA = expF16UI(a);
sigA = fracF16UI(a);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (expA == 0x1F) {
if (sigA) {
return softfloat_propagateNaNF16UI(a, 0, status);
}
if (! signA) return a;
goto invalid;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (softfloat_denormalsAreZeros(status)) {
if (!expA) {
sigA = 0;
a = packToF16UI(signA, 0, 0);
}
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (signA) {
if (! (expA | sigA)) return a;
goto invalid;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (! expA) {
if (! sigA) return a;
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalF16Sig(sigA);
expA = normExpSig.exp;
sigA = normExpSig.sig;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
expZ = ((expA - 0xF)>>1) + 0xE;
expA &= 1;
sigA |= 0x0400;
index = (sigA>>6 & 0xE) + expA;
r0 = softfloat_approxRecipSqrt_1k0s[index]
- (((uint32_t) softfloat_approxRecipSqrt_1k1s[index] * (sigA & 0x7F)) >>11);
ESqrR0 = ((uint32_t) r0 * r0)>>1;
if (expA) ESqrR0 >>= 1;
sigma0 = ~(uint16_t) ((ESqrR0 * sigA)>>16);
recipSqrt16 = r0 + (((uint32_t) r0 * sigma0)>>25);
if (! (recipSqrt16 & 0x8000)) recipSqrt16 = 0x8000;
sigZ = ((uint32_t) (sigA<<5) * recipSqrt16)>>16;
if (expA) sigZ >>= 1;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
++sigZ;
if (! (sigZ & 7)) {
shiftedSigZ = sigZ>>1;
negRem = shiftedSigZ * shiftedSigZ;
sigZ &= ~1;
if (negRem & 0x8000) {
sigZ |= 1;
} else {
if (negRem) --sigZ;
}
}
return softfloat_roundPackToF16(0, expZ, sigZ, status);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
invalid:
softfloat_raiseFlags(status, softfloat_flag_invalid);
return defaultNaNF16UI;
}

View File

@@ -0,0 +1,88 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
extFloat80_t f16_to_extF80(float16 a, struct softfloat_status_t *status)
{
bool sign;
int8_t exp;
uint16_t frac;
struct commonNaN commonNaN;
struct uint128 uiZ;
uint16_t uiZ64;
uint64_t uiZ0;
struct exp8_sig16 normExpSig;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sign = signF16UI(a);
exp = expF16UI(a);
frac = fracF16UI(a);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (exp == 0x1F) {
if (frac) {
softfloat_f16UIToCommonNaN(a, &commonNaN, status);
uiZ = softfloat_commonNaNToExtF80UI(&commonNaN);
uiZ64 = uiZ.v64;
uiZ0 = uiZ.v0;
} else {
uiZ64 = packToExtF80UI64(sign, 0x7FFF);
uiZ0 = UINT64_C(0x8000000000000000);
}
return packToExtF80_twoargs(uiZ64, uiZ0);
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (! exp) {
if (! frac) {
return packToExtF80(sign, 0, 0);
}
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalF16Sig(frac);
exp = normExpSig.exp;
frac = normExpSig.sig;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiZ64 = packToExtF80UI64(sign, exp + 0x3FF0);
uiZ0 = (uint64_t) (frac | 0x0400)<<53;
return packToExtF80_twoargs(uiZ64, uiZ0);
}

View File

@@ -0,0 +1,81 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
float32 f16_to_f32(float16 a, struct softfloat_status_t *status)
{
bool sign;
int8_t exp;
uint16_t frac;
struct commonNaN commonNaN;
uint32_t uiZ;
struct exp8_sig16 normExpSig;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sign = signF16UI(a);
exp = expF16UI(a);
frac = fracF16UI(a);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (exp == 0x1F) {
if (frac) {
softfloat_f16UIToCommonNaN(a, &commonNaN, status);
uiZ = softfloat_commonNaNToF32UI(&commonNaN);
} else {
uiZ = packToF32UI(sign, 0xFF, 0);
}
return uiZ;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (! exp) {
if (! frac || softfloat_denormalsAreZeros(status)) {
return packToF32UI(sign, 0, 0);
}
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalF16Sig(frac);
exp = normExpSig.exp - 1;
frac = normExpSig.sig;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
return packToF32UI(sign, exp + 0x70, (uint32_t) frac<<13);
}

View File

@@ -0,0 +1,81 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
float64 f16_to_f64(float16 a, struct softfloat_status_t *status)
{
bool sign;
int8_t exp;
uint16_t frac;
struct commonNaN commonNaN;
uint64_t uiZ;
struct exp8_sig16 normExpSig;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sign = signF16UI(a);
exp = expF16UI(a);
frac = fracF16UI(a);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (exp == 0x1F) {
if (frac) {
softfloat_f16UIToCommonNaN(a, &commonNaN, status);
uiZ = softfloat_commonNaNToF64UI(&commonNaN);
} else {
uiZ = packToF64UI(sign, 0x7FF, 0);
}
return uiZ;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (! exp) {
if (! frac || softfloat_denormalsAreZeros(status)) {
return packToF64UI(sign, 0, 0);
}
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalF16Sig(frac);
exp = normExpSig.exp - 1;
frac = normExpSig.sig;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
return packToF64UI(sign, exp + 0x3F0, (uint64_t) frac<<42);
}

View File

@@ -0,0 +1,81 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
University of California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
int32_t f16_to_i32(float16 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
{
bool sign;
int8_t exp;
uint16_t frac;
int32_t sig32;
int8_t shiftDist;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sign = signF16UI(a);
exp = expF16UI(a);
frac = fracF16UI(a);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (exp == 0x1F) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return
frac ? i32_fromNaN
: sign ? i32_fromNegOverflow : i32_fromPosOverflow;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sig32 = frac;
if (exp) {
sig32 |= 0x0400;
shiftDist = exp - 0x19;
if (0 <= shiftDist) {
sig32 <<= shiftDist;
return sign ? -sig32 : sig32;
}
shiftDist = exp - 0x0D;
if (0 < shiftDist) sig32 <<= shiftDist;
}
else {
if (softfloat_denormalsAreZeros(status)) sig32 = 0;
}
return softfloat_roundToI32(sign, (uint32_t) sig32, roundingMode, exact, status);
}

View File

@@ -0,0 +1,82 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
int32_t f16_to_i32_r_minMag(float16 a, bool exact, struct softfloat_status_t *status)
{
int8_t exp;
uint16_t frac;
int8_t shiftDist;
bool sign;
int32_t alignedSig;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
exp = expF16UI(a);
frac = fracF16UI(a);
if (softfloat_denormalsAreZeros(status))
if (!exp && frac) frac = 0;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
shiftDist = exp - 0x0F;
if (shiftDist < 0) {
if (exact && (exp | frac)) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
return 0;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sign = signF16UI(a);
if (exp == 0x1F) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return (exp == 0x1F) && frac
? i32_fromNaN
: sign ? i32_fromNegOverflow : i32_fromPosOverflow;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
alignedSig = (int32_t) (frac | 0x0400)<<shiftDist;
if (exact && (alignedSig & 0x3FF)) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
alignedSig >>= 10;
return sign ? -alignedSig : alignedSig;
}

View File

@@ -0,0 +1,80 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
University of California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
int64_t f16_to_i64(float16 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
{
bool sign;
int8_t exp;
uint16_t frac;
int32_t sig32;
int8_t shiftDist;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sign = signF16UI(a);
exp = expF16UI(a);
frac = fracF16UI(a);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (exp == 0x1F) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return
frac ? i64_fromNaN
: sign ? i64_fromNegOverflow : i64_fromPosOverflow;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sig32 = frac;
if (exp) {
sig32 |= 0x0400;
shiftDist = exp - 0x19;
if (0 <= shiftDist) {
sig32 <<= shiftDist;
return sign ? -sig32 : sig32;
}
shiftDist = exp - 0x0D;
if (0 < shiftDist) sig32 <<= shiftDist;
}
else {
if (softfloat_denormalsAreZeros(status)) sig32 = 0;
}
return softfloat_roundToI32(sign, (uint32_t) sig32, roundingMode, exact, status);
}

View File

@@ -0,0 +1,82 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
int64_t f16_to_i64_r_minMag(float16 a, bool exact, struct softfloat_status_t *status)
{
int8_t exp;
uint16_t frac;
int8_t shiftDist;
bool sign;
int32_t alignedSig;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
exp = expF16UI(a);
frac = fracF16UI(a);
if (softfloat_denormalsAreZeros(status))
if (!exp && frac) frac = 0;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
shiftDist = exp - 0x0F;
if (shiftDist < 0) {
if (exact && (exp | frac)) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
return 0;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sign = signF16UI(a);
if (exp == 0x1F) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return (exp == 0x1F) && frac
? i64_fromNaN
: sign ? i64_fromNegOverflow : i64_fromPosOverflow;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
alignedSig = (int32_t) (frac | 0x0400)<<shiftDist;
if (exact && (alignedSig & 0x3FF)) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
alignedSig >>= 10;
return sign ? -alignedSig : alignedSig;
}

View File

@@ -0,0 +1,79 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
University of California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
uint32_t f16_to_ui32(float16 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
{
bool sign;
int8_t exp;
uint16_t frac;
uint32_t sig32;
int8_t shiftDist;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sign = signF16UI(a);
exp = expF16UI(a);
frac = fracF16UI(a);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (exp == 0x1F) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return
frac ? ui32_fromNaN
: sign ? ui32_fromNegOverflow : ui32_fromPosOverflow;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sig32 = frac;
if (exp) {
sig32 |= 0x0400;
shiftDist = exp - 0x19;
if ((0 <= shiftDist) && ! sign) {
return sig32<<shiftDist;
}
shiftDist = exp - 0x0D;
if (0 < shiftDist) sig32 <<= shiftDist;
}
else {
if (softfloat_denormalsAreZeros(status)) sig32 = 0;
}
return softfloat_roundToUI32(sign, sig32, roundingMode, exact, status);
}

View File

@@ -0,0 +1,81 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
uint32_t f16_to_ui32_r_minMag(float16 a, bool exact, struct softfloat_status_t *status)
{
int8_t exp;
uint16_t frac;
int8_t shiftDist;
bool sign;
uint32_t alignedSig;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
exp = expF16UI(a);
frac = fracF16UI(a);
if (softfloat_denormalsAreZeros(status))
if (!exp && frac) frac = 0;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
shiftDist = exp - 0x0F;
if (shiftDist < 0) {
if (exact && (exp | frac)) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
return 0;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sign = signF16UI(a);
if (sign || (exp == 0x1F)) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return (exp == 0x1F) && frac
? ui32_fromNaN
: sign ? ui32_fromNegOverflow : ui32_fromPosOverflow;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
alignedSig = (uint32_t) (frac | 0x0400)<<shiftDist;
if (exact && (alignedSig & 0x3FF)) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
return alignedSig>>10;
}

View File

@@ -0,0 +1,79 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the
University of California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
uint64_t f16_to_ui64(float16 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
{
bool sign;
int8_t exp;
uint16_t frac;
uint32_t sig32;
int8_t shiftDist;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sign = signF16UI(a);
exp = expF16UI(a);
frac = fracF16UI(a);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (exp == 0x1F) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return
frac ? ui64_fromNaN
: sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sig32 = frac;
if (exp) {
sig32 |= 0x0400;
shiftDist = exp - 0x19;
if ((0 <= shiftDist) && ! sign) {
return sig32<<shiftDist;
}
shiftDist = exp - 0x0D;
if (0 < shiftDist) sig32 <<= shiftDist;
}
else {
if (softfloat_denormalsAreZeros(status)) sig32 = 0;
}
return softfloat_roundToUI64(sign, sig32>>12, (uint64_t) sig32<<52, roundingMode, exact, status);
}

View File

@@ -0,0 +1,81 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
uint64_t f16_to_ui64_r_minMag(float16 a, bool exact, struct softfloat_status_t *status)
{
int8_t exp;
uint16_t frac;
int8_t shiftDist;
bool sign;
uint32_t alignedSig;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
exp = expF16UI(a);
frac = fracF16UI(a);
if (softfloat_denormalsAreZeros(status))
if (!exp && frac) frac = 0;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
shiftDist = exp - 0x0F;
if (shiftDist < 0) {
if (exact && (exp | frac)) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
return 0;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sign = signF16UI(a);
if (sign || (exp == 0x1F)) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return (exp == 0x1F) && frac
? ui64_fromNaN
: sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
alignedSig = (uint32_t) (frac | 0x0400)<<shiftDist;
if (exact && (alignedSig & 0x3FF)) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
return alignedSig>>10;
}

View File

@@ -0,0 +1,187 @@
/*============================================================================
This source file is an extension to the SoftFloat IEC/IEEE Floating-point
Arithmetic Package, Release 2b, written for Bochs (x86 achitecture simulator)
floating point emulation.
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
Derivative works are acceptable, even for commercial purposes, so long as
(1) the source code for the derivative work includes prominent notice that
the work is derivative, and (2) the source code includes prominent notice with
these four paragraphs for those parts of this code that are retained.
=============================================================================*/
/*============================================================================
* Written for Bochs (x86 achitecture simulator) by
* Stanislav Shwartsman [sshwarts at sourceforge net]
* ==========================================================================*/
#define FLOAT128
#include "config.h"
#include "specialize.h"
#include "fpu_trans.h"
#include "softfloat-helpers.h"
static const floatx80 floatx80_negone = packFloatx80(1, 0x3fff, BX_CONST64(0x8000000000000000));
static const floatx80 floatx80_neghalf = packFloatx80(1, 0x3ffe, BX_CONST64(0x8000000000000000));
static const float128_t float128_ln2 =
packFloat128(BX_CONST64(0x3ffe62e42fefa39e), BX_CONST64(0xf35793c7673007e6));
#ifdef BETTER_THAN_PENTIUM
#define LN2_SIG_HI BX_CONST64(0xb17217f7d1cf79ab)
#define LN2_SIG_LO BX_CONST64(0xc9e3b39800000000) /* 96 bit precision */
#else
#define LN2_SIG_HI BX_CONST64(0xb17217f7d1cf79ab)
#define LN2_SIG_LO BX_CONST64(0xc000000000000000) /* 67-bit precision */
#endif
#define EXP_ARR_SIZE 15
static float128_t exp_arr[EXP_ARR_SIZE] =
{
PACK_FLOAT_128(0x3fff000000000000, 0x0000000000000000), /* 1 */
PACK_FLOAT_128(0x3ffe000000000000, 0x0000000000000000), /* 2 */
PACK_FLOAT_128(0x3ffc555555555555, 0x5555555555555555), /* 3 */
PACK_FLOAT_128(0x3ffa555555555555, 0x5555555555555555), /* 4 */
PACK_FLOAT_128(0x3ff8111111111111, 0x1111111111111111), /* 5 */
PACK_FLOAT_128(0x3ff56c16c16c16c1, 0x6c16c16c16c16c17), /* 6 */
PACK_FLOAT_128(0x3ff2a01a01a01a01, 0xa01a01a01a01a01a), /* 7 */
PACK_FLOAT_128(0x3fefa01a01a01a01, 0xa01a01a01a01a01a), /* 8 */
PACK_FLOAT_128(0x3fec71de3a556c73, 0x38faac1c88e50017), /* 9 */
PACK_FLOAT_128(0x3fe927e4fb7789f5, 0xc72ef016d3ea6679), /* 10 */
PACK_FLOAT_128(0x3fe5ae64567f544e, 0x38fe747e4b837dc7), /* 11 */
PACK_FLOAT_128(0x3fe21eed8eff8d89, 0x7b544da987acfe85), /* 12 */
PACK_FLOAT_128(0x3fde6124613a86d0, 0x97ca38331d23af68), /* 13 */
PACK_FLOAT_128(0x3fda93974a8c07c9, 0xd20badf145dfa3e5), /* 14 */
PACK_FLOAT_128(0x3fd6ae7f3e733b81, 0xf11d8656b0ee8cb0) /* 15 */
};
extern float128_t EvalPoly(float128_t x, const float128_t *arr, int n, struct softfloat_status_t *status);
/* required -1 < x < 1 */
static float128_t poly_exp(float128_t x, struct softfloat_status_t *status)
{
/*
// 2 3 4 5 6 7 8 9
// x x x x x x x x x
// e - 1 ~ x + --- + --- + --- + --- + --- + --- + --- + --- + ...
// 2! 3! 4! 5! 6! 7! 8! 9!
//
// 2 3 4 5 6 7 8
// x x x x x x x x
// = x [ 1 + --- + --- + --- + --- + --- + --- + --- + --- + ... ]
// 2! 3! 4! 5! 6! 7! 8! 9!
//
// 8 8
// -- 2k -- 2k+1
// p(x) = > C * x q(x) = > C * x
// -- 2k -- 2k+1
// k=0 k=0
//
// x
// e - 1 ~ x * [ p(x) + x * q(x) ]
//
*/
float128_t t = EvalPoly(x, (const float128_t*) exp_arr, EXP_ARR_SIZE, status);
return f128_mul(t, x, status);
}
// =================================================
// x
// FX2M1 Compute 2 - 1
// =================================================
//
// Uses the following identities:
//
// 1. ----------------------------------------------------------
// x x*ln(2)
// 2 = e
//
// 2. ----------------------------------------------------------
// 2 3 4 5 n
// x x x x x x x
// e = 1 + --- + --- + --- + --- + --- + ... + --- + ...
// 1! 2! 3! 4! 5! n!
//
floatx80 f2xm1(floatx80 a, struct softfloat_status_t *status)
{
/*----------------------------------------------------------------------------
| The pattern for a default generated extended double-precision NaN.
*----------------------------------------------------------------------------*/
static const floatx80 floatx80_default_nan =
packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
uint64_t zSig0, zSig1, zSig2;
struct exp32_sig64 normExpSig;
// handle unsupported extended double-precision floating encodings
if (extF80_isUnsupported(a)) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return floatx80_default_nan;
}
uint64_t aSig = extF80_fraction(a);
int32_t aExp = extF80_exp(a);
int aSign = extF80_sign(a);
if (aExp == 0x7FFF) {
if (aSig << 1)
return softfloat_propagateNaNExtF80UI(a.signExp, aSig, 0, 0, status);
return (aSign) ? floatx80_negone : a;
}
if (! aExp) {
if (! aSig) return a;
softfloat_raiseFlags(status, softfloat_flag_denormal | softfloat_flag_inexact);
normExpSig = softfloat_normSubnormalExtF80Sig(aSig);
aExp = normExpSig.exp + 1;
aSig = normExpSig.sig;
tiny_argument:
mul128By64To192(LN2_SIG_HI, LN2_SIG_LO, aSig, &zSig0, &zSig1, &zSig2);
if (0 < (int64_t) zSig0) {
shortShift128Left(zSig0, zSig1, 1, &zSig0, &zSig1);
--aExp;
}
return softfloat_roundPackToExtF80(aSign, aExp, zSig0, zSig1, 80, status);
}
softfloat_raiseFlags(status, softfloat_flag_inexact);
if (aExp < 0x3FFF)
{
if (aExp < FLOATX80_EXP_BIAS-68)
goto tiny_argument;
/* ******************************** */
/* using float128 for approximation */
/* ******************************** */
float128_t x = extF80_to_f128(a, status);
x = f128_mul(x, float128_ln2, status);
x = poly_exp(x, status);
return f128_to_extF80(x, status);
}
else
{
if (a.signExp == 0xBFFF && ! (aSig<<1))
return floatx80_neghalf;
return a;
}
}

View File

@@ -0,0 +1,60 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "softfloat.h"
extern float32 softfloat_addMagsF32(uint32_t, uint32_t, struct softfloat_status_t *);
extern float32 softfloat_subMagsF32(uint32_t, uint32_t, struct softfloat_status_t *);
float32 f32_add(float32 a, float32 b, struct softfloat_status_t *status)
{
if (signF32UI((uint32_t) a ^ (uint32_t) b)) {
return softfloat_subMagsF32(a, b, status);
} else {
return softfloat_addMagsF32(a, b, status);
}
}
float32 f32_sub(float32 a, float32 b, struct softfloat_status_t *status)
{
if (signF32UI((uint32_t) a ^ (uint32_t) b)) {
return softfloat_addMagsF32(a, b, status);
} else {
return softfloat_subMagsF32(a, b, status);
}
}

View File

@@ -0,0 +1,64 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "softfloat.h"
softfloat_class_t f32_class(float32 a)
{
bool signA;
int16_t expA;
uint32_t sigA;
signA = signF32UI(a);
expA = expF32UI(a);
sigA = fracF32UI(a);
if (expA == 0xFF) {
if (sigA == 0)
return (signA) ? softfloat_negative_inf : softfloat_positive_inf;
return (sigA & 0x00400000) ? softfloat_QNaN : softfloat_SNaN;
}
if (expA == 0) {
if (sigA == 0) return softfloat_zero;
return softfloat_denormal;
}
return softfloat_normalized;
}

View File

@@ -0,0 +1,92 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "softfloat.h"
/*----------------------------------------------------------------------------
| Compare between two single precision floating point numbers. Returns
| 'float_relation_equal' if the operands are equal, 'float_relation_less' if
| the value 'a' is less than the corresponding value `b',
| 'float_relation_greater' if the value 'a' is greater than the corresponding
| value `b', or 'float_relation_unordered' otherwise.
*----------------------------------------------------------------------------*/
int f32_compare(float32 a, float32 b, bool quiet, struct softfloat_status_t *status)
{
softfloat_class_t aClass;
softfloat_class_t bClass;
bool signA;
bool signB;
aClass = f32_class(a);
bClass = f32_class(b);
if (aClass == softfloat_SNaN || bClass == softfloat_SNaN) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return softfloat_relation_unordered;
}
if (aClass == softfloat_QNaN || bClass == softfloat_QNaN) {
if (! quiet) softfloat_raiseFlags(status, softfloat_flag_invalid);
return softfloat_relation_unordered;
}
if (aClass == softfloat_denormal) {
if (softfloat_denormalsAreZeros(status))
a = a & 0x80000000;
else
softfloat_raiseFlags(status, softfloat_flag_denormal);
}
if (bClass == softfloat_denormal) {
if (softfloat_denormalsAreZeros(status))
b = b & 0x80000000;
else
softfloat_raiseFlags(status, softfloat_flag_denormal);
}
if ((a == b) || ((uint32_t) ((a | b)<<1) == 0)) return softfloat_relation_equal;
signA = signF32UI(a);
signB = signF32UI(b);
if (signA != signB)
return (signA) ? softfloat_relation_less : softfloat_relation_greater;
if (signA ^ (a < b)) return softfloat_relation_less;
return softfloat_relation_greater;
}

View File

@@ -0,0 +1,146 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
#define SOFTFLOAT_FAST_DIV64TO32
float32 f32_div(float32 a, float32 b, struct softfloat_status_t *status)
{
bool signA;
int16_t expA;
uint32_t sigA;
bool signB;
int16_t expB;
uint32_t sigB;
bool signZ;
struct exp16_sig32 normExpSig;
int16_t expZ;
#ifdef SOFTFLOAT_FAST_DIV64TO32
uint64_t sig64A;
uint32_t sigZ;
#endif
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
signA = signF32UI(a);
expA = expF32UI(a);
sigA = fracF32UI(a);
signB = signF32UI(b);
expB = expF32UI(b);
sigB = fracF32UI(b);
signZ = signA ^ signB;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (softfloat_denormalsAreZeros(status)) {
if (!expA) sigA = 0;
if (!expB) sigB = 0;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (expA == 0xFF) {
if (sigA) goto propagateNaN;
if (expB == 0xFF) {
if (sigB) goto propagateNaN;
goto invalid;
}
if (sigB && !expB)
softfloat_raiseFlags(status, softfloat_flag_denormal);
goto infinity;
}
if (expB == 0xFF) {
if (sigB) goto propagateNaN;
if (sigA && !expA)
softfloat_raiseFlags(status, softfloat_flag_denormal);
goto zero;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (! expB) {
if (! sigB) {
if (! (expA | sigA)) goto invalid;
softfloat_raiseFlags(status, softfloat_flag_infinite);
goto infinity;
}
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalF32Sig(sigB);
expB = normExpSig.exp;
sigB = normExpSig.sig;
}
if (! expA) {
if (! sigA) goto zero;
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalF32Sig(sigA);
expA = normExpSig.exp;
sigA = normExpSig.sig;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
expZ = expA - expB + 0x7E;
sigA |= 0x00800000;
sigB |= 0x00800000;
#ifdef SOFTFLOAT_FAST_DIV64TO32
if (sigA < sigB) {
--expZ;
sig64A = (uint64_t) sigA<<31;
} else {
sig64A = (uint64_t) sigA<<30;
}
sigZ = sig64A / sigB;
if (! (sigZ & 0x3F)) sigZ |= ((uint64_t) sigB * sigZ != sig64A);
#endif
return softfloat_roundPackToF32(signZ, expZ, sigZ, status);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
propagateNaN:
return softfloat_propagateNaNF32UI(a, b, status);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
invalid:
softfloat_raiseFlags(status, softfloat_flag_invalid);
return defaultNaNF32UI;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
infinity:
return packToF32UI(signZ, 0xFF, 0);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
zero:
return packToF32UI(signZ, 0, 0);
}

View File

@@ -0,0 +1,101 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
/*----------------------------------------------------------------------------
| Extracts the fractional portion of single-precision floating-point value `a',
| and returns the result as a single-precision floating-point value. The
| fractional results are precise. The operation is performed according to the
| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
float32 f32_frc(float32 a, struct softfloat_status_t *status)
{
int roundingMode = softfloat_getRoundingMode(status);
bool signA;
int16_t expA;
uint32_t sigA;
uint32_t lastBitMask;
uint32_t roundBitsMask;
signA = signF32UI(a);
expA = expF32UI(a);
sigA = fracF32UI(a);
if (expA == 0xFF) {
if (sigA) return softfloat_propagateNaNF32UI(a, 0, status);
softfloat_raiseFlags(status, softfloat_flag_invalid);
return defaultNaNF32UI;
}
if (expA >= 0x96) {
return packToF32UI(roundingMode == softfloat_round_down, 0, 0);
}
if (expA < 0x7F) {
if (! expA) {
if (! sigA || softfloat_denormalsAreZeros(status))
return packToF32UI(roundingMode == softfloat_round_down, 0, 0);
softfloat_raiseFlags(status, softfloat_flag_denormal);
if (! softfloat_isMaskedException(status, softfloat_flag_underflow))
softfloat_raiseFlags(status, softfloat_flag_underflow);
if (softfloat_flushUnderflowToZero(status)) {
softfloat_raiseFlags(status, softfloat_flag_underflow | softfloat_flag_inexact);
return packToF32UI(signA, 0, 0);
}
}
return a;
}
lastBitMask = 1 << (0x96 - expA);
roundBitsMask = lastBitMask - 1;
sigA &= roundBitsMask;
sigA <<= 7;
expA--;
if (! sigA)
return packToF32UI(roundingMode == softfloat_round_down, 0, 0);
return softfloat_normRoundPackToF32(signA, expA, sigA, status);
}

View File

@@ -0,0 +1,73 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
/*----------------------------------------------------------------------------
| Extracts the exponent portion of single-precision floating-point value 'a',
| and returns the result as a single-precision floating-point value
| representing unbiased integer exponent. The operation is performed according
| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
float32 f32_getExp(float32 a, struct softfloat_status_t *status)
{
int16_t expA;
uint32_t sigA;
struct exp16_sig32 normExpSig;
expA = expF32UI(a);
sigA = fracF32UI(a);
if (expA == 0xFF) {
if (sigA) return softfloat_propagateNaNF32UI(a, 0, status);
return packToF32UI(0, 0xFF, 0);
}
if (! expA) {
if (! sigA || softfloat_denormalsAreZeros(status))
return packToF32UI(1, 0xFF, 0);
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalF32Sig(sigA);
expA = normExpSig.exp;
}
return i32_to_f32((int32_t)(expA) - 0x7F, status);
}

View File

@@ -0,0 +1,108 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
/*----------------------------------------------------------------------------
| Extracts the mantissa of single-precision floating-point value 'a' and
| returns the result as a single-precision floating-point after applying
| the mantissa interval normalization and sign control. The operation is
| performed according to the IEC/IEEE Standard for Binary Floating-Point
| Arithmetic.
*----------------------------------------------------------------------------*/
float32 f32_getMant(float32 a, struct softfloat_status_t *status, int sign_ctrl, int interv)
{
bool signA;
int16_t expA;
uint32_t sigA;
struct exp16_sig32 normExpSig;
signA = signF32UI(a);
expA = expF32UI(a);
sigA = fracF32UI(a);
if (expA == 0xFF) {
if (sigA) return softfloat_propagateNaNF32UI(a, 0, status);
if (signA) {
if (sign_ctrl & 0x2) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return defaultNaNF32UI;
}
}
return packToF32UI(~sign_ctrl & signA, 0x7F, 0);
}
if (! expA && (! sigA || softfloat_denormalsAreZeros(status))) {
return packToF32UI(~sign_ctrl & signA, 0x7F, 0);
}
if (signA) {
if (sign_ctrl & 0x2) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return defaultNaNF32UI;
}
}
if (! expA) {
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalF32Sig(sigA);
expA = normExpSig.exp;
sigA = normExpSig.sig;
sigA &= 0x7FFFFF;
}
switch(interv) {
case 0x0: // interval [1,2)
expA = 0x7F;
break;
case 0x1: // interval [1/2,2)
expA -= 0x7F;
expA = 0x7F - (expA & 0x1);
break;
case 0x2: // interval [1/2,1)
expA = 0x7E;
break;
case 0x3: // interval [3/4,3/2)
expA = 0x7F - ((sigA >> 22) & 0x1);
break;
}
return packToF32UI(~sign_ctrl & signA, expA, sigA);
}

View File

@@ -0,0 +1,69 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "softfloat.h"
/*----------------------------------------------------------------------------
| Compare between two single precision floating point numbers and return the
| smaller of them.
*----------------------------------------------------------------------------*/
float32 f32_min(float32 a, float32 b, struct softfloat_status_t *status)
{
if (softfloat_denormalsAreZeros(status)) {
a = f32_denormal_to_zero(a);
b = f32_denormal_to_zero(b);
}
return (f32_compare_normal(a, b, status) == softfloat_relation_less) ? a : b;
}
/*----------------------------------------------------------------------------
| Compare between two single precision floating point numbers and return the
| larger of them.
*----------------------------------------------------------------------------*/
float32 f32_max(float32 a, float32 b, struct softfloat_status_t *status)
{
if (softfloat_denormalsAreZeros(status)) {
a = f32_denormal_to_zero(a);
b = f32_denormal_to_zero(b);
}
return (f32_compare_normal(a, b, status) == softfloat_relation_greater) ? a : b;
}

View File

@@ -0,0 +1,137 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "primitives.h"
#include "specialize.h"
#include "softfloat.h"
float32 f32_mul(float32 a, float32 b, struct softfloat_status_t *status)
{
bool signA;
int16_t expA;
uint32_t sigA;
bool signB;
int16_t expB;
uint32_t sigB;
bool signZ;
uint32_t magBits;
struct exp16_sig32 normExpSig;
int16_t expZ;
uint32_t sigZ, uiZ;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
signA = signF32UI(a);
expA = expF32UI(a);
sigA = fracF32UI(a);
signB = signF32UI(b);
expB = expF32UI(b);
sigB = fracF32UI(b);
signZ = signA ^ signB;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (softfloat_denormalsAreZeros(status)) {
if (!expA) sigA = 0;
if (!expB) sigB = 0;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (expA == 0xFF) {
if (sigA || ((expB == 0xFF) && sigB)) goto propagateNaN;
magBits = expB | sigB;
if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal);
goto infArg;
}
if (expB == 0xFF) {
if (sigB) goto propagateNaN;
magBits = expA | sigA;
if (sigA && !expA) softfloat_raiseFlags(status, softfloat_flag_denormal);
goto infArg;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (! expA) {
if (! sigA) {
if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal);
goto zero;
}
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalF32Sig(sigA);
expA = normExpSig.exp;
sigA = normExpSig.sig;
}
if (! expB) {
if (! sigB) {
if (sigA && !expA) softfloat_raiseFlags(status, softfloat_flag_denormal);
goto zero;
}
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalF32Sig(sigB);
expB = normExpSig.exp;
sigB = normExpSig.sig;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
expZ = expA + expB - 0x7F;
sigA = (sigA | 0x00800000)<<7;
sigB = (sigB | 0x00800000)<<8;
sigZ = softfloat_shortShiftRightJam64((uint64_t) sigA * sigB, 32);
if (sigZ < 0x40000000) {
--expZ;
sigZ <<= 1;
}
return softfloat_roundPackToF32(signZ, expZ, sigZ, status);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
propagateNaN:
return softfloat_propagateNaNF32UI(a, b, status);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
infArg:
if (! magBits) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
uiZ = defaultNaNF32UI;
} else {
uiZ = packToF32UI(signZ, 0xFF, 0);
}
return uiZ;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
zero:
return packToF32UI(signZ, 0, 0);
}

View File

@@ -0,0 +1,233 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdint.h>
#include "internals.h"
#include "primitives.h"
#include "softfloat.h"
#include "specialize.h"
float32 f32_mulAdd(float32 a, float32 b, float32 c, uint8_t op, struct softfloat_status_t *status)
{
bool signA;
int16_t expA;
uint32_t sigA;
bool signB;
int16_t expB;
uint32_t sigB;
bool signC;
int16_t expC;
uint32_t sigC;
bool signProd;
uint32_t magBits, uiA, uiB, uiC, uiZ;
struct exp16_sig32 normExpSig;
int16_t expProd;
uint64_t sigProd;
bool signZ;
int16_t expZ;
uint32_t sigZ;
int16_t expDiff;
uint64_t sig64Z, sig64C;
int8_t shiftDist;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiA = a;
uiB = b;
uiC = c;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
signA = signF32UI(uiA);
expA = expF32UI(uiA);
sigA = fracF32UI(uiA);
signB = signF32UI(uiB);
expB = expF32UI(uiB);
sigB = fracF32UI(uiB);
signC = signF32UI(uiC) ^ ((op & softfloat_mulAdd_subC) != 0);
expC = expF32UI(uiC);
sigC = fracF32UI(uiC);
signProd = signA ^ signB ^ ((op & softfloat_mulAdd_subProd) != 0);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
bool aisNaN = (expA == 0xFF) && sigA;
bool bisNaN = (expB == 0xFF) && sigB;
bool cisNaN = (expC == 0xFF) && sigC;
if (aisNaN | bisNaN | cisNaN) {
uiZ = (aisNaN | bisNaN) ? softfloat_propagateNaNF32UI(uiA, uiB, status) : 0;
return softfloat_propagateNaNF32UI(uiZ, uiC, status);
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (softfloat_denormalsAreZeros(status)) {
if (!expA) sigA = 0;
if (!expB) sigB = 0;
if (!expC) sigC = 0;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (expA == 0xFF) {
magBits = expB | sigB;
goto infProdArg;
}
if (expB == 0xFF) {
magBits = expA | sigA;
goto infProdArg;
}
if (expC == 0xFF) {
if ((sigA && !expA) || (sigB && !expB)) {
softfloat_raiseFlags(status, softfloat_flag_denormal);
}
return packToF32UI(signC, 0xFF, 0);
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (! expA) {
if (! sigA) goto zeroProd;
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalF32Sig(sigA);
expA = normExpSig.exp;
sigA = normExpSig.sig;
}
if (! expB) {
if (! sigB) goto zeroProd;
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalF32Sig(sigB);
expB = normExpSig.exp;
sigB = normExpSig.sig;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
expProd = expA + expB - 0x7E;
sigA = (sigA | 0x00800000)<<7;
sigB = (sigB | 0x00800000)<<7;
sigProd = (uint64_t) sigA * sigB;
if (sigProd < UINT64_C(0x2000000000000000)) {
--expProd;
sigProd <<= 1;
}
signZ = signProd;
if (! expC) {
if (! sigC) {
expZ = expProd - 1;
sigZ = softfloat_shortShiftRightJam64(sigProd, 31);
goto roundPack;
}
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalF32Sig(sigC);
expC = normExpSig.exp;
sigC = normExpSig.sig;
}
sigC = (sigC | 0x00800000)<<6;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
expDiff = expProd - expC;
if (signProd == signC) {
/*--------------------------------------------------------------------
*--------------------------------------------------------------------*/
if (expDiff <= 0) {
expZ = expC;
sigZ = sigC + softfloat_shiftRightJam64(sigProd, 32 - expDiff);
} else {
expZ = expProd;
sig64Z = sigProd + softfloat_shiftRightJam64((uint64_t) sigC<<32, expDiff);
sigZ = softfloat_shortShiftRightJam64(sig64Z, 32);
}
if (sigZ < 0x40000000) {
--expZ;
sigZ <<= 1;
}
} else {
/*--------------------------------------------------------------------
*--------------------------------------------------------------------*/
sig64C = (uint64_t) sigC<<32;
if (expDiff < 0) {
signZ = signC;
expZ = expC;
sig64Z = sig64C - softfloat_shiftRightJam64(sigProd, -expDiff);
} else if (! expDiff) {
expZ = expProd;
sig64Z = sigProd - sig64C;
if (! sig64Z) goto completeCancellation;
if (sig64Z & UINT64_C(0x8000000000000000)) {
signZ = ! signZ;
sig64Z = -sig64Z;
}
} else {
expZ = expProd;
sig64Z = sigProd - softfloat_shiftRightJam64(sig64C, expDiff);
}
shiftDist = softfloat_countLeadingZeros64(sig64Z) - 1;
expZ -= shiftDist;
shiftDist -= 32;
if (shiftDist < 0) {
sigZ = softfloat_shortShiftRightJam64(sig64Z, -shiftDist);
} else {
sigZ = (uint32_t) sig64Z<<shiftDist;
}
}
roundPack:
return softfloat_roundPackToF32(signZ, expZ, sigZ, status);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
infProdArg:
if (magBits) {
uiZ = packToF32UI(signProd, 0xFF, 0);
if (signProd == signC || expC != 0xFF) {
if ((sigA && !expA) || (sigB && !expB) || (sigC && !expC))
softfloat_raiseFlags(status, softfloat_flag_denormal);
return uiZ;
}
}
softfloat_raiseFlags(status, softfloat_flag_invalid);
uiZ = defaultNaNF32UI;
return softfloat_propagateNaNF32UI(uiZ, uiC, status);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
zeroProd:
uiZ = packToF32UI(signC, expC, sigC);
if (!expC && sigC) {
/* Exact zero plus a denormal */
softfloat_raiseFlags(status, softfloat_flag_denormal);
if (softfloat_flushUnderflowToZero(status)) {
softfloat_raiseFlags(status, softfloat_flag_underflow | softfloat_flag_inexact);
return packToF32UI(signC, 0, 0);
}
}
if (! (expC | sigC) && (signProd != signC)) {
completeCancellation:
uiZ = packToF32UI((softfloat_getRoundingMode(status) == softfloat_round_min), 0, 0);
}
return uiZ;
}

View File

@@ -0,0 +1,134 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
float32 f32_range(float32 a, float32 b, bool is_max, bool is_abs, int sign_ctrl, struct softfloat_status_t *status)
{
bool signA;
int16_t expA;
uint32_t sigA;
bool signB;
int16_t expB;
uint32_t sigB;
bool aIsNaN, bIsNaN;
uint32_t z;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
signA = signF32UI(a);
expA = expF32UI(a);
sigA = fracF32UI(a);
signB = signF32UI(b);
expB = expF32UI(b);
sigB = fracF32UI(b);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (softfloat_isSigNaNF32UI(a)) {
return softfloat_propagateNaNF32UI(a, 0, status);
}
if (softfloat_isSigNaNF32UI(b)) {
return softfloat_propagateNaNF32UI(b, 0, status);
}
aIsNaN = isNaNF32UI(a);
bIsNaN = isNaNF32UI(b);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (! expA && sigA) {
if (softfloat_denormalsAreZeros(status)) {
a = packToF32UI(signA, 0, 0);
}
else if (! bIsNaN) {
softfloat_raiseFlags(status, softfloat_flag_denormal);
}
}
if (! expB && sigB) {
if (softfloat_denormalsAreZeros(status)) {
b = packToF32UI(signB, 0, 0);
}
else if (! aIsNaN) {
softfloat_raiseFlags(status, softfloat_flag_denormal);
}
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (bIsNaN) {
z = a;
}
else if (aIsNaN) {
z = b;
}
else if (signA != signB && ! is_abs) {
if (! is_max) {
z = signA ? a : b;
} else {
z = signA ? b : a;
}
} else {
float32 tmp_a = a, tmp_b = b;
if (is_abs) {
tmp_a = tmp_a & ~0x80000000; // clear the sign bit
tmp_b = tmp_b & ~0x80000000;
signA = 0;
}
if (! is_max) {
z = (signA ^ (tmp_a < tmp_b)) ? a : b;
} else {
z = (signA ^ (tmp_a < tmp_b)) ? b : a;
}
}
switch(sign_ctrl) {
case 0:
z = (z & ~0x80000000) | (a & 0x80000000); // keep sign of a
break;
case 1:
break; // preserve sign of compare result
case 2:
z = z & ~0x80000000; // zero out the sign bit
break;
case 3:
z = z | 0x80000000; // set the sign bit
break;
}
return z;
}

View File

@@ -0,0 +1,112 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
float32 f32_roundToInt(float32 a, uint8_t scale, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
{
int16_t exp;
int32_t frac;
uint32_t uiZ, lastBitMask, roundBitsMask;
bool sign;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
scale &= 0xF;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
exp = expF32UI(a);
frac = fracF32UI(a);
sign = signF32UI(a);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (0x96 <= (exp + scale)) {
if ((exp == 0xFF) && frac) {
return softfloat_propagateNaNF32UI(a, 0, status);
}
return a;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (softfloat_denormalsAreZeros(status)) {
if (!exp) {
frac = 0;
a = packToF32UI(sign, 0, 0);
}
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if ((exp + scale) <= 0x7E) {
if (!(exp | frac)) return a;
if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact);
uiZ = packToF32UI(sign, 0, 0);
switch (roundingMode) {
case softfloat_round_near_even:
if (!frac) break;
case softfloat_round_near_maxMag:
if ((exp + scale) == 0x7E) uiZ |= packToF32UI(0, 0x7F - scale, 0);
break;
case softfloat_round_min:
if (uiZ) uiZ = packToF32UI(1, 0x7F - scale, 0);
break;
case softfloat_round_max:
if (!uiZ) uiZ = packToF32UI(0, 0x7F - scale, 0);
break;
}
return uiZ;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiZ = a;
lastBitMask = (uint32_t) 1<<(0x96 - exp - scale);
roundBitsMask = lastBitMask - 1;
if (roundingMode == softfloat_round_near_maxMag) {
uiZ += lastBitMask>>1;
} else if (roundingMode == softfloat_round_near_even) {
uiZ += lastBitMask>>1;
if (!(uiZ & roundBitsMask)) uiZ &= ~lastBitMask;
} else if (roundingMode == (signF32UI(uiZ) ? softfloat_round_min : softfloat_round_max)) {
uiZ += roundBitsMask;
}
uiZ &= ~roundBitsMask;
if (uiZ != a) {
if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact);
}
return uiZ;
}

View File

@@ -0,0 +1,155 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
/*----------------------------------------------------------------------------
| Return the result of a floating point scale of the single-precision floating
| point value `a' by multiplying it by 2 power of the single-precision
| floating point value 'b' converted to integral value. If the result cannot
| be represented in single precision, then the proper overflow response (for
| positive scaling operand), or the proper underflow response (for negative
| scaling operand) is issued. The operation is performed according to the
| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
float32 f32_scalef(float32 a, float32 b, struct softfloat_status_t *status)
{
bool signA;
int16_t expA;
uint32_t sigA;
bool signB;
int16_t expB;
uint32_t sigB;
int shiftCount;
int scale = 0;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
signA = signF32UI(a);
expA = expF32UI(a);
sigA = fracF32UI(a);
signB = signF32UI(b);
expB = expF32UI(b);
sigB = fracF32UI(b);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (expB == 0xFF) {
if (sigB) return softfloat_propagateNaNF32UI(a, b, status);
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (softfloat_denormalsAreZeros(status)) {
if (!expA) sigA = 0;
if (!expB) sigB = 0;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (expA == 0xFF) {
if (sigA) {
int aIsSignalingNaN = (sigA & 0x00400000) == 0;
if (aIsSignalingNaN || expB != 0xFF || sigB)
return softfloat_propagateNaNF32UI(a, b, status);
return signB ? 0 : packToF32UI(0, 0xFF, 0);
}
if (expB == 0xFF && signB) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return defaultNaNF32UI;
}
return a;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (! expA) {
if (! sigA) {
if (expB == 0xFF && ! signB) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return defaultNaNF32UI;
}
return packToF32UI(signA, 0, 0);
}
softfloat_raiseFlags(status, softfloat_flag_denormal);
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if ((expB | sigB) == 0) return a;
if (expB == 0xFF) {
if (signB) return packToF32UI(signA, 0, 0);
return packToF32UI(signA, 0xFF, 0);
}
if (expB >= 0x8E) {
// handle obvious overflow/underflow result
return softfloat_roundPackToF32(signA, signB ? -0x7F : 0xFF, sigA, status);
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (expB <= 0x7E) {
if (! expB)
softfloat_raiseFlags(status, softfloat_flag_denormal);
scale = -signB;
}
else {
shiftCount = expB - 0x9E;
sigB = (sigB | 0x800000)<<8;
scale = sigB>>(-shiftCount);
if (signB) {
if ((uint32_t) (sigB<<(shiftCount & 31))) scale++;
scale = -scale;
}
if (scale > 0x200) scale = 0x200;
if (scale < -0x200) scale = -0x200;
}
if (expA != 0) {
sigA |= 0x00800000;
} else {
expA++;
}
expA += scale - 1;
sigA <<= 7;
return softfloat_normRoundPackToF32(signA, expA, sigA, status);
}

View File

@@ -0,0 +1,117 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "primitives.h"
#include "specialize.h"
#include "softfloat.h"
float32 f32_sqrt(float32 a, struct softfloat_status_t *status)
{
bool signA;
int16_t expA;
uint32_t sigA;
struct exp16_sig32 normExpSig;
int16_t expZ;
uint32_t sigZ, shiftedSigZ;
uint32_t negRem;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
signA = signF32UI(a);
expA = expF32UI(a);
sigA = fracF32UI(a);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (expA == 0xFF) {
if (sigA) {
return softfloat_propagateNaNF32UI(a, 0, status);
}
if (! signA) return a;
goto invalid;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (softfloat_denormalsAreZeros(status)) {
if (!expA) {
sigA = 0;
a = packToF32UI(signA, 0, 0);
}
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (signA) {
if (! (expA | sigA)) return a;
goto invalid;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (! expA) {
if (! sigA) return a;
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalF32Sig(sigA);
expA = normExpSig.exp;
sigA = normExpSig.sig;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
expZ = ((expA - 0x7F)>>1) + 0x7E;
expA &= 1;
sigA = (sigA | 0x00800000)<<8;
sigZ =
((uint64_t) sigA * softfloat_approxRecipSqrt32_1(expA, sigA))>>32;
if (expA) sigZ >>= 1;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sigZ += 2;
if ((sigZ & 0x3F) < 2) {
shiftedSigZ = sigZ>>2;
negRem = shiftedSigZ * shiftedSigZ;
sigZ &= ~3;
if (negRem & 0x80000000) {
sigZ |= 1;
} else {
if (negRem) --sigZ;
}
}
return softfloat_roundPackToF32(0, expZ, sigZ, status);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
invalid:
softfloat_raiseFlags(status, softfloat_flag_invalid);
return defaultNaNF32UI;
}

View File

@@ -0,0 +1,88 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
extFloat80_t f32_to_extF80(float32 a, struct softfloat_status_t *status)
{
bool sign;
int16_t exp;
uint32_t frac;
struct commonNaN commonNaN;
struct uint128 uiZ;
uint16_t uiZ64;
uint64_t uiZ0;
struct exp16_sig32 normExpSig;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sign = signF32UI(a);
exp = expF32UI(a);
frac = fracF32UI(a);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (exp == 0xFF) {
if (frac) {
softfloat_f32UIToCommonNaN(a, &commonNaN, status);
uiZ = softfloat_commonNaNToExtF80UI(&commonNaN);
uiZ64 = uiZ.v64;
uiZ0 = uiZ.v0;
} else {
uiZ64 = packToExtF80UI64(sign, 0x7FFF);
uiZ0 = UINT64_C(0x8000000000000000);
}
return packToExtF80_twoargs(uiZ64, uiZ0);
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (! exp) {
if (! frac) {
return packToExtF80(sign, 0, 0);
}
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalF32Sig(frac);
exp = normExpSig.exp;
frac = normExpSig.sig;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiZ64 = packToExtF80UI64(sign, exp + 0x3F80);
uiZ0 = (uint64_t) (frac | 0x00800000)<<40;
return packToExtF80_twoargs(uiZ64, uiZ0);
}

View File

@@ -0,0 +1,86 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
float128_t f32_to_f128(float32 a, struct softfloat_status_t *status)
{
bool sign;
int16_t exp;
uint32_t frac;
struct commonNaN commonNaN;
struct uint128 uiZ;
struct exp16_sig32 normExpSig;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sign = signF32UI(a);
exp = expF32UI(a);
frac = fracF32UI(a);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (exp == 0xFF) {
if (frac) {
softfloat_f32UIToCommonNaN(a, &commonNaN, status);
uiZ = softfloat_commonNaNToF128UI(&commonNaN);
} else {
uiZ.v64 = packToF128UI64(sign, 0x7FFF, 0);
uiZ.v0 = 0;
}
return uiZ;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (! exp) {
if (! frac) {
uiZ.v64 = packToF128UI64(sign, 0, 0);
uiZ.v0 = 0;
return uiZ;
}
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalF32Sig(frac);
exp = normExpSig.exp - 1;
frac = normExpSig.sig;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiZ.v64 = packToF128UI64(sign, exp + 0x3F80, (uint64_t) frac<<25);
uiZ.v0 = 0;
return uiZ;
}

View File

@@ -0,0 +1,82 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
float16 f32_to_f16(float32 a, struct softfloat_status_t *status)
{
bool sign;
int16_t exp;
uint32_t frac;
struct commonNaN commonNaN;
uint16_t uiZ, frac16;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sign = signF32UI(a);
exp = expF32UI(a);
frac = fracF32UI(a);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (exp == 0xFF) {
if (frac) {
softfloat_f32UIToCommonNaN(a, &commonNaN, status);
uiZ = softfloat_commonNaNToF16UI(&commonNaN);
} else {
uiZ = packToF16UI(sign, 0x1F, 0);
}
return uiZ;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (!exp && frac) {
if (softfloat_denormalsAreZeros(status))
return packToF16UI(sign, 0, 0);
softfloat_raiseFlags(status, softfloat_flag_denormal);
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
frac16 = frac>>9 | ((frac & 0x1FF) != 0);
if (! (exp | frac16)) {
return packToF16UI(sign, 0, 0);
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
return softfloat_roundPackToF16(sign, exp - 0x71, frac16 | 0x4000, status);
}

View File

@@ -0,0 +1,81 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
float64 f32_to_f64(float32 a, struct softfloat_status_t *status)
{
bool sign;
int16_t exp;
uint32_t frac;
struct commonNaN commonNaN;
uint64_t uiZ;
struct exp16_sig32 normExpSig;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sign = signF32UI(a);
exp = expF32UI(a);
frac = fracF32UI(a);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (exp == 0xFF) {
if (frac) {
softfloat_f32UIToCommonNaN(a, &commonNaN, status);
uiZ = softfloat_commonNaNToF64UI(&commonNaN);
} else {
uiZ = packToF64UI(sign, 0x7FF, 0);
}
return uiZ;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (! exp) {
if (! frac || softfloat_denormalsAreZeros(status)) {
return packToF64UI(sign, 0, 0);
}
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalF32Sig(frac);
exp = normExpSig.exp - 1;
frac = normExpSig.sig;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
return packToF64UI(sign, exp + 0x380, (uint64_t) frac<<29);
}

View File

@@ -0,0 +1,78 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
University of California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "primitives.h"
#include "specialize.h"
#include "softfloat.h"
int32_t f32_to_i32(float32 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
{
bool sign;
int16_t exp;
uint32_t sig;
uint64_t sig64;
int16_t shiftDist;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sign = signF32UI(a);
exp = expF32UI(a);
sig = fracF32UI(a);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
#if (i32_fromNaN != i32_fromPosOverflow) || (i32_fromNaN != i32_fromNegOverflow)
if ((exp == 0xFF) && sig) {
#if (i32_fromNaN == i32_fromPosOverflow)
sign = 0;
#elif (i32_fromNaN == i32_fromNegOverflow)
sign = 1;
#else
softfloat_raiseFlags(status, softfloat_flag_invalid);
return i32_fromNaN;
#endif
}
#endif
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (exp) sig |= 0x00800000;
else if (softfloat_denormalsAreZeros(status)) sig = 0;
sig64 = (uint64_t) sig<<32;
shiftDist = 0xAA - exp;
if (0 < shiftDist) sig64 = softfloat_shiftRightJam64(sig64, shiftDist);
return softfloat_roundToI32(sign, sig64, roundingMode, exact, status);
}

View File

@@ -0,0 +1,83 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
int32_t f32_to_i32_r_minMag(float32 a, bool exact, struct softfloat_status_t *status)
{
int16_t exp;
uint32_t sig;
int16_t shiftDist;
bool sign;
int32_t absZ;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
exp = expF32UI(a);
sig = fracF32UI(a);
if (softfloat_denormalsAreZeros(status))
if (!exp && sig) sig = 0;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
shiftDist = 0x9E - exp;
if (32 <= shiftDist) {
if (exact && (exp | sig)) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
return 0;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sign = signF32UI(a);
if (shiftDist <= 0) {
if (a == packToF32UI(1, 0x9E, 0)) return -0x7FFFFFFF - 1;
softfloat_raiseFlags(status, softfloat_flag_invalid);
return (exp == 0xFF) && sig
? i32_fromNaN
: sign ? i32_fromNegOverflow : i32_fromPosOverflow;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sig = (sig | 0x00800000)<<8;
absZ = sig>>shiftDist;
if (exact && ((uint32_t) absZ<<shiftDist != sig)) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
return sign ? -absZ : absZ;
}

View File

@@ -0,0 +1,79 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
University of California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "primitives.h"
#include "specialize.h"
#include "softfloat.h"
int64_t f32_to_i64(float32 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
{
bool sign;
int16_t exp;
uint32_t sig;
int16_t shiftDist;
uint64_t sig64, extra;
struct uint64_extra sig64Extra;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sign = signF32UI(a);
exp = expF32UI(a);
sig = fracF32UI(a);
if (softfloat_denormalsAreZeros(status))
if (!exp && sig) sig = 0;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
shiftDist = 0xBE - exp;
if (shiftDist < 0) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return (exp == 0xFF) && sig
? i64_fromNaN
: sign ? i64_fromNegOverflow : i64_fromPosOverflow;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (exp) sig |= 0x00800000;
sig64 = (uint64_t) sig<<40;
extra = 0;
if (shiftDist) {
sig64Extra = softfloat_shiftRightJam64Extra(sig64, 0, shiftDist);
sig64 = sig64Extra.v;
extra = sig64Extra.extra;
}
return softfloat_roundToI64(sign, sig64, extra, roundingMode, exact, status);
}

View File

@@ -0,0 +1,88 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
int64_t f32_to_i64_r_minMag(float32 a, bool exact, struct softfloat_status_t *status)
{
int16_t exp;
uint32_t sig;
int16_t shiftDist;
bool sign;
uint64_t sig64;
int64_t absZ;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
exp = expF32UI(a);
sig = fracF32UI(a);
if (softfloat_denormalsAreZeros(status))
if (!exp && sig) sig = 0;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
shiftDist = 0xBE - exp;
if (64 <= shiftDist) {
if (exact && (exp | sig)) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
return 0;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sign = signF32UI(a);
if (shiftDist <= 0) {
if (a == packToF32UI(1, 0xBE, 0)) {
return -INT64_C(0x7FFFFFFFFFFFFFFF) - 1;
}
softfloat_raiseFlags(status, softfloat_flag_invalid);
return (exp == 0xFF) && sig
? i64_fromNaN
: sign ? i64_fromNegOverflow : i64_fromPosOverflow;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sig |= 0x00800000;
sig64 = (uint64_t) sig<<40;
absZ = sig64>>shiftDist;
shiftDist = 40 - shiftDist;
if (exact && (shiftDist < 0) && (uint32_t) (sig<<(shiftDist & 31))) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
return sign ? -absZ : absZ;
}

View File

@@ -0,0 +1,80 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
University of California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "primitives.h"
#include "specialize.h"
#include "softfloat.h"
uint32_t f32_to_ui32(float32 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
{
bool sign;
int16_t exp;
uint32_t sig;
uint64_t sig64;
int16_t shiftDist;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sign = signF32UI(a);
exp = expF32UI(a);
sig = fracF32UI(a);
if (softfloat_denormalsAreZeros(status))
if (!exp && sig) sig = 0;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
#if (ui32_fromNaN != ui32_fromPosOverflow) || (ui32_fromNaN != ui32_fromNegOverflow)
if ((exp == 0xFF) && sig) {
#if (ui32_fromNaN == ui32_fromPosOverflow)
sign = 0;
#elif (ui32_fromNaN == ui32_fromNegOverflow)
sign = 1;
#else
softfloat_raiseFlags(status, softfloat_flag_invalid);
return ui32_fromNaN;
#endif
}
#endif
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (exp) sig |= 0x00800000;
else if (softfloat_denormalsAreZeros(status)) sig = 0;
sig64 = (uint64_t) sig<<32;
shiftDist = 0xAA - exp;
if (0 < shiftDist) sig64 = softfloat_shiftRightJam64(sig64, shiftDist);
return softfloat_roundToUI32(sign, sig64, roundingMode, exact, status);
}

View File

@@ -0,0 +1,83 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
uint32_t f32_to_ui32_r_minMag(float32 a, bool exact, struct softfloat_status_t *status)
{
int16_t exp;
uint32_t sig;
int16_t shiftDist;
bool sign;
uint32_t z;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
exp = expF32UI(a);
sig = fracF32UI(a);
if (softfloat_denormalsAreZeros(status))
if (!exp && sig) sig = 0;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
shiftDist = 0x9E - exp;
if (32 <= shiftDist) {
if (exact && (exp | sig)) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
return 0;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sign = signF32UI(a);
if (sign || (shiftDist < 0)) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return (exp == 0xFF) && sig
? ui32_fromNaN
: sign ? ui32_fromNegOverflow : ui32_fromPosOverflow;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sig = (sig | 0x00800000)<<8;
z = sig>>shiftDist;
if (exact && (z<<shiftDist != sig)) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
return z;
}

View File

@@ -0,0 +1,79 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
University of California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "primitives.h"
#include "specialize.h"
#include "softfloat.h"
uint64_t f32_to_ui64(float32 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
{
bool sign;
int16_t exp;
uint32_t sig;
int16_t shiftDist;
uint64_t sig64, extra;
struct uint64_extra sig64Extra;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sign = signF32UI(a);
exp = expF32UI(a);
sig = fracF32UI(a);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
shiftDist = 0xBE - exp;
if (shiftDist < 0) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return (exp == 0xFF) && sig
? ui64_fromNaN
: sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (exp) sig |= 0x00800000;
else if (softfloat_denormalsAreZeros(status)) sig = 0;
sig64 = (uint64_t) sig<<40;
extra = 0;
if (shiftDist) {
sig64Extra = softfloat_shiftRightJam64Extra(sig64, 0, shiftDist);
sig64 = sig64Extra.v;
extra = sig64Extra.extra;
}
return softfloat_roundToUI64(sign, sig64, extra, roundingMode, exact, status);
}

View File

@@ -0,0 +1,84 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
uint64_t f32_to_ui64_r_minMag(float32 a, bool exact, struct softfloat_status_t *status)
{
int16_t exp;
uint32_t sig;
int16_t shiftDist;
bool sign;
uint64_t sig64, z;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
exp = expF32UI(a);
sig = fracF32UI(a);
if (softfloat_denormalsAreZeros(status))
if (!exp && sig) sig = 0;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
shiftDist = 0xBE - exp;
if (64 <= shiftDist) {
if (exact && (exp | sig)) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
return 0;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sign = signF32UI(a);
if (sign || (shiftDist < 0)) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return (exp == 0xFF) && sig
? ui64_fromNaN
: sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
sig |= 0x00800000;
sig64 = (uint64_t) sig<<40;
z = sig64>>shiftDist;
shiftDist = 40 - shiftDist;
if (exact && (shiftDist < 0) && (uint32_t) (sig<<(shiftDist & 31))) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
return z;
}

View File

@@ -0,0 +1,70 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "softfloat.h"
extern float64 softfloat_addMagsF64(uint64_t, uint64_t, bool, struct softfloat_status_t *);
extern float64 softfloat_subMagsF64(uint64_t, uint64_t, bool, struct softfloat_status_t *);
float64 f64_add(float64 a, float64 b, struct softfloat_status_t *status)
{
bool signA;
bool signB;
signA = signF64UI(a);
signB = signF64UI(b);
if (signA == signB) {
return softfloat_addMagsF64(a, b, signA, status);
} else {
return softfloat_subMagsF64(a, b, signA, status);
}
}
float64 f64_sub(float64 a, float64 b, struct softfloat_status_t *status)
{
bool signA;
bool signB;
signA = signF64UI(a);
signB = signF64UI(b);
if (signA == signB) {
return softfloat_subMagsF64(a, b, signA, status);
} else {
return softfloat_addMagsF64(a, b, signA, status);
}
}

View File

@@ -0,0 +1,64 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "softfloat.h"
softfloat_class_t f64_class(float64 a)
{
bool signA;
int16_t expA;
uint64_t sigA;
signA = signF64UI(a);
expA = expF64UI(a);
sigA = fracF64UI(a);
if (expA == 0x7FF) {
if (sigA == 0)
return (signA) ? softfloat_negative_inf : softfloat_positive_inf;
return (sigA & UINT64_C(0x0008000000000000)) ? softfloat_QNaN : softfloat_SNaN;
}
if (expA == 0) {
if (sigA == 0) return softfloat_zero;
return softfloat_denormal;
}
return softfloat_normalized;
}

View File

@@ -0,0 +1,92 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3e, by John R. Hauser.
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
#include <stdbool.h>
#include <stdint.h>
#include "internals.h"
#include "softfloat.h"
/*----------------------------------------------------------------------------
| Compare between two double precision floating point numbers. Returns
| 'float_relation_equal' if the operands are equal, 'float_relation_less' if
| the value 'a' is less than the corresponding value `b',
| 'float_relation_greater' if the value 'a' is greater than the corresponding
| value `b', or 'float_relation_unordered' otherwise.
*----------------------------------------------------------------------------*/
int f64_compare(float64 a, float64 b, bool quiet, struct softfloat_status_t *status)
{
softfloat_class_t aClass;
softfloat_class_t bClass;
bool signA;
bool signB;
aClass = f64_class(a);
bClass = f64_class(b);
if (aClass == softfloat_SNaN || bClass == softfloat_SNaN) {
softfloat_raiseFlags(status, softfloat_flag_invalid);
return softfloat_relation_unordered;
}
if (aClass == softfloat_QNaN || bClass == softfloat_QNaN) {
if (! quiet) softfloat_raiseFlags(status, softfloat_flag_invalid);
return softfloat_relation_unordered;
}
if (aClass == softfloat_denormal) {
if (softfloat_denormalsAreZeros(status))
a = a & UINT64_C(0x8000000000000000);
else
softfloat_raiseFlags(status, softfloat_flag_denormal);
}
if (bClass == softfloat_denormal) {
if (softfloat_denormalsAreZeros(status))
b = b & UINT64_C(0x8000000000000000);
else
softfloat_raiseFlags(status, softfloat_flag_denormal);
}
if ((a == b) || ((uint64_t) ((a | b)<<1) == 0)) return softfloat_relation_equal;
signA = signF64UI(a);
signB = signF64UI(b);
if (signA != signB)
return (signA) ? softfloat_relation_less : softfloat_relation_greater;
if (signA ^ (a < b)) return softfloat_relation_less;
return softfloat_relation_greater;
}

Some files were not shown because too many files have changed in this diff Show More