54{
55 bool signA;
57 struct uint128 sigA;
58 bool signB;
60 struct uint128 sigB;
61 bool signC;
63 struct uint128 sigC;
64 bool signZ;
66 struct uint128 uiZ;
67 struct exp32_sig128 normExpSig;
70 struct uint128 sigZ;
72 struct uint128 x128;
76 union ui128_f128 uZ;
77
78
79
80 signA = signF128UI64( uiA64 );
81 expA = expF128UI64( uiA64 );
82 sigA.v64 = fracF128UI64( uiA64 );
83 sigA.v0 = uiA0;
84 signB = signF128UI64( uiB64 );
85 expB = expF128UI64( uiB64 );
86 sigB.v64 = fracF128UI64( uiB64 );
87 sigB.v0 = uiB0;
89 expC = expF128UI64( uiC64 );
90 sigC.v64 = fracF128UI64( uiC64 );
91 sigC.v0 = uiC0;
93
94
95 if ( expA == 0x7FFF ) {
96 if (
97 (sigA.v64 | sigA.v0) || ((expB == 0x7FFF) && (sigB.v64 | sigB.v0))
98 ) {
99 goto propagateNaN_ABC;
100 }
101 magBits = expB | sigB.v64 | sigB.v0;
102 goto infProdArg;
103 }
104 if ( expB == 0x7FFF ) {
105 if ( sigB.v64 | sigB.v0 ) goto propagateNaN_ABC;
106 magBits = expA | sigA.v64 | sigA.v0;
107 goto infProdArg;
108 }
109 if ( expC == 0x7FFF ) {
110 if ( sigC.v64 | sigC.v0 ) {
111 uiZ.v64 = 0;
112 uiZ.v0 = 0;
113 goto propagateNaN_ZC;
114 }
115 uiZ.v64 = uiC64;
116 uiZ.v0 = uiC0;
117 goto uiZ;
118 }
119
120
121 if ( ! expA ) {
122 if ( ! (sigA.v64 | sigA.v0) ) goto zeroProd;
124 expA = normExpSig.exp;
125 sigA = normExpSig.sig;
126 }
127 if ( ! expB ) {
128 if ( ! (sigB.v64 | sigB.v0) ) goto zeroProd;
130 expB = normExpSig.exp;
131 sigB = normExpSig.sig;
132 }
133
134
135 expZ = expA + expB - 0x3FFE;
136 sigA.v64 |=
UINT64_C( 0x0001000000000000 );
137 sigB.v64 |=
UINT64_C( 0x0001000000000000 );
143 shiftDist = 0;
144 if ( ! (sigZ.v64 &
UINT64_C( 0x0100000000000000 )) ) {
145 --expZ;
146 shiftDist = -1;
147 }
148 if ( ! expC ) {
149 if ( ! (sigC.v64 | sigC.v0) ) {
150 shiftDist += 8;
151 goto sigZ;
152 }
154 expC = normExpSig.exp;
155 sigC = normExpSig.sig;
156 }
157 sigC.v64 |=
UINT64_C( 0x0001000000000000 );
159
160
161 expDiff = expZ - expC;
162 if ( expDiff < 0 ) {
163 expZ = expC;
164 if ( (signZ == signC) || (expDiff < -1) ) {
165 shiftDist -= expDiff;
166 if ( shiftDist ) {
167 sigZ =
169 }
170 } else {
171 if ( ! shiftDist ) {
172 x128 =
175 1
176 );
177 sig256Z[
indexWord( 4, 1 )] = (sigZ.v0<<63) | x128.v64;
182 }
183 }
184 } else {
186 if ( ! expDiff ) {
189 } else {
195 }
196 }
197
198
199 shiftDist = 8;
200 if ( signZ == signC ) {
201
202
203 if ( expDiff <= 0 ) {
205 } else {
209 }
210 if ( sigZ.v64 &
UINT64_C( 0x0200000000000000 ) ) {
211 ++expZ;
212 shiftDist = 9;
213 }
214 } else {
215
216
217 if ( expDiff < 0 ) {
218 signZ = signC;
219 if ( expDiff < -1 ) {
220 sigZ =
222 sigZExtra =
224 if ( sigZExtra ) {
226 }
227 if ( ! (sigZ.v64 &
UINT64_C( 0x0100000000000000 )) ) {
228 --expZ;
229 shiftDist = 7;
230 }
231 goto shiftRightRoundPack;
232 } else {
238 }
239 } else if ( ! expDiff ) {
241 if (
242 ! (sigZ.v64 | sigZ.v0) && ! sig256Z[
indexWord( 4, 1 )]
244 ) {
245 goto completeCancellation;
246 }
249 if ( sigZ.v64 &
UINT64_C( 0x8000000000000000 ) ) {
250 signZ = ! signZ;
252 }
253 } else {
255 if ( 1 < expDiff ) {
258 if ( ! (sigZ.v64 &
UINT64_C( 0x0100000000000000 )) ) {
259 --expZ;
260 shiftDist = 7;
261 }
262 goto sigZ;
263 }
264 }
265
266
271 if ( sigZ.v64 ) {
272 if ( sig256Z0 ) sigZExtra |= 1;
273 } else {
274 expZ -= 64;
275 sigZ.v64 = sigZ.v0;
276 sigZ.v0 = sigZExtra;
277 sigZExtra = sig256Z0;
278 if ( ! sigZ.v64 ) {
279 expZ -= 64;
280 sigZ.v64 = sigZ.v0;
281 sigZ.v0 = sigZExtra;
282 sigZExtra = 0;
283 if ( ! sigZ.v64 ) {
284 expZ -= 64;
285 sigZ.v64 = sigZ.v0;
286 sigZ.v0 = 0;
287 }
288 }
289 }
291 expZ += 7 - shiftDist;
292 shiftDist = 15 - shiftDist;
293 if ( 0 < shiftDist ) goto shiftRightRoundPack;
294 if ( shiftDist ) {
295 shiftDist = -shiftDist;
298 sigZ.v0 |= x128.v64;
299 sigZExtra = x128.v0;
300 }
301 goto roundPack;
302 }
303 sigZ:
305 shiftRightRoundPack:
306 sigZExtra = (
uint64_t) (sigZ.v0<<(64 - shiftDist)) | (sigZExtra != 0);
308 roundPack:
309 return
311 signZ, expZ - 1, sigZ.v64, sigZ.v0, sigZExtra );
312
313
314 propagateNaN_ABC:
316 goto propagateNaN_ZC;
317
318
319 infProdArg:
320 if ( magBits ) {
321 uiZ.v64 = packToF128UI64( signZ, 0x7FFF, 0 );
322 uiZ.v0 = 0;
323 if ( expC != 0x7FFF ) goto uiZ;
324 if ( sigC.v64 | sigC.v0 ) goto propagateNaN_ZC;
325 if ( signZ == signC ) goto uiZ;
326 }
330 propagateNaN_ZC:
332 goto uiZ;
333
334
335 zeroProd:
336 uiZ.v64 = uiC64;
337 uiZ.v0 = uiC0;
338 if ( ! (expC | sigC.v64 | sigC.v0) && (signZ != signC) ) {
339 completeCancellation:
340 uiZ.v64 =
341 packToF128UI64(
343 uiZ.v0 = 0;
344 }
345 uiZ:
346 uZ.ui = uiZ;
347 return uZ.f;
348
349}
struct uint128 softfloat_propagateNaNF128UI(uint_fast64_t uiA64, uint_fast64_t uiA0, uint_fast64_t uiB64, uint_fast64_t uiB0)
void softfloat_raiseFlags(uint_fast8_t flags)
#define defaultNaNF128UI64
#define defaultNaNF128UI0
@ softfloat_mulAdd_subProd
#define INIT_UINTM4(v3, v2, v1, v0)
#define indexWord(total, n)
THREAD_LOCAL uint_fast8_t softfloat_roundingMode
struct uint128 softfloat_add128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0)
void softfloat_add256M(const uint64_t *aPtr, const uint64_t *bPtr, uint64_t *zPtr)
#define softfloat_countLeadingZeros64
#define softfloat_mul128To256M
struct exp32_sig128 softfloat_normSubnormalF128Sig(uint_fast64_t sig64, uint_fast64_t sig0)
float128_t softfloat_roundPackToF128(bool sign, int_fast32_t exp, uint_fast64_t sig64, uint_fast64_t sig0, uint_fast64_t sigExtra)
struct uint128 softfloat_shiftRightJam128(uint64_t a64, uint64_t a0, uint_fast32_t dist)
void softfloat_shiftRightJam256M(const uint64_t *aPtr, uint_fast32_t dist, uint64_t *zPtr)
struct uint128 softfloat_shortShiftLeft128(uint64_t a64, uint64_t a0, uint_fast8_t dist)
struct uint128 softfloat_shortShiftRight128(uint64_t a64, uint64_t a0, uint_fast8_t dist)
struct uint128 softfloat_sub128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0)
void softfloat_sub256M(const uint64_t *aPtr, const uint64_t *bPtr, uint64_t *zPtr)
unsigned __int64 uint64_t