Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
internals.h File Reference
#include <stdbool.h>
#include <stdint.h>
#include "primitives.h"
#include "softfloat_types.h"
Include dependency graph for internals.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

union  ui16_f16
 
union  ui32_f32
 
union  ui64_f64
 
struct  exp8_sig16
 
struct  exp16_sig32
 
struct  exp16_sig64
 

Macros

#define signF16UI(a)
 
#define expF16UI(a)
 
#define fracF16UI(a)
 
#define packToF16UI(sign, exp, sig)
 
#define isNaNF16UI(a)
 
#define signF32UI(a)
 
#define expF32UI(a)
 
#define fracF32UI(a)
 
#define packToF32UI(sign, exp, sig)
 
#define isNaNF32UI(a)
 
#define signF64UI(a)
 
#define expF64UI(a)
 
#define fracF64UI(a)
 
#define packToF64UI(sign, exp, sig)
 
#define isNaNF64UI(a)
 
#define signExtF80UI64(a64)
 
#define expExtF80UI64(a64)
 
#define packToExtF80UI64(sign, exp)
 
#define isNaNExtF80UI(a64, a0)
 
#define signF128UI96(a96)
 
#define expF128UI96(a96)
 
#define fracF128UI96(a96)
 
#define packToF128UI96(sign, exp, sig96)
 

Enumerations

enum  { softfloat_mulAdd_subC = 1 , softfloat_mulAdd_subProd = 2 }
 

Functions

uint_fast32_t softfloat_roundToUI32 (bool, uint_fast64_t, uint_fast8_t, bool)
 
uint_fast64_t softfloat_roundMToUI64 (bool, uint32_t *, uint_fast8_t, bool)
 
int_fast32_t softfloat_roundToI32 (bool, uint_fast64_t, uint_fast8_t, bool)
 
int_fast64_t softfloat_roundMToI64 (bool, uint32_t *, uint_fast8_t, bool)
 
struct exp8_sig16 softfloat_normSubnormalF16Sig (uint_fast16_t)
 
float16_t softfloat_roundPackToF16 (bool, int_fast16_t, uint_fast16_t)
 
float16_t softfloat_normRoundPackToF16 (bool, int_fast16_t, uint_fast16_t)
 
float16_t softfloat_addMagsF16 (uint_fast16_t, uint_fast16_t)
 
float16_t softfloat_subMagsF16 (uint_fast16_t, uint_fast16_t)
 
float16_t softfloat_mulAddF16 (uint_fast16_t, uint_fast16_t, uint_fast16_t, uint_fast8_t)
 
struct exp16_sig32 softfloat_normSubnormalF32Sig (uint_fast32_t)
 
float32_t softfloat_roundPackToF32 (bool, int_fast16_t, uint_fast32_t)
 
float32_t softfloat_normRoundPackToF32 (bool, int_fast16_t, uint_fast32_t)
 
float32_t softfloat_addMagsF32 (uint_fast32_t, uint_fast32_t)
 
float32_t softfloat_subMagsF32 (uint_fast32_t, uint_fast32_t)
 
float32_t softfloat_mulAddF32 (uint_fast32_t, uint_fast32_t, uint_fast32_t, uint_fast8_t)
 
struct exp16_sig64 softfloat_normSubnormalF64Sig (uint_fast64_t)
 
float64_t softfloat_roundPackToF64 (bool, int_fast16_t, uint_fast64_t)
 
float64_t softfloat_normRoundPackToF64 (bool, int_fast16_t, uint_fast64_t)
 
float64_t softfloat_addMagsF64 (uint_fast64_t, uint_fast64_t, bool)
 
float64_t softfloat_subMagsF64 (uint_fast64_t, uint_fast64_t, bool)
 
float64_t softfloat_mulAddF64 (uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast8_t)
 
bool softfloat_tryPropagateNaNExtF80M (const struct extFloat80M *, const struct extFloat80M *, struct extFloat80M *)
 
void softfloat_invalidExtF80M (struct extFloat80M *)
 
int softfloat_normExtF80SigM (uint64_t *)
 
void softfloat_roundPackMToExtF80M (bool, int32_t, uint32_t *, uint_fast8_t, struct extFloat80M *)
 
void softfloat_normRoundPackMToExtF80M (bool, int32_t, uint32_t *, uint_fast8_t, struct extFloat80M *)
 
void softfloat_addExtF80M (const struct extFloat80M *, const struct extFloat80M *, struct extFloat80M *, bool)
 
int softfloat_compareNonnormExtF80M (const struct extFloat80M *, const struct extFloat80M *)
 
bool softfloat_isNaNF128M (const uint32_t *)
 
bool softfloat_tryPropagateNaNF128M (const uint32_t *, const uint32_t *, uint32_t *)
 
void softfloat_invalidF128M (uint32_t *)
 
int softfloat_shiftNormSigF128M (const uint32_t *, uint_fast8_t, uint32_t *)
 
void softfloat_roundPackMToF128M (bool, int32_t, uint32_t *, uint32_t *)
 
void softfloat_normRoundPackMToF128M (bool, int32_t, uint32_t *, uint32_t *)
 
void softfloat_addF128M (const uint32_t *, const uint32_t *, uint32_t *, bool)
 
void softfloat_mulAddF128M (const uint32_t *, const uint32_t *, const uint32_t *, uint32_t *, uint_fast8_t)
 

Macro Definition Documentation

◆ expExtF80UI64

#define expExtF80UI64 ( a64)
Value:
((a64) & 0x7FFF)

Definition at line 147 of file internals.h.

◆ expF128UI96

#define expF128UI96 ( a96)
Value:
((int32_t) ((a96)>>16) & 0x7FFF)
signed int int32_t
Definition stdint.h:123

Definition at line 248 of file internals.h.

◆ expF16UI

#define expF16UI ( a)
Value:
((int_fast8_t) ((a)>>10) & 0x1F)
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1181
int8_t int_fast8_t
Definition stdint.h:150

Definition at line 84 of file internals.h.

◆ expF32UI

#define expF32UI ( a)
Value:
((int_fast16_t) ((a)>>23) & 0xFF)
int16_t int_fast16_t
Definition stdint.h:151

Definition at line 105 of file internals.h.

◆ expF64UI

#define expF64UI ( a)
Value:
((int_fast16_t) ((a)>>52) & 0x7FF)

Definition at line 126 of file internals.h.

◆ fracF128UI96

#define fracF128UI96 ( a96)
Value:
((a96) & 0x0000FFFF)

Definition at line 249 of file internals.h.

◆ fracF16UI

#define fracF16UI ( a)
Value:
((a) & 0x03FF)

Definition at line 85 of file internals.h.

◆ fracF32UI

#define fracF32UI ( a)
Value:
((a) & 0x007FFFFF)

Definition at line 106 of file internals.h.

◆ fracF64UI

#define fracF64UI ( a)
Value:
((a) & UINT64_C( 0x000FFFFFFFFFFFFF ))
#define UINT64_C(val)
Definition stdint.h:284

Definition at line 127 of file internals.h.

◆ isNaNExtF80UI

#define isNaNExtF80UI ( a64,
a0 )
Value:
((((a64) & 0x7FFF) == 0x7FFF) && ((a0) & UINT64_C( 0x7FFFFFFFFFFFFFFF )))

Definition at line 150 of file internals.h.

◆ isNaNF16UI

#define isNaNF16UI ( a)
Value:
(((~(a) & 0x7C00) == 0) && ((a) & 0x03FF))

Definition at line 88 of file internals.h.

◆ isNaNF32UI

#define isNaNF32UI ( a)
Value:
(((~(a) & 0x7F800000) == 0) && ((a) & 0x007FFFFF))

Definition at line 109 of file internals.h.

◆ isNaNF64UI

#define isNaNF64UI ( a)
Value:
(((~(a) & UINT64_C( 0x7FF0000000000000 )) == 0) && ((a) & UINT64_C( 0x000FFFFFFFFFFFFF )))

Definition at line 130 of file internals.h.

◆ packToExtF80UI64

#define packToExtF80UI64 ( sign,
exp )
Value:
((uint_fast16_t) (sign)<<15 | (exp))
uint16_t uint_fast16_t
Definition stdint.h:155

Definition at line 148 of file internals.h.

◆ packToF128UI96

#define packToF128UI96 ( sign,
exp,
sig96 )
Value:
(((uint32_t) (sign)<<31) + ((uint32_t) (exp)<<16) + (sig96))
unsigned int uint32_t
Definition stdint.h:126

Definition at line 250 of file internals.h.

◆ packToF16UI

#define packToF16UI ( sign,
exp,
sig )
Value:
(((uint16_t) (sign)<<15) + ((uint16_t) (exp)<<10) + (sig))
unsigned short uint16_t
Definition stdint.h:125

Definition at line 86 of file internals.h.

◆ packToF32UI

#define packToF32UI ( sign,
exp,
sig )
Value:
(((uint32_t) (sign)<<31) + ((uint32_t) (exp)<<23) + (sig))

Definition at line 107 of file internals.h.

◆ packToF64UI

#define packToF64UI ( sign,
exp,
sig )
Value:
((uint64_t) (((uint_fast64_t) (sign)<<63) + ((uint_fast64_t) (exp)<<52) + (sig)))
uint64_t uint_fast64_t
Definition stdint.h:157
unsigned __int64 uint64_t
Definition stdint.h:136

Definition at line 128 of file internals.h.

◆ signExtF80UI64

#define signExtF80UI64 ( a64)
Value:
((bool) ((uint16_t) (a64)>>15))

Definition at line 146 of file internals.h.

◆ signF128UI96

#define signF128UI96 ( a96)
Value:
((bool) ((uint32_t) (a96)>>31))

Definition at line 247 of file internals.h.

◆ signF16UI

#define signF16UI ( a)
Value:
((bool) ((uint16_t) (a)>>15))

Definition at line 83 of file internals.h.

◆ signF32UI

#define signF32UI ( a)
Value:
((bool) ((uint32_t) (a)>>31))

Definition at line 104 of file internals.h.

◆ signF64UI

#define signF64UI ( a)
Value:
((bool) ((uint64_t) (a)>>63))

Definition at line 125 of file internals.h.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
softfloat_mulAdd_subC 
softfloat_mulAdd_subProd 

Definition at line 54 of file internals.h.

54 {
57};
@ softfloat_mulAdd_subProd
Definition internals.h:56
@ softfloat_mulAdd_subC
Definition internals.h:55

Function Documentation

◆ softfloat_addExtF80M()

void softfloat_addExtF80M ( const struct extFloat80M * aSPtr,
const struct extFloat80M * bSPtr,
struct extFloat80M * zSPtr,
bool negateB )

Definition at line 45 of file s_addExtF80M.c.

51{
52 uint32_t uiA64;
53 int32_t expA;
54 uint32_t uiB64;
55 int32_t expB;
56 uint32_t uiZ64;
57 bool signZ, signB;
58 const struct extFloat80M *tempSPtr;
59 uint64_t sigZ, sigB;
60 void
61 (*roundPackRoutinePtr)(
62 bool, int32_t, uint32_t *, uint_fast8_t, struct extFloat80M * );
63 int32_t expDiff;
64 uint32_t extSigX[3], sigZExtra;
65
66 /*------------------------------------------------------------------------
67 *------------------------------------------------------------------------*/
68 uiA64 = aSPtr->signExp;
69 expA = expExtF80UI64( uiA64 );
70 uiB64 = bSPtr->signExp;
71 expB = expExtF80UI64( uiB64 );
72 /*------------------------------------------------------------------------
73 *------------------------------------------------------------------------*/
74 if ( (expA == 0x7FFF) || (expB == 0x7FFF) ) {
75 if ( softfloat_tryPropagateNaNExtF80M( aSPtr, bSPtr, zSPtr ) ) return;
76 uiZ64 = uiA64;
77 if ( expB == 0x7FFF ) {
78 uiZ64 = uiB64 ^ packToExtF80UI64( negateB, 0 );
79 if ( (expA == 0x7FFF) && (uiZ64 != uiA64) ) {
81 return;
82 }
83 }
84 zSPtr->signExp = uiZ64;
85 zSPtr->signif = UINT64_C( 0x8000000000000000 );
86 return;
87 }
88 /*------------------------------------------------------------------------
89 *------------------------------------------------------------------------*/
90 signZ = signExtF80UI64( uiA64 );
91 signB = signExtF80UI64( uiB64 ) ^ negateB;
92 negateB = (signZ != signB);
93 if ( expA < expB ) {
94 signZ = signB;
95 expA = expB;
96 expB = expExtF80UI64( uiA64 );
97 tempSPtr = aSPtr;
98 aSPtr = bSPtr;
99 bSPtr = tempSPtr;
100 }
101 if ( ! expB ) {
102 expB = 1;
103 if ( ! expA ) expA = 1;
104 }
105 sigZ = aSPtr->signif;
106 sigB = bSPtr->signif;
107 /*------------------------------------------------------------------------
108 *------------------------------------------------------------------------*/
109 roundPackRoutinePtr = softfloat_roundPackMToExtF80M;
110 expDiff = expA - expB;
111 if ( expDiff ) {
112 /*--------------------------------------------------------------------
113 *--------------------------------------------------------------------*/
114 extSigX[indexWord( 3, 2 )] = sigB>>32;
115 extSigX[indexWord( 3, 1 )] = sigB;
116 extSigX[indexWord( 3, 0 )] = 0;
117 softfloat_shiftRightJam96M( extSigX, expDiff, extSigX );
118 sigB =
119 (uint64_t) extSigX[indexWord( 3, 2 )]<<32
120 | extSigX[indexWord( 3, 1 )];
121 if ( negateB ) {
122 sigZ -= sigB;
123 sigZExtra = extSigX[indexWordLo( 3 )];
124 if ( sigZExtra ) {
125 --sigZ;
126 sigZExtra = -sigZExtra;
127 }
128 if ( ! (sigZ & UINT64_C( 0x8000000000000000 )) ) {
129 if ( sigZ & UINT64_C( 0x4000000000000000 ) ) {
130 --expA;
131 sigZ = sigZ<<1 | sigZExtra>>31;
132 sigZExtra <<= 1;
133 } else {
134 roundPackRoutinePtr = softfloat_normRoundPackMToExtF80M;
135 }
136 }
137 } else {
138 sigZ += sigB;
139 if ( sigZ & UINT64_C( 0x8000000000000000 ) ) goto sigZ;
140 sigZExtra = (uint32_t) sigZ<<31 | (extSigX[indexWordLo( 3 )] != 0);
141 goto completeNormAfterAdd;
142 }
143 } else {
144 /*--------------------------------------------------------------------
145 *--------------------------------------------------------------------*/
146 sigZExtra = 0;
147 if ( negateB ) {
148 if ( sigZ < sigB ) {
149 signZ = ! signZ;
150 sigZ = sigB - sigZ;
151 } else {
152 sigZ -= sigB;
153 if ( ! sigZ ) {
155 zSPtr->signExp = packToExtF80UI64( signZ, 0 );
156 zSPtr->signif = 0;
157 return;
158 }
159 }
160 roundPackRoutinePtr = softfloat_normRoundPackMToExtF80M;
161 } else {
162 sigZ += sigB;
163 if ( sigZ < sigB ) {
164 sigZExtra = (uint32_t) sigZ<<31;
165 completeNormAfterAdd:
166 ++expA;
167 sigZ = UINT64_C( 0x8000000000000000 ) | sigZ>>1;
168 } else {
169 if ( ! (sigZ & UINT64_C( 0x8000000000000000 )) ) {
170 roundPackRoutinePtr = softfloat_normRoundPackMToExtF80M;
171 }
172 }
173 }
174 }
175 extSigX[indexWord( 3, 0 )] = sigZExtra;
176 sigZ:
177 extSigX[indexWord( 3, 2 )] = sigZ>>32;
178 extSigX[indexWord( 3, 1 )] = sigZ;
179 /*------------------------------------------------------------------------
180 *------------------------------------------------------------------------*/
181 roundPack:
182 (*roundPackRoutinePtr)(
183 signZ, expA, extSigX, extF80_roundingPrecision, zSPtr );
184
185}
void softfloat_normRoundPackMToExtF80M(bool, int32_t, uint32_t *, uint_fast8_t, struct extFloat80M *)
#define packToExtF80UI64(sign, exp)
Definition internals.h:148
#define expExtF80UI64(a64)
Definition internals.h:147
void softfloat_invalidExtF80M(struct extFloat80M *)
void softfloat_roundPackMToExtF80M(bool, int32_t, uint32_t *, uint_fast8_t, struct extFloat80M *)
#define signExtF80UI64(a64)
Definition internals.h:146
bool softfloat_tryPropagateNaNExtF80M(const struct extFloat80M *, const struct extFloat80M *, struct extFloat80M *)
#define indexWordLo(total)
#define indexWord(total, n)
#define softfloat_shiftRightJam96M(aPtr, dist, zPtr)
Definition primitives.h:873
THREAD_LOCAL uint_fast8_t softfloat_roundingMode
THREAD_LOCAL uint_fast8_t extF80_roundingPrecision
@ softfloat_round_min
Definition softfloat.h:74
uint8_t uint_fast8_t
Definition stdint.h:154
uint64_t signif
uint16_t signExp
Here is the call graph for this function:

