Commit f090c9d4ad5812fb92843d6470a1111c15190c4c
1 parent
b881c2c6
Add strict checking mode for softfp code.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3688 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
8 changed files
with
210 additions
and
117 deletions
fpu/softfloat-specialize.h
... | ... | @@ -66,9 +66,9 @@ typedef struct { |
66 | 66 | | The pattern for a default generated single-precision NaN. |
67 | 67 | *----------------------------------------------------------------------------*/ |
68 | 68 | #if SNAN_BIT_IS_ONE |
69 | -#define float32_default_nan 0x7FBFFFFF | |
69 | +#define float32_default_nan make_float32(0x7FBFFFFF) | |
70 | 70 | #else |
71 | -#define float32_default_nan 0xFFC00000 | |
71 | +#define float32_default_nan make_float32(0xFFC00000) | |
72 | 72 | #endif |
73 | 73 | |
74 | 74 | /*---------------------------------------------------------------------------- |
... | ... | @@ -76,8 +76,9 @@ typedef struct { |
76 | 76 | | NaN; otherwise returns 0. |
77 | 77 | *----------------------------------------------------------------------------*/ |
78 | 78 | |
79 | -int float32_is_nan( float32 a ) | |
79 | +int float32_is_nan( float32 a_ ) | |
80 | 80 | { |
81 | + uint32_t a = float32_val(a_); | |
81 | 82 | #if SNAN_BIT_IS_ONE |
82 | 83 | return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); |
83 | 84 | #else |
... | ... | @@ -90,8 +91,9 @@ int float32_is_nan( float32 a ) |
90 | 91 | | NaN; otherwise returns 0. |
91 | 92 | *----------------------------------------------------------------------------*/ |
92 | 93 | |
93 | -int float32_is_signaling_nan( float32 a ) | |
94 | +int float32_is_signaling_nan( float32 a_ ) | |
94 | 95 | { |
96 | + uint32_t a = float32_val(a_); | |
95 | 97 | #if SNAN_BIT_IS_ONE |
96 | 98 | return ( 0xFF800000 <= (bits32) ( a<<1 ) ); |
97 | 99 | #else |
... | ... | @@ -110,9 +112,9 @@ static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM ) |
110 | 112 | commonNaNT z; |
111 | 113 | |
112 | 114 | if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR ); |
113 | - z.sign = a>>31; | |
115 | + z.sign = float32_val(a)>>31; | |
114 | 116 | z.low = 0; |
115 | - z.high = ( (bits64) a )<<41; | |
117 | + z.high = ( (bits64) float32_val(a) )<<41; | |
116 | 118 | return z; |
117 | 119 | } |
118 | 120 | |
... | ... | @@ -123,7 +125,8 @@ static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM ) |
123 | 125 | |
124 | 126 | static float32 commonNaNToFloat32( commonNaNT a ) |
125 | 127 | { |
126 | - return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 ); | |
128 | + return make_float32( | |
129 | + ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 ) ); | |
127 | 130 | } |
128 | 131 | |
129 | 132 | /*---------------------------------------------------------------------------- |
... | ... | @@ -135,42 +138,52 @@ static float32 commonNaNToFloat32( commonNaNT a ) |
135 | 138 | static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM) |
136 | 139 | { |
137 | 140 | flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; |
141 | + bits32 av, bv, res; | |
138 | 142 | |
139 | 143 | aIsNaN = float32_is_nan( a ); |
140 | 144 | aIsSignalingNaN = float32_is_signaling_nan( a ); |
141 | 145 | bIsNaN = float32_is_nan( b ); |
142 | 146 | bIsSignalingNaN = float32_is_signaling_nan( b ); |
147 | + av = float32_val(a); | |
148 | + bv = float32_val(b); | |
143 | 149 | #if SNAN_BIT_IS_ONE |
144 | - a &= ~0x00400000; | |
145 | - b &= ~0x00400000; | |
150 | + av &= ~0x00400000; | |
151 | + bv &= ~0x00400000; | |
146 | 152 | #else |
147 | - a |= 0x00400000; | |
148 | - b |= 0x00400000; | |
153 | + av |= 0x00400000; | |
154 | + bv |= 0x00400000; | |
149 | 155 | #endif |
150 | 156 | if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR); |
151 | 157 | if ( aIsSignalingNaN ) { |
152 | 158 | if ( bIsSignalingNaN ) goto returnLargerSignificand; |
153 | - return bIsNaN ? b : a; | |
159 | + res = bIsNaN ? bv : av; | |
154 | 160 | } |
155 | 161 | else if ( aIsNaN ) { |
156 | - if ( bIsSignalingNaN | ! bIsNaN ) return a; | |
162 | + if ( bIsSignalingNaN | ! bIsNaN ) | |
163 | + res = av; | |
164 | + else { | |
157 | 165 | returnLargerSignificand: |
158 | - if ( (bits32) ( a<<1 ) < (bits32) ( b<<1 ) ) return b; | |
159 | - if ( (bits32) ( b<<1 ) < (bits32) ( a<<1 ) ) return a; | |
160 | - return ( a < b ) ? a : b; | |
166 | + if ( (bits32) ( av<<1 ) < (bits32) ( bv<<1 ) ) | |
167 | + res = bv; | |
168 | + else if ( (bits32) ( bv<<1 ) < (bits32) ( av<<1 ) ) | |
169 | + res = av; | |
170 | + else | |
171 | + res = ( av < bv ) ? av : bv; | |
172 | + } | |
161 | 173 | } |
162 | 174 | else { |
163 | - return b; | |
175 | + res = bv; | |
164 | 176 | } |
177 | + return make_float32(res); | |
165 | 178 | } |
166 | 179 | |
167 | 180 | /*---------------------------------------------------------------------------- |
168 | 181 | | The pattern for a default generated double-precision NaN. |
169 | 182 | *----------------------------------------------------------------------------*/ |
170 | 183 | #if SNAN_BIT_IS_ONE |
171 | -#define float64_default_nan LIT64( 0x7FF7FFFFFFFFFFFF ) | |
184 | +#define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF )) | |
172 | 185 | #else |
173 | -#define float64_default_nan LIT64( 0xFFF8000000000000 ) | |
186 | +#define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 )) | |
174 | 187 | #endif |
175 | 188 | |
176 | 189 | /*---------------------------------------------------------------------------- |
... | ... | @@ -178,8 +191,9 @@ static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM) |
178 | 191 | | NaN; otherwise returns 0. |
179 | 192 | *----------------------------------------------------------------------------*/ |
180 | 193 | |
181 | -int float64_is_nan( float64 a ) | |
194 | +int float64_is_nan( float64 a_ ) | |
182 | 195 | { |
196 | + bits64 a = float64_val(a_); | |
183 | 197 | #if SNAN_BIT_IS_ONE |
184 | 198 | return |
185 | 199 | ( ( ( a>>51 ) & 0xFFF ) == 0xFFE ) |
... | ... | @@ -194,8 +208,9 @@ int float64_is_nan( float64 a ) |
194 | 208 | | NaN; otherwise returns 0. |
195 | 209 | *----------------------------------------------------------------------------*/ |
196 | 210 | |
197 | -int float64_is_signaling_nan( float64 a ) | |
211 | +int float64_is_signaling_nan( float64 a_ ) | |
198 | 212 | { |
213 | + bits64 a = float64_val(a_); | |
199 | 214 | #if SNAN_BIT_IS_ONE |
200 | 215 | return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) ); |
201 | 216 | #else |
... | ... | @@ -216,9 +231,9 @@ static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM) |
216 | 231 | commonNaNT z; |
217 | 232 | |
218 | 233 | if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR); |
219 | - z.sign = a>>63; | |
234 | + z.sign = float64_val(a)>>63; | |
220 | 235 | z.low = 0; |
221 | - z.high = a<<12; | |
236 | + z.high = float64_val(a)<<12; | |
222 | 237 | return z; |
223 | 238 | } |
224 | 239 | |
... | ... | @@ -229,10 +244,10 @@ static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM) |
229 | 244 | |
230 | 245 | static float64 commonNaNToFloat64( commonNaNT a ) |
231 | 246 | { |
232 | - return | |
247 | + return make_float64( | |
233 | 248 | ( ( (bits64) a.sign )<<63 ) |
234 | 249 | | LIT64( 0x7FF8000000000000 ) |
235 | - | ( a.high>>12 ); | |
250 | + | ( a.high>>12 )); | |
236 | 251 | } |
237 | 252 | |
238 | 253 | /*---------------------------------------------------------------------------- |
... | ... | @@ -244,33 +259,43 @@ static float64 commonNaNToFloat64( commonNaNT a ) |
244 | 259 | static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM) |
245 | 260 | { |
246 | 261 | flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; |
262 | + bits64 av, bv, res; | |
247 | 263 | |
248 | 264 | aIsNaN = float64_is_nan( a ); |
249 | 265 | aIsSignalingNaN = float64_is_signaling_nan( a ); |
250 | 266 | bIsNaN = float64_is_nan( b ); |
251 | 267 | bIsSignalingNaN = float64_is_signaling_nan( b ); |
268 | + av = float64_val(a); | |
269 | + bv = float64_val(b); | |
252 | 270 | #if SNAN_BIT_IS_ONE |
253 | - a &= ~LIT64( 0x0008000000000000 ); | |
254 | - b &= ~LIT64( 0x0008000000000000 ); | |
271 | + av &= ~LIT64( 0x0008000000000000 ); | |
272 | + bv &= ~LIT64( 0x0008000000000000 ); | |
255 | 273 | #else |
256 | - a |= LIT64( 0x0008000000000000 ); | |
257 | - b |= LIT64( 0x0008000000000000 ); | |
274 | + av |= LIT64( 0x0008000000000000 ); | |
275 | + bv |= LIT64( 0x0008000000000000 ); | |
258 | 276 | #endif |
259 | 277 | if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR); |
260 | 278 | if ( aIsSignalingNaN ) { |
261 | 279 | if ( bIsSignalingNaN ) goto returnLargerSignificand; |
262 | - return bIsNaN ? b : a; | |
280 | + res = bIsNaN ? bv : av; | |
263 | 281 | } |
264 | 282 | else if ( aIsNaN ) { |
265 | - if ( bIsSignalingNaN | ! bIsNaN ) return a; | |
283 | + if ( bIsSignalingNaN | ! bIsNaN ) | |
284 | + res = av; | |
285 | + else { | |
266 | 286 | returnLargerSignificand: |
267 | - if ( (bits64) ( a<<1 ) < (bits64) ( b<<1 ) ) return b; | |
268 | - if ( (bits64) ( b<<1 ) < (bits64) ( a<<1 ) ) return a; | |
269 | - return ( a < b ) ? a : b; | |
287 | + if ( (bits64) ( av<<1 ) < (bits64) ( bv<<1 ) ) | |
288 | + res = bv; | |
289 | + else if ( (bits64) ( bv<<1 ) < (bits64) ( av<<1 ) ) | |
290 | + res = av; | |
291 | + else | |
292 | + res = ( av < bv ) ? av : bv; | |
293 | + } | |
270 | 294 | } |
271 | 295 | else { |
272 | - return b; | |
296 | + res = bv; | |
273 | 297 | } |
298 | + return make_float64(res); | |
274 | 299 | } |
275 | 300 | |
276 | 301 | #ifdef FLOATX80 | ... | ... |
fpu/softfloat.c
... | ... | @@ -175,7 +175,7 @@ static int64 roundAndPackInt64( flag zSign, bits64 absZ0, bits64 absZ1 STATUS_PA |
175 | 175 | INLINE bits32 extractFloat32Frac( float32 a ) |
176 | 176 | { |
177 | 177 | |
178 | - return a & 0x007FFFFF; | |
178 | + return float32_val(a) & 0x007FFFFF; | |
179 | 179 | |
180 | 180 | } |
181 | 181 | |
... | ... | @@ -186,7 +186,7 @@ INLINE bits32 extractFloat32Frac( float32 a ) |
186 | 186 | INLINE int16 extractFloat32Exp( float32 a ) |
187 | 187 | { |
188 | 188 | |
189 | - return ( a>>23 ) & 0xFF; | |
189 | + return ( float32_val(a)>>23 ) & 0xFF; | |
190 | 190 | |
191 | 191 | } |
192 | 192 | |
... | ... | @@ -197,7 +197,7 @@ INLINE int16 extractFloat32Exp( float32 a ) |
197 | 197 | INLINE flag extractFloat32Sign( float32 a ) |
198 | 198 | { |
199 | 199 | |
200 | - return a>>31; | |
200 | + return float32_val(a)>>31; | |
201 | 201 | |
202 | 202 | } |
203 | 203 | |
... | ... | @@ -233,7 +233,8 @@ static void |
233 | 233 | INLINE float32 packFloat32( flag zSign, int16 zExp, bits32 zSig ) |
234 | 234 | { |
235 | 235 | |
236 | - return ( ( (bits32) zSign )<<31 ) + ( ( (bits32) zExp )<<23 ) + zSig; | |
236 | + return make_float32( | |
237 | + ( ( (bits32) zSign )<<31 ) + ( ( (bits32) zExp )<<23 ) + zSig); | |
237 | 238 | |
238 | 239 | } |
239 | 240 | |
... | ... | @@ -290,7 +291,7 @@ static float32 roundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig STATUS_P |
290 | 291 | && ( (sbits32) ( zSig + roundIncrement ) < 0 ) ) |
291 | 292 | ) { |
292 | 293 | float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR); |
293 | - return packFloat32( zSign, 0xFF, 0 ) - ( roundIncrement == 0 ); | |
294 | + return packFloat32( zSign, 0xFF, - ( roundIncrement == 0 )); | |
294 | 295 | } |
295 | 296 | if ( zExp < 0 ) { |
296 | 297 | isTiny = |
... | ... | @@ -337,7 +338,7 @@ static float32 |
337 | 338 | INLINE bits64 extractFloat64Frac( float64 a ) |
338 | 339 | { |
339 | 340 | |
340 | - return a & LIT64( 0x000FFFFFFFFFFFFF ); | |
341 | + return float64_val(a) & LIT64( 0x000FFFFFFFFFFFFF ); | |
341 | 342 | |
342 | 343 | } |
343 | 344 | |
... | ... | @@ -348,7 +349,7 @@ INLINE bits64 extractFloat64Frac( float64 a ) |
348 | 349 | INLINE int16 extractFloat64Exp( float64 a ) |
349 | 350 | { |
350 | 351 | |
351 | - return ( a>>52 ) & 0x7FF; | |
352 | + return ( float64_val(a)>>52 ) & 0x7FF; | |
352 | 353 | |
353 | 354 | } |
354 | 355 | |
... | ... | @@ -359,7 +360,7 @@ INLINE int16 extractFloat64Exp( float64 a ) |
359 | 360 | INLINE flag extractFloat64Sign( float64 a ) |
360 | 361 | { |
361 | 362 | |
362 | - return a>>63; | |
363 | + return float64_val(a)>>63; | |
363 | 364 | |
364 | 365 | } |
365 | 366 | |
... | ... | @@ -395,7 +396,8 @@ static void |
395 | 396 | INLINE float64 packFloat64( flag zSign, int16 zExp, bits64 zSig ) |
396 | 397 | { |
397 | 398 | |
398 | - return ( ( (bits64) zSign )<<63 ) + ( ( (bits64) zExp )<<52 ) + zSig; | |
399 | + return make_float64( | |
400 | + ( ( (bits64) zSign )<<63 ) + ( ( (bits64) zExp )<<52 ) + zSig); | |
399 | 401 | |
400 | 402 | } |
401 | 403 | |
... | ... | @@ -452,7 +454,7 @@ static float64 roundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig STATUS_P |
452 | 454 | && ( (sbits64) ( zSig + roundIncrement ) < 0 ) ) |
453 | 455 | ) { |
454 | 456 | float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR); |
455 | - return packFloat64( zSign, 0x7FF, 0 ) - ( roundIncrement == 0 ); | |
457 | + return packFloat64( zSign, 0x7FF, - ( roundIncrement == 0 )); | |
456 | 458 | } |
457 | 459 | if ( zExp < 0 ) { |
458 | 460 | isTiny = |
... | ... | @@ -1050,7 +1052,7 @@ float32 int32_to_float32( int32 a STATUS_PARAM ) |
1050 | 1052 | { |
1051 | 1053 | flag zSign; |
1052 | 1054 | |
1053 | - if ( a == 0 ) return 0; | |
1055 | + if ( a == 0 ) return float32_zero; | |
1054 | 1056 | if ( a == (sbits32) 0x80000000 ) return packFloat32( 1, 0x9E, 0 ); |
1055 | 1057 | zSign = ( a < 0 ); |
1056 | 1058 | return normalizeRoundAndPackFloat32( zSign, 0x9C, zSign ? - a : a STATUS_VAR ); |
... | ... | @@ -1070,7 +1072,7 @@ float64 int32_to_float64( int32 a STATUS_PARAM ) |
1070 | 1072 | int8 shiftCount; |
1071 | 1073 | bits64 zSig; |
1072 | 1074 | |
1073 | - if ( a == 0 ) return 0; | |
1075 | + if ( a == 0 ) return float64_zero; | |
1074 | 1076 | zSign = ( a < 0 ); |
1075 | 1077 | absA = zSign ? - a : a; |
1076 | 1078 | shiftCount = countLeadingZeros32( absA ) + 21; |
... | ... | @@ -1144,7 +1146,7 @@ float32 int64_to_float32( int64 a STATUS_PARAM ) |
1144 | 1146 | uint64 absA; |
1145 | 1147 | int8 shiftCount; |
1146 | 1148 | |
1147 | - if ( a == 0 ) return 0; | |
1149 | + if ( a == 0 ) return float32_zero; | |
1148 | 1150 | zSign = ( a < 0 ); |
1149 | 1151 | absA = zSign ? - a : a; |
1150 | 1152 | shiftCount = countLeadingZeros64( absA ) - 40; |
... | ... | @@ -1168,7 +1170,7 @@ float32 uint64_to_float32( uint64 a STATUS_PARAM ) |
1168 | 1170 | { |
1169 | 1171 | int8 shiftCount; |
1170 | 1172 | |
1171 | - if ( a == 0 ) return 0; | |
1173 | + if ( a == 0 ) return float32_zero; | |
1172 | 1174 | shiftCount = countLeadingZeros64( a ) - 40; |
1173 | 1175 | if ( 0 <= shiftCount ) { |
1174 | 1176 | return packFloat32( 1 > 0, 0x95 - shiftCount, a<<shiftCount ); |
... | ... | @@ -1195,7 +1197,7 @@ float64 int64_to_float64( int64 a STATUS_PARAM ) |
1195 | 1197 | { |
1196 | 1198 | flag zSign; |
1197 | 1199 | |
1198 | - if ( a == 0 ) return 0; | |
1200 | + if ( a == 0 ) return float64_zero; | |
1199 | 1201 | if ( a == (sbits64) LIT64( 0x8000000000000000 ) ) { |
1200 | 1202 | return packFloat64( 1, 0x43E, 0 ); |
1201 | 1203 | } |
... | ... | @@ -1206,7 +1208,7 @@ float64 int64_to_float64( int64 a STATUS_PARAM ) |
1206 | 1208 | |
1207 | 1209 | float64 uint64_to_float64( uint64 a STATUS_PARAM ) |
1208 | 1210 | { |
1209 | - if ( a == 0 ) return 0; | |
1211 | + if ( a == 0 ) return float64_zero; | |
1210 | 1212 | return normalizeRoundAndPackFloat64( 0, 0x43C, a STATUS_VAR ); |
1211 | 1213 | |
1212 | 1214 | } |
... | ... | @@ -1325,7 +1327,7 @@ int32 float32_to_int32_round_to_zero( float32 a STATUS_PARAM ) |
1325 | 1327 | aSign = extractFloat32Sign( a ); |
1326 | 1328 | shiftCount = aExp - 0x9E; |
1327 | 1329 | if ( 0 <= shiftCount ) { |
1328 | - if ( a != 0xCF000000 ) { | |
1330 | + if ( float32_val(a) != 0xCF000000 ) { | |
1329 | 1331 | float_raise( float_flag_invalid STATUS_VAR); |
1330 | 1332 | if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) return 0x7FFFFFFF; |
1331 | 1333 | } |
... | ... | @@ -1404,7 +1406,7 @@ int64 float32_to_int64_round_to_zero( float32 a STATUS_PARAM ) |
1404 | 1406 | aSign = extractFloat32Sign( a ); |
1405 | 1407 | shiftCount = aExp - 0xBE; |
1406 | 1408 | if ( 0 <= shiftCount ) { |
1407 | - if ( a != 0xDF000000 ) { | |
1409 | + if ( float32_val(a) != 0xDF000000 ) { | |
1408 | 1410 | float_raise( float_flag_invalid STATUS_VAR); |
1409 | 1411 | if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) { |
1410 | 1412 | return LIT64( 0x7FFFFFFFFFFFFFFF ); |
... | ... | @@ -1535,7 +1537,7 @@ float32 float32_round_to_int( float32 a STATUS_PARAM) |
1535 | 1537 | int16 aExp; |
1536 | 1538 | bits32 lastBitMask, roundBitsMask; |
1537 | 1539 | int8 roundingMode; |
1538 | - float32 z; | |
1540 | + bits32 z; | |
1539 | 1541 | |
1540 | 1542 | aExp = extractFloat32Exp( a ); |
1541 | 1543 | if ( 0x96 <= aExp ) { |
... | ... | @@ -1545,7 +1547,7 @@ float32 float32_round_to_int( float32 a STATUS_PARAM) |
1545 | 1547 | return a; |
1546 | 1548 | } |
1547 | 1549 | if ( aExp <= 0x7E ) { |
1548 | - if ( (bits32) ( a<<1 ) == 0 ) return a; | |
1550 | + if ( (bits32) ( float32_val(a)<<1 ) == 0 ) return a; | |
1549 | 1551 | STATUS(float_exception_flags) |= float_flag_inexact; |
1550 | 1552 | aSign = extractFloat32Sign( a ); |
1551 | 1553 | switch ( STATUS(float_rounding_mode) ) { |
... | ... | @@ -1555,29 +1557,29 @@ float32 float32_round_to_int( float32 a STATUS_PARAM) |
1555 | 1557 | } |
1556 | 1558 | break; |
1557 | 1559 | case float_round_down: |
1558 | - return aSign ? 0xBF800000 : 0; | |
1560 | + return make_float32(aSign ? 0xBF800000 : 0); | |
1559 | 1561 | case float_round_up: |
1560 | - return aSign ? 0x80000000 : 0x3F800000; | |
1562 | + return make_float32(aSign ? 0x80000000 : 0x3F800000); | |
1561 | 1563 | } |
1562 | 1564 | return packFloat32( aSign, 0, 0 ); |
1563 | 1565 | } |
1564 | 1566 | lastBitMask = 1; |
1565 | 1567 | lastBitMask <<= 0x96 - aExp; |
1566 | 1568 | roundBitsMask = lastBitMask - 1; |
1567 | - z = a; | |
1569 | + z = float32_val(a); | |
1568 | 1570 | roundingMode = STATUS(float_rounding_mode); |
1569 | 1571 | if ( roundingMode == float_round_nearest_even ) { |
1570 | 1572 | z += lastBitMask>>1; |
1571 | 1573 | if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask; |
1572 | 1574 | } |
1573 | 1575 | else if ( roundingMode != float_round_to_zero ) { |
1574 | - if ( extractFloat32Sign( z ) ^ ( roundingMode == float_round_up ) ) { | |
1576 | + if ( extractFloat32Sign( make_float32(z) ) ^ ( roundingMode == float_round_up ) ) { | |
1575 | 1577 | z += roundBitsMask; |
1576 | 1578 | } |
1577 | 1579 | } |
1578 | 1580 | z &= ~ roundBitsMask; |
1579 | - if ( z != a ) STATUS(float_exception_flags) |= float_flag_inexact; | |
1580 | - return z; | |
1581 | + if ( z != float32_val(a) ) STATUS(float_exception_flags) |= float_flag_inexact; | |
1582 | + return make_float32(z); | |
1581 | 1583 | |
1582 | 1584 | } |
1583 | 1585 | |
... | ... | @@ -2008,7 +2010,7 @@ float32 float32_sqrt( float32 a STATUS_PARAM ) |
2008 | 2010 | aExp = extractFloat32Exp( a ); |
2009 | 2011 | aSign = extractFloat32Sign( a ); |
2010 | 2012 | if ( aExp == 0xFF ) { |
2011 | - if ( aSig ) return propagateFloat32NaN( a, 0 STATUS_VAR ); | |
2013 | + if ( aSig ) return propagateFloat32NaN( a, float32_zero STATUS_VAR ); | |
2012 | 2014 | if ( ! aSign ) return a; |
2013 | 2015 | float_raise( float_flag_invalid STATUS_VAR); |
2014 | 2016 | return float32_default_nan; |
... | ... | @@ -2019,7 +2021,7 @@ float32 float32_sqrt( float32 a STATUS_PARAM ) |
2019 | 2021 | return float32_default_nan; |
2020 | 2022 | } |
2021 | 2023 | if ( aExp == 0 ) { |
2022 | - if ( aSig == 0 ) return 0; | |
2024 | + if ( aSig == 0 ) return float32_zero; | |
2023 | 2025 | normalizeFloat32Subnormal( aSig, &aExp, &aSig ); |
2024 | 2026 | } |
2025 | 2027 | zExp = ( ( aExp - 0x7F )>>1 ) + 0x7E; |
... | ... | @@ -2062,7 +2064,8 @@ int float32_eq( float32 a, float32 b STATUS_PARAM ) |
2062 | 2064 | } |
2063 | 2065 | return 0; |
2064 | 2066 | } |
2065 | - return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 ); | |
2067 | + return ( float32_val(a) == float32_val(b) ) || | |
2068 | + ( (bits32) ( ( float32_val(a) | float32_val(b) )<<1 ) == 0 ); | |
2066 | 2069 | |
2067 | 2070 | } |
2068 | 2071 | |
... | ... | @@ -2076,6 +2079,7 @@ int float32_eq( float32 a, float32 b STATUS_PARAM ) |
2076 | 2079 | int float32_le( float32 a, float32 b STATUS_PARAM ) |
2077 | 2080 | { |
2078 | 2081 | flag aSign, bSign; |
2082 | + bits32 av, bv; | |
2079 | 2083 | |
2080 | 2084 | if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) |
2081 | 2085 | || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) |
... | ... | @@ -2085,8 +2089,10 @@ int float32_le( float32 a, float32 b STATUS_PARAM ) |
2085 | 2089 | } |
2086 | 2090 | aSign = extractFloat32Sign( a ); |
2087 | 2091 | bSign = extractFloat32Sign( b ); |
2088 | - if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 ); | |
2089 | - return ( a == b ) || ( aSign ^ ( a < b ) ); | |
2092 | + av = float32_val(a); | |
2093 | + bv = float32_val(b); | |
2094 | + if ( aSign != bSign ) return aSign || ( (bits32) ( ( av | bv )<<1 ) == 0 ); | |
2095 | + return ( av == bv ) || ( aSign ^ ( av < bv ) ); | |
2090 | 2096 | |
2091 | 2097 | } |
2092 | 2098 | |
... | ... | @@ -2099,6 +2105,7 @@ int float32_le( float32 a, float32 b STATUS_PARAM ) |
2099 | 2105 | int float32_lt( float32 a, float32 b STATUS_PARAM ) |
2100 | 2106 | { |
2101 | 2107 | flag aSign, bSign; |
2108 | + bits32 av, bv; | |
2102 | 2109 | |
2103 | 2110 | if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) |
2104 | 2111 | || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) |
... | ... | @@ -2108,8 +2115,10 @@ int float32_lt( float32 a, float32 b STATUS_PARAM ) |
2108 | 2115 | } |
2109 | 2116 | aSign = extractFloat32Sign( a ); |
2110 | 2117 | bSign = extractFloat32Sign( b ); |
2111 | - if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 ); | |
2112 | - return ( a != b ) && ( aSign ^ ( a < b ) ); | |
2118 | + av = float32_val(a); | |
2119 | + bv = float32_val(b); | |
2120 | + if ( aSign != bSign ) return aSign && ( (bits32) ( ( av | bv )<<1 ) != 0 ); | |
2121 | + return ( av != bv ) && ( aSign ^ ( av < bv ) ); | |
2113 | 2122 | |
2114 | 2123 | } |
2115 | 2124 | |
... | ... | @@ -2122,6 +2131,7 @@ int float32_lt( float32 a, float32 b STATUS_PARAM ) |
2122 | 2131 | |
2123 | 2132 | int float32_eq_signaling( float32 a, float32 b STATUS_PARAM ) |
2124 | 2133 | { |
2134 | + bits32 av, bv; | |
2125 | 2135 | |
2126 | 2136 | if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) |
2127 | 2137 | || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) |
... | ... | @@ -2129,7 +2139,9 @@ int float32_eq_signaling( float32 a, float32 b STATUS_PARAM ) |
2129 | 2139 | float_raise( float_flag_invalid STATUS_VAR); |
2130 | 2140 | return 0; |
2131 | 2141 | } |
2132 | - return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 ); | |
2142 | + av = float32_val(a); | |
2143 | + bv = float32_val(b); | |
2144 | + return ( av == bv ) || ( (bits32) ( ( av | bv )<<1 ) == 0 ); | |
2133 | 2145 | |
2134 | 2146 | } |
2135 | 2147 | |
... | ... | @@ -2143,6 +2155,7 @@ int float32_eq_signaling( float32 a, float32 b STATUS_PARAM ) |
2143 | 2155 | int float32_le_quiet( float32 a, float32 b STATUS_PARAM ) |
2144 | 2156 | { |
2145 | 2157 | flag aSign, bSign; |
2158 | + bits32 av, bv; | |
2146 | 2159 | |
2147 | 2160 | if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) |
2148 | 2161 | || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) |
... | ... | @@ -2154,8 +2167,10 @@ int float32_le_quiet( float32 a, float32 b STATUS_PARAM ) |
2154 | 2167 | } |
2155 | 2168 | aSign = extractFloat32Sign( a ); |
2156 | 2169 | bSign = extractFloat32Sign( b ); |
2157 | - if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 ); | |
2158 | - return ( a == b ) || ( aSign ^ ( a < b ) ); | |
2170 | + av = float32_val(a); | |
2171 | + bv = float32_val(b); | |
2172 | + if ( aSign != bSign ) return aSign || ( (bits32) ( ( av | bv )<<1 ) == 0 ); | |
2173 | + return ( av == bv ) || ( aSign ^ ( av < bv ) ); | |
2159 | 2174 | |
2160 | 2175 | } |
2161 | 2176 | |
... | ... | @@ -2169,6 +2184,7 @@ int float32_le_quiet( float32 a, float32 b STATUS_PARAM ) |
2169 | 2184 | int float32_lt_quiet( float32 a, float32 b STATUS_PARAM ) |
2170 | 2185 | { |
2171 | 2186 | flag aSign, bSign; |
2187 | + bits32 av, bv; | |
2172 | 2188 | |
2173 | 2189 | if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) |
2174 | 2190 | || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) |
... | ... | @@ -2180,8 +2196,10 @@ int float32_lt_quiet( float32 a, float32 b STATUS_PARAM ) |
2180 | 2196 | } |
2181 | 2197 | aSign = extractFloat32Sign( a ); |
2182 | 2198 | bSign = extractFloat32Sign( b ); |
2183 | - if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 ); | |
2184 | - return ( a != b ) && ( aSign ^ ( a < b ) ); | |
2199 | + av = float32_val(a); | |
2200 | + bv = float32_val(b); | |
2201 | + if ( aSign != bSign ) return aSign && ( (bits32) ( ( av | bv )<<1 ) != 0 ); | |
2202 | + return ( av != bv ) && ( aSign ^ ( av < bv ) ); | |
2185 | 2203 | |
2186 | 2204 | } |
2187 | 2205 | |
... | ... | @@ -2324,7 +2342,7 @@ int64 float64_to_int64_round_to_zero( float64 a STATUS_PARAM ) |
2324 | 2342 | shiftCount = aExp - 0x433; |
2325 | 2343 | if ( 0 <= shiftCount ) { |
2326 | 2344 | if ( 0x43E <= aExp ) { |
2327 | - if ( a != LIT64( 0xC3E0000000000000 ) ) { | |
2345 | + if ( float64_val(a) != LIT64( 0xC3E0000000000000 ) ) { | |
2328 | 2346 | float_raise( float_flag_invalid STATUS_VAR); |
2329 | 2347 | if ( ! aSign |
2330 | 2348 | || ( ( aExp == 0x7FF ) |
... | ... | @@ -2464,7 +2482,7 @@ float64 float64_round_to_int( float64 a STATUS_PARAM ) |
2464 | 2482 | int16 aExp; |
2465 | 2483 | bits64 lastBitMask, roundBitsMask; |
2466 | 2484 | int8 roundingMode; |
2467 | - float64 z; | |
2485 | + bits64 z; | |
2468 | 2486 | |
2469 | 2487 | aExp = extractFloat64Exp( a ); |
2470 | 2488 | if ( 0x433 <= aExp ) { |
... | ... | @@ -2474,7 +2492,7 @@ float64 float64_round_to_int( float64 a STATUS_PARAM ) |
2474 | 2492 | return a; |
2475 | 2493 | } |
2476 | 2494 | if ( aExp < 0x3FF ) { |
2477 | - if ( (bits64) ( a<<1 ) == 0 ) return a; | |
2495 | + if ( (bits64) ( float64_val(a)<<1 ) == 0 ) return a; | |
2478 | 2496 | STATUS(float_exception_flags) |= float_flag_inexact; |
2479 | 2497 | aSign = extractFloat64Sign( a ); |
2480 | 2498 | switch ( STATUS(float_rounding_mode) ) { |
... | ... | @@ -2484,30 +2502,31 @@ float64 float64_round_to_int( float64 a STATUS_PARAM ) |
2484 | 2502 | } |
2485 | 2503 | break; |
2486 | 2504 | case float_round_down: |
2487 | - return aSign ? LIT64( 0xBFF0000000000000 ) : 0; | |
2505 | + return make_float64(aSign ? LIT64( 0xBFF0000000000000 ) : 0); | |
2488 | 2506 | case float_round_up: |
2489 | - return | |
2490 | - aSign ? LIT64( 0x8000000000000000 ) : LIT64( 0x3FF0000000000000 ); | |
2507 | + return make_float64( | |
2508 | + aSign ? LIT64( 0x8000000000000000 ) : LIT64( 0x3FF0000000000000 )); | |
2491 | 2509 | } |
2492 | 2510 | return packFloat64( aSign, 0, 0 ); |
2493 | 2511 | } |
2494 | 2512 | lastBitMask = 1; |
2495 | 2513 | lastBitMask <<= 0x433 - aExp; |
2496 | 2514 | roundBitsMask = lastBitMask - 1; |
2497 | - z = a; | |
2515 | + z = float64_val(a); | |
2498 | 2516 | roundingMode = STATUS(float_rounding_mode); |
2499 | 2517 | if ( roundingMode == float_round_nearest_even ) { |
2500 | 2518 | z += lastBitMask>>1; |
2501 | 2519 | if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask; |
2502 | 2520 | } |
2503 | 2521 | else if ( roundingMode != float_round_to_zero ) { |
2504 | - if ( extractFloat64Sign( z ) ^ ( roundingMode == float_round_up ) ) { | |
2522 | + if ( extractFloat64Sign( make_float64(z) ) ^ ( roundingMode == float_round_up ) ) { | |
2505 | 2523 | z += roundBitsMask; |
2506 | 2524 | } |
2507 | 2525 | } |
2508 | 2526 | z &= ~ roundBitsMask; |
2509 | - if ( z != a ) STATUS(float_exception_flags) |= float_flag_inexact; | |
2510 | - return z; | |
2527 | + if ( z != float64_val(a) ) | |
2528 | + STATUS(float_exception_flags) |= float_flag_inexact; | |
2529 | + return make_float64(z); | |
2511 | 2530 | |
2512 | 2531 | } |
2513 | 2532 | |
... | ... | @@ -2951,7 +2970,7 @@ float64 float64_sqrt( float64 a STATUS_PARAM ) |
2951 | 2970 | return float64_default_nan; |
2952 | 2971 | } |
2953 | 2972 | if ( aExp == 0 ) { |
2954 | - if ( aSig == 0 ) return 0; | |
2973 | + if ( aSig == 0 ) return float64_zero; | |
2955 | 2974 | normalizeFloat64Subnormal( aSig, &aExp, &aSig ); |
2956 | 2975 | } |
2957 | 2976 | zExp = ( ( aExp - 0x3FF )>>1 ) + 0x3FE; |
... | ... | @@ -2982,6 +3001,7 @@ float64 float64_sqrt( float64 a STATUS_PARAM ) |
2982 | 3001 | |
2983 | 3002 | int float64_eq( float64 a, float64 b STATUS_PARAM ) |
2984 | 3003 | { |
3004 | + bits64 av, bv; | |
2985 | 3005 | |
2986 | 3006 | if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) |
2987 | 3007 | || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) |
... | ... | @@ -2991,7 +3011,9 @@ int float64_eq( float64 a, float64 b STATUS_PARAM ) |
2991 | 3011 | } |
2992 | 3012 | return 0; |
2993 | 3013 | } |
2994 | - return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 ); | |
3014 | + av = float64_val(a); | |
3015 | + bv = float64_val(a); | |
3016 | + return ( av == bv ) || ( (bits64) ( ( av | bv )<<1 ) == 0 ); | |
2995 | 3017 | |
2996 | 3018 | } |
2997 | 3019 | |
... | ... | @@ -3005,6 +3027,7 @@ int float64_eq( float64 a, float64 b STATUS_PARAM ) |
3005 | 3027 | int float64_le( float64 a, float64 b STATUS_PARAM ) |
3006 | 3028 | { |
3007 | 3029 | flag aSign, bSign; |
3030 | + bits64 av, bv; | |
3008 | 3031 | |
3009 | 3032 | if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) |
3010 | 3033 | || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) |
... | ... | @@ -3014,8 +3037,10 @@ int float64_le( float64 a, float64 b STATUS_PARAM ) |
3014 | 3037 | } |
3015 | 3038 | aSign = extractFloat64Sign( a ); |
3016 | 3039 | bSign = extractFloat64Sign( b ); |
3017 | - if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 ); | |
3018 | - return ( a == b ) || ( aSign ^ ( a < b ) ); | |
3040 | + av = float64_val(a); | |
3041 | + bv = float64_val(a); | |
3042 | + if ( aSign != bSign ) return aSign || ( (bits64) ( ( av | bv )<<1 ) == 0 ); | |
3043 | + return ( av == bv ) || ( aSign ^ ( av < bv ) ); | |
3019 | 3044 | |
3020 | 3045 | } |
3021 | 3046 | |
... | ... | @@ -3028,6 +3053,7 @@ int float64_le( float64 a, float64 b STATUS_PARAM ) |
3028 | 3053 | int float64_lt( float64 a, float64 b STATUS_PARAM ) |
3029 | 3054 | { |
3030 | 3055 | flag aSign, bSign; |
3056 | + bits64 av, bv; | |
3031 | 3057 | |
3032 | 3058 | if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) |
3033 | 3059 | || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) |
... | ... | @@ -3037,8 +3063,10 @@ int float64_lt( float64 a, float64 b STATUS_PARAM ) |
3037 | 3063 | } |
3038 | 3064 | aSign = extractFloat64Sign( a ); |
3039 | 3065 | bSign = extractFloat64Sign( b ); |
3040 | - if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 ); | |
3041 | - return ( a != b ) && ( aSign ^ ( a < b ) ); | |
3066 | + av = float64_val(a); | |
3067 | + bv = float64_val(a); | |
3068 | + if ( aSign != bSign ) return aSign && ( (bits64) ( ( av | bv )<<1 ) != 0 ); | |
3069 | + return ( av != bv ) && ( aSign ^ ( av < bv ) ); | |
3042 | 3070 | |
3043 | 3071 | } |
3044 | 3072 | |
... | ... | @@ -3051,6 +3079,7 @@ int float64_lt( float64 a, float64 b STATUS_PARAM ) |
3051 | 3079 | |
3052 | 3080 | int float64_eq_signaling( float64 a, float64 b STATUS_PARAM ) |
3053 | 3081 | { |
3082 | + bits64 av, bv; | |
3054 | 3083 | |
3055 | 3084 | if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) |
3056 | 3085 | || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) |
... | ... | @@ -3058,7 +3087,9 @@ int float64_eq_signaling( float64 a, float64 b STATUS_PARAM ) |
3058 | 3087 | float_raise( float_flag_invalid STATUS_VAR); |
3059 | 3088 | return 0; |
3060 | 3089 | } |
3061 | - return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 ); | |
3090 | + av = float64_val(a); | |
3091 | + bv = float64_val(a); | |
3092 | + return ( av == bv ) || ( (bits64) ( ( av | bv )<<1 ) == 0 ); | |
3062 | 3093 | |
3063 | 3094 | } |
3064 | 3095 | |
... | ... | @@ -3072,6 +3103,7 @@ int float64_eq_signaling( float64 a, float64 b STATUS_PARAM ) |
3072 | 3103 | int float64_le_quiet( float64 a, float64 b STATUS_PARAM ) |
3073 | 3104 | { |
3074 | 3105 | flag aSign, bSign; |
3106 | + bits64 av, bv; | |
3075 | 3107 | |
3076 | 3108 | if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) |
3077 | 3109 | || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) |
... | ... | @@ -3083,8 +3115,10 @@ int float64_le_quiet( float64 a, float64 b STATUS_PARAM ) |
3083 | 3115 | } |
3084 | 3116 | aSign = extractFloat64Sign( a ); |
3085 | 3117 | bSign = extractFloat64Sign( b ); |
3086 | - if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 ); | |
3087 | - return ( a == b ) || ( aSign ^ ( a < b ) ); | |
3118 | + av = float64_val(a); | |
3119 | + bv = float64_val(a); | |
3120 | + if ( aSign != bSign ) return aSign || ( (bits64) ( ( av | bv )<<1 ) == 0 ); | |
3121 | + return ( av == bv ) || ( aSign ^ ( av < bv ) ); | |
3088 | 3122 | |
3089 | 3123 | } |
3090 | 3124 | |
... | ... | @@ -3098,6 +3132,7 @@ int float64_le_quiet( float64 a, float64 b STATUS_PARAM ) |
3098 | 3132 | int float64_lt_quiet( float64 a, float64 b STATUS_PARAM ) |
3099 | 3133 | { |
3100 | 3134 | flag aSign, bSign; |
3135 | + bits64 av, bv; | |
3101 | 3136 | |
3102 | 3137 | if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) |
3103 | 3138 | || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) |
... | ... | @@ -3109,8 +3144,10 @@ int float64_lt_quiet( float64 a, float64 b STATUS_PARAM ) |
3109 | 3144 | } |
3110 | 3145 | aSign = extractFloat64Sign( a ); |
3111 | 3146 | bSign = extractFloat64Sign( b ); |
3112 | - if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 ); | |
3113 | - return ( a != b ) && ( aSign ^ ( a < b ) ); | |
3147 | + av = float64_val(a); | |
3148 | + bv = float64_val(a); | |
3149 | + if ( aSign != bSign ) return aSign && ( (bits64) ( ( av | bv )<<1 ) != 0 ); | |
3150 | + return ( av != bv ) && ( aSign ^ ( av < bv ) ); | |
3114 | 3151 | |
3115 | 3152 | } |
3116 | 3153 | |
... | ... | @@ -5310,12 +5347,14 @@ unsigned int float64_to_uint32_round_to_zero( float64 a STATUS_PARAM ) |
5310 | 5347 | return res; |
5311 | 5348 | } |
5312 | 5349 | |
5350 | +/* FIXME: This looks broken. */ | |
5313 | 5351 | uint64_t float64_to_uint64 (float64 a STATUS_PARAM) |
5314 | 5352 | { |
5315 | 5353 | int64_t v; |
5316 | 5354 | |
5317 | - v = int64_to_float64(INT64_MIN STATUS_VAR); | |
5318 | - v = float64_to_int64((a + v) STATUS_VAR); | |
5355 | + v = float64_val(int64_to_float64(INT64_MIN STATUS_VAR)); | |
5356 | + v += float64_val(a); | |
5357 | + v = float64_to_int64(make_float64(v) STATUS_VAR); | |
5319 | 5358 | |
5320 | 5359 | return v - INT64_MIN; |
5321 | 5360 | } |
... | ... | @@ -5324,8 +5363,9 @@ uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM) |
5324 | 5363 | { |
5325 | 5364 | int64_t v; |
5326 | 5365 | |
5327 | - v = int64_to_float64(INT64_MIN STATUS_VAR); | |
5328 | - v = float64_to_int64_round_to_zero((a + v) STATUS_VAR); | |
5366 | + v = float64_val(int64_to_float64(INT64_MIN STATUS_VAR)); | |
5367 | + v += float64_val(a); | |
5368 | + v = float64_to_int64_round_to_zero(make_float64(v) STATUS_VAR); | |
5329 | 5369 | |
5330 | 5370 | return v - INT64_MIN; |
5331 | 5371 | } |
... | ... | @@ -5335,6 +5375,7 @@ INLINE int float ## s ## _compare_internal( float ## s a, float ## s b, \ |
5335 | 5375 | int is_quiet STATUS_PARAM ) \ |
5336 | 5376 | { \ |
5337 | 5377 | flag aSign, bSign; \ |
5378 | + bits ## s av, bv; \ | |
5338 | 5379 | \ |
5339 | 5380 | if (( ( extractFloat ## s ## Exp( a ) == nan_exp ) && \ |
5340 | 5381 | extractFloat ## s ## Frac( a ) ) || \ |
... | ... | @@ -5349,18 +5390,20 @@ INLINE int float ## s ## _compare_internal( float ## s a, float ## s b, \ |
5349 | 5390 | } \ |
5350 | 5391 | aSign = extractFloat ## s ## Sign( a ); \ |
5351 | 5392 | bSign = extractFloat ## s ## Sign( b ); \ |
5393 | + av = float ## s ## _val(a); \ | |
5394 | + bv = float ## s ## _val(a); \ | |
5352 | 5395 | if ( aSign != bSign ) { \ |
5353 | - if ( (bits ## s) ( ( a | b )<<1 ) == 0 ) { \ | |
5396 | + if ( (bits ## s) ( ( av | bv )<<1 ) == 0 ) { \ | |
5354 | 5397 | /* zero case */ \ |
5355 | 5398 | return float_relation_equal; \ |
5356 | 5399 | } else { \ |
5357 | 5400 | return 1 - (2 * aSign); \ |
5358 | 5401 | } \ |
5359 | 5402 | } else { \ |
5360 | - if (a == b) { \ | |
5403 | + if (av == bv) { \ | |
5361 | 5404 | return float_relation_equal; \ |
5362 | 5405 | } else { \ |
5363 | - return 1 - 2 * (aSign ^ ( a < b )); \ | |
5406 | + return 1 - 2 * (aSign ^ ( av < bv )); \ | |
5364 | 5407 | } \ |
5365 | 5408 | } \ |
5366 | 5409 | } \ | ... | ... |
fpu/softfloat.h
... | ... | @@ -111,8 +111,31 @@ enum { |
111 | 111 | /*---------------------------------------------------------------------------- |
112 | 112 | | Software IEC/IEEE floating-point types. |
113 | 113 | *----------------------------------------------------------------------------*/ |
114 | +/* Use structures for soft-float types. This prevents accidentally mixing | |
115 | + them with native int/float types. A sufficiently clever compiler and | |
116 | + sane ABI should be able to see though these structs. However | |
117 | + x86/gcc 3.x seems to struggle a bit, so leave them disabled by default. */ | |
118 | +//#define USE_SOFTFLOAT_STRUCT_TYPES | |
119 | +#ifdef USE_SOFTFLOAT_STRUCT_TYPES | |
120 | +typedef struct { | |
121 | + uint32_t v; | |
122 | +} float32; | |
123 | +/* The cast ensures an error if the wrong type is passed. */ | |
124 | +#define float32_val(x) (((float32)(x)).v) | |
125 | +#define make_float32(x) __extension__ ({ float32 f32_val = {x}; f32_val; }) | |
126 | +typedef struct { | |
127 | + uint64_t v; | |
128 | +} float64; | |
129 | +#define float64_val(x) (((float64)(x)).v) | |
130 | +#define make_float64(x) __extension__ ({ float64 f64_val = {x}; f64_val; }) | |
131 | +#else | |
114 | 132 | typedef uint32_t float32; |
115 | 133 | typedef uint64_t float64; |
134 | +#define float32_val(x) (x) | |
135 | +#define float64_val(x) (x) | |
136 | +#define make_float32(x) (x) | |
137 | +#define make_float64(x) (x) | |
138 | +#endif | |
116 | 139 | #ifdef FLOATX80 |
117 | 140 | typedef struct { |
118 | 141 | uint64_t low; |
... | ... | @@ -248,14 +271,16 @@ float32 float32_scalbn( float32, int STATUS_PARAM ); |
248 | 271 | |
249 | 272 | INLINE float32 float32_abs(float32 a) |
250 | 273 | { |
251 | - return a & 0x7fffffff; | |
274 | + return make_float32(float32_val(a) & 0x7fffffff); | |
252 | 275 | } |
253 | 276 | |
254 | 277 | INLINE float32 float32_chs(float32 a) |
255 | 278 | { |
256 | - return a ^ 0x80000000; | |
279 | + return make_float32(float32_val(a) ^ 0x80000000); | |
257 | 280 | } |
258 | 281 | |
282 | +#define float32_zero make_float32(0) | |
283 | + | |
259 | 284 | /*---------------------------------------------------------------------------- |
260 | 285 | | Software IEC/IEEE double-precision conversion routines. |
261 | 286 | *----------------------------------------------------------------------------*/ |
... | ... | @@ -300,14 +325,16 @@ float64 float64_scalbn( float64, int STATUS_PARAM ); |
300 | 325 | |
301 | 326 | INLINE float64 float64_abs(float64 a) |
302 | 327 | { |
303 | - return a & 0x7fffffffffffffffLL; | |
328 | + return make_float64(float64_val(a) & 0x7fffffffffffffffLL); | |
304 | 329 | } |
305 | 330 | |
306 | 331 | INLINE float64 float64_chs(float64 a) |
307 | 332 | { |
308 | - return a ^ 0x8000000000000000LL; | |
333 | + return make_float64(float64_val(a) ^ 0x8000000000000000LL); | |
309 | 334 | } |
310 | 335 | |
336 | +#define float64_zero make_float64(0) | |
337 | + | |
311 | 338 | #ifdef FLOATX80 |
312 | 339 | |
313 | 340 | /*---------------------------------------------------------------------------- | ... | ... |
target-arm/nwfpe/double_cpdo.c
... | ... | @@ -38,7 +38,7 @@ float64 float64_pol(float64 rFn,float64 rFm); |
38 | 38 | unsigned int DoubleCPDO(const unsigned int opcode) |
39 | 39 | { |
40 | 40 | FPA11 *fpa11 = GET_FPA11(); |
41 | - float64 rFm, rFn = 0; | |
41 | + float64 rFm, rFn = float64_zero; | |
42 | 42 | unsigned int Fd, Fm, Fn, nRc = 1; |
43 | 43 | |
44 | 44 | //printk("DoubleCPDO(0x%08x)\n",opcode); | ... | ... |
target-arm/nwfpe/single_cpdo.c
... | ... | @@ -38,7 +38,7 @@ float32 float32_pol(float32 rFn,float32 rFm); |
38 | 38 | unsigned int SingleCPDO(const unsigned int opcode) |
39 | 39 | { |
40 | 40 | FPA11 *fpa11 = GET_FPA11(); |
41 | - float32 rFm, rFn = 0; | |
41 | + float32 rFm, rFn = float32_zero; | |
42 | 42 | unsigned int Fd, Fm, Fn, nRc = 1; |
43 | 43 | |
44 | 44 | Fm = getFm(opcode); |
... | ... | @@ -128,13 +128,11 @@ unsigned int SingleCPDO(const unsigned int opcode) |
128 | 128 | break; |
129 | 129 | |
130 | 130 | case MNF_CODE: |
131 | - rFm ^= 0x80000000; | |
132 | - fpa11->fpreg[Fd].fSingle = rFm; | |
131 | + fpa11->fpreg[Fd].fSingle = float32_chs(rFm); | |
133 | 132 | break; |
134 | 133 | |
135 | 134 | case ABS_CODE: |
136 | - rFm &= 0x7fffffff; | |
137 | - fpa11->fpreg[Fd].fSingle = rFm; | |
135 | + fpa11->fpreg[Fd].fSingle = float32_abs(rFm); | |
138 | 136 | break; |
139 | 137 | |
140 | 138 | case RND_CODE: | ... | ... |
target-m68k/helper.c
... | ... | @@ -255,7 +255,7 @@ float64 helper_sub_cmpf64(CPUM68KState *env, float64 src0, float64 src1) |
255 | 255 | /* +/-inf compares equal against itself, but sub returns nan. */ |
256 | 256 | if (!float64_is_nan(src0) |
257 | 257 | && !float64_is_nan(src1)) { |
258 | - res = 0; | |
258 | + res = float64_zero; | |
259 | 259 | if (float64_lt_quiet(src0, res, &env->fp_status)) |
260 | 260 | res = float64_chs(res); |
261 | 261 | } | ... | ... |
target-m68k/op.c
target-mips/op_helper.c
... | ... | @@ -624,10 +624,10 @@ void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec, |
624 | 624 | |
625 | 625 | /* Complex FPU operations which may need stack space. */ |
626 | 626 | |
627 | -#define FLOAT_ONE32 (0x3f8 << 20) | |
628 | -#define FLOAT_ONE64 (0x3ffULL << 52) | |
629 | -#define FLOAT_TWO32 (1 << 30) | |
630 | -#define FLOAT_TWO64 (1ULL << 62) | |
627 | +#define FLOAT_ONE32 make_float32(0x3f8 << 20) | |
628 | +#define FLOAT_ONE64 make_float64(0x3ffULL << 52) | |
629 | +#define FLOAT_TWO32 make_float32(1 << 30) | |
630 | +#define FLOAT_TWO64 make_float64(1ULL << 62) | |
631 | 631 | #define FLOAT_QNAN32 0x7fbfffff |
632 | 632 | #define FLOAT_QNAN64 0x7ff7ffffffffffffULL |
633 | 633 | #define FLOAT_SNAN32 0x7fffffff | ... | ... |