52{
58 bool signC;
60 bool signProd, prodIsInfinite;
66 bool doSub;
68 (*addCarryMRoutinePtr)(
74 );
76 bool signZ;
81
82
83
91 signProd =
94
95
96 prodIsInfinite = false;
97 if ( (expA == 0x7FFF) || (expB == 0x7FFF) ) {
99 goto propagateNaN_ZC;
100 }
102 if ( ! (
uint32_t) (uiA96<<1) )
goto possibleInvalidProd;
105 possibleInvalidProd:
106 if (
109 ) {
110 goto invalid;
111 }
112 }
113 prodIsInfinite = true;
114 }
115 if ( expC == 0x7FFF ) {
116 if (
120 ) {
122 goto propagateNaN_ZC;
123 }
124 if ( prodIsInfinite && (signProd != signC) ) goto invalid;
125 goto copyC;
126 }
127 if ( prodIsInfinite ) {
129 goto uiZ;
130 }
131
132
133 if ( expA ) {
138 } else {
140 if ( expA == -128 ) goto zeroProd;
141 }
142 if ( expB ) {
147 } else {
149 if ( expB == -128 ) goto zeroProd;
150 }
151
152
153 expProd = expA + expB - 0x3FF0;
155
156
158 if ( expC ) {
159 --expC;
160 wordSig |= 0x00010000;
161 }
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 (
180 ) {
182 }
184 if ( expDiff ) {
186 }
187 carry = 0;
188 if ( doSub ) {
191 carry = ! wordSig;
192 }
193 (*addCarryMRoutinePtr)(
194 4,
197 carry,
199 );
201 if ( ! expZ ) {
202 if ( wordSig & 0x80000000 ) {
203 signZ = ! signZ;
206 }
207 goto checkCancellation;
208 }
209 if ( wordSig < 0x00010000 ) {
210 --expZ;
212 goto roundPack;
213 }
214 goto extSigReady_noCancellation;
215 } else {
216
217
218 signZ = signProd;
219 expZ = expProd;
221 expDiff -= 128;
222 if ( 0 <= expDiff ) {
223
224
227 carry = 0;
228 if ( doSub ) {
229 carry = ! wordSig;
230 wordSig = -wordSig;
231 }
232 carry =
233 (*addCarryMRoutinePtr)(
234 4,
237 carry,
239 );
242 } else {
243
244
245 shiftDist = expDiff & 31;
246 if ( shiftDist ) {
248 }
249 expDiff >>= 5;
250 extSigPtr =
253 carry =
254 (*addCarryMRoutinePtr)( 5, extSigPtr, sigX, doSub, extSigPtr );
255 if ( expDiff == -4 ) {
256
257
259 if ( wordSig & 0x80000000 ) {
260 signZ = ! signZ;
263 }
264
265
266 if ( wordSig ) goto expProdBigger_noWordShift;
268 if ( 0x00040000 <= wordSig ) goto expProdBigger_noWordShift;
269 expZ -= 32;
271 for (;;) {
272 if ( wordSig ) break;
274 if ( 0x00040000 <= wordSig ) break;
275 expZ -= 32;
278 goto checkCancellation;
279 }
280 }
281
282
284 do {
286 if ( *ptr ) {
288 break;
289 }
292 goto extSigReady;
293 }
295 }
296
297
298 if ( carry != doSub ) {
299 if ( doSub ) {
300 do {
301 wordSig = *ptr;
302 *ptr = wordSig - 1;
304 } while ( ! wordSig );
305 } else {
306 do {
307 wordSig = *ptr + 1;
308 *ptr = wordSig;
310 } while ( ! wordSig );
311 }
312 }
313
314
315 expProdBigger_noWordShift:
316 if (
319 ) {
321 }
324 }
325 extSigReady:
327 if ( wordSig < 0x00010000 ) goto doRoundPack;
328 extSigReady_noCancellation:
329 if ( 0x00020000 <= wordSig ) {
330 ++expZ;
332 }
333 roundPack:
335 doRoundPack:
336 (*roundPackRoutinePtr)( signZ, expZ, extSigPtr, zWPtr );
337 return;
338
339
340 invalid:
342 propagateNaN_ZC:
344 return;
345
346
347 zeroProd:
348 if (
349 ! (
uint32_t) (uiC96<<1) && (signProd != signC)
352 ) {
353 goto completeCancellation;
354 }
355 copyC:
360 return;
361
362
363 checkCancellation:
364 if (
365 wordSig
368 ) {
369 goto extSigReady;
370 }
371 completeCancellation:
372 uiZ96 =
375 uiZ:
380
381}
void softfloat_propagateNaNF128M(const uint32_t *aWPtr, const uint32_t *bWPtr, uint32_t *zWPtr)
void softfloat_invalidF128M(uint32_t *)
void softfloat_normRoundPackMToF128M(bool, int32_t, uint32_t *, uint32_t *)
#define fracF128UI96(a96)
void softfloat_roundPackMToF128M(bool, int32_t, uint32_t *, uint32_t *)
#define packToF128UI96(sign, exp, sig96)
int softfloat_shiftNormSigF128M(const uint32_t *, uint_fast8_t, uint32_t *)
bool softfloat_tryPropagateNaNF128M(const uint32_t *, const uint32_t *, uint32_t *)
@ softfloat_mulAdd_subProd
#define signF128UI96(a96)
#define indexMultiwordHi(total, n)
#define indexMultiwordLo(total, n)
#define indexWordLo(total)
#define indexWord(total, n)
#define indexWordHi(total)
#define softfloat_negX160M(zPtr)
#define softfloat_shortShiftRight160M(aPtr, dist, zPtr)
#define softfloat_shiftRightJam160M(aPtr, dist, zPtr)
#define softfloat_add160M(aPtr, bPtr, zPtr)
#define softfloat_negX256M(zPtr)
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)
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)
void softfloat_mul128MTo256M(const uint32_t *aPtr, const uint32_t *bPtr, uint32_t *zPtr)
#define softfloat_shortShiftRightJam160M(aPtr, dist, zPtr)
THREAD_LOCAL uint_fast8_t softfloat_roundingMode