◆ softfloat_addF128M()

void softfloat_addF128M ( const uint32_t * aWPtr,
const uint32_t * bWPtr,
uint32_t * zWPtr,
bool negateB )

Definition at line 45 of file s_addF128M.c.

51{
52 uint32_t uiA96;
53 int32_t expA;
54 uint32_t uiB96;
55 int32_t expB;
56 uint32_t uiZ96;
57 bool signZ, signB;
58 const uint32_t *tempPtr;
59 uint32_t sig96A, sig96B;
60 int32_t expDiff;
62 (*addCarryMRoutinePtr)(
64 const uint32_t *,
65 const uint32_t *,
67 uint32_t *
68 );
69 uint32_t extSigZ[5], wordSigZ;
70 uint_fast8_t carry;
71 void (*roundPackRoutinePtr)( bool, int32_t, uint32_t *, uint32_t * );
72
73 /*------------------------------------------------------------------------
74 *------------------------------------------------------------------------*/
75 uiA96 = aWPtr[indexWordHi( 4 )];
76 expA = expF128UI96( uiA96 );
77 uiB96 = bWPtr[indexWordHi( 4 )];
78 expB = expF128UI96( uiB96 );
79 /*------------------------------------------------------------------------
80 *------------------------------------------------------------------------*/
81 if ( (expA == 0x7FFF) || (expB == 0x7FFF) ) {
82 if ( softfloat_tryPropagateNaNF128M( aWPtr, bWPtr, zWPtr ) ) return;
83 uiZ96 = uiA96;
84 if ( expB == 0x7FFF ) {
85 uiZ96 = uiB96 ^ packToF128UI96( negateB, 0, 0 );
86 if ( (expA == 0x7FFF) && (uiZ96 != uiA96) ) {
88 return;
89 }
90 }
91 zWPtr[indexWordHi( 4 )] = uiZ96;
92 zWPtr[indexWord( 4, 2 )] = 0;
93 zWPtr[indexWord( 4, 1 )] = 0;
94 zWPtr[indexWord( 4, 0 )] = 0;
95 return;
96 }
97 /*------------------------------------------------------------------------
98 *------------------------------------------------------------------------*/
99 signZ = signF128UI96( uiA96 );
100 signB = signF128UI96( uiB96 ) ^ negateB;
101 negateB = (signZ != signB);
102 if ( (uint32_t) (uiA96<<1) < (uint32_t) (uiB96<<1) ) {
103 signZ = signB;
104 expA = expB;
105 expB = expF128UI96( uiA96 );
106 tempPtr = aWPtr;
107 aWPtr = bWPtr;
108 bWPtr = tempPtr;
109 uiA96 = uiB96;
110 uiB96 = bWPtr[indexWordHi( 4 )];
111 }
112 sig96A = fracF128UI96( uiA96 );
113 sig96B = fracF128UI96( uiB96 );
114 if ( expA ) {
115 --expA;
116 sig96A |= 0x00010000;
117 if ( expB ) {
118 --expB;
119 sig96B |= 0x00010000;
120 }
121 }
122 /*------------------------------------------------------------------------
123 *------------------------------------------------------------------------*/
124 addCarryMRoutinePtr =
126 expDiff = expA - expB;
127 if ( expDiff ) {
128 /*--------------------------------------------------------------------
129 *--------------------------------------------------------------------*/
130 extSigZ[indexWordHi( 5 )] = sig96B;
131 extSigZ[indexWord( 5, 3 )] = bWPtr[indexWord( 4, 2 )];
132 extSigZ[indexWord( 5, 2 )] = bWPtr[indexWord( 4, 1 )];
133 extSigZ[indexWord( 5, 1 )] = bWPtr[indexWord( 4, 0 )];
134 extSigZ[indexWord( 5, 0 )] = 0;
135 softfloat_shiftRightJam160M( extSigZ, expDiff, extSigZ );
136 sig96B = extSigZ[indexWordHi( 5 )];
137 carry = 0;
138 if ( negateB ) {
139 sig96B = ~sig96B;
140 wordSigZ = extSigZ[indexWordLo( 5 )];
141 extSigZ[indexWordLo( 5 )] = -wordSigZ;
142 carry = ! wordSigZ;
143 }
144 carry =
145 (*addCarryMRoutinePtr)(
146 3,
147 &aWPtr[indexMultiwordLo( 4, 3 )],
148 &extSigZ[indexMultiword( 5, 3, 1 )],
149 carry,
150 &extSigZ[indexMultiword( 5, 3, 1 )]
151 );
152 wordSigZ = sig96A + sig96B + carry;
153 } else {
154 /*--------------------------------------------------------------------
155 *--------------------------------------------------------------------*/
156 extSigZ[indexWordLo( 5 )] = 0;
157 carry =
158 (*addCarryMRoutinePtr)(
159 3,
160 &aWPtr[indexMultiwordLo( 4, 3 )],
161 &bWPtr[indexMultiwordLo( 4, 3 )],
162 negateB,
163 &extSigZ[indexMultiword( 5, 3, 1 )]
164 );
165 if ( negateB ) {
166 wordSigZ = sig96A + ~sig96B + carry;
167 if ( wordSigZ & 0x80000000 ) {
168 signZ = ! signZ;
169 carry =
171 &bWPtr[indexMultiwordLo( 4, 3 )],
172 &aWPtr[indexMultiwordLo( 4, 3 )],
173 1,
174 &extSigZ[indexMultiword( 5, 3, 1 )]
175 );
176 wordSigZ = sig96B + ~sig96A + carry;
177 } else {
178 if (
179 ! wordSigZ && ! extSigZ[indexWord( 5, 3 )]
180 && ! ( extSigZ[indexWord( 5, 2 )]
181 | extSigZ[indexWord( 5, 1 )]
182 | extSigZ[indexWord( 5, 0 )]
183 )
184 ) {
186 zWPtr[indexWordHi( 4 )] = packToF128UI96( signZ, 0, 0 );
187 zWPtr[indexWord( 4, 2 )] = 0;
188 zWPtr[indexWord( 4, 1 )] = 0;
189 zWPtr[indexWord( 4, 0 )] = 0;
190 return;
191 }
192 }
193 } else {
194 wordSigZ = sig96A + sig96B + carry;
195 }
196 }
197 extSigZ[indexWordHi( 5 )] = wordSigZ;
198 /*------------------------------------------------------------------------
199 *------------------------------------------------------------------------*/
200 roundPackRoutinePtr = softfloat_normRoundPackMToF128M;
201 if ( 0x00010000 <= wordSigZ ) {
202 if ( 0x00020000 <= wordSigZ ) {
203 ++expA;
204 softfloat_shortShiftRightJam160M( extSigZ, 1, extSigZ );
205 }
206 roundPackRoutinePtr = softfloat_roundPackMToF128M;
207 }
208 (*roundPackRoutinePtr)( signZ, expA, extSigZ, zWPtr );
209
210}
void softfloat_invalidF128M(uint32_t *)
void softfloat_normRoundPackMToF128M(bool, int32_t, uint32_t *, uint32_t *)
#define fracF128UI96(a96)
Definition internals.h:249
void softfloat_roundPackMToF128M(bool, int32_t, uint32_t *, uint32_t *)
#define packToF128UI96(sign, exp, sig96)
Definition internals.h:250
bool softfloat_tryPropagateNaNF128M(const uint32_t *, const uint32_t *, uint32_t *)
#define signF128UI96(a96)
Definition internals.h:247
#define expF128UI96(a96)
Definition internals.h:248
#define indexMultiwordLo(total, n)
#define indexMultiword(total, m, n)
#define indexWordHi(total)
#define softfloat_shiftRightJam160M(aPtr, dist, zPtr)
Definition primitives.h:889
uint_fast8_t softfloat_addCarryM(uint_fast8_t size_words, const uint32_t *aPtr, const uint32_t *bPtr, uint_fast8_t carry, uint32_t *zPtr)
Definition s_addCarryM.c:44
uint_fast8_t softfloat_addComplCarryM(uint_fast8_t size_words, const uint32_t *aPtr, const uint32_t *bPtr, uint_fast8_t carry, uint32_t *zPtr)
#define softfloat_shortShiftRightJam160M(aPtr, dist, zPtr)
Definition primitives.h:814
#define softfloat_addComplCarry96M(aPtr, bPtr, carry, zPtr)
Definition primitives.h:974
Here is the call graph for this function:

◆ softfloat_addMagsF16()

float16_t softfloat_addMagsF16 ( uint_fast16_t uiA,
uint_fast16_t uiB )

Definition at line 44 of file s_addMagsF16.c.

