51{
53 bool roundNearEven;
55 bool isTiny, doIncrement;
56 struct uint64_extra sig64Extra;
58
59
60
63 if ( roundingPrecision == 80 ) goto precision80;
64 if ( roundingPrecision == 64 ) {
65 roundIncrement =
UINT64_C( 0x0000000000000400 );
66 roundMask =
UINT64_C( 0x00000000000007FF );
67 } else if ( roundingPrecision == 32 ) {
68 roundIncrement =
UINT64_C( 0x0000008000000000 );
69 roundMask =
UINT64_C( 0x000000FFFFFFFFFF );
70 } else {
71 goto precision80;
72 }
73 sig |= (sigExtra != 0);
75 roundIncrement =
76 (roundingMode
78 ? roundMask
79 : 0;
80 }
81 roundBits = sig & roundMask;
82
83
84 if ( 0x7FFD <= (
uint32_t) (exp - 1) ) {
85 if ( exp <= 0 ) {
86
87
88 isTiny =
91 || (exp < 0)
92 || (sig <= (
uint64_t) (sig + roundIncrement));
94 roundBits = sig & roundMask;
95 if ( roundBits ) {
98#ifdef SOFTFLOAT_ROUND_ODD
100 sig |= roundMask + 1;
101 }
102#endif
103 }
104 sig += roundIncrement;
105 exp = ((sig &
UINT64_C( 0x8000000000000000 )) != 0);
106 roundIncrement = roundMask + 1;
107 if ( roundNearEven && (roundBits<<1 == roundIncrement) ) {
108 roundMask |= roundIncrement;
109 }
110 sig &= ~roundMask;
111 goto packReturn;
112 }
113 if (
114 (0x7FFE < exp)
115 || ((exp == 0x7FFE) && ((
uint64_t) (sig + roundIncrement) < sig))
116 ) {
118 }
119 }
120
121
122 if ( roundBits ) {
124#ifdef SOFTFLOAT_ROUND_ODD
126 sig = (sig & ~roundMask) | (roundMask + 1);
127 goto packReturn;
128 }
129#endif
130 }
131 sig = (
uint64_t) (sig + roundIncrement);
132 if ( sig < roundIncrement ) {
133 ++exp;
134 sig =
UINT64_C( 0x8000000000000000 );
135 }
136 roundIncrement = roundMask + 1;
137 if ( roundNearEven && (roundBits<<1 == roundIncrement) ) {
138 roundMask |= roundIncrement;
139 }
140 sig &= ~roundMask;
141 goto packReturn;
142
143
144 precision80:
145 doIncrement = (
UINT64_C( 0x8000000000000000 ) <= sigExtra);
147 doIncrement =
148 (roundingMode
150 && sigExtra;
151 }
152
153
154 if ( 0x7FFD <= (
uint32_t) (exp - 1) ) {
155 if ( exp <= 0 ) {
156
157
158 isTiny =
161 || (exp < 0)
162 || ! doIncrement
163 || (sig <
UINT64_C( 0xFFFFFFFFFFFFFFFF ));
164 sig64Extra =
166 exp = 0;
167 sig = sig64Extra.v;
168 sigExtra = sig64Extra.extra;
169 if ( sigExtra ) {
172#ifdef SOFTFLOAT_ROUND_ODD
174 sig |= 1;
175 goto packReturn;
176 }
177#endif
178 }
179 doIncrement = (
UINT64_C( 0x8000000000000000 ) <= sigExtra);
180 if (
181 ! roundNearEven
183 ) {
184 doIncrement =
185 (roundingMode
187 && sigExtra;
188 }
189 if ( doIncrement ) {
190 ++sig;
191 sig &=
193 (! (sigExtra &
UINT64_C( 0x7FFFFFFFFFFFFFFF ))
194 & roundNearEven);
195 exp = ((sig &
UINT64_C( 0x8000000000000000 )) != 0);
196 }
197 goto packReturn;
198 }
199 if (
200 (0x7FFE < exp)
201 || ((exp == 0x7FFE) && (sig ==
UINT64_C( 0xFFFFFFFFFFFFFFFF ))
202 && doIncrement)
203 ) {
204
205
206 roundMask = 0;
210 if (
211 roundNearEven
213 || (roundingMode
215 ) {
216 exp = 0x7FFF;
217 sig =
UINT64_C( 0x8000000000000000 );
218 } else {
219 exp = 0x7FFE;
220 sig = ~roundMask;
221 }
222 goto packReturn;
223 }
224 }
225
226
227 if ( sigExtra ) {
229#ifdef SOFTFLOAT_ROUND_ODD
231 sig |= 1;
232 goto packReturn;
233 }
234#endif
235 }
236 if ( doIncrement ) {
237 ++sig;
238 if ( ! sig ) {
239 ++exp;
240 sig =
UINT64_C( 0x8000000000000000 );
241 } else {
242 sig &=
244 (! (sigExtra &
UINT64_C( 0x7FFFFFFFFFFFFFFF ))
245 & roundNearEven);
246 }
247 }
248
249
250 packReturn:
252 uZ.s.signif = sig;
253 return uZ.f;
254
255}
void softfloat_raiseFlags(uint_fast8_t flags)
#define packToExtF80UI64(sign, exp)
uint64_t softfloat_shiftRightJam64(uint64_t a, uint_fast32_t dist)
THREAD_LOCAL uint_fast8_t softfloat_roundingMode
@ softfloat_flag_underflow
@ softfloat_flag_overflow
THREAD_LOCAL uint_fast8_t softfloat_exceptionFlags
THREAD_LOCAL uint_fast8_t softfloat_detectTininess
@ softfloat_round_near_even
@ softfloat_round_near_maxMag
@ softfloat_tininess_beforeRounding
unsigned __int64 uint64_t