47{
48 bool signA;
51 bool signB;
54 bool signC;
57 bool signProd;
62 bool signZ;
69
70
71
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;
107 expA = normExpSig.exp;
108 sigA = normExpSig.sig;
109 }
110 if ( ! expB ) {
111 if ( ! sigB ) goto zeroProd;
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;
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 }
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;
147 } else {
148 expZ = expProd;
149 sig32Z =
150 sigProd
153 sigZ = sig32Z>>16 | ((sig32Z & 0xFFFF) != 0 );
154 }
155 if ( sigZ < 0x4000 ) {
156 --expZ;
157 sigZ <<= 1;
158 }
159 } else {
160
161
163 if ( expDiff < 0 ) {
164 signZ = signC;
165 expZ = expC;
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;
178 }
180 expZ -= shiftDist;
181 shiftDist -= 16;
182 if ( shiftDist < 0 ) {
183 sigZ =
184 sig32Z>>(-shiftDist)
185 | ((
uint32_t) (sig32Z<<(shiftDist & 31)) != 0);
186 } else {
188 }
189 }
190 roundPack:
192
193
194 propagateNaN_ABC:
196 goto propagateNaN_ZC;
197
198
199 infProdArg:
200 if ( magBits ) {
202 if ( expC != 0x1F ) goto uiZ;
203 if ( sigC ) goto propagateNaN_ZC;
204 if ( signProd == signC ) goto uiZ;
205 }
208 propagateNaN_ZC:
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}
uint_fast16_t softfloat_propagateNaNF16UI(uint_fast16_t uiA, uint_fast16_t uiB)
void softfloat_raiseFlags(uint_fast8_t flags)
float16_t softfloat_roundPackToF16(bool, int_fast16_t, uint_fast16_t)
struct exp8_sig16 softfloat_normSubnormalF16Sig(uint_fast16_t)
@ softfloat_mulAdd_subProd
#define packToF16UI(sign, exp, sig)
uint32_t softfloat_shiftRightJam32(uint32_t a, uint_fast16_t dist)
THREAD_LOCAL uint_fast8_t softfloat_roundingMode
#define softfloat_countLeadingZeros32