45{
46 int_fast8_t expA;
47 uint_fast16_t sigA;
48 int_fast8_t expB;
49 uint_fast16_t sigB;
50 int_fast8_t expDiff;
51 uint_fast16_t uiZ;
52 bool signZ;
53 int_fast8_t expZ;
54 uint_fast16_t sigZ;
55 uint_fast16_t sigX, sigY;
56 int_fast8_t shiftDist;
57 uint_fast32_t sig32Z;
58 int_fast8_t roundingMode;
59 union ui16_f16 uZ;
60
61 /*------------------------------------------------------------------------
62 *------------------------------------------------------------------------*/
63 expA = expF16UI( uiA );
64 sigA = fracF16UI( uiA );
65 expB = expF16UI( uiB );
66 sigB = fracF16UI( uiB );
67 /*------------------------------------------------------------------------
68 *------------------------------------------------------------------------*/
69 expDiff = expA - expB;
70 if ( ! expDiff ) {
71 /*--------------------------------------------------------------------
72 *--------------------------------------------------------------------*/
73 if ( ! expA ) {
74 uiZ = uiA + sigB;
75 goto uiZ;
76 }
77 if ( expA == 0x1F ) {
78 if ( sigA | sigB ) goto propagateNaN;
79 uiZ = uiA;
80 goto uiZ;
81 }
82 signZ = signF16UI( uiA );
83 expZ = expA;
84 sigZ = 0x0800 + sigA + sigB;
85 if ( ! (sigZ & 1) && (expZ < 0x1E) ) {
86 sigZ >>= 1;
87 goto pack;
88 }
89 sigZ <<= 3;
90 } else {
91 /*--------------------------------------------------------------------
92 *--------------------------------------------------------------------*/
93 signZ = signF16UI( uiA );
94 if ( expDiff < 0 ) {
95 /*----------------------------------------------------------------
96 *----------------------------------------------------------------*/
97 if ( expB == 0x1F ) {
98 if ( sigB ) goto propagateNaN;
99 uiZ = packToF16UI( signZ, 0x1F, 0 );
100 goto uiZ;
101 }
102 if ( expDiff <= -13 ) {
103 uiZ = packToF16UI( signZ, expB, sigB );
104 if ( expA | sigA ) goto addEpsilon;
105 goto uiZ;
106 }
107 expZ = expB;
108 sigX = sigB | 0x0400;
109 sigY = sigA + (expA ? 0x0400 : sigA);
110 shiftDist = 19 + expDiff;
111 } else {
112 /*----------------------------------------------------------------
113 *----------------------------------------------------------------*/
114 uiZ = uiA;
115 if ( expA == 0x1F ) {
116 if ( sigA ) goto propagateNaN;
117 goto uiZ;
118 }
119 if ( 13 <= expDiff ) {
120 if ( expB | sigB ) goto addEpsilon;
121 goto uiZ;
122 }
123 expZ = expA;
124 sigX = sigA | 0x0400;
125 sigY = sigB + (expB ? 0x0400 : sigB);
126 shiftDist = 19 - expDiff;
127 }
128 sig32Z =
129 ((uint_fast32_t) sigX<<19) + ((uint_fast32_t) sigY<<shiftDist);
130 if ( sig32Z < 0x40000000 ) {
131 --expZ;
132 sig32Z <<= 1;
133 }
134 sigZ = sig32Z>>16;
135 if ( sig32Z & 0xFFFF ) {
136 sigZ |= 1;
137 } else {
138 if ( ! (sigZ & 0xF) && (expZ < 0x1E) ) {
139 sigZ >>= 4;
140 goto pack;
141 }
142 }
143 }
144 return softfloat_roundPackToF16( signZ, expZ, sigZ );
145 /*------------------------------------------------------------------------
146 *------------------------------------------------------------------------*/
147 propagateNaN:
148 uiZ = softfloat_propagateNaNF16UI( uiA, uiB );
149 goto uiZ;
150 /*------------------------------------------------------------------------
151 *------------------------------------------------------------------------*/
152 addEpsilon:
153 roundingMode = softfloat_roundingMode;
154 if ( roundingMode != softfloat_round_near_even ) {
155 if (
156 roundingMode
157 == (signF16UI( uiZ ) ? softfloat_round_min
159 ) {
160 ++uiZ;
161 if ( (uint16_t) (uiZ<<1) == 0xF800 ) {
164 }
165 }
166#ifdef SOFTFLOAT_ROUND_ODD
167 else if ( roundingMode == softfloat_round_odd ) {
168 uiZ |= 1;
169 }
170#endif
171 }
173 goto uiZ;
174 /*------------------------------------------------------------------------
175 *------------------------------------------------------------------------*/
176 pack:
177 uiZ = packToF16UI( signZ, expZ, sigZ );
178 uiZ:
179 uZ.ui = uiZ;
180 return uZ.f;
181
182}
void pack(instruction_stream *stream, uint32_t field)
uint_fast16_t softfloat_propagateNaNF16UI(uint_fast16_t uiA, uint_fast16_t uiB)
void softfloat_raiseFlags(uint_fast8_t flags)
#define expF16UI(a)
Definition internals.h:84
#define signF16UI(a)
Definition internals.h:83
float16_t softfloat_roundPackToF16(bool, int_fast16_t, uint_fast16_t)
#define fracF16UI(a)
Definition internals.h:85
#define packToF16UI(sign, exp, sig)
Definition internals.h:86
@ softfloat_flag_inexact
Definition softfloat.h:85
@ softfloat_flag_overflow
Definition softfloat.h:87
THREAD_LOCAL uint_fast8_t softfloat_exceptionFlags
@ softfloat_round_odd
Definition softfloat.h:77
@ softfloat_round_max
Definition softfloat.h:75
@ softfloat_round_near_even
Definition softfloat.h:72
uint32_t uint_fast32_t
Definition stdint.h:156
Here is the call graph for this function:

◆ softfloat_addMagsF32()

float32_t softfloat_addMagsF32 ( uint_fast32_t uiA,
uint_fast32_t uiB )

Definition at line 43 of file s_addMagsF32.c.

44{
45 int_fast16_t expA;
46 uint_fast32_t sigA;
47 int_fast16_t expB;
48 uint_fast32_t sigB;
49 int_fast16_t expDiff;
50 uint_fast32_t uiZ;
51 bool signZ;
52 int_fast16_t expZ;
53 uint_fast32_t sigZ;
54 union ui32_f32 uZ;
55
56 /*------------------------------------------------------------------------
57 *------------------------------------------------------------------------*/
58 expA = expF32UI( uiA );
59 sigA = fracF32UI( uiA );
60 expB = expF32UI( uiB );
61 sigB = fracF32UI( uiB );
62 /*------------------------------------------------------------------------
63 *------------------------------------------------------------------------*/
64 expDiff = expA - expB;
65 if ( ! expDiff ) {
66 /*--------------------------------------------------------------------
67 *--------------------------------------------------------------------*/
68 if ( ! expA ) {
69 uiZ = uiA + sigB;
70 goto uiZ;
71 }
72 if ( expA == 0xFF ) {
73 if ( sigA | sigB ) goto propagateNaN;
74 uiZ = uiA;
75 goto uiZ;
76 }
77 signZ = signF32UI( uiA );
78 expZ = expA;
79 sigZ = 0x01000000 + sigA + sigB;
80 if ( ! (sigZ & 1) && (expZ < 0xFE) ) {
81 uiZ = packToF32UI( signZ, expZ, sigZ>>1 );
82 goto uiZ;
83 }
84 sigZ <<= 6;
85 } else {
86 /*--------------------------------------------------------------------
87 *--------------------------------------------------------------------*/
88 signZ = signF32UI( uiA );
89 sigA <<= 6;
90 sigB <<= 6;
91 if ( expDiff < 0 ) {
92 if ( expB == 0xFF ) {
93 if ( sigB ) goto propagateNaN;
94 uiZ = packToF32UI( signZ, 0xFF, 0 );
95 goto uiZ;
96 }
97 expZ = expB;
98 sigA += expA ? 0x20000000 : sigA;
99 sigA = softfloat_shiftRightJam32( sigA, -expDiff );
100 } else {
101 if ( expA == 0xFF ) {
102 if ( sigA ) goto propagateNaN;
103 uiZ = uiA;
104 goto uiZ;
105 }
106 expZ = expA;
107 sigB += expB ? 0x20000000 : sigB;
108 sigB = softfloat_shiftRightJam32( sigB, expDiff );
109 }
110 sigZ = 0x20000000 + sigA + sigB;
111 if ( sigZ < 0x40000000 ) {
112 --expZ;
113 sigZ <<= 1;
114 }
115 }
116 return softfloat_roundPackToF32( signZ, expZ, sigZ );
117 /*------------------------------------------------------------------------
118 *------------------------------------------------------------------------*/
119 propagateNaN:
120 uiZ = softfloat_propagateNaNF32UI( uiA, uiB );
121 uiZ:
122 uZ.ui = uiZ;
123 return uZ.f;
124
125}
uint_fast32_t softfloat_propagateNaNF32UI(uint_fast32_t uiA, uint_fast32_t uiB)
#define expF32UI(a)
Definition internals.h:105
float32_t softfloat_roundPackToF32(bool, int_fast16_t, uint_fast32_t)
#define fracF32UI(a)
Definition internals.h:106
#define signF32UI(a)
Definition internals.h:104
#define packToF32UI(sign, exp, sig)
Definition internals.h:107
uint32_t softfloat_shiftRightJam32(uint32_t a, uint_fast16_t dist)
Here is the call graph for this function:

◆ softfloat_addMagsF64()

float64_t softfloat_addMagsF64 ( uint_fast64_t uiA,
uint_fast64_t uiB,
bool signZ )

Definition at line 44 of file s_addMagsF64.c.

45{
46 int_fast16_t expA;
47 uint_fast64_t sigA;
48 int_fast16_t expB;
49 uint_fast64_t sigB;
50 int_fast16_t expDiff;
51 uint_fast64_t uiZ;
52 int_fast16_t expZ;
53 uint_fast64_t sigZ;
54 union ui64_f64 uZ;
55
56 /*------------------------------------------------------------------------
57 *------------------------------------------------------------------------*/
58 expA = expF64UI( uiA );
59 sigA = fracF64UI( uiA );
60 expB = expF64UI( uiB );
61 sigB = fracF64UI( uiB );
62 /*------------------------------------------------------------------------
63 *------------------------------------------------------------------------*/
64 expDiff = expA - expB;
65 if ( ! expDiff ) {
66 /*--------------------------------------------------------------------
67 *--------------------------------------------------------------------*/
68 if ( ! expA ) {
69 uiZ = uiA + sigB;
70 goto uiZ;
71 }
72 if ( expA == 0x7FF ) {
73 if ( sigA | sigB ) goto propagateNaN;
74 uiZ = uiA;
75 goto uiZ;
76 }
77 expZ = expA;
78 sigZ = UINT64_C( 0x0020000000000000 ) + sigA + sigB;
79 sigZ <<= 9;
80 } else {
81 /*--------------------------------------------------------------------
82 *--------------------------------------------------------------------*/
83 sigA <<= 9;
84 sigB <<= 9;
85 if ( expDiff < 0 ) {
86 if ( expB == 0x7FF ) {
87 if ( sigB ) goto propagateNaN;
88 uiZ = packToF64UI( signZ, 0x7FF, 0 );
89 goto uiZ;
90 }
91 expZ = expB;
92 if ( expA ) {
93 sigA += UINT64_C( 0x2000000000000000 );
94 } else {
95 sigA <<= 1;
96 }
97 sigA = softfloat_shiftRightJam64( sigA, -expDiff );
98 } else {
99 if ( expA == 0x7FF ) {
100 if ( sigA ) goto propagateNaN;
101 uiZ = uiA;
102 goto uiZ;
103 }
104 expZ = expA;
105 if ( expB ) {
106 sigB += UINT64_C( 0x2000000000000000 );
107 } else {
108 sigB <<= 1;
109 }
110 sigB = softfloat_shiftRightJam64( sigB, expDiff );
111 }
112 sigZ = UINT64_C( 0x2000000000000000 ) + sigA + sigB;
113 if ( sigZ < UINT64_C( 0x4000000000000000 ) ) {
114 --expZ;
115 sigZ <<= 1;
116 }
117 }
118 return softfloat_roundPackToF64( signZ, expZ, sigZ );
119 /*------------------------------------------------------------------------
120 *------------------------------------------------------------------------*/
121 propagateNaN:
122 uiZ = softfloat_propagateNaNF64UI( uiA, uiB );
123 uiZ:
124 uZ.ui = uiZ;
125 return uZ.f;
126
127}
uint_fast64_t softfloat_propagateNaNF64UI(uint_fast64_t uiA, uint_fast64_t uiB)
float64_t softfloat_roundPackToF64(bool, int_fast16_t, uint_fast64_t)
#define packToF64UI(sign, exp, sig)
Definition internals.h:128
#define expF64UI(a)
Definition internals.h:126
#define fracF64UI(a)
Definition internals.h:127
uint64_t softfloat_shiftRightJam64(uint64_t a, uint_fast32_t dist)
Here is the call graph for this function:

◆ softfloat_compareNonnormExtF80M()

int softfloat_compareNonnormExtF80M ( const struct extFloat80M * aSPtr,
const struct extFloat80M * bSPtr )

Definition at line 43 of file s_compareNonnormExtF80M.c.

45{
46 uint_fast16_t uiA64, uiB64;
47 uint64_t sigA;
48 bool signB;
49 uint64_t sigB;
50 int32_t expA, expB;
51
52 /*------------------------------------------------------------------------
53 *------------------------------------------------------------------------*/
54 uiA64 = aSPtr->signExp;
55 uiB64 = bSPtr->signExp;
56 sigA = aSPtr->signif;
57 signB = signExtF80UI64( uiB64 );
58 sigB = bSPtr->signif;
59 /*------------------------------------------------------------------------
60 *------------------------------------------------------------------------*/
61 if ( (uiA64 ^ uiB64) & 0x8000 ) {
62 if ( ! (sigA | sigB) ) return 0;
63 goto resultFromSignB;
64 }
65 /*------------------------------------------------------------------------
66 *------------------------------------------------------------------------*/
67 expA = expExtF80UI64( uiA64 );
68 expB = expExtF80UI64( uiB64 );
69 if ( expA == 0x7FFF ) {
70 if (expB == 0x7FFF) return 0;
71 signB = ! signB;
72 goto resultFromSignB;
73 }
74 if ( expB == 0x7FFF ) {
75 goto resultFromSignB;
76 }
77 /*------------------------------------------------------------------------
78 *------------------------------------------------------------------------*/
79 if ( ! expA ) expA = 1;
80 if ( ! (sigA & UINT64_C( 0x8000000000000000 )) ) {
81 if ( sigA ) {
82 expA += softfloat_normExtF80SigM( &sigA );
83 } else {
84 expA = -128;
85 }
86 }
87 if ( ! expB ) expB = 1;
88 if ( ! (sigB & UINT64_C( 0x8000000000000000 )) ) {
89 if ( sigB ) {
90 expB += softfloat_normExtF80SigM( &sigB );
91 } else {
92 expB = -128;
93 }
94 }
95 /*------------------------------------------------------------------------
96 *------------------------------------------------------------------------*/
97 if ( signB ) {
98 if ( expA < expB ) return 1;
99 if ( (expB < expA) || (sigB < sigA) ) return -1;
100 } else {
101 if ( expB < expA ) return 1;
102 if ( (expA < expB) || (sigA < sigB) ) return -1;
103 }
104 return (sigA != sigB);
105 /*------------------------------------------------------------------------
106 *------------------------------------------------------------------------*/
107 resultFromSignB:
108 return signB ? 1 : -1;
109
110}
int softfloat_normExtF80SigM(uint64_t *)
Here is the call graph for this function:

◆ softfloat_invalidExtF80M()

void softfloat_invalidExtF80M ( struct extFloat80M * zSPtr)

Definition at line 41 of file s_invalidExtF80M.c.

42{
43
47
48}
#define defaultNaNExtF80UI0
Definition specialize.h:194
#define defaultNaNExtF80UI64
Definition specialize.h:193
@ softfloat_flag_invalid
Definition softfloat.h:89
Here is the call graph for this function:

◆ softfloat_invalidF128M()

void softfloat_invalidF128M ( uint32_t * zWPtr)

Definition at line 43 of file s_invalidF128M.c.

44{
45
47 zWPtr[indexWord( 4, 3 )] = defaultNaNF128UI96;
48 zWPtr[indexWord( 4, 2 )] = defaultNaNF128UI64;
49 zWPtr[indexWord( 4, 1 )] = defaultNaNF128UI32;
50 zWPtr[indexWord( 4, 0 )] = defaultNaNF128UI0;
51
52}
#define defaultNaNF128UI64
Definition specialize.h:337
#define defaultNaNF128UI96
Definition specialize.h:336
#define defaultNaNF128UI32
Definition specialize.h:338
#define defaultNaNF128UI0
Definition specialize.h:339
Here is the call graph for this function:

◆ softfloat_isNaNF128M()

bool softfloat_isNaNF128M ( const uint32_t * aWPtr)

Definition at line 44 of file s_isNaNF128M.c.

45{
46 uint32_t uiA96;
47
48 uiA96 = aWPtr[indexWordHi( 4 )];
49 if ( (~uiA96 & 0x7FFF0000) != 0 ) return false;
50 return
51 ((uiA96 & 0x0000FFFF) != 0)
52 || ((aWPtr[indexWord( 4, 2 )] | aWPtr[indexWord( 4, 1 )]
53 | aWPtr[indexWord( 4, 0 )])
54 != 0);
55
56}

◆ softfloat_mulAddF128M()

void softfloat_mulAddF128M ( const uint32_t * aWPtr,
const uint32_t * bWPtr,
const uint32_t * cWPtr,
uint32_t * zWPtr,
uint_fast8_t op )

Definition at line 45 of file s_mulAddF128M.c.

52{
53 uint32_t uiA96;
54 int32_t expA;
55 uint32_t uiB96;
56 int32_t expB;
57 uint32_t uiC96;
58 bool signC;
59 int32_t expC;
60 bool signProd, prodIsInfinite;
61 uint32_t *ptr, uiZ96, sigA[4];
62 uint_fast8_t shiftDist;
63 uint32_t sigX[5];
64 int32_t expProd;
65 uint32_t sigProd[8], wordSig;
66 bool doSub;
68 (*addCarryMRoutinePtr)(
70 const uint32_t *,
71 const uint32_t *,
73 uint32_t *
74 );
75 int32_t expDiff;
76 bool signZ;
77 int32_t expZ;
78 uint32_t *extSigPtr;
79 uint_fast8_t carry;
80 void (*roundPackRoutinePtr)( bool, int32_t, uint32_t *, uint32_t * );
81
82 /*------------------------------------------------------------------------
83 *------------------------------------------------------------------------*/
84 uiA96 = aWPtr[indexWordHi( 4 )];
85 expA = expF128UI96( uiA96 );
86 uiB96 = bWPtr[indexWordHi( 4 )];
87 expB = expF128UI96( uiB96 );
88 uiC96 = cWPtr[indexWordHi( 4 )];
89 signC = signF128UI96( uiC96 ) ^ (op == softfloat_mulAdd_subC);
90 expC = expF128UI96( uiC96 );
91 signProd =
92 signF128UI96( uiA96 ) ^ signF128UI96( uiB96 )
94 /*------------------------------------------------------------------------
95 *------------------------------------------------------------------------*/
96 prodIsInfinite = false;
97 if ( (expA == 0x7FFF) || (expB == 0x7FFF) ) {
98 if ( softfloat_tryPropagateNaNF128M( aWPtr, bWPtr, zWPtr ) ) {
99 goto propagateNaN_ZC;
100 }
101 ptr = (uint32_t *) aWPtr;
102 if ( ! (uint32_t) (uiA96<<1) ) goto possibleInvalidProd;
103 if ( ! (uint32_t) (uiB96<<1) ) {
104 ptr = (uint32_t *) bWPtr;
105 possibleInvalidProd:
106 if (
107 ! (ptr[indexWord( 4, 2 )] | ptr[indexWord( 4, 1 )]
108 | ptr[indexWord( 4, 0 )])
109 ) {
110 goto invalid;
111 }
112 }
113 prodIsInfinite = true;
114 }
115 if ( expC == 0x7FFF ) {
116 if (
117 fracF128UI96( uiC96 )
118 || (cWPtr[indexWord( 4, 2 )] | cWPtr[indexWord( 4, 1 )]
119 | cWPtr[indexWord( 4, 0 )])
120 ) {
121 zWPtr[indexWordHi( 4 )] = 0;
122 goto propagateNaN_ZC;
123 }
124 if ( prodIsInfinite && (signProd != signC) ) goto invalid;
125 goto copyC;
126 }
127 if ( prodIsInfinite ) {
128 uiZ96 = packToF128UI96( signProd, 0x7FFF, 0 );
129 goto uiZ;
130 }
131 /*------------------------------------------------------------------------
132 *------------------------------------------------------------------------*/
133 if ( expA ) {
134 sigA[indexWordHi( 4 )] = fracF128UI96( uiA96 ) | 0x00010000;
135 sigA[indexWord( 4, 2 )] = aWPtr[indexWord( 4, 2 )];
136 sigA[indexWord( 4, 1 )] = aWPtr[indexWord( 4, 1 )];
137 sigA[indexWord( 4, 0 )] = aWPtr[indexWord( 4, 0 )];
138 } else {
139 expA = softfloat_shiftNormSigF128M( aWPtr, 0, sigA );
140 if ( expA == -128 ) goto zeroProd;
141 }
142 if ( expB ) {
143 sigX[indexWordHi( 4 )] = fracF128UI96( uiB96 ) | 0x00010000;
144 sigX[indexWord( 4, 2 )] = bWPtr[indexWord( 4, 2 )];
145 sigX[indexWord( 4, 1 )] = bWPtr[indexWord( 4, 1 )];
146 sigX[indexWord( 4, 0 )] = bWPtr[indexWord( 4, 0 )];
147 } else {
148 expB = softfloat_shiftNormSigF128M( bWPtr, 0, sigX );
149 if ( expB == -128 ) goto zeroProd;
150 }
151 /*------------------------------------------------------------------------
152 *------------------------------------------------------------------------*/
153 expProd = expA + expB - 0x3FF0;
154 softfloat_mul128MTo256M( sigA, sigX, sigProd );
155 /*------------------------------------------------------------------------
156 *------------------------------------------------------------------------*/
157 wordSig = fracF128UI96( uiC96 );
158 if ( expC ) {
159 --expC;
160 wordSig |= 0x00010000;
161 }
162 sigX[indexWordHi( 5 )] = wordSig;
163 sigX[indexWord( 5, 3 )] = cWPtr[indexWord( 4, 2 )];
164 sigX[indexWord( 5, 2 )] = cWPtr[indexWord( 4, 1 )];
165 sigX[indexWord( 5, 1 )] = cWPtr[indexWord( 4, 0 )];
166 /*------------------------------------------------------------------------
167 *------------------------------------------------------------------------*/
168 doSub = (signProd != signC);
169 addCarryMRoutinePtr =
171 expDiff = expProd - expC;
172 if ( expDiff <= 0 ) {
173 /*--------------------------------------------------------------------
174 *--------------------------------------------------------------------*/
175 signZ = signC;
176 expZ = expC;
177 if (
178 sigProd[indexWord( 8, 2 )]
179 || (sigProd[indexWord( 8, 1 )] | sigProd[indexWord( 8, 0 )])
180 ) {
181 sigProd[indexWord( 8, 3 )] |= 1;
182 }
183 extSigPtr = &sigProd[indexMultiwordHi( 8, 5 )];
184 if ( expDiff ) {
185 softfloat_shiftRightJam160M( extSigPtr, -expDiff, extSigPtr );
186 }
187 carry = 0;
188 if ( doSub ) {
189 wordSig = extSigPtr[indexWordLo( 5 )];
190 extSigPtr[indexWordLo( 5 )] = -wordSig;
191 carry = ! wordSig;
192 }
193 (*addCarryMRoutinePtr)(
194 4,
195 &sigX[indexMultiwordHi( 5, 4 )],
196 extSigPtr + indexMultiwordHi( 5, 4 ),
197 carry,
198 extSigPtr + indexMultiwordHi( 5, 4 )
199 );
200 wordSig = extSigPtr[indexWordHi( 5 )];
201 if ( ! expZ ) {
202 if ( wordSig & 0x80000000 ) {
203 signZ = ! signZ;
204 softfloat_negX160M( extSigPtr );
205 wordSig = extSigPtr[indexWordHi( 5 )];
206 }
207 goto checkCancellation;
208 }
209 if ( wordSig < 0x00010000 ) {
210 --expZ;
211 softfloat_add160M( extSigPtr, extSigPtr, extSigPtr );
212 goto roundPack;
213 }
214 goto extSigReady_noCancellation;
215 } else {
216 /*--------------------------------------------------------------------
217 *--------------------------------------------------------------------*/
218 signZ = signProd;
219 expZ = expProd;
220 sigX[indexWordLo( 5 )] = 0;
221 expDiff -= 128;
222 if ( 0 <= expDiff ) {
223 /*----------------------------------------------------------------
224 *----------------------------------------------------------------*/
225 if ( expDiff ) softfloat_shiftRightJam160M( sigX, expDiff, sigX );
226 wordSig = sigX[indexWordLo( 5 )];
227 carry = 0;
228 if ( doSub ) {
229 carry = ! wordSig;
230 wordSig = -wordSig;
231 }
232 carry =
233 (*addCarryMRoutinePtr)(
234 4,
235 &sigProd[indexMultiwordLo( 8, 4 )],
236 &sigX[indexMultiwordHi( 5, 4 )],
237 carry,
238 &sigProd[indexMultiwordLo( 8, 4 )]
239 );
240 sigProd[indexWord( 8, 2 )] |= wordSig;
241 ptr = &sigProd[indexWord( 8, 4 )];
242 } else {
243 /*----------------------------------------------------------------
244 *----------------------------------------------------------------*/
245 shiftDist = expDiff & 31;
246 if ( shiftDist ) {
247 softfloat_shortShiftRight160M( sigX, shiftDist, sigX );
248 }
249 expDiff >>= 5;
250 extSigPtr =
251 &sigProd[indexMultiwordLo( 8, 5 )] - wordIncr
252 + expDiff * -wordIncr;
253 carry =
254 (*addCarryMRoutinePtr)( 5, extSigPtr, sigX, doSub, extSigPtr );
255 if ( expDiff == -4 ) {
256 /*------------------------------------------------------------
257 *------------------------------------------------------------*/
258 wordSig = sigProd[indexWordHi( 8 )];
259 if ( wordSig & 0x80000000 ) {
260 signZ = ! signZ;
261 softfloat_negX256M( sigProd );
262 wordSig = sigProd[indexWordHi( 8 )];
263 }
264 /*------------------------------------------------------------
265 *------------------------------------------------------------*/
266 if ( wordSig ) goto expProdBigger_noWordShift;
267 wordSig = sigProd[indexWord( 8, 6 )];
268 if ( 0x00040000 <= wordSig ) goto expProdBigger_noWordShift;
269 expZ -= 32;
270 extSigPtr = &sigProd[indexMultiwordHi( 8, 5 )] - wordIncr;
271 for (;;) {
272 if ( wordSig ) break;
273 wordSig = extSigPtr[indexWord( 5, 3 )];
274 if ( 0x00040000 <= wordSig ) break;
275 expZ -= 32;
276 extSigPtr -= wordIncr;
277 if ( extSigPtr == &sigProd[indexMultiwordLo( 8, 5 )] ) {
278 goto checkCancellation;
279 }
280 }
281 /*------------------------------------------------------------
282 *------------------------------------------------------------*/
283 ptr = extSigPtr + indexWordLo( 5 );
284 do {
285 ptr -= wordIncr;
286 if ( *ptr ) {
287 extSigPtr[indexWordLo( 5 )] |= 1;
288 break;
289 }
290 } while ( ptr != &sigProd[indexWordLo( 8 )] );
291 wordSig = extSigPtr[indexWordHi( 5 )];
292 goto extSigReady;
293 }
294 ptr = extSigPtr + indexWordHi( 5 ) + wordIncr;
295 }
296 /*--------------------------------------------------------------------
297 *--------------------------------------------------------------------*/
298 if ( carry != doSub ) {
299 if ( doSub ) {
300 do {
301 wordSig = *ptr;
302 *ptr = wordSig - 1;
303 ptr += wordIncr;
304 } while ( ! wordSig );
305 } else {
306 do {
307 wordSig = *ptr + 1;
308 *ptr = wordSig;
309 ptr += wordIncr;
310 } while ( ! wordSig );
311 }
312 }
313 /*--------------------------------------------------------------------
314 *--------------------------------------------------------------------*/
315 expProdBigger_noWordShift:
316 if (
317 sigProd[indexWord( 8, 2 )]
318 || (sigProd[indexWord( 8, 1 )] | sigProd[indexWord( 8, 0 )])
319 ) {
320 sigProd[indexWord( 8, 3 )] |= 1;
321 }
322 extSigPtr = &sigProd[indexMultiwordHi( 8, 5 )];
323 wordSig = extSigPtr[indexWordHi( 5 )];
324 }
325 extSigReady:
326 roundPackRoutinePtr = softfloat_normRoundPackMToF128M;
327 if ( wordSig < 0x00010000 ) goto doRoundPack;
328 extSigReady_noCancellation:
329 if ( 0x00020000 <= wordSig ) {
330 ++expZ;
331 softfloat_shortShiftRightJam160M( extSigPtr, 1, extSigPtr );
332 }
333 roundPack:
334 roundPackRoutinePtr = softfloat_roundPackMToF128M;
335 doRoundPack:
336 (*roundPackRoutinePtr)( signZ, expZ, extSigPtr, zWPtr );
337 return;
338 /*------------------------------------------------------------------------
339 *------------------------------------------------------------------------*/
340 invalid:
341 softfloat_invalidF128M( zWPtr );
342 propagateNaN_ZC:
343 softfloat_propagateNaNF128M( zWPtr, cWPtr, zWPtr );
344 return;
345 /*------------------------------------------------------------------------
346 *------------------------------------------------------------------------*/
347 zeroProd:
348 if (
349 ! (uint32_t) (uiC96<<1) && (signProd != signC)
350 && ! cWPtr[indexWord( 4, 2 )]
351 && ! (cWPtr[indexWord( 4, 1 )] | cWPtr[indexWord( 4, 0 )])
352 ) {
353 goto completeCancellation;
354 }
355 copyC:
356 zWPtr[indexWordHi( 4 )] = uiC96;
357 zWPtr[indexWord( 4, 2 )] = cWPtr[indexWord( 4, 2 )];
358 zWPtr[indexWord( 4, 1 )] = cWPtr[indexWord( 4, 1 )];
359 zWPtr[indexWord( 4, 0 )] = cWPtr[indexWord( 4, 0 )];
360 return;
361 /*------------------------------------------------------------------------
362 *------------------------------------------------------------------------*/
363 checkCancellation:
364 if (
365 wordSig
366 || (extSigPtr[indexWord( 5, 3 )] | extSigPtr[indexWord( 5, 2 )])
367 || (extSigPtr[indexWord( 5, 1 )] | extSigPtr[indexWord( 5, 0 )])
368 ) {
369 goto extSigReady;
370 }
371 completeCancellation:
372 uiZ96 =
375 uiZ:
376 zWPtr[indexWordHi( 4 )] = uiZ96;
377 zWPtr[indexWord( 4, 2 )] = 0;
378 zWPtr[indexWord( 4, 1 )] = 0;
379 zWPtr[indexWord( 4, 0 )] = 0;
380
381}
void softfloat_propagateNaNF128M(const uint32_t *aWPtr, const uint32_t *bWPtr, uint32_t *zWPtr)
int softfloat_shiftNormSigF128M(const uint32_t *, uint_fast8_t, uint32_t *)
#define indexMultiwordHi(total, n)
#define wordIncr
#define softfloat_negX160M(zPtr)
#define softfloat_shortShiftRight160M(aPtr, dist, zPtr)
Definition primitives.h:790
#define softfloat_add160M(aPtr, bPtr, zPtr)
Definition primitives.h:931
#define softfloat_negX256M(zPtr)
void softfloat_mul128MTo256M(const uint32_t *aPtr, const uint32_t *bPtr, uint32_t *zPtr)
Here is the call graph for this function:

◆ softfloat_mulAddF16()

float16_t softfloat_mulAddF16 ( uint_fast16_t uiA,
uint_fast16_t uiB,
uint_fast16_t uiC,
uint_fast8_t op )

Definition at line 45 of file s_mulAddF16.c.

47{
48 bool signA;
49 int_fast8_t expA;
50 uint_fast16_t sigA;
51 bool signB;
52 int_fast8_t expB;
53 uint_fast16_t sigB;
54 bool signC;
55 int_fast8_t expC;
56 uint_fast16_t sigC;
57 bool signProd;
58 uint_fast16_t magBits, uiZ;
59 struct exp8_sig16 normExpSig;
60 int_fast8_t expProd;
61 uint_fast32_t sigProd;
62 bool signZ;
63 int_fast8_t expZ;
64 uint_fast16_t sigZ;
65 int_fast8_t expDiff;
66 uint_fast32_t sig32Z, sig32C;
67 int_fast8_t shiftDist;
68 union ui16_f16 uZ;
69
70 /*------------------------------------------------------------------------
71 *------------------------------------------------------------------------*/
72 signA = signF16UI( uiA );
73 expA = expF16UI( uiA );
74 sigA = fracF16UI( uiA );
75 signB = signF16UI( uiB );
76 expB = expF16UI( uiB );
77 sigB = fracF16UI( uiB );
78 signC = signF16UI( uiC ) ^ (op == softfloat_mulAdd_subC);
79 expC = expF16UI( uiC );
80 sigC = fracF16UI( uiC );
81 signProd = signA ^ signB ^ (op == softfloat_mulAdd_subProd);
82 /*------------------------------------------------------------------------
83 *------------------------------------------------------------------------*/
84 if ( expA == 0x1F ) {
85 if ( sigA || ((expB == 0x1F) && sigB) ) goto propagateNaN_ABC;
86 magBits = expB | sigB;
87 goto infProdArg;
88 }
89 if ( expB == 0x1F ) {
90 if ( sigB ) goto propagateNaN_ABC;
91 magBits = expA | sigA;
92 goto infProdArg;
93 }
94 if ( expC == 0x1F ) {
95 if ( sigC ) {
96 uiZ = 0;
97 goto propagateNaN_ZC;
98 }
99 uiZ = uiC;
100 goto uiZ;
101 }
102 /*------------------------------------------------------------------------
103 *------------------------------------------------------------------------*/
104 if ( ! expA ) {
105 if ( ! sigA ) goto zeroProd;
106 normExpSig = softfloat_normSubnormalF16Sig( sigA );
107 expA = normExpSig.exp;
108 sigA = normExpSig.sig;
109 }
110 if ( ! expB ) {
111 if ( ! sigB ) goto zeroProd;
112 normExpSig = softfloat_normSubnormalF16Sig( sigB );
113 expB = normExpSig.exp;
114 sigB = normExpSig.sig;
115 }
116 /*------------------------------------------------------------------------
117 *------------------------------------------------------------------------*/
118 expProd = expA + expB - 0xE;
119 sigA = (sigA | 0x0400)<<4;
120 sigB = (sigB | 0x0400)<<4;
121 sigProd = (uint_fast32_t) sigA * sigB;
122 if ( sigProd < 0x20000000 ) {
123 --expProd;
124 sigProd <<= 1;
125 }
126 signZ = signProd;
127 if ( ! expC ) {
128 if ( ! sigC ) {
129 expZ = expProd - 1;
130 sigZ = sigProd>>15 | ((sigProd & 0x7FFF) != 0);
131 goto roundPack;
132 }
133 normExpSig = softfloat_normSubnormalF16Sig( sigC );
134 expC = normExpSig.exp;
135 sigC = normExpSig.sig;
136 }
137 sigC = (sigC | 0x0400)<<3;
138 /*------------------------------------------------------------------------
139 *------------------------------------------------------------------------*/
140 expDiff = expProd - expC;
141 if ( signProd == signC ) {
142 /*--------------------------------------------------------------------
143 *--------------------------------------------------------------------*/
144 if ( expDiff <= 0 ) {
145 expZ = expC;
146 sigZ = sigC + softfloat_shiftRightJam32( sigProd, 16 - expDiff );
147 } else {
148 expZ = expProd;
149 sig32Z =
150 sigProd
152 (uint_fast32_t) sigC<<16, expDiff );
153 sigZ = sig32Z>>16 | ((sig32Z & 0xFFFF) != 0 );
154 }
155 if ( sigZ < 0x4000 ) {
156 --expZ;
157 sigZ <<= 1;
158 }
159 } else {
160 /*--------------------------------------------------------------------
161 *--------------------------------------------------------------------*/
162 sig32C = (uint_fast32_t) sigC<<16;
163 if ( expDiff < 0 ) {
164 signZ = signC;
165 expZ = expC;
166 sig32Z = sig32C - softfloat_shiftRightJam32( sigProd, -expDiff );
167 } else if ( ! expDiff ) {
168 expZ = expProd;
169 sig32Z = sigProd - sig32C;
170 if ( ! sig32Z ) goto completeCancellation;
171 if ( sig32Z & 0x80000000 ) {
172 signZ = ! signZ;
173 sig32Z = -sig32Z;
174 }
175 } else {
176 expZ = expProd;
177 sig32Z = sigProd - softfloat_shiftRightJam32( sig32C, expDiff );
178 }
179 shiftDist = softfloat_countLeadingZeros32( sig32Z ) - 1;
180 expZ -= shiftDist;
181 shiftDist -= 16;
182 if ( shiftDist < 0 ) {
183 sigZ =
184 sig32Z>>(-shiftDist)
185 | ((uint32_t) (sig32Z<<(shiftDist & 31)) != 0);
186 } else {
187 sigZ = (uint_fast16_t) sig32Z<<shiftDist;
188 }
189 }
190 roundPack:
191 return softfloat_roundPackToF16( signZ, expZ, sigZ );
192 /*------------------------------------------------------------------------
193 *------------------------------------------------------------------------*/
194 propagateNaN_ABC:
195 uiZ = softfloat_propagateNaNF16UI( uiA, uiB );
196 goto propagateNaN_ZC;
197 /*------------------------------------------------------------------------
198 *------------------------------------------------------------------------*/
199 infProdArg:
200 if ( magBits ) {
201 uiZ = packToF16UI( signProd, 0x1F, 0 );
202 if ( expC != 0x1F ) goto uiZ;
203 if ( sigC ) goto propagateNaN_ZC;
204 if ( signProd == signC ) goto uiZ;
205 }
207 uiZ = defaultNaNF16UI;
208 propagateNaN_ZC:
209 uiZ = softfloat_propagateNaNF16UI( uiZ, uiC );
210 goto uiZ;
211 /*------------------------------------------------------------------------
212 *------------------------------------------------------------------------*/
213 zeroProd:
214 uiZ = uiC;
215 if ( ! (expC | sigC) && (signProd != signC) ) {
216 completeCancellation:
217 uiZ =
220 }
221 uiZ:
222 uZ.ui = uiZ;
223 return uZ.f;
224
225}
#define defaultNaNF16UI
Definition specialize.h:88
struct exp8_sig16 softfloat_normSubnormalF16Sig(uint_fast16_t)
#define softfloat_countLeadingZeros32
Here is the call graph for this function:

