45{
49 bool signA;
57 struct exp32_sig64 normExpSig;
59 struct uint128 rem, shiftedSigB;
62 struct uint128 term, altRem, meanRem;
63 bool signRem;
64 struct uint128 uiZ;
68
69
70
72 uiA64 = uA.s.signExp;
73 uiA0 = uA.s.signif;
76 sigA = uiA0;
77 uB.f = b;
79 uiB0 = uB.s.signif;
81 sigB = uiB0;
82
83
84 if ( expA == 0x7FFF ) {
85 if (
86 (sigA &
UINT64_C( 0x7FFFFFFFFFFFFFFF ))
87 || ((expB == 0x7FFF) && (sigB &
UINT64_C( 0x7FFFFFFFFFFFFFFF )))
88 ) {
89 goto propagateNaN;
90 }
91 goto invalid;
92 }
93 if ( expB == 0x7FFF ) {
94 if ( sigB &
UINT64_C( 0x7FFFFFFFFFFFFFFF ) )
goto propagateNaN;
95
96
97
98
99
100 expB += expB;
101 }
102
103
104 if ( ! expB ) expB = 1;
105 if ( ! (sigB &
UINT64_C( 0x8000000000000000 )) ) {
106 if ( ! sigB ) goto invalid;
108 expB += normExpSig.exp;
109 sigB = normExpSig.sig;
110 }
111 if ( ! expA ) expA = 1;
112 if ( ! (sigA &
UINT64_C( 0x8000000000000000 )) ) {
113 if ( ! sigA ) {
114 expA = 0;
115 goto copyA;
116 }
118 expA += normExpSig.exp;
119 sigA = normExpSig.sig;
120 }
121
122
123 expDiff = expA - expB;
124 if ( expDiff < -1 ) goto copyA;
127 if ( expDiff < 1 ) {
128 if ( expDiff ) {
129 --expB;
131 q = 0;
132 } else {
133 q = (sigB <= sigA);
134 if ( q ) {
135 rem =
137 rem.v64, rem.v0, shiftedSigB.v64, shiftedSigB.v0 );
138 }
139 }
140 } else {
142 expDiff -= 30;
143 for (;;) {
145 if ( expDiff < 0 ) break;
146 q = (q64 + 0x80000000)>>32;
150 if ( rem.v64 &
UINT64_C( 0x8000000000000000 ) ) {
151 rem =
153 rem.v64, rem.v0, shiftedSigB.v64, shiftedSigB.v0 );
154 }
155 expDiff -= 29;
156 }
157
158
159
160 q = (
uint32_t) (q64>>32)>>(~expDiff & 31);
164 if ( rem.v64 &
UINT64_C( 0x8000000000000000 ) ) {
165 altRem =
167 rem.v64, rem.v0, shiftedSigB.v64, shiftedSigB.v0 );
168 goto selectRem;
169 }
170 }
171
172
173 do {
174 altRem = rem;
175 ++q;
176 rem =
178 rem.v64, rem.v0, shiftedSigB.v64, shiftedSigB.v0 );
179 }
while ( ! (rem.v64 &
UINT64_C( 0x8000000000000000 )) );
180 selectRem:
182 if (
183 (meanRem.v64 &
UINT64_C( 0x8000000000000000 ))
184 || (! (meanRem.v64 | meanRem.v0) && (q & 1))
185 ) {
186 rem = altRem;
187 }
188 signRem = signA;
189 if ( rem.v64 &
UINT64_C( 0x8000000000000000 ) ) {
190 signRem = ! signRem;
192 }
193 return
195 signRem, rem.v64 | rem.v0 ? expB + 32 : 0, rem.v64, rem.v0, 80 );
196
197
198 propagateNaN:
200 uiZ64 = uiZ.v64;
201 uiZ0 = uiZ.v0;
202 goto uiZ;
203
204
205 invalid:
209 goto uiZ;
210
211
212 copyA:
213 if ( expA < 1 ) {
214 sigA >>= 1 - expA;
215 expA = 0;
216 }
218 uiZ0 = sigA;
219 uiZ:
220 uZ.s.signExp = uiZ64;
221 uZ.s.signif = uiZ0;
222 return uZ.f;
223
224}
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
struct uint128 softfloat_propagateNaNExtF80UI(uint_fast16_t uiA64, uint_fast64_t uiA0, uint_fast16_t uiB64, uint_fast64_t uiB0)
void softfloat_raiseFlags(uint_fast8_t flags)
#define defaultNaNExtF80UI0
#define defaultNaNExtF80UI64
#define packToExtF80UI64(sign, exp)
#define expExtF80UI64(a64)
#define signExtF80UI64(a64)
uint32_t softfloat_approxRecip32_1(uint32_t a)
struct uint128 softfloat_add128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0)
struct uint128 softfloat_mul64ByShifted32To128(uint64_t a, uint32_t b)
extFloat80_t softfloat_normRoundPackToExtF80(bool sign, int_fast32_t exp, uint_fast64_t sig, uint_fast64_t sigExtra, uint_fast8_t roundingPrecision)
struct exp32_sig64 softfloat_normSubnormalExtF80Sig(uint_fast64_t sig)
struct uint128 softfloat_shortShiftLeft128(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)