5 #include "primitives.h"
7 #include "specialize.h"
12 int op
, uint_fast32_t uiA
, uint_fast32_t uiB
, uint_fast32_t uiC
)
24 uint_fast32_t magBits
, uiZ
;
25 struct exp16_sig32 normExpSig
;
27 uint_fast64_t sigProd
;
32 uint_fast64_t sigZ64
, sigC64
;
36 signA
= signF32UI( uiA
);
37 expA
= expF32UI( uiA
);
38 sigA
= fracF32UI( uiA
);
39 signB
= signF32UI( uiB
);
40 expB
= expF32UI( uiB
);
41 sigB
= fracF32UI( uiB
);
42 signC
= signF32UI( uiC
) ^ ( op
== softfloat_mulAdd_subC
);
43 expC
= expF32UI( uiC
);
44 sigC
= fracF32UI( uiC
);
45 signProd
= signA
^ signB
^ ( op
== softfloat_mulAdd_subProd
);
47 if ( sigA
|| ( ( expB
== 0xFF ) && sigB
) ) goto propagateNaN_ABC
;
48 magBits
= expB
| sigB
;
52 if ( sigB
) goto propagateNaN_ABC
;
53 magBits
= expA
| sigA
;
65 if ( ! sigA
) goto zeroProd
;
66 normExpSig
= softfloat_normSubnormalF32Sig( sigA
);
67 expA
= normExpSig
.exp
;
68 sigA
= normExpSig
.sig
;
71 if ( ! sigB
) goto zeroProd
;
72 normExpSig
= softfloat_normSubnormalF32Sig( sigB
);
73 expB
= normExpSig
.exp
;
74 sigB
= normExpSig
.sig
;
76 expProd
= expA
+ expB
- 0x7E;
77 sigA
= ( sigA
| 0x00800000 )<<7;
78 sigB
= ( sigB
| 0x00800000 )<<7;
79 sigProd
= (uint_fast64_t) sigA
* sigB
;
80 if ( sigProd
< UINT64_C( 0x2000000000000000 ) ) {
88 sigZ
= softfloat_shortShift64RightJam( sigProd
, 31 );
91 normExpSig
= softfloat_normSubnormalF32Sig( sigC
);
92 expC
= normExpSig
.exp
;
93 sigC
= normExpSig
.sig
;
95 sigC
= ( sigC
| 0x00800000 )<<6;
96 expDiff
= expProd
- expC
;
97 if ( signProd
== signC
) {
100 sigZ
= sigC
+ softfloat_shift64RightJam( sigProd
, 32 - expDiff
);
105 + softfloat_shift64RightJam(
106 (uint_fast64_t) sigC
<<32, expDiff
);
107 sigZ
= softfloat_shortShift64RightJam( sigZ64
, 32 );
109 if ( sigZ
< 0x40000000 ) {
114 /*** OPTIMIZE BETTER? ***/
115 sigC64
= (uint_fast64_t) sigC
<<32;
119 sigZ64
= sigC64
- softfloat_shift64RightJam( sigProd
, - expDiff
);
120 } else if ( ! expDiff
) {
122 sigZ64
= sigProd
- sigC64
;
123 if ( ! sigZ64
) goto completeCancellation
;
124 if ( sigZ64
& UINT64_C( 0x8000000000000000 ) ) {
130 sigZ64
= sigProd
- softfloat_shift64RightJam( sigC64
, expDiff
);
132 shiftCount
= softfloat_countLeadingZeros64( sigZ64
) - 1;
135 if ( shiftCount
< 0 ) {
136 sigZ
= softfloat_shortShift64RightJam( sigZ64
, - shiftCount
);
138 sigZ
= (uint_fast32_t) sigZ64
<<shiftCount
;
142 return softfloat_roundPackToF32( signZ
, expZ
, sigZ
);
144 uiZ
= softfloat_propagateNaNF32UI( uiA
, uiB
);
145 goto propagateNaN_ZC
;
148 uiZ
= packToF32UI( signProd
, 0xFF, 0 );
149 if ( expC
!= 0xFF ) goto uiZ
;
150 if ( sigC
) goto propagateNaN_ZC
;
151 if ( signProd
== signC
) goto uiZ
;
154 softfloat_raiseFlags( softfloat_flag_invalid
);
155 uiZ
= defaultNaNF32UI
;
157 uiZ
= softfloat_propagateNaNF32UI( uiZ
, uiC
);
161 if ( ! ( expC
| sigC
) && ( signProd
!= signC
) ) {
162 completeCancellation
:
164 packToF32UI( softfloat_roundingMode
== softfloat_round_min
, 0, 0 );