◆ softfloat_mulAddF32()

float32_t softfloat_mulAddF32 ( uint_fast32_t uiA,
uint_fast32_t uiB,
uint_fast32_t uiC,
uint_fast8_t op )

Definition at line 45 of file s_mulAddF32.c.

47{
48 bool signA;
49 int_fast16_t expA;
50 uint_fast32_t sigA;
51 bool signB;
52 int_fast16_t expB;
53 uint_fast32_t sigB;
54 bool signC;
55 int_fast16_t expC;
56 uint_fast32_t sigC;
57 bool signProd;
58 uint_fast32_t magBits, uiZ;
59 struct exp16_sig32 normExpSig;
60 int_fast16_t expProd;
61 uint_fast64_t sigProd;
62 bool signZ;
63 int_fast16_t expZ;
64 uint_fast32_t sigZ;
65 int_fast16_t expDiff;
66 uint_fast64_t sig64Z, sig64C;
67 int_fast8_t shiftDist;
68 union ui32_f32 uZ;
69
70 /*------------------------------------------------------------------------
71 *------------------------------------------------------------------------*/
72 signA = signF32UI( uiA );
73 expA = expF32UI( uiA );
74 sigA = fracF32UI( uiA );
75 signB = signF32UI( uiB );
76 expB = expF32UI( uiB );
77 sigB = fracF32UI( uiB );
78 signC = signF32UI( uiC ) ^ (op == softfloat_mulAdd_subC);
79 expC = expF32UI( uiC );
80 sigC = fracF32UI( uiC );
81 signProd = signA ^ signB ^ (op == softfloat_mulAdd_subProd);
82 /*------------------------------------------------------------------------
83 *------------------------------------------------------------------------*/
84 if ( expA == 0xFF ) {
85 if ( sigA || ((expB == 0xFF) && sigB) ) goto propagateNaN_ABC;
86 magBits = expB | sigB;
87 goto infProdArg;
88 }
89 if ( expB == 0xFF ) {
90 if ( sigB ) goto propagateNaN_ABC;
91 magBits = expA | sigA;
92 goto infProdArg;
93 }
94 if ( expC == 0xFF ) {
95 if ( sigC ) {
96 uiZ = 0;
97 goto propagateNaN_ZC;
98 }
99 uiZ = uiC;
100 goto uiZ;
101 }
102 /*------------------------------------------------------------------------
103 *------------------------------------------------------------------------*/
104 if ( ! expA ) {
105 if ( ! sigA ) goto zeroProd;
106 normExpSig = softfloat_normSubnormalF32Sig( sigA );
107 expA = normExpSig.exp;
108 sigA = normExpSig.sig;
109 }
110 if ( ! expB ) {
111 if ( ! sigB ) goto zeroProd;
112 normExpSig = softfloat_normSubnormalF32Sig( sigB );
113 expB = normExpSig.exp;
114 sigB = normExpSig.sig;
115 }
116 /*------------------------------------------------------------------------
117 *------------------------------------------------------------------------*/
118 expProd = expA + expB - 0x7E;
119 sigA = (sigA | 0x00800000)<<7;
120 sigB = (sigB | 0x00800000)<<7;
121 sigProd = (uint_fast64_t) sigA * sigB;
122 if ( sigProd < UINT64_C( 0x2000000000000000 ) ) {
123 --expProd;
124 sigProd <<= 1;
125 }
126 signZ = signProd;
127 if ( ! expC ) {
128 if ( ! sigC ) {
129 expZ = expProd - 1;
130 sigZ = softfloat_shortShiftRightJam64( sigProd, 31 );
131 goto roundPack;
132 }
133 normExpSig = softfloat_normSubnormalF32Sig( sigC );
134 expC = normExpSig.exp;
135 sigC = normExpSig.sig;
136 }
137 sigC = (sigC | 0x00800000)<<6;
138 /*------------------------------------------------------------------------
139 *------------------------------------------------------------------------*/
140 expDiff = expProd - expC;
141 if ( signProd == signC ) {
142 /*--------------------------------------------------------------------
143 *--------------------------------------------------------------------*/
144 if ( expDiff <= 0 ) {
145 expZ = expC;
146 sigZ = sigC + softfloat_shiftRightJam64( sigProd, 32 - expDiff );
147 } else {
148 expZ = expProd;
149 sig64Z =
150 sigProd
152 (uint_fast64_t) sigC<<32, expDiff );
153 sigZ = softfloat_shortShiftRightJam64( sig64Z, 32 );
154 }
155 if ( sigZ < 0x40000000 ) {
156 --expZ;
157 sigZ <<= 1;
158 }
159 } else {
160 /*--------------------------------------------------------------------
161 *--------------------------------------------------------------------*/
162 sig64C = (uint_fast64_t) sigC<<32;
163 if ( expDiff < 0 ) {
164 signZ = signC;
165 expZ = expC;
166 sig64Z = sig64C - softfloat_shiftRightJam64( sigProd, -expDiff );
167 } else if ( ! expDiff ) {
168 expZ = expProd;
169 sig64Z = sigProd - sig64C;
170 if ( ! sig64Z ) goto completeCancellation;
171 if ( sig64Z & UINT64_C( 0x8000000000000000 ) ) {
172 signZ = ! signZ;
173 sig64Z = -sig64Z;
174 }
175 } else {
176 expZ = expProd;
177 sig64Z = sigProd - softfloat_shiftRightJam64( sig64C, expDiff );
178 }
179 shiftDist = softfloat_countLeadingZeros64( sig64Z ) - 1;
180 expZ -= shiftDist;
181 shiftDist -= 32;
182 if ( shiftDist < 0 ) {
183 sigZ = softfloat_shortShiftRightJam64( sig64Z, -shiftDist );
184 } else {
185 sigZ = (uint_fast32_t) sig64Z<<shiftDist;
186 }
187 }
188 roundPack:
189 return softfloat_roundPackToF32( signZ, expZ, sigZ );
190 /*------------------------------------------------------------------------
191 *------------------------------------------------------------------------*/
192 propagateNaN_ABC:
193 uiZ = softfloat_propagateNaNF32UI( uiA, uiB );
194 goto propagateNaN_ZC;
195 /*------------------------------------------------------------------------
196 *------------------------------------------------------------------------*/
197 infProdArg:
198 if ( magBits ) {
199 uiZ = packToF32UI( signProd, 0xFF, 0 );
200 if ( expC != 0xFF ) goto uiZ;
201 if ( sigC ) goto propagateNaN_ZC;
202 if ( signProd == signC ) goto uiZ;
203 }
205 uiZ = defaultNaNF32UI;
206 propagateNaN_ZC:
207 uiZ = softfloat_propagateNaNF32UI( uiZ, uiC );
208 goto uiZ;
209 /*------------------------------------------------------------------------
210 *------------------------------------------------------------------------*/
211 zeroProd:
212 uiZ = uiC;
213 if ( ! (expC | sigC) && (signProd != signC) ) {
214 completeCancellation:
215 uiZ =
218 }
219 uiZ:
220 uZ.ui = uiZ;
221 return uZ.f;
222
223}
#define defaultNaNF32UI
Definition specialize.h:123
struct exp16_sig32 softfloat_normSubnormalF32Sig(uint_fast32_t)
uint64_t softfloat_shortShiftRightJam64(uint64_t a, uint_fast8_t dist)
#define softfloat_countLeadingZeros64
Here is the call graph for this function:

◆ softfloat_mulAddF64()

float64_t softfloat_mulAddF64 ( uint_fast64_t uiA,
uint_fast64_t uiB,
uint_fast64_t uiC,
uint_fast8_t op )

Definition at line 247 of file s_mulAddF64.c.

249{
250 bool signA;
251 int_fast16_t expA;
252 uint64_t sigA;
253 bool signB;
254 int_fast16_t expB;
255 uint64_t sigB;
256 bool signC;
257 int_fast16_t expC;
258 uint64_t sigC;
259 bool signZ;
260 uint64_t magBits, uiZ;
261 struct exp16_sig64 normExpSig;
262 int_fast16_t expZ;
263 uint32_t sig128Z[4];
264 uint64_t sigZ;
265 int_fast16_t shiftDist, expDiff;
266 uint32_t sig128C[4];
267 union ui64_f64 uZ;
268
269 /*------------------------------------------------------------------------
270 *------------------------------------------------------------------------*/
271 signA = signF64UI( uiA );
272 expA = expF64UI( uiA );
273 sigA = fracF64UI( uiA );
274 signB = signF64UI( uiB );
275 expB = expF64UI( uiB );
276 sigB = fracF64UI( uiB );
277 signC = signF64UI( uiC ) ^ (op == softfloat_mulAdd_subC);
278 expC = expF64UI( uiC );
279 sigC = fracF64UI( uiC );
280 signZ = signA ^ signB ^ (op == softfloat_mulAdd_subProd);
281 /*------------------------------------------------------------------------
282 *------------------------------------------------------------------------*/
283 if ( expA == 0x7FF ) {
284 if ( sigA || ((expB == 0x7FF) && sigB) ) goto propagateNaN_ABC;
285 magBits = expB | sigB;
286 goto infProdArg;
287 }
288 if ( expB == 0x7FF ) {
289 if ( sigB ) goto propagateNaN_ABC;
290 magBits = expA | sigA;
291 goto infProdArg;
292 }
293 if ( expC == 0x7FF ) {
294 if ( sigC ) {
295 uiZ = 0;
296 goto propagateNaN_ZC;
297 }
298 uiZ = uiC;
299 goto uiZ;
300 }
301 /*------------------------------------------------------------------------
302 *------------------------------------------------------------------------*/
303 if ( ! expA ) {
304 if ( ! sigA ) goto zeroProd;
305 normExpSig = softfloat_normSubnormalF64Sig( sigA );
306 expA = normExpSig.exp;
307 sigA = normExpSig.sig;
308 }
309 if ( ! expB ) {
310 if ( ! sigB ) goto zeroProd;
311 normExpSig = softfloat_normSubnormalF64Sig( sigB );
312 expB = normExpSig.exp;
313 sigB = normExpSig.sig;
314 }
315 /*------------------------------------------------------------------------
316 *------------------------------------------------------------------------*/
317 expZ = expA + expB - 0x3FE;
318 sigA = (sigA | UINT64_C( 0x0010000000000000 ))<<10;
319 sigB = (sigB | UINT64_C( 0x0010000000000000 ))<<11;
320 softfloat_mul64To128M( sigA, sigB, sig128Z );
321 sigZ =
322 (uint64_t) sig128Z[indexWord( 4, 3 )]<<32 | sig128Z[indexWord( 4, 2 )];
323 shiftDist = 0;
324 if ( ! (sigZ & UINT64_C( 0x4000000000000000 )) ) {
325 --expZ;
326 shiftDist = -1;
327 }
328 if ( ! expC ) {
329 if ( ! sigC ) {
330 if ( shiftDist ) sigZ <<= 1;
331 goto sigZ;
332 }
333 normExpSig = softfloat_normSubnormalF64Sig( sigC );
334 expC = normExpSig.exp;
335 sigC = normExpSig.sig;
336 }
337 sigC = (sigC | UINT64_C( 0x0010000000000000 ))<<10;
338 /*------------------------------------------------------------------------
339 *------------------------------------------------------------------------*/
340 expDiff = expZ - expC;
341 if ( expDiff < 0 ) {
342 expZ = expC;
343 if ( (signZ == signC) || (expDiff < -1) ) {
344 shiftDist -= expDiff;
345 if ( shiftDist) {
346 sigZ = softfloat_shiftRightJam64( sigZ, shiftDist );
347 }
348 } else {
349 if ( ! shiftDist ) {
350 softfloat_shortShiftRight128M( sig128Z, 1, sig128Z );
351 }
352 }
353 } else {
354 if ( shiftDist ) softfloat_add128M( sig128Z, sig128Z, sig128Z );
355 if ( ! expDiff ) {
356 sigZ =
357 (uint64_t) sig128Z[indexWord( 4, 3 )]<<32
358 | sig128Z[indexWord( 4, 2 )];
359 } else {
360 sig128C[indexWord( 4, 3 )] = sigC>>32;
361 sig128C[indexWord( 4, 2 )] = sigC;
362 sig128C[indexWord( 4, 1 )] = 0;
363 sig128C[indexWord( 4, 0 )] = 0;
364 softfloat_shiftRightJam128M( sig128C, expDiff, sig128C );
365 }
366 }
367 /*------------------------------------------------------------------------
368 *------------------------------------------------------------------------*/
369 if ( signZ == signC ) {
370 /*--------------------------------------------------------------------
371 *--------------------------------------------------------------------*/
372 if ( expDiff <= 0 ) {
373 sigZ += sigC;
374 } else {
375 softfloat_add128M( sig128Z, sig128C, sig128Z );
376 sigZ =
377 (uint64_t) sig128Z[indexWord( 4, 3 )]<<32
378 | sig128Z[indexWord( 4, 2 )];
379 }
380 if ( sigZ & UINT64_C( 0x8000000000000000 ) ) {
381 ++expZ;
382 sigZ = softfloat_shortShiftRightJam64( sigZ, 1 );
383 }
384 } else {
385 /*--------------------------------------------------------------------
386 *--------------------------------------------------------------------*/
387 if ( expDiff < 0 ) {
388 signZ = signC;
389 if ( expDiff < -1 ) {
390 sigZ = sigC - sigZ;
391 if (
392 sig128Z[indexWord( 4, 1 )] || sig128Z[indexWord( 4, 0 )]
393 ) {
394 sigZ = (sigZ - 1) | 1;
395 }
396 if ( ! (sigZ & UINT64_C( 0x4000000000000000 )) ) {
397 --expZ;
398 sigZ <<= 1;
399 }
400 goto roundPack;
401 } else {
402 sig128C[indexWord( 4, 3 )] = sigC>>32;
403 sig128C[indexWord( 4, 2 )] = sigC;
404 sig128C[indexWord( 4, 1 )] = 0;
405 sig128C[indexWord( 4, 0 )] = 0;
406 softfloat_sub128M( sig128C, sig128Z, sig128Z );
407 }
408 } else if ( ! expDiff ) {
409 sigZ -= sigC;
410 if (
411 ! sigZ && ! sig128Z[indexWord( 4, 1 )]
412 && ! sig128Z[indexWord( 4, 0 )]
413 ) {
414 goto completeCancellation;
415 }
416 sig128Z[indexWord( 4, 3 )] = sigZ>>32;
417 sig128Z[indexWord( 4, 2 )] = sigZ;
418 if ( sigZ & UINT64_C( 0x8000000000000000 ) ) {
419 signZ = ! signZ;
420 softfloat_negX128M( sig128Z );
421 }
422 } else {
423 softfloat_sub128M( sig128Z, sig128C, sig128Z );
424 if ( 1 < expDiff ) {
425 sigZ =
426 (uint64_t) sig128Z[indexWord( 4, 3 )]<<32
427 | sig128Z[indexWord( 4, 2 )];
428 if ( ! (sigZ & UINT64_C( 0x4000000000000000 )) ) {
429 --expZ;
430 sigZ <<= 1;
431 }
432 goto sigZ;
433 }
434 }
435 /*--------------------------------------------------------------------
436 *--------------------------------------------------------------------*/
437 shiftDist = 0;
438 sigZ =
439 (uint64_t) sig128Z[indexWord( 4, 3 )]<<32
440 | sig128Z[indexWord( 4, 2 )];
441 if ( ! sigZ ) {
442 shiftDist = 64;
443 sigZ =
444 (uint64_t) sig128Z[indexWord( 4, 1 )]<<32
445 | sig128Z[indexWord( 4, 0 )];
446 }
447 shiftDist += softfloat_countLeadingZeros64( sigZ ) - 1;
448 if ( shiftDist ) {
449 expZ -= shiftDist;
450 softfloat_shiftLeft128M( sig128Z, shiftDist, sig128Z );
451 sigZ =
452 (uint64_t) sig128Z[indexWord( 4, 3 )]<<32
453 | sig128Z[indexWord( 4, 2 )];
454 }
455 }
456 sigZ:
457 if ( sig128Z[indexWord( 4, 1 )] || sig128Z[indexWord( 4, 0 )] ) sigZ |= 1;
458 roundPack:
459 return softfloat_roundPackToF64( signZ, expZ - 1, sigZ );
460 /*------------------------------------------------------------------------
461 *------------------------------------------------------------------------*/
462 propagateNaN_ABC:
463 uiZ = softfloat_propagateNaNF64UI( uiA, uiB );
464 goto propagateNaN_ZC;
465 /*------------------------------------------------------------------------
466 *------------------------------------------------------------------------*/
467 infProdArg:
468 if ( magBits ) {
469 uiZ = packToF64UI( signZ, 0x7FF, 0 );
470 if ( expC != 0x7FF ) goto uiZ;
471 if ( sigC ) goto propagateNaN_ZC;
472 if ( signZ == signC ) goto uiZ;
473 }
475 uiZ = defaultNaNF64UI;
476 propagateNaN_ZC:
477 uiZ = softfloat_propagateNaNF64UI( uiZ, uiC );
478 goto uiZ;
479 /*------------------------------------------------------------------------
480 *------------------------------------------------------------------------*/
481 zeroProd:
482 uiZ = uiC;
483 if ( ! (expC | sigC) && (signZ != signC) ) {
484 completeCancellation:
485 uiZ =
488 }
489 uiZ:
490 uZ.ui = uiZ;
491 return uZ.f;
492
493}
#define defaultNaNF64UI
Definition specialize.h:158
struct exp16_sig64 softfloat_normSubnormalF64Sig(uint_fast64_t)
#define signF64UI(a)
Definition internals.h:125
#define softfloat_add128M(aPtr, bPtr, zPtr)
Definition primitives.h:923
#define softfloat_sub128M(aPtr, bPtr, zPtr)
void softfloat_mul64To128M(uint64_t a, uint64_t b, uint32_t *zPtr)
#define softfloat_shiftRightJam128M(aPtr, dist, zPtr)
Definition primitives.h:881
#define softfloat_negX128M(zPtr)
#define softfloat_shiftLeft128M(aPtr, dist, zPtr)
Definition primitives.h:747
#define softfloat_shortShiftRight128M(aPtr, dist, zPtr)
Definition primitives.h:782
Here is the call graph for this function:

◆ softfloat_normExtF80SigM()

int softfloat_normExtF80SigM ( uint64_t * sigPtr)

Definition at line 41 of file s_normExtF80SigM.c.

42{
43 uint64_t sig;
44 int_fast8_t shiftDist;
45
46 sig = *sigPtr;
47 shiftDist = softfloat_countLeadingZeros64( sig );
48 *sigPtr = sig<<shiftDist;
49 return -shiftDist;
50
51}

◆ softfloat_normRoundPackMToExtF80M()

void softfloat_normRoundPackMToExtF80M ( bool sign,
int32_t exp,
uint32_t * extSigPtr,
uint_fast8_t roundingPrecision,
struct extFloat80M * zSPtr )

Definition at line 43 of file s_normRoundPackMToExtF80M.c.

50{
51 int_fast16_t shiftDist;
52 uint32_t wordSig;
53
54 shiftDist = 0;
55 wordSig = extSigPtr[indexWord( 3, 2 )];
56 if ( ! wordSig ) {
57 shiftDist = 32;
58 wordSig = extSigPtr[indexWord( 3, 1 )];
59 if ( ! wordSig ) {
60 shiftDist = 64;
61 wordSig = extSigPtr[indexWord( 3, 0 )];
62 if ( ! wordSig ) {
63 zSPtr->signExp = packToExtF80UI64( sign, 0 );
64 zSPtr->signif = 0;
65 return;
66 }
67 }
68 }
69 shiftDist += softfloat_countLeadingZeros32( wordSig );
70 if ( shiftDist ) {
71 exp -= shiftDist;
72 softfloat_shiftLeft96M( extSigPtr, shiftDist, extSigPtr );
73 }
75 sign, exp, extSigPtr, roundingPrecision, zSPtr );
76
77}
#define softfloat_shiftLeft96M(aPtr, dist, zPtr)
Definition primitives.h:739
Here is the call graph for this function:

◆ softfloat_normRoundPackMToF128M()

void softfloat_normRoundPackMToF128M ( bool sign,
int32_t exp,
uint32_t * extSigPtr,
uint32_t * zWPtr )

Definition at line 43 of file s_normRoundPackMToF128M.c.

45{
46 const uint32_t *ptr;
47 int_fast16_t shiftDist;
48 uint32_t wordSig;
49
50 ptr = extSigPtr + indexWordHi( 5 );
51 shiftDist = 0;
52 for (;;) {
53 wordSig = *ptr;
54 if ( wordSig ) break;
55 shiftDist += 32;
56 if ( 160 <= shiftDist ) {
57 zWPtr[indexWordHi( 4 )] = packToF128UI96( sign, 0, 0 );
58 zWPtr[indexWord( 4, 2 )] = 0;
59 zWPtr[indexWord( 4, 1 )] = 0;
60 zWPtr[indexWord( 4, 0 )] = 0;
61 return;
62 }
63 ptr -= wordIncr;
64 }
65 shiftDist += softfloat_countLeadingZeros32( wordSig ) - 15;
66 if ( shiftDist ) {
67 exp -= shiftDist;
68 softfloat_shiftLeft160M( extSigPtr, shiftDist, extSigPtr );
69 }
70 softfloat_roundPackMToF128M( sign, exp, extSigPtr, zWPtr );
71
72}
#define softfloat_shiftLeft160M(aPtr, dist, zPtr)
Definition primitives.h:755
Here is the call graph for this function:

◆ softfloat_normRoundPackToF16()

float16_t softfloat_normRoundPackToF16 ( bool sign,
int_fast16_t exp,
uint_fast16_t sig )

Definition at line 43 of file s_normRoundPackToF16.c.

44{
45 int_fast8_t shiftDist;
46 union ui16_f16 uZ;
47
48 shiftDist = softfloat_countLeadingZeros16( sig ) - 1;
49 exp -= shiftDist;
50 if ( (4 <= shiftDist) && ((unsigned int) exp < 0x1D) ) {
51 uZ.ui = packToF16UI( sign, sig ? exp : 0, sig<<(shiftDist - 4) );
52 return uZ.f;
53 } else {
54 return softfloat_roundPackToF16( sign, exp, sig<<shiftDist );
55 }
56
57}
#define softfloat_countLeadingZeros16
Here is the call graph for this function:

◆ softfloat_normRoundPackToF32()

float32_t softfloat_normRoundPackToF32 ( bool sign,
int_fast16_t exp,
uint_fast32_t sig )

Definition at line 43 of file s_normRoundPackToF32.c.

44{
45 int_fast8_t shiftDist;
46 union ui32_f32 uZ;
47
48 shiftDist = softfloat_countLeadingZeros32( sig ) - 1;
49 exp -= shiftDist;
50 if ( (7 <= shiftDist) && ((unsigned int) exp < 0xFD) ) {
51 uZ.ui = packToF32UI( sign, sig ? exp : 0, sig<<(shiftDist - 7) );
52 return uZ.f;
53 } else {
54 return softfloat_roundPackToF32( sign, exp, sig<<shiftDist );
55 }
56
57}
Here is the call graph for this function:

◆ softfloat_normRoundPackToF64()

float64_t softfloat_normRoundPackToF64 ( bool sign,
int_fast16_t exp,
uint_fast64_t sig )

Definition at line 43 of file s_normRoundPackToF64.c.

44{
45 int_fast8_t shiftDist;
46 union ui64_f64 uZ;
47
48 shiftDist = softfloat_countLeadingZeros64( sig ) - 1;
49 exp -= shiftDist;
50 if ( (10 <= shiftDist) && ((unsigned int) exp < 0x7FD) ) {
51 uZ.ui = packToF64UI( sign, sig ? exp : 0, sig<<(shiftDist - 10) );
52 return uZ.f;
53 } else {
54 return softfloat_roundPackToF64( sign, exp, sig<<shiftDist );
55 }
56
57}
Here is the call graph for this function:

◆ softfloat_normSubnormalF16Sig()

struct exp8_sig16 softfloat_normSubnormalF16Sig ( uint_fast16_t sig)

Definition at line 41 of file s_normSubnormalF16Sig.c.

42{
43 int_fast8_t shiftDist;
44 struct exp8_sig16 z;
45
46 shiftDist = softfloat_countLeadingZeros16( sig ) - 5;
47 z.exp = 1 - shiftDist;
48 z.sig = sig<<shiftDist;
49 return z;
50
51}
int_fast8_t exp
Definition internals.h:90
uint_fast16_t sig
Definition internals.h:90

◆ softfloat_normSubnormalF32Sig()

struct exp16_sig32 softfloat_normSubnormalF32Sig ( uint_fast32_t sig)

Definition at line 41 of file s_normSubnormalF32Sig.c.

42{
43 int_fast8_t shiftDist;
44 struct exp16_sig32 z;
45
46 shiftDist = softfloat_countLeadingZeros32( sig ) - 8;
47 z.exp = 1 - shiftDist;
48 z.sig = sig<<shiftDist;
49 return z;
50
51}
uint_fast32_t sig
Definition internals.h:111
int_fast16_t exp
Definition internals.h:111

◆ softfloat_normSubnormalF64Sig()

struct exp16_sig64 softfloat_normSubnormalF64Sig ( uint_fast64_t sig)

Definition at line 41 of file s_normSubnormalF64Sig.c.

42{
43 int_fast8_t shiftDist;
44 struct exp16_sig64 z;
45
46 shiftDist = softfloat_countLeadingZeros64( sig ) - 11;
47 z.exp = 1 - shiftDist;
48 z.sig = sig<<shiftDist;
49 return z;
50
51}
int_fast16_t exp
Definition internals.h:132
uint_fast64_t sig
Definition internals.h:132

◆ softfloat_roundMToI64()

int_fast64_t softfloat_roundMToI64 ( bool sign,
uint32_t * extSigPtr,
uint_fast8_t roundingMode,
bool exact )

Definition at line 45 of file s_roundMToI64.c.

47{
48 uint64_t sig;
49 uint32_t sigExtra;
50 union { uint64_t ui; int64_t i; } uZ;
51 int64_t z;
52
53 /*------------------------------------------------------------------------
54 *------------------------------------------------------------------------*/
55 sig =
56 (uint64_t) extSigPtr[indexWord( 3, 2 )]<<32
57 | extSigPtr[indexWord( 3, 1 )];
58 sigExtra = extSigPtr[indexWordLo( 3 )];
59 if (
60 (roundingMode == softfloat_round_near_maxMag)
61 || (roundingMode == softfloat_round_near_even)
62 ) {
63 if ( 0x80000000 <= sigExtra ) goto increment;
64 } else {
65 if (
66 sigExtra
67 && (sign
68 ? (roundingMode == softfloat_round_min)
69#ifdef SOFTFLOAT_ROUND_ODD
70 || (roundingMode == softfloat_round_odd)
71#endif
72 : (roundingMode == softfloat_round_max))
73 ) {
74 increment:
75 ++sig;
76 if ( !sig ) goto invalid;
77 if (
78 (sigExtra == 0x80000000)
79 && (roundingMode == softfloat_round_near_even)
80 ) {
81 sig &= ~(uint_fast64_t) 1;
82 }
83 }
84 }
85 uZ.ui = sign ? -sig : sig;
86 z = uZ.i;
87 if ( z && ((z < 0) ^ sign) ) goto invalid;
88 if ( sigExtra ) {
89#ifdef SOFTFLOAT_ROUND_ODD
90 if ( roundingMode == softfloat_round_odd ) z |= 1;
91#endif
93 }
94 return z;
95 /*------------------------------------------------------------------------
96 *------------------------------------------------------------------------*/
97 invalid:
100
101}
#define i64_fromNegOverflow
Definition specialize.h:69
#define i64_fromPosOverflow
Definition specialize.h:68
@ softfloat_round_near_maxMag
Definition softfloat.h:76
signed __int64 int64_t
Definition stdint.h:135
Here is the call graph for this function:

◆ softfloat_roundMToUI64()

uint_fast64_t softfloat_roundMToUI64 ( bool sign,
uint32_t * extSigPtr,
uint_fast8_t roundingMode,
bool exact )

Definition at line 45 of file s_roundMToUI64.c.

47{
48 uint64_t sig;
49 uint32_t sigExtra;
50
51 /*------------------------------------------------------------------------
52 *------------------------------------------------------------------------*/
53 sig =
54 (uint64_t) extSigPtr[indexWord( 3, 2 )]<<32
55 | extSigPtr[indexWord( 3, 1 )];
56 sigExtra = extSigPtr[indexWordLo( 3 )];
57 if (
58 (roundingMode == softfloat_round_near_maxMag)
59 || (roundingMode == softfloat_round_near_even)
60 ) {
61 if ( 0x80000000 <= sigExtra ) goto increment;
62 } else {
63 if ( sign ) {
64 if ( !(sig | sigExtra) ) return 0;
65 if ( roundingMode == softfloat_round_min ) goto invalid;
66#ifdef SOFTFLOAT_ROUND_ODD
67 if ( roundingMode == softfloat_round_odd ) goto invalid;
68#endif
69 } else {
70 if ( (roundingMode == softfloat_round_max) && sigExtra ) {
71 increment:
72 ++sig;
73 if ( !sig ) goto invalid;
74 if (
75 (sigExtra == 0x80000000)
76 && (roundingMode == softfloat_round_near_even)
77 ) {
78 sig &= ~(uint_fast64_t) 1;
79 }
80 }
81 }
82 }
83 if ( sign && sig ) goto invalid;
84 if ( sigExtra ) {
85#ifdef SOFTFLOAT_ROUND_ODD
86 if ( roundingMode == softfloat_round_odd ) sig |= 1;
87#endif
89 }
90 return sig;
91 /*------------------------------------------------------------------------
92 *------------------------------------------------------------------------*/
93 invalid:
96
97}
#define ui64_fromPosOverflow
Definition specialize.h:65
#define ui64_fromNegOverflow
Definition specialize.h:66
Here is the call graph for this function:

◆ softfloat_roundPackMToExtF80M()

void softfloat_roundPackMToExtF80M ( bool sign,
int32_t exp,
uint32_t * extSigPtr,
uint_fast8_t roundingPrecision,
struct extFloat80M * zSPtr )

Definition at line 44 of file s_roundPackMToExtF80M.c.

51{
52 uint_fast8_t roundingMode;
53 bool roundNearEven;
54 uint64_t sig, roundIncrement, roundMask, roundBits;
55 bool isTiny;
56 uint32_t sigExtra;
57 bool doIncrement;
58
59 /*------------------------------------------------------------------------
60 *------------------------------------------------------------------------*/
61 roundingMode = softfloat_roundingMode;
62 roundNearEven = (roundingMode == softfloat_round_near_even);
63 sig =
64 (uint64_t) extSigPtr[indexWord( 3, 2 )]<<32
65 | extSigPtr[indexWord( 3, 1 )];
66 if ( roundingPrecision == 80 ) goto precision80;
67 if ( roundingPrecision == 64 ) {
68 roundIncrement = UINT64_C( 0x0000000000000400 );
69 roundMask = UINT64_C( 0x00000000000007FF );
70 } else if ( roundingPrecision == 32 ) {
71 roundIncrement = UINT64_C( 0x0000008000000000 );
72 roundMask = UINT64_C( 0x000000FFFFFFFFFF );
73 } else {
74 goto precision80;
75 }
76 /*------------------------------------------------------------------------
77 *------------------------------------------------------------------------*/
78 if ( extSigPtr[indexWordLo( 3 )] ) sig |= 1;
79 if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) {
80 roundIncrement =
81 (roundingMode
83 ? roundMask
84 : 0;
85 }
86 roundBits = sig & roundMask;
87 /*------------------------------------------------------------------------
88 *------------------------------------------------------------------------*/
89 if ( 0x7FFD <= (uint32_t) (exp - 1) ) {
90 if ( exp <= 0 ) {
91 /*----------------------------------------------------------------
92 *----------------------------------------------------------------*/
93 isTiny =
96 || (exp < 0)
97 || (sig <= (uint64_t) (sig + roundIncrement));
98 sig = softfloat_shiftRightJam64( sig, 1 - exp );
99 roundBits = sig & roundMask;
100 if ( roundBits ) {
103#ifdef SOFTFLOAT_ROUND_ODD
104 if ( roundingMode == softfloat_round_odd ) {
105 sig |= roundMask + 1;
106 }
107#endif
108 }
109 sig += roundIncrement;
110 exp = ((sig & UINT64_C( 0x8000000000000000 )) != 0);
111 roundIncrement = roundMask + 1;
112 if ( roundNearEven && (roundBits<<1 == roundIncrement) ) {
113 roundMask |= roundIncrement;
114 }
115 sig &= ~roundMask;
116 goto packReturn;
117 }
118 if (
119 (0x7FFE < exp)
120 || ((exp == 0x7FFE) && ((uint64_t) (sig + roundIncrement) < sig))
121 ) {
122 goto overflow;
123 }
124 }
125 /*------------------------------------------------------------------------
126 *------------------------------------------------------------------------*/
127 if ( roundBits ) {
129#ifdef SOFTFLOAT_ROUND_ODD
130 if ( roundingMode == softfloat_round_odd ) {
131 sig = (sig & ~roundMask) | (roundMask + 1);
132 goto packReturn;
133 }
134#endif
135 }
136 sig += roundIncrement;
137 if ( sig < roundIncrement ) {
138 ++exp;
139 sig = UINT64_C( 0x8000000000000000 );
140 }
141 roundIncrement = roundMask + 1;
142 if ( roundNearEven && (roundBits<<1 == roundIncrement) ) {
143 roundMask |= roundIncrement;
144 }
145 sig &= ~roundMask;
146 goto packReturn;
147 /*------------------------------------------------------------------------
148 *------------------------------------------------------------------------*/
149 precision80:
150 sigExtra = extSigPtr[indexWordLo( 3 )];
151 doIncrement = (0x80000000 <= sigExtra);
152 if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) {
153 doIncrement =
154 (roundingMode
156 && sigExtra;
157 }
158 /*------------------------------------------------------------------------
159 *------------------------------------------------------------------------*/
160 if ( 0x7FFD <= (uint32_t) (exp - 1) ) {
161 if ( exp <= 0 ) {
162 /*----------------------------------------------------------------
163 *----------------------------------------------------------------*/
164 isTiny =
167 || (exp < 0)
168 || ! doIncrement
169 || (sig < UINT64_C( 0xFFFFFFFFFFFFFFFF ));
170 softfloat_shiftRightJam96M( extSigPtr, 1 - exp, extSigPtr );
171 exp = 0;
172 sig =
173 (uint64_t) extSigPtr[indexWord( 3, 2 )]<<32
174 | extSigPtr[indexWord( 3, 1 )];
175 sigExtra = extSigPtr[indexWordLo( 3 )];
176 if ( sigExtra ) {
179#ifdef SOFTFLOAT_ROUND_ODD
180 if ( roundingMode == softfloat_round_odd ) {
181 sig |= 1;
182 goto packReturn;
183 }
184#endif
185 }
186 doIncrement = (0x80000000 <= sigExtra);
187 if (
188 ! roundNearEven
189 && (roundingMode != softfloat_round_near_maxMag)
190 ) {
191 doIncrement =
192 (roundingMode
194 && sigExtra;
195 }
196 if ( doIncrement ) {
197 ++sig;
198 sig &= ~(uint64_t) (! (sigExtra & 0x7FFFFFFF) & roundNearEven);
199 exp = ((sig & UINT64_C( 0x8000000000000000 )) != 0);
200 }
201 goto packReturn;
202 }
203 if (
204 (0x7FFE < exp)
205 || ((exp == 0x7FFE) && (sig == UINT64_C( 0xFFFFFFFFFFFFFFFF ))
206 && doIncrement)
207 ) {
208 /*----------------------------------------------------------------
209 *----------------------------------------------------------------*/
210 roundMask = 0;
211 overflow:
214 if (
215 roundNearEven
216 || (roundingMode == softfloat_round_near_maxMag)
217 || (roundingMode
219 ) {
220 exp = 0x7FFF;
221 sig = UINT64_C( 0x8000000000000000 );
222 } else {
223 exp = 0x7FFE;
224 sig = ~roundMask;
225 }
226 goto packReturn;
227 }
228 }
229 /*------------------------------------------------------------------------
230 *------------------------------------------------------------------------*/
231 if ( sigExtra ) {
233#ifdef SOFTFLOAT_ROUND_ODD
234 if ( roundingMode == softfloat_round_odd ) {
235 sig |= 1;
236 goto packReturn;
237 }
238#endif
239 }
240 if ( doIncrement ) {
241 ++sig;
242 if ( ! sig ) {
243 ++exp;
244 sig = UINT64_C( 0x8000000000000000 );
245 } else {
246 sig &= ~(uint64_t) (! (sigExtra & 0x7FFFFFFF) & roundNearEven);
247 }
248 }
249 /*------------------------------------------------------------------------
250 *------------------------------------------------------------------------*/
251 packReturn:
252 zSPtr->signExp = packToExtF80UI64( sign, exp );
253 zSPtr->signif = sig;
254
255}
@ softfloat_flag_underflow
Definition softfloat.h:86
THREAD_LOCAL uint_fast8_t softfloat_detectTininess
@ softfloat_tininess_beforeRounding
Definition softfloat.h:62
bool overflow
Here is the call graph for this function:

◆ softfloat_roundPackMToF128M()

void softfloat_roundPackMToF128M ( bool sign,
int32_t exp,
uint32_t * extSigPtr,
uint32_t * zWPtr )

Definition at line 44 of file s_roundPackMToF128M.c.

46{
47 uint_fast8_t roundingMode;
48 bool roundNearEven;
49 uint32_t sigExtra;
50 bool doIncrement, isTiny;
51 static const uint32_t maxSig[4] =
52 INIT_UINTM4( 0x0001FFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF );
53 uint32_t ui, uj;
54
55 /*------------------------------------------------------------------------
56 *------------------------------------------------------------------------*/
57 roundingMode = softfloat_roundingMode;
58 roundNearEven = (roundingMode == softfloat_round_near_even);
59 sigExtra = extSigPtr[indexWordLo( 5 )];
60 doIncrement = (0x80000000 <= sigExtra);
61 if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) {
62 doIncrement =
63 (roundingMode
65 && sigExtra;
66 }
67 /*------------------------------------------------------------------------
68 *------------------------------------------------------------------------*/
69 if ( 0x7FFD <= (uint32_t) exp ) {
70 if ( exp < 0 ) {
71 /*----------------------------------------------------------------
72 *----------------------------------------------------------------*/
73 isTiny =
76 || (exp < -1)
77 || ! doIncrement
79 extSigPtr + indexMultiwordHi( 5, 4 ), maxSig )
80 < 0);
81 softfloat_shiftRightJam160M( extSigPtr, -exp, extSigPtr );
82 exp = 0;
83 sigExtra = extSigPtr[indexWordLo( 5 )];
84 if ( isTiny && sigExtra ) {
86 }
87 doIncrement = (0x80000000 <= sigExtra);
88 if (
89 ! roundNearEven
90 && (roundingMode != softfloat_round_near_maxMag)
91 ) {
92 doIncrement =
93 (roundingMode
95 && sigExtra;
96 }
97 } else if (
98 (0x7FFD < exp)
99 || ((exp == 0x7FFD) && doIncrement
101 extSigPtr + indexMultiwordHi( 5, 4 ), maxSig )
102 == 0))
103 ) {
104 /*----------------------------------------------------------------
105 *----------------------------------------------------------------*/
108 if (
109 roundNearEven
110 || (roundingMode == softfloat_round_near_maxMag)
111 || (roundingMode
113 ) {
114 ui = packToF128UI96( sign, 0x7FFF, 0 );
115 uj = 0;
116 } else {
117 ui = packToF128UI96( sign, 0x7FFE, 0x0000FFFF );
118 uj = 0xFFFFFFFF;
119 }
120 zWPtr[indexWordHi( 4 )] = ui;
121 zWPtr[indexWord( 4, 2 )] = uj;
122 zWPtr[indexWord( 4, 1 )] = uj;
123 zWPtr[indexWord( 4, 0 )] = uj;
124 return;
125 }
126 }
127 /*------------------------------------------------------------------------
128 *------------------------------------------------------------------------*/
129 uj = extSigPtr[indexWord( 5, 1 )];
130 if ( sigExtra ) {
132#ifdef SOFTFLOAT_ROUND_ODD
133 if ( roundingMode == softfloat_round_odd ) {
134 uj |= 1;
135 goto noIncrementPackReturn;
136 }
137#endif
138 }
139 if ( doIncrement ) {
140 ++uj;
141 if ( uj ) {
142 if ( ! (sigExtra & 0x7FFFFFFF) && roundNearEven ) uj &= ~1;
143 zWPtr[indexWord( 4, 2 )] = extSigPtr[indexWord( 5, 3 )];
144 zWPtr[indexWord( 4, 1 )] = extSigPtr[indexWord( 5, 2 )];
145 zWPtr[indexWord( 4, 0 )] = uj;
146 ui = extSigPtr[indexWordHi( 5 )];
147 } else {
148 zWPtr[indexWord( 4, 0 )] = uj;
149 ui = extSigPtr[indexWord( 5, 2 )] + 1;
150 zWPtr[indexWord( 4, 1 )] = ui;
151 uj = extSigPtr[indexWord( 5, 3 )];
152 if ( ui ) {
153 zWPtr[indexWord( 4, 2 )] = uj;
154 ui = extSigPtr[indexWordHi( 5 )];
155 } else {
156 ++uj;
157 zWPtr[indexWord( 4, 2 )] = uj;
158 ui = extSigPtr[indexWordHi( 5 )];
159 if ( ! uj ) ++ui;
160 }
161 }
162 } else {
163 noIncrementPackReturn:
164 zWPtr[indexWord( 4, 0 )] = uj;
165 ui = extSigPtr[indexWord( 5, 2 )];
166 zWPtr[indexWord( 4, 1 )] = ui;
167 uj |= ui;
168 ui = extSigPtr[indexWord( 5, 3 )];
169 zWPtr[indexWord( 4, 2 )] = ui;
170 uj |= ui;
171 ui = extSigPtr[indexWordHi( 5 )];
172 uj |= ui;
173 if ( ! uj ) exp = 0;
174 }
175 zWPtr[indexWordHi( 4 )] = packToF128UI96( sign, exp, ui );
176
177}
#define INIT_UINTM4(v3, v2, v1, v0)
int_fast8_t softfloat_compare128M(const uint32_t *aPtr, const uint32_t *bPtr)
Here is the call graph for this function:

◆ softfloat_roundPackToF16()

float16_t softfloat_roundPackToF16 ( bool sign,
int_fast16_t exp,
uint_fast16_t sig )

Definition at line 44 of file s_roundPackToF16.c.

45{
46 uint_fast8_t roundingMode;
47 bool roundNearEven;
48 uint_fast8_t roundIncrement, roundBits;
49 bool isTiny;
50 uint_fast16_t uiZ;
51 union ui16_f16 uZ;
52
53 /*------------------------------------------------------------------------
54 *------------------------------------------------------------------------*/
55 roundingMode = softfloat_roundingMode;
56 roundNearEven = (roundingMode == softfloat_round_near_even);
57 roundIncrement = 0x8;
58 if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) {
59 roundIncrement =
60 (roundingMode
62 ? 0xF
63 : 0;
64 }
65 roundBits = sig & 0xF;
66 /*------------------------------------------------------------------------
67 *------------------------------------------------------------------------*/
68 if ( 0x1D <= (unsigned int) exp ) {
69 if ( exp < 0 ) {
70 /*----------------------------------------------------------------
71 *----------------------------------------------------------------*/
72 isTiny =
74 || (exp < -1) || (sig + roundIncrement < 0x8000);
75 sig = softfloat_shiftRightJam32( sig, -exp );
76 exp = 0;
77 roundBits = sig & 0xF;
78 if ( isTiny && roundBits ) {
80 }
81 } else if ( (0x1D < exp) || (0x8000 <= sig + roundIncrement) ) {
82 /*----------------------------------------------------------------
83 *----------------------------------------------------------------*/
86 uiZ = packToF16UI( sign, 0x1F, 0 ) - ! roundIncrement;
87 goto uiZ;
88 }
89 }
90 /*------------------------------------------------------------------------
91 *------------------------------------------------------------------------*/
92 sig = (sig + roundIncrement)>>4;
93 if ( roundBits ) {
95#ifdef SOFTFLOAT_ROUND_ODD
96 if ( roundingMode == softfloat_round_odd ) {
97 sig |= 1;
98 goto packReturn;
99 }
100#endif
101 }
102 sig &= ~(uint_fast16_t) (! (roundBits ^ 8) & roundNearEven);
103 if ( ! sig ) exp = 0;
104 /*------------------------------------------------------------------------
105 *------------------------------------------------------------------------*/
106 packReturn:
107 uiZ = packToF16UI( sign, exp, sig );
108 uiZ:
109 uZ.ui = uiZ;
110 return uZ.f;
111
112}
Here is the call graph for this function:

◆ softfloat_roundPackToF32()

float32_t softfloat_roundPackToF32 ( bool sign,
int_fast16_t exp,
uint_fast32_t sig )

Definition at line 44 of file s_roundPackToF32.c.

45{
46 uint_fast8_t roundingMode;
47 bool roundNearEven;
48 uint_fast8_t roundIncrement, roundBits;
49 bool isTiny;
50 uint_fast32_t uiZ;
51 union ui32_f32 uZ;
52
53 /*------------------------------------------------------------------------
54 *------------------------------------------------------------------------*/
55 roundingMode = softfloat_roundingMode;
56 roundNearEven = (roundingMode == softfloat_round_near_even);
57 roundIncrement = 0x40;
58 if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) {
59 roundIncrement =
60 (roundingMode
62 ? 0x7F
63 : 0;
64 }
65 roundBits = sig & 0x7F;
66 /*------------------------------------------------------------------------
67 *------------------------------------------------------------------------*/
68 if ( 0xFD <= (unsigned int) exp ) {
69 if ( exp < 0 ) {
70 /*----------------------------------------------------------------
71 *----------------------------------------------------------------*/
72 isTiny =
74 || (exp < -1) || (sig + roundIncrement < 0x80000000);
75 sig = softfloat_shiftRightJam32( sig, -exp );
76 exp = 0;
77 roundBits = sig & 0x7F;
78 if ( isTiny && roundBits ) {
80 }
81 } else if ( (0xFD < exp) || (0x80000000 <= sig + roundIncrement) ) {
82 /*----------------------------------------------------------------
83 *----------------------------------------------------------------*/
86 uiZ = packToF32UI( sign, 0xFF, 0 ) - ! roundIncrement;
87 goto uiZ;
88 }
89 }
90 /*------------------------------------------------------------------------
91 *------------------------------------------------------------------------*/
92 sig = (sig + roundIncrement)>>7;
93 if ( roundBits ) {
95#ifdef SOFTFLOAT_ROUND_ODD
96 if ( roundingMode == softfloat_round_odd ) {
97 sig |= 1;
98 goto packReturn;
99 }
100#endif
101 }
102 sig &= ~(uint_fast32_t) (! (roundBits ^ 0x40) & roundNearEven);
103 if ( ! sig ) exp = 0;
104 /*------------------------------------------------------------------------
105 *------------------------------------------------------------------------*/
106 packReturn:
107 uiZ = packToF32UI( sign, exp, sig );
108 uiZ:
109 uZ.ui = uiZ;
110 return uZ.f;
111
112}
Here is the call graph for this function:

◆ softfloat_roundPackToF64()

float64_t softfloat_roundPackToF64 ( bool sign,
int_fast16_t exp,
uint_fast64_t sig )

Definition at line 44 of file s_roundPackToF64.c.

45{
46 uint_fast8_t roundingMode;
47 bool roundNearEven;
48 uint_fast16_t roundIncrement, roundBits;
49 bool isTiny;
50 uint_fast64_t uiZ;
51 union ui64_f64 uZ;
52
53 /*------------------------------------------------------------------------
54 *------------------------------------------------------------------------*/
55 roundingMode = softfloat_roundingMode;
56 roundNearEven = (roundingMode == softfloat_round_near_even);
57 roundIncrement = 0x200;
58 if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) {
59 roundIncrement =
60 (roundingMode
62 ? 0x3FF
63 : 0;
64 }
65 roundBits = sig & 0x3FF;
66 /*------------------------------------------------------------------------
67 *------------------------------------------------------------------------*/
68 if ( 0x7FD <= (uint16_t) exp ) {
69 if ( exp < 0 ) {
70 /*----------------------------------------------------------------
71 *----------------------------------------------------------------*/
72 isTiny =
74 || (exp < -1)
75 || (sig + roundIncrement < UINT64_C( 0x8000000000000000 ));
76 sig = softfloat_shiftRightJam64( sig, -exp );
77 exp = 0;
78 roundBits = sig & 0x3FF;
79 if ( isTiny && roundBits ) {
81 }
82 } else if (
83 (0x7FD < exp)
84 || (UINT64_C( 0x8000000000000000 ) <= sig + roundIncrement)
85 ) {
86 /*----------------------------------------------------------------
87 *----------------------------------------------------------------*/
90 uiZ = packToF64UI( sign, 0x7FF, 0 ) - ! roundIncrement;
91 goto uiZ;
92 }
93 }
94 /*------------------------------------------------------------------------
95 *------------------------------------------------------------------------*/
96 sig = (sig + roundIncrement)>>10;
97 if ( roundBits ) {
99#ifdef SOFTFLOAT_ROUND_ODD
100 if ( roundingMode == softfloat_round_odd ) {
101 sig |= 1;
102 goto packReturn;
103 }
104#endif
105 }
106 sig &= ~(uint_fast64_t) (! (roundBits ^ 0x200) & roundNearEven);
107 if ( ! sig ) exp = 0;
108 /*------------------------------------------------------------------------
109 *------------------------------------------------------------------------*/
110 packReturn:
111 uiZ = packToF64UI( sign, exp, sig );
112 uiZ:
113 uZ.ui = uiZ;
114 return uZ.f;
115
116}
Here is the call graph for this function:

◆ softfloat_roundToI32()

int_fast32_t softfloat_roundToI32 ( bool sign,
uint_fast64_t sig,
uint_fast8_t roundingMode,
bool exact )

Definition at line 45 of file s_roundToI32.c.

47{
48 uint_fast16_t roundIncrement, roundBits;
49 uint_fast32_t sig32;
50 union { uint32_t ui; int32_t i; } uZ;
52
53 /*------------------------------------------------------------------------
54 *------------------------------------------------------------------------*/
55 roundIncrement = 0x800;
56 if (
57 (roundingMode != softfloat_round_near_maxMag)
58 && (roundingMode != softfloat_round_near_even)
59 ) {
60 roundIncrement = 0;
61 if (
62 sign
63 ? (roundingMode == softfloat_round_min)
64#ifdef SOFTFLOAT_ROUND_ODD
65 || (roundingMode == softfloat_round_odd)
66#endif
67 : (roundingMode == softfloat_round_max)
68 ) {
69 roundIncrement = 0xFFF;
70 }
71 }
72 roundBits = sig & 0xFFF;
73 sig += roundIncrement;
74 if ( sig & UINT64_C( 0xFFFFF00000000000 ) ) goto invalid;
75 sig32 = sig>>12;
76 if (
77 (roundBits == 0x800) && (roundingMode == softfloat_round_near_even)
78 ) {
79 sig32 &= ~(uint_fast32_t) 1;
80 }
81 uZ.ui = sign ? -sig32 : sig32;
82 z = uZ.i;
83 if ( z && ((z < 0) ^ sign) ) goto invalid;
84 if ( roundBits ) {
85#ifdef SOFTFLOAT_ROUND_ODD
86 if ( roundingMode == softfloat_round_odd ) z |= 1;
87#endif
89 }
90 return z;
91 /*------------------------------------------------------------------------
92 *------------------------------------------------------------------------*/
93 invalid:
96
97}
#define i32_fromNegOverflow
Definition specialize.h:58
#define i32_fromPosOverflow
Definition specialize.h:57
int32_t int_fast32_t
Definition stdint.h:152
Here is the call graph for this function:

◆ softfloat_roundToUI32()

uint_fast32_t softfloat_roundToUI32 ( bool sign,
uint_fast64_t sig,
uint_fast8_t roundingMode,
bool exact )

Definition at line 45 of file s_roundToUI32.c.

47{
48 uint_fast16_t roundIncrement, roundBits;
50
51 /*------------------------------------------------------------------------
52 *------------------------------------------------------------------------*/
53 roundIncrement = 0x800;
54 if (
55 (roundingMode != softfloat_round_near_maxMag)
56 && (roundingMode != softfloat_round_near_even)
57 ) {
58 roundIncrement = 0;
59 if ( sign ) {
60 if ( !sig ) return 0;
61 if ( roundingMode == softfloat_round_min ) goto invalid;
62#ifdef SOFTFLOAT_ROUND_ODD
63 if ( roundingMode == softfloat_round_odd ) goto invalid;
64#endif
65 } else {
66 if ( roundingMode == softfloat_round_max ) roundIncrement = 0xFFF;
67 }
68 }
69 roundBits = sig & 0xFFF;
70 sig += roundIncrement;
71 if ( sig & UINT64_C( 0xFFFFF00000000000 ) ) goto invalid;
72 z = sig>>12;
73 if (
74 (roundBits == 0x800) && (roundingMode == softfloat_round_near_even)
75 ) {
76 z &= ~(uint_fast32_t) 1;
77 }
78 if ( sign && z ) goto invalid;
79 if ( roundBits ) {
80#ifdef SOFTFLOAT_ROUND_ODD
81 if ( roundingMode == softfloat_round_odd ) z |= 1;
82#endif
84 }
85 return z;
86 /*------------------------------------------------------------------------
87 *------------------------------------------------------------------------*/
88 invalid:
91
92}
#define ui32_fromNegOverflow
Definition specialize.h:55
#define ui32_fromPosOverflow
Definition specialize.h:54
Here is the call graph for this function:

◆ softfloat_shiftNormSigF128M()

int softfloat_shiftNormSigF128M ( const uint32_t * wPtr,
uint_fast8_t shiftDist,
uint32_t * sigPtr )

Definition at line 42 of file s_shiftNormSigF128M.c.

44{
45 uint32_t wordSig;
46 int32_t exp;
47 uint32_t leadingBit;
48
49 wordSig = wPtr[indexWordHi( 4 )];
50 exp = expF128UI96( wordSig );
51 if ( exp ) {
52 softfloat_shortShiftLeft128M( wPtr, shiftDist, sigPtr );
53 leadingBit = 0x00010000<<shiftDist;
54 sigPtr[indexWordHi( 4 )] =
55 (sigPtr[indexWordHi( 4 )] & (leadingBit - 1)) | leadingBit;
56 } else {
57 exp = 16;
58 wordSig &= 0x7FFFFFFF;
59 if ( ! wordSig ) {
60 exp = -16;
61 wordSig = wPtr[indexWord( 4, 2 )];
62 if ( ! wordSig ) {
63 exp = -48;
64 wordSig = wPtr[indexWord( 4, 1 )];
65 if ( ! wordSig ) {
66 wordSig = wPtr[indexWord( 4, 0 )];
67 if ( ! wordSig ) return -128;
68 exp = -80;
69 }
70 }
71 }
72 exp -= softfloat_countLeadingZeros32( wordSig );
73 softfloat_shiftLeft128M( wPtr, 1 - exp + shiftDist, sigPtr );
74 }
75 return exp;
76
77}
#define softfloat_shortShiftLeft128M(aPtr, dist, zPtr)
Definition primitives.h:703

◆ softfloat_subMagsF16()

float16_t softfloat_subMagsF16 ( uint_fast16_t uiA,
uint_fast16_t uiB )

Definition at line 44 of file s_subMagsF16.c.

45{
46 int_fast8_t expA;
47 uint_fast16_t sigA;
48 int_fast8_t expB;
49 uint_fast16_t sigB;
50 int_fast8_t expDiff;
51 uint_fast16_t uiZ;
52 int_fast16_t sigDiff;
53 bool signZ;
54 int_fast8_t shiftDist, expZ;
55 uint_fast16_t sigZ, sigX, sigY;
56 uint_fast32_t sig32Z;
57 int_fast8_t roundingMode;
58 union ui16_f16 uZ;
59
60 /*------------------------------------------------------------------------
61 *------------------------------------------------------------------------*/
62 expA = expF16UI( uiA );
63 sigA = fracF16UI( uiA );
64 expB = expF16UI( uiB );
65 sigB = fracF16UI( uiB );
66 /*------------------------------------------------------------------------
67 *------------------------------------------------------------------------*/
68 expDiff = expA - expB;
69 if ( ! expDiff ) {
70 /*--------------------------------------------------------------------
71 *--------------------------------------------------------------------*/
72 if ( expA == 0x1F ) {
73 if ( sigA | sigB ) goto propagateNaN;
75 uiZ = defaultNaNF16UI;
76 goto uiZ;
77 }
78 sigDiff = sigA - sigB;
79 if ( ! sigDiff ) {
80 uiZ =
83 goto uiZ;
84 }
85 if ( expA ) --expA;
86 signZ = signF16UI( uiA );
87 if ( sigDiff < 0 ) {
88 signZ = ! signZ;
89 sigDiff = -sigDiff;
90 }
91 shiftDist = softfloat_countLeadingZeros16( sigDiff ) - 5;
92 expZ = expA - shiftDist;
93 if ( expZ < 0 ) {
94 shiftDist = expA;
95 expZ = 0;
96 }
97 sigZ = sigDiff<<shiftDist;
98 goto pack;
99 } else {
100 /*--------------------------------------------------------------------
101 *--------------------------------------------------------------------*/
102 signZ = signF16UI( uiA );
103 if ( expDiff < 0 ) {
104 /*----------------------------------------------------------------
105 *----------------------------------------------------------------*/
106 signZ = ! signZ;
107 if ( expB == 0x1F ) {
108 if ( sigB ) goto propagateNaN;
109 uiZ = packToF16UI( signZ, 0x1F, 0 );
110 goto uiZ;
111 }
112 if ( expDiff <= -13 ) {
113 uiZ = packToF16UI( signZ, expB, sigB );
114 if ( expA | sigA ) goto subEpsilon;
115 goto uiZ;
116 }
117 expZ = expA + 19;
118 sigX = sigB | 0x0400;
119 sigY = sigA + (expA ? 0x0400 : sigA);
120 expDiff = -expDiff;
121 } else {
122 /*----------------------------------------------------------------
123 *----------------------------------------------------------------*/
124 uiZ = uiA;
125 if ( expA == 0x1F ) {
126 if ( sigA ) goto propagateNaN;
127 goto uiZ;
128 }
129 if ( 13 <= expDiff ) {
130 if ( expB | sigB ) goto subEpsilon;
131 goto uiZ;
132 }
133 expZ = expB + 19;
134 sigX = sigA | 0x0400;
135 sigY = sigB + (expB ? 0x0400 : sigB);
136 }
137 sig32Z = ((uint_fast32_t) sigX<<expDiff) - sigY;
138 shiftDist = softfloat_countLeadingZeros32( sig32Z ) - 1;
139 sig32Z <<= shiftDist;
140 expZ -= shiftDist;
141 sigZ = sig32Z>>16;
142 if ( sig32Z & 0xFFFF ) {
143 sigZ |= 1;
144 } else {
145 if ( ! (sigZ & 0xF) && ((unsigned int) expZ < 0x1E) ) {
146 sigZ >>= 4;
147 goto pack;
148 }
149 }
150 return softfloat_roundPackToF16( signZ, expZ, sigZ );
151 }
152 /*------------------------------------------------------------------------
153 *------------------------------------------------------------------------*/
154 propagateNaN:
155 uiZ = softfloat_propagateNaNF16UI( uiA, uiB );
156 goto uiZ;
157 /*------------------------------------------------------------------------
158 *------------------------------------------------------------------------*/
159 subEpsilon:
160 roundingMode = softfloat_roundingMode;
161 if ( roundingMode != softfloat_round_near_even ) {
162 if (
163 (roundingMode == softfloat_round_minMag)
164 || (roundingMode
165 == (signF16UI( uiZ ) ? softfloat_round_max
167 ) {
168 --uiZ;
169 }
170#ifdef SOFTFLOAT_ROUND_ODD
171 else if ( roundingMode == softfloat_round_odd ) {
172 uiZ = (uiZ - 1) | 1;
173 }
174#endif
175 }
177 goto uiZ;
178 /*------------------------------------------------------------------------
179 *------------------------------------------------------------------------*/
180 pack:
181 uiZ = packToF16UI( signZ, expZ, sigZ );
182 uiZ:
183 uZ.ui = uiZ;
184 return uZ.f;
185
186}
@ softfloat_round_minMag
Definition softfloat.h:73
Here is the call graph for this function:

◆ softfloat_subMagsF32()

float32_t softfloat_subMagsF32 ( uint_fast32_t uiA,
uint_fast32_t uiB )

Definition at line 44 of file s_subMagsF32.c.

45{
46 int_fast16_t expA;
47 uint_fast32_t sigA;
48 int_fast16_t expB;
49 uint_fast32_t sigB;
50 int_fast16_t expDiff;
51 uint_fast32_t uiZ;
52 int_fast32_t sigDiff;
53 bool signZ;
54 int_fast8_t shiftDist;
55 int_fast16_t expZ;
56 uint_fast32_t sigX, sigY;
57 union ui32_f32 uZ;
58
59 /*------------------------------------------------------------------------
60 *------------------------------------------------------------------------*/
61 expA = expF32UI( uiA );
62 sigA = fracF32UI( uiA );
63 expB = expF32UI( uiB );
64 sigB = fracF32UI( uiB );
65 /*------------------------------------------------------------------------
66 *------------------------------------------------------------------------*/
67 expDiff = expA - expB;
68 if ( ! expDiff ) {
69 /*--------------------------------------------------------------------
70 *--------------------------------------------------------------------*/
71 if ( expA == 0xFF ) {
72 if ( sigA | sigB ) goto propagateNaN;
74 uiZ = defaultNaNF32UI;
75 goto uiZ;
76 }
77 sigDiff = sigA - sigB;
78 if ( ! sigDiff ) {
79 uiZ =
82 goto uiZ;
83 }
84 if ( expA ) --expA;
85 signZ = signF32UI( uiA );
86 if ( sigDiff < 0 ) {
87 signZ = ! signZ;
88 sigDiff = -sigDiff;
89 }
90 shiftDist = softfloat_countLeadingZeros32( sigDiff ) - 8;
91 expZ = expA - shiftDist;
92 if ( expZ < 0 ) {
93 shiftDist = expA;
94 expZ = 0;
95 }
96 uiZ = packToF32UI( signZ, expZ, sigDiff<<shiftDist );
97 goto uiZ;
98 } else {
99 /*--------------------------------------------------------------------
100 *--------------------------------------------------------------------*/
101 signZ = signF32UI( uiA );
102 sigA <<= 7;
103 sigB <<= 7;
104 if ( expDiff < 0 ) {
105 /*----------------------------------------------------------------
106 *----------------------------------------------------------------*/
107 signZ = ! signZ;
108 if ( expB == 0xFF ) {
109 if ( sigB ) goto propagateNaN;
110 uiZ = packToF32UI( signZ, 0xFF, 0 );
111 goto uiZ;
112 }
113 expZ = expB - 1;
114 sigX = sigB | 0x40000000;
115 sigY = sigA + (expA ? 0x40000000 : sigA);
116 expDiff = -expDiff;
117 } else {
118 /*----------------------------------------------------------------
119 *----------------------------------------------------------------*/
120 if ( expA == 0xFF ) {
121 if ( sigA ) goto propagateNaN;
122 uiZ = uiA;
123 goto uiZ;
124 }
125 expZ = expA - 1;
126 sigX = sigA | 0x40000000;
127 sigY = sigB + (expB ? 0x40000000 : sigB);
128 }
129 return
131 signZ, expZ, sigX - softfloat_shiftRightJam32( sigY, expDiff )
132 );
133 }
134 /*------------------------------------------------------------------------
135 *------------------------------------------------------------------------*/
136 propagateNaN:
137 uiZ = softfloat_propagateNaNF32UI( uiA, uiB );
138 uiZ:
139 uZ.ui = uiZ;
140 return uZ.f;
141
142}
float32_t softfloat_normRoundPackToF32(bool, int_fast16_t, uint_fast32_t)
Here is the call graph for this function:

◆ softfloat_subMagsF64()

float64_t softfloat_subMagsF64 ( uint_fast64_t uiA,
uint_fast64_t uiB,
bool signZ )

Definition at line 45 of file s_subMagsF64.c.

46{
47 int_fast16_t expA;
48 uint_fast64_t sigA;
49 int_fast16_t expB;
50 uint_fast64_t sigB;
51 int_fast16_t expDiff;
52 uint_fast64_t uiZ;
53 int_fast64_t sigDiff;
54 int_fast8_t shiftDist;
55 int_fast16_t expZ;
56 uint_fast64_t sigZ;
57 union ui64_f64 uZ;
58
59 /*------------------------------------------------------------------------
60 *------------------------------------------------------------------------*/
61 expA = expF64UI( uiA );
62 sigA = fracF64UI( uiA );
63 expB = expF64UI( uiB );
64 sigB = fracF64UI( uiB );
65 /*------------------------------------------------------------------------
66 *------------------------------------------------------------------------*/
67 expDiff = expA - expB;
68 if ( ! expDiff ) {
69 /*--------------------------------------------------------------------
70 *--------------------------------------------------------------------*/
71 if ( expA == 0x7FF ) {
72 if ( sigA | sigB ) goto propagateNaN;
74 uiZ = defaultNaNF64UI;
75 goto uiZ;
76 }
77 sigDiff = sigA - sigB;
78 if ( ! sigDiff ) {
79 uiZ =
82 goto uiZ;
83 }
84 if ( expA ) --expA;
85 if ( sigDiff < 0 ) {
86 signZ = ! signZ;
87 sigDiff = -sigDiff;
88 }
89 shiftDist = softfloat_countLeadingZeros64( sigDiff ) - 11;
90 expZ = expA - shiftDist;
91 if ( expZ < 0 ) {
92 shiftDist = expA;
93 expZ = 0;
94 }
95 uiZ = packToF64UI( signZ, expZ, sigDiff<<shiftDist );
96 goto uiZ;
97 } else {
98 /*--------------------------------------------------------------------
99 *--------------------------------------------------------------------*/
100 sigA <<= 10;
101 sigB <<= 10;
102 if ( expDiff < 0 ) {
103 /*----------------------------------------------------------------
104 *----------------------------------------------------------------*/
105 signZ = ! signZ;
106 if ( expB == 0x7FF ) {
107 if ( sigB ) goto propagateNaN;
108 uiZ = packToF64UI( signZ, 0x7FF, 0 );
109 goto uiZ;
110 }
111 sigA += expA ? UINT64_C( 0x4000000000000000 ) : sigA;
112 sigA = softfloat_shiftRightJam64( sigA, -expDiff );
113 sigB |= UINT64_C( 0x4000000000000000 );
114 expZ = expB;
115 sigZ = sigB - sigA;
116 } else {
117 /*----------------------------------------------------------------
118 *----------------------------------------------------------------*/
119 if ( expA == 0x7FF ) {
120 if ( sigA ) goto propagateNaN;
121 uiZ = uiA;
122 goto uiZ;
123 }
124 sigB += expB ? UINT64_C( 0x4000000000000000 ) : sigB;
125 sigB = softfloat_shiftRightJam64( sigB, expDiff );
126 sigA |= UINT64_C( 0x4000000000000000 );
127 expZ = expA;
128 sigZ = sigA - sigB;
129 }
130 return softfloat_normRoundPackToF64( signZ, expZ - 1, sigZ );
131 }
132 /*------------------------------------------------------------------------
133 *------------------------------------------------------------------------*/
134 propagateNaN:
135 uiZ = softfloat_propagateNaNF64UI( uiA, uiB );
136 uiZ:
137 uZ.ui = uiZ;
138 return uZ.f;
139
140}
float64_t softfloat_normRoundPackToF64(bool, int_fast16_t, uint_fast64_t)
int64_t int_fast64_t
Definition stdint.h:153
Here is the call graph for this function:

◆ softfloat_tryPropagateNaNExtF80M()

bool softfloat_tryPropagateNaNExtF80M ( const struct extFloat80M * aSPtr,
const struct extFloat80M * bSPtr,
struct extFloat80M * zSPtr )

Definition at line 43 of file s_tryPropagateNaNExtF80M.c.

48{
49 uint_fast16_t ui64;
50 uint64_t ui0;
51
52 ui64 = aSPtr->signExp;
53 ui0 = aSPtr->signif;
54 if ( isNaNExtF80UI( ui64, ui0 ) ) goto propagateNaN;
55 ui64 = bSPtr->signExp;
56 ui0 = bSPtr->signif;
57 if ( isNaNExtF80UI( ui64, ui0 ) ) goto propagateNaN;
58 return false;
59 propagateNaN:
60 softfloat_propagateNaNExtF80M( aSPtr, bSPtr, zSPtr );
61 return true;
62
63}
void softfloat_propagateNaNExtF80M(const struct extFloat80M *aSPtr, const struct extFloat80M *bSPtr, struct extFloat80M *zSPtr)
#define isNaNExtF80UI(a64, a0)
Definition internals.h:150
Here is the call graph for this function:

◆ softfloat_tryPropagateNaNF128M()

bool softfloat_tryPropagateNaNF128M ( const uint32_t * aWPtr,
const uint32_t * bWPtr,
uint32_t * zWPtr )

Definition at line 44 of file s_tryPropagateNaNF128M.c.

46{
47
48 if ( softfloat_isNaNF128M( aWPtr ) || softfloat_isNaNF128M( bWPtr ) ) {
49 softfloat_propagateNaNF128M( aWPtr, bWPtr, zWPtr );
50 return true;
51 }
52 return false;
53
54}
bool softfloat_isNaNF128M(const uint32_t *)
Here is the call graph for this function: