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,9 +66,9 @@ typedef struct { | ||
66 | | The pattern for a default generated single-precision NaN. | 66 | | The pattern for a default generated single-precision NaN. |
67 | *----------------------------------------------------------------------------*/ | 67 | *----------------------------------------------------------------------------*/ |
68 | #if SNAN_BIT_IS_ONE | 68 | #if SNAN_BIT_IS_ONE |
69 | -#define float32_default_nan 0x7FBFFFFF | 69 | +#define float32_default_nan make_float32(0x7FBFFFFF) |
70 | #else | 70 | #else |
71 | -#define float32_default_nan 0xFFC00000 | 71 | +#define float32_default_nan make_float32(0xFFC00000) |
72 | #endif | 72 | #endif |
73 | 73 | ||
74 | /*---------------------------------------------------------------------------- | 74 | /*---------------------------------------------------------------------------- |
@@ -76,8 +76,9 @@ typedef struct { | @@ -76,8 +76,9 @@ typedef struct { | ||
76 | | NaN; otherwise returns 0. | 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 | #if SNAN_BIT_IS_ONE | 82 | #if SNAN_BIT_IS_ONE |
82 | return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); | 83 | return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); |
83 | #else | 84 | #else |
@@ -90,8 +91,9 @@ int float32_is_nan( float32 a ) | @@ -90,8 +91,9 @@ int float32_is_nan( float32 a ) | ||
90 | | NaN; otherwise returns 0. | 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 | #if SNAN_BIT_IS_ONE | 97 | #if SNAN_BIT_IS_ONE |
96 | return ( 0xFF800000 <= (bits32) ( a<<1 ) ); | 98 | return ( 0xFF800000 <= (bits32) ( a<<1 ) ); |
97 | #else | 99 | #else |
@@ -110,9 +112,9 @@ static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM ) | @@ -110,9 +112,9 @@ static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM ) | ||
110 | commonNaNT z; | 112 | commonNaNT z; |
111 | 113 | ||
112 | if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR ); | 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 | z.low = 0; | 116 | z.low = 0; |
115 | - z.high = ( (bits64) a )<<41; | 117 | + z.high = ( (bits64) float32_val(a) )<<41; |
116 | return z; | 118 | return z; |
117 | } | 119 | } |
118 | 120 | ||
@@ -123,7 +125,8 @@ static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM ) | @@ -123,7 +125,8 @@ static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM ) | ||
123 | 125 | ||
124 | static float32 commonNaNToFloat32( commonNaNT a ) | 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,42 +138,52 @@ static float32 commonNaNToFloat32( commonNaNT a ) | ||
135 | static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM) | 138 | static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM) |
136 | { | 139 | { |
137 | flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; | 140 | flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; |
141 | + bits32 av, bv, res; | ||
138 | 142 | ||
139 | aIsNaN = float32_is_nan( a ); | 143 | aIsNaN = float32_is_nan( a ); |
140 | aIsSignalingNaN = float32_is_signaling_nan( a ); | 144 | aIsSignalingNaN = float32_is_signaling_nan( a ); |
141 | bIsNaN = float32_is_nan( b ); | 145 | bIsNaN = float32_is_nan( b ); |
142 | bIsSignalingNaN = float32_is_signaling_nan( b ); | 146 | bIsSignalingNaN = float32_is_signaling_nan( b ); |
147 | + av = float32_val(a); | ||
148 | + bv = float32_val(b); | ||
143 | #if SNAN_BIT_IS_ONE | 149 | #if SNAN_BIT_IS_ONE |
144 | - a &= ~0x00400000; | ||
145 | - b &= ~0x00400000; | 150 | + av &= ~0x00400000; |
151 | + bv &= ~0x00400000; | ||
146 | #else | 152 | #else |
147 | - a |= 0x00400000; | ||
148 | - b |= 0x00400000; | 153 | + av |= 0x00400000; |
154 | + bv |= 0x00400000; | ||
149 | #endif | 155 | #endif |
150 | if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR); | 156 | if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR); |
151 | if ( aIsSignalingNaN ) { | 157 | if ( aIsSignalingNaN ) { |
152 | if ( bIsSignalingNaN ) goto returnLargerSignificand; | 158 | if ( bIsSignalingNaN ) goto returnLargerSignificand; |
153 | - return bIsNaN ? b : a; | 159 | + res = bIsNaN ? bv : av; |
154 | } | 160 | } |
155 | else if ( aIsNaN ) { | 161 | else if ( aIsNaN ) { |
156 | - if ( bIsSignalingNaN | ! bIsNaN ) return a; | 162 | + if ( bIsSignalingNaN | ! bIsNaN ) |
163 | + res = av; | ||
164 | + else { | ||
157 | returnLargerSignificand: | 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 | else { | 174 | else { |
163 | - return b; | 175 | + res = bv; |
164 | } | 176 | } |
177 | + return make_float32(res); | ||
165 | } | 178 | } |
166 | 179 | ||
167 | /*---------------------------------------------------------------------------- | 180 | /*---------------------------------------------------------------------------- |
168 | | The pattern for a default generated double-precision NaN. | 181 | | The pattern for a default generated double-precision NaN. |
169 | *----------------------------------------------------------------------------*/ | 182 | *----------------------------------------------------------------------------*/ |
170 | #if SNAN_BIT_IS_ONE | 183 | #if SNAN_BIT_IS_ONE |
171 | -#define float64_default_nan LIT64( 0x7FF7FFFFFFFFFFFF ) | 184 | +#define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF )) |
172 | #else | 185 | #else |
173 | -#define float64_default_nan LIT64( 0xFFF8000000000000 ) | 186 | +#define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 )) |
174 | #endif | 187 | #endif |
175 | 188 | ||
176 | /*---------------------------------------------------------------------------- | 189 | /*---------------------------------------------------------------------------- |
@@ -178,8 +191,9 @@ static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM) | @@ -178,8 +191,9 @@ static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM) | ||
178 | | NaN; otherwise returns 0. | 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 | #if SNAN_BIT_IS_ONE | 197 | #if SNAN_BIT_IS_ONE |
184 | return | 198 | return |
185 | ( ( ( a>>51 ) & 0xFFF ) == 0xFFE ) | 199 | ( ( ( a>>51 ) & 0xFFF ) == 0xFFE ) |
@@ -194,8 +208,9 @@ int float64_is_nan( float64 a ) | @@ -194,8 +208,9 @@ int float64_is_nan( float64 a ) | ||
194 | | NaN; otherwise returns 0. | 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 | #if SNAN_BIT_IS_ONE | 214 | #if SNAN_BIT_IS_ONE |
200 | return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) ); | 215 | return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) ); |
201 | #else | 216 | #else |
@@ -216,9 +231,9 @@ static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM) | @@ -216,9 +231,9 @@ static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM) | ||
216 | commonNaNT z; | 231 | commonNaNT z; |
217 | 232 | ||
218 | if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR); | 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 | z.low = 0; | 235 | z.low = 0; |
221 | - z.high = a<<12; | 236 | + z.high = float64_val(a)<<12; |
222 | return z; | 237 | return z; |
223 | } | 238 | } |
224 | 239 | ||
@@ -229,10 +244,10 @@ static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM) | @@ -229,10 +244,10 @@ static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM) | ||
229 | 244 | ||
230 | static float64 commonNaNToFloat64( commonNaNT a ) | 245 | static float64 commonNaNToFloat64( commonNaNT a ) |
231 | { | 246 | { |
232 | - return | 247 | + return make_float64( |
233 | ( ( (bits64) a.sign )<<63 ) | 248 | ( ( (bits64) a.sign )<<63 ) |
234 | | LIT64( 0x7FF8000000000000 ) | 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,33 +259,43 @@ static float64 commonNaNToFloat64( commonNaNT a ) | ||
244 | static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM) | 259 | static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM) |
245 | { | 260 | { |
246 | flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; | 261 | flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; |
262 | + bits64 av, bv, res; | ||
247 | 263 | ||
248 | aIsNaN = float64_is_nan( a ); | 264 | aIsNaN = float64_is_nan( a ); |
249 | aIsSignalingNaN = float64_is_signaling_nan( a ); | 265 | aIsSignalingNaN = float64_is_signaling_nan( a ); |
250 | bIsNaN = float64_is_nan( b ); | 266 | bIsNaN = float64_is_nan( b ); |
251 | bIsSignalingNaN = float64_is_signaling_nan( b ); | 267 | bIsSignalingNaN = float64_is_signaling_nan( b ); |
268 | + av = float64_val(a); | ||
269 | + bv = float64_val(b); | ||
252 | #if SNAN_BIT_IS_ONE | 270 | #if SNAN_BIT_IS_ONE |
253 | - a &= ~LIT64( 0x0008000000000000 ); | ||
254 | - b &= ~LIT64( 0x0008000000000000 ); | 271 | + av &= ~LIT64( 0x0008000000000000 ); |
272 | + bv &= ~LIT64( 0x0008000000000000 ); | ||
255 | #else | 273 | #else |
256 | - a |= LIT64( 0x0008000000000000 ); | ||
257 | - b |= LIT64( 0x0008000000000000 ); | 274 | + av |= LIT64( 0x0008000000000000 ); |
275 | + bv |= LIT64( 0x0008000000000000 ); | ||
258 | #endif | 276 | #endif |
259 | if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR); | 277 | if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR); |
260 | if ( aIsSignalingNaN ) { | 278 | if ( aIsSignalingNaN ) { |
261 | if ( bIsSignalingNaN ) goto returnLargerSignificand; | 279 | if ( bIsSignalingNaN ) goto returnLargerSignificand; |
262 | - return bIsNaN ? b : a; | 280 | + res = bIsNaN ? bv : av; |
263 | } | 281 | } |
264 | else if ( aIsNaN ) { | 282 | else if ( aIsNaN ) { |
265 | - if ( bIsSignalingNaN | ! bIsNaN ) return a; | 283 | + if ( bIsSignalingNaN | ! bIsNaN ) |
284 | + res = av; | ||
285 | + else { | ||
266 | returnLargerSignificand: | 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 | else { | 295 | else { |
272 | - return b; | 296 | + res = bv; |
273 | } | 297 | } |
298 | + return make_float64(res); | ||
274 | } | 299 | } |
275 | 300 | ||
276 | #ifdef FLOATX80 | 301 | #ifdef FLOATX80 |
fpu/softfloat.c
@@ -175,7 +175,7 @@ static int64 roundAndPackInt64( flag zSign, bits64 absZ0, bits64 absZ1 STATUS_PA | @@ -175,7 +175,7 @@ static int64 roundAndPackInt64( flag zSign, bits64 absZ0, bits64 absZ1 STATUS_PA | ||
175 | INLINE bits32 extractFloat32Frac( float32 a ) | 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,7 +186,7 @@ INLINE bits32 extractFloat32Frac( float32 a ) | ||
186 | INLINE int16 extractFloat32Exp( float32 a ) | 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,7 +197,7 @@ INLINE int16 extractFloat32Exp( float32 a ) | ||
197 | INLINE flag extractFloat32Sign( float32 a ) | 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,7 +233,8 @@ static void | ||
233 | INLINE float32 packFloat32( flag zSign, int16 zExp, bits32 zSig ) | 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,7 +291,7 @@ static float32 roundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig STATUS_P | ||
290 | && ( (sbits32) ( zSig + roundIncrement ) < 0 ) ) | 291 | && ( (sbits32) ( zSig + roundIncrement ) < 0 ) ) |
291 | ) { | 292 | ) { |
292 | float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR); | 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 | if ( zExp < 0 ) { | 296 | if ( zExp < 0 ) { |
296 | isTiny = | 297 | isTiny = |
@@ -337,7 +338,7 @@ static float32 | @@ -337,7 +338,7 @@ static float32 | ||
337 | INLINE bits64 extractFloat64Frac( float64 a ) | 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,7 +349,7 @@ INLINE bits64 extractFloat64Frac( float64 a ) | ||
348 | INLINE int16 extractFloat64Exp( float64 a ) | 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,7 +360,7 @@ INLINE int16 extractFloat64Exp( float64 a ) | ||
359 | INLINE flag extractFloat64Sign( float64 a ) | 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,7 +396,8 @@ static void | ||
395 | INLINE float64 packFloat64( flag zSign, int16 zExp, bits64 zSig ) | 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,7 +454,7 @@ static float64 roundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig STATUS_P | ||
452 | && ( (sbits64) ( zSig + roundIncrement ) < 0 ) ) | 454 | && ( (sbits64) ( zSig + roundIncrement ) < 0 ) ) |
453 | ) { | 455 | ) { |
454 | float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR); | 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 | if ( zExp < 0 ) { | 459 | if ( zExp < 0 ) { |
458 | isTiny = | 460 | isTiny = |
@@ -1050,7 +1052,7 @@ float32 int32_to_float32( int32 a STATUS_PARAM ) | @@ -1050,7 +1052,7 @@ float32 int32_to_float32( int32 a STATUS_PARAM ) | ||
1050 | { | 1052 | { |
1051 | flag zSign; | 1053 | flag zSign; |
1052 | 1054 | ||
1053 | - if ( a == 0 ) return 0; | 1055 | + if ( a == 0 ) return float32_zero; |
1054 | if ( a == (sbits32) 0x80000000 ) return packFloat32( 1, 0x9E, 0 ); | 1056 | if ( a == (sbits32) 0x80000000 ) return packFloat32( 1, 0x9E, 0 ); |
1055 | zSign = ( a < 0 ); | 1057 | zSign = ( a < 0 ); |
1056 | return normalizeRoundAndPackFloat32( zSign, 0x9C, zSign ? - a : a STATUS_VAR ); | 1058 | return normalizeRoundAndPackFloat32( zSign, 0x9C, zSign ? - a : a STATUS_VAR ); |
@@ -1070,7 +1072,7 @@ float64 int32_to_float64( int32 a STATUS_PARAM ) | @@ -1070,7 +1072,7 @@ float64 int32_to_float64( int32 a STATUS_PARAM ) | ||
1070 | int8 shiftCount; | 1072 | int8 shiftCount; |
1071 | bits64 zSig; | 1073 | bits64 zSig; |
1072 | 1074 | ||
1073 | - if ( a == 0 ) return 0; | 1075 | + if ( a == 0 ) return float64_zero; |
1074 | zSign = ( a < 0 ); | 1076 | zSign = ( a < 0 ); |
1075 | absA = zSign ? - a : a; | 1077 | absA = zSign ? - a : a; |
1076 | shiftCount = countLeadingZeros32( absA ) + 21; | 1078 | shiftCount = countLeadingZeros32( absA ) + 21; |
@@ -1144,7 +1146,7 @@ float32 int64_to_float32( int64 a STATUS_PARAM ) | @@ -1144,7 +1146,7 @@ float32 int64_to_float32( int64 a STATUS_PARAM ) | ||
1144 | uint64 absA; | 1146 | uint64 absA; |
1145 | int8 shiftCount; | 1147 | int8 shiftCount; |
1146 | 1148 | ||
1147 | - if ( a == 0 ) return 0; | 1149 | + if ( a == 0 ) return float32_zero; |
1148 | zSign = ( a < 0 ); | 1150 | zSign = ( a < 0 ); |
1149 | absA = zSign ? - a : a; | 1151 | absA = zSign ? - a : a; |
1150 | shiftCount = countLeadingZeros64( absA ) - 40; | 1152 | shiftCount = countLeadingZeros64( absA ) - 40; |
@@ -1168,7 +1170,7 @@ float32 uint64_to_float32( uint64 a STATUS_PARAM ) | @@ -1168,7 +1170,7 @@ float32 uint64_to_float32( uint64 a STATUS_PARAM ) | ||
1168 | { | 1170 | { |
1169 | int8 shiftCount; | 1171 | int8 shiftCount; |
1170 | 1172 | ||
1171 | - if ( a == 0 ) return 0; | 1173 | + if ( a == 0 ) return float32_zero; |
1172 | shiftCount = countLeadingZeros64( a ) - 40; | 1174 | shiftCount = countLeadingZeros64( a ) - 40; |
1173 | if ( 0 <= shiftCount ) { | 1175 | if ( 0 <= shiftCount ) { |
1174 | return packFloat32( 1 > 0, 0x95 - shiftCount, a<<shiftCount ); | 1176 | return packFloat32( 1 > 0, 0x95 - shiftCount, a<<shiftCount ); |
@@ -1195,7 +1197,7 @@ float64 int64_to_float64( int64 a STATUS_PARAM ) | @@ -1195,7 +1197,7 @@ float64 int64_to_float64( int64 a STATUS_PARAM ) | ||
1195 | { | 1197 | { |
1196 | flag zSign; | 1198 | flag zSign; |
1197 | 1199 | ||
1198 | - if ( a == 0 ) return 0; | 1200 | + if ( a == 0 ) return float64_zero; |
1199 | if ( a == (sbits64) LIT64( 0x8000000000000000 ) ) { | 1201 | if ( a == (sbits64) LIT64( 0x8000000000000000 ) ) { |
1200 | return packFloat64( 1, 0x43E, 0 ); | 1202 | return packFloat64( 1, 0x43E, 0 ); |
1201 | } | 1203 | } |
@@ -1206,7 +1208,7 @@ float64 int64_to_float64( int64 a STATUS_PARAM ) | @@ -1206,7 +1208,7 @@ float64 int64_to_float64( int64 a STATUS_PARAM ) | ||
1206 | 1208 | ||
1207 | float64 uint64_to_float64( uint64 a STATUS_PARAM ) | 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 | return normalizeRoundAndPackFloat64( 0, 0x43C, a STATUS_VAR ); | 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,7 +1327,7 @@ int32 float32_to_int32_round_to_zero( float32 a STATUS_PARAM ) | ||
1325 | aSign = extractFloat32Sign( a ); | 1327 | aSign = extractFloat32Sign( a ); |
1326 | shiftCount = aExp - 0x9E; | 1328 | shiftCount = aExp - 0x9E; |
1327 | if ( 0 <= shiftCount ) { | 1329 | if ( 0 <= shiftCount ) { |
1328 | - if ( a != 0xCF000000 ) { | 1330 | + if ( float32_val(a) != 0xCF000000 ) { |
1329 | float_raise( float_flag_invalid STATUS_VAR); | 1331 | float_raise( float_flag_invalid STATUS_VAR); |
1330 | if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) return 0x7FFFFFFF; | 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,7 +1406,7 @@ int64 float32_to_int64_round_to_zero( float32 a STATUS_PARAM ) | ||
1404 | aSign = extractFloat32Sign( a ); | 1406 | aSign = extractFloat32Sign( a ); |
1405 | shiftCount = aExp - 0xBE; | 1407 | shiftCount = aExp - 0xBE; |
1406 | if ( 0 <= shiftCount ) { | 1408 | if ( 0 <= shiftCount ) { |
1407 | - if ( a != 0xDF000000 ) { | 1409 | + if ( float32_val(a) != 0xDF000000 ) { |
1408 | float_raise( float_flag_invalid STATUS_VAR); | 1410 | float_raise( float_flag_invalid STATUS_VAR); |
1409 | if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) { | 1411 | if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) { |
1410 | return LIT64( 0x7FFFFFFFFFFFFFFF ); | 1412 | return LIT64( 0x7FFFFFFFFFFFFFFF ); |
@@ -1535,7 +1537,7 @@ float32 float32_round_to_int( float32 a STATUS_PARAM) | @@ -1535,7 +1537,7 @@ float32 float32_round_to_int( float32 a STATUS_PARAM) | ||
1535 | int16 aExp; | 1537 | int16 aExp; |
1536 | bits32 lastBitMask, roundBitsMask; | 1538 | bits32 lastBitMask, roundBitsMask; |
1537 | int8 roundingMode; | 1539 | int8 roundingMode; |
1538 | - float32 z; | 1540 | + bits32 z; |
1539 | 1541 | ||
1540 | aExp = extractFloat32Exp( a ); | 1542 | aExp = extractFloat32Exp( a ); |
1541 | if ( 0x96 <= aExp ) { | 1543 | if ( 0x96 <= aExp ) { |
@@ -1545,7 +1547,7 @@ float32 float32_round_to_int( float32 a STATUS_PARAM) | @@ -1545,7 +1547,7 @@ float32 float32_round_to_int( float32 a STATUS_PARAM) | ||
1545 | return a; | 1547 | return a; |
1546 | } | 1548 | } |
1547 | if ( aExp <= 0x7E ) { | 1549 | if ( aExp <= 0x7E ) { |
1548 | - if ( (bits32) ( a<<1 ) == 0 ) return a; | 1550 | + if ( (bits32) ( float32_val(a)<<1 ) == 0 ) return a; |
1549 | STATUS(float_exception_flags) |= float_flag_inexact; | 1551 | STATUS(float_exception_flags) |= float_flag_inexact; |
1550 | aSign = extractFloat32Sign( a ); | 1552 | aSign = extractFloat32Sign( a ); |
1551 | switch ( STATUS(float_rounding_mode) ) { | 1553 | switch ( STATUS(float_rounding_mode) ) { |
@@ -1555,29 +1557,29 @@ float32 float32_round_to_int( float32 a STATUS_PARAM) | @@ -1555,29 +1557,29 @@ float32 float32_round_to_int( float32 a STATUS_PARAM) | ||
1555 | } | 1557 | } |
1556 | break; | 1558 | break; |
1557 | case float_round_down: | 1559 | case float_round_down: |
1558 | - return aSign ? 0xBF800000 : 0; | 1560 | + return make_float32(aSign ? 0xBF800000 : 0); |
1559 | case float_round_up: | 1561 | case float_round_up: |
1560 | - return aSign ? 0x80000000 : 0x3F800000; | 1562 | + return make_float32(aSign ? 0x80000000 : 0x3F800000); |
1561 | } | 1563 | } |
1562 | return packFloat32( aSign, 0, 0 ); | 1564 | return packFloat32( aSign, 0, 0 ); |
1563 | } | 1565 | } |
1564 | lastBitMask = 1; | 1566 | lastBitMask = 1; |
1565 | lastBitMask <<= 0x96 - aExp; | 1567 | lastBitMask <<= 0x96 - aExp; |
1566 | roundBitsMask = lastBitMask - 1; | 1568 | roundBitsMask = lastBitMask - 1; |
1567 | - z = a; | 1569 | + z = float32_val(a); |
1568 | roundingMode = STATUS(float_rounding_mode); | 1570 | roundingMode = STATUS(float_rounding_mode); |
1569 | if ( roundingMode == float_round_nearest_even ) { | 1571 | if ( roundingMode == float_round_nearest_even ) { |
1570 | z += lastBitMask>>1; | 1572 | z += lastBitMask>>1; |
1571 | if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask; | 1573 | if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask; |
1572 | } | 1574 | } |
1573 | else if ( roundingMode != float_round_to_zero ) { | 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 | z += roundBitsMask; | 1577 | z += roundBitsMask; |
1576 | } | 1578 | } |
1577 | } | 1579 | } |
1578 | z &= ~ roundBitsMask; | 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,7 +2010,7 @@ float32 float32_sqrt( float32 a STATUS_PARAM ) | ||
2008 | aExp = extractFloat32Exp( a ); | 2010 | aExp = extractFloat32Exp( a ); |
2009 | aSign = extractFloat32Sign( a ); | 2011 | aSign = extractFloat32Sign( a ); |
2010 | if ( aExp == 0xFF ) { | 2012 | if ( aExp == 0xFF ) { |
2011 | - if ( aSig ) return propagateFloat32NaN( a, 0 STATUS_VAR ); | 2013 | + if ( aSig ) return propagateFloat32NaN( a, float32_zero STATUS_VAR ); |
2012 | if ( ! aSign ) return a; | 2014 | if ( ! aSign ) return a; |
2013 | float_raise( float_flag_invalid STATUS_VAR); | 2015 | float_raise( float_flag_invalid STATUS_VAR); |
2014 | return float32_default_nan; | 2016 | return float32_default_nan; |
@@ -2019,7 +2021,7 @@ float32 float32_sqrt( float32 a STATUS_PARAM ) | @@ -2019,7 +2021,7 @@ float32 float32_sqrt( float32 a STATUS_PARAM ) | ||
2019 | return float32_default_nan; | 2021 | return float32_default_nan; |
2020 | } | 2022 | } |
2021 | if ( aExp == 0 ) { | 2023 | if ( aExp == 0 ) { |
2022 | - if ( aSig == 0 ) return 0; | 2024 | + if ( aSig == 0 ) return float32_zero; |
2023 | normalizeFloat32Subnormal( aSig, &aExp, &aSig ); | 2025 | normalizeFloat32Subnormal( aSig, &aExp, &aSig ); |
2024 | } | 2026 | } |
2025 | zExp = ( ( aExp - 0x7F )>>1 ) + 0x7E; | 2027 | zExp = ( ( aExp - 0x7F )>>1 ) + 0x7E; |
@@ -2062,7 +2064,8 @@ int float32_eq( float32 a, float32 b STATUS_PARAM ) | @@ -2062,7 +2064,8 @@ int float32_eq( float32 a, float32 b STATUS_PARAM ) | ||
2062 | } | 2064 | } |
2063 | return 0; | 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,6 +2079,7 @@ int float32_eq( float32 a, float32 b STATUS_PARAM ) | ||
2076 | int float32_le( float32 a, float32 b STATUS_PARAM ) | 2079 | int float32_le( float32 a, float32 b STATUS_PARAM ) |
2077 | { | 2080 | { |
2078 | flag aSign, bSign; | 2081 | flag aSign, bSign; |
2082 | + bits32 av, bv; | ||
2079 | 2083 | ||
2080 | if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) | 2084 | if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) |
2081 | || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) | 2085 | || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) |
@@ -2085,8 +2089,10 @@ int float32_le( float32 a, float32 b STATUS_PARAM ) | @@ -2085,8 +2089,10 @@ int float32_le( float32 a, float32 b STATUS_PARAM ) | ||
2085 | } | 2089 | } |
2086 | aSign = extractFloat32Sign( a ); | 2090 | aSign = extractFloat32Sign( a ); |
2087 | bSign = extractFloat32Sign( b ); | 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,6 +2105,7 @@ int float32_le( float32 a, float32 b STATUS_PARAM ) | ||
2099 | int float32_lt( float32 a, float32 b STATUS_PARAM ) | 2105 | int float32_lt( float32 a, float32 b STATUS_PARAM ) |
2100 | { | 2106 | { |
2101 | flag aSign, bSign; | 2107 | flag aSign, bSign; |
2108 | + bits32 av, bv; | ||
2102 | 2109 | ||
2103 | if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) | 2110 | if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) |
2104 | || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) | 2111 | || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) |
@@ -2108,8 +2115,10 @@ int float32_lt( float32 a, float32 b STATUS_PARAM ) | @@ -2108,8 +2115,10 @@ int float32_lt( float32 a, float32 b STATUS_PARAM ) | ||
2108 | } | 2115 | } |
2109 | aSign = extractFloat32Sign( a ); | 2116 | aSign = extractFloat32Sign( a ); |
2110 | bSign = extractFloat32Sign( b ); | 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,6 +2131,7 @@ int float32_lt( float32 a, float32 b STATUS_PARAM ) | ||
2122 | 2131 | ||
2123 | int float32_eq_signaling( float32 a, float32 b STATUS_PARAM ) | 2132 | int float32_eq_signaling( float32 a, float32 b STATUS_PARAM ) |
2124 | { | 2133 | { |
2134 | + bits32 av, bv; | ||
2125 | 2135 | ||
2126 | if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) | 2136 | if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) |
2127 | || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) | 2137 | || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) |
@@ -2129,7 +2139,9 @@ int float32_eq_signaling( float32 a, float32 b STATUS_PARAM ) | @@ -2129,7 +2139,9 @@ int float32_eq_signaling( float32 a, float32 b STATUS_PARAM ) | ||
2129 | float_raise( float_flag_invalid STATUS_VAR); | 2139 | float_raise( float_flag_invalid STATUS_VAR); |
2130 | return 0; | 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,6 +2155,7 @@ int float32_eq_signaling( float32 a, float32 b STATUS_PARAM ) | ||
2143 | int float32_le_quiet( float32 a, float32 b STATUS_PARAM ) | 2155 | int float32_le_quiet( float32 a, float32 b STATUS_PARAM ) |
2144 | { | 2156 | { |
2145 | flag aSign, bSign; | 2157 | flag aSign, bSign; |
2158 | + bits32 av, bv; | ||
2146 | 2159 | ||
2147 | if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) | 2160 | if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) |
2148 | || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) | 2161 | || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) |
@@ -2154,8 +2167,10 @@ int float32_le_quiet( float32 a, float32 b STATUS_PARAM ) | @@ -2154,8 +2167,10 @@ int float32_le_quiet( float32 a, float32 b STATUS_PARAM ) | ||
2154 | } | 2167 | } |
2155 | aSign = extractFloat32Sign( a ); | 2168 | aSign = extractFloat32Sign( a ); |
2156 | bSign = extractFloat32Sign( b ); | 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,6 +2184,7 @@ int float32_le_quiet( float32 a, float32 b STATUS_PARAM ) | ||
2169 | int float32_lt_quiet( float32 a, float32 b STATUS_PARAM ) | 2184 | int float32_lt_quiet( float32 a, float32 b STATUS_PARAM ) |
2170 | { | 2185 | { |
2171 | flag aSign, bSign; | 2186 | flag aSign, bSign; |
2187 | + bits32 av, bv; | ||
2172 | 2188 | ||
2173 | if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) | 2189 | if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) |
2174 | || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) | 2190 | || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) |
@@ -2180,8 +2196,10 @@ int float32_lt_quiet( float32 a, float32 b STATUS_PARAM ) | @@ -2180,8 +2196,10 @@ int float32_lt_quiet( float32 a, float32 b STATUS_PARAM ) | ||
2180 | } | 2196 | } |
2181 | aSign = extractFloat32Sign( a ); | 2197 | aSign = extractFloat32Sign( a ); |
2182 | bSign = extractFloat32Sign( b ); | 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,7 +2342,7 @@ int64 float64_to_int64_round_to_zero( float64 a STATUS_PARAM ) | ||
2324 | shiftCount = aExp - 0x433; | 2342 | shiftCount = aExp - 0x433; |
2325 | if ( 0 <= shiftCount ) { | 2343 | if ( 0 <= shiftCount ) { |
2326 | if ( 0x43E <= aExp ) { | 2344 | if ( 0x43E <= aExp ) { |
2327 | - if ( a != LIT64( 0xC3E0000000000000 ) ) { | 2345 | + if ( float64_val(a) != LIT64( 0xC3E0000000000000 ) ) { |
2328 | float_raise( float_flag_invalid STATUS_VAR); | 2346 | float_raise( float_flag_invalid STATUS_VAR); |
2329 | if ( ! aSign | 2347 | if ( ! aSign |
2330 | || ( ( aExp == 0x7FF ) | 2348 | || ( ( aExp == 0x7FF ) |
@@ -2464,7 +2482,7 @@ float64 float64_round_to_int( float64 a STATUS_PARAM ) | @@ -2464,7 +2482,7 @@ float64 float64_round_to_int( float64 a STATUS_PARAM ) | ||
2464 | int16 aExp; | 2482 | int16 aExp; |
2465 | bits64 lastBitMask, roundBitsMask; | 2483 | bits64 lastBitMask, roundBitsMask; |
2466 | int8 roundingMode; | 2484 | int8 roundingMode; |
2467 | - float64 z; | 2485 | + bits64 z; |
2468 | 2486 | ||
2469 | aExp = extractFloat64Exp( a ); | 2487 | aExp = extractFloat64Exp( a ); |
2470 | if ( 0x433 <= aExp ) { | 2488 | if ( 0x433 <= aExp ) { |
@@ -2474,7 +2492,7 @@ float64 float64_round_to_int( float64 a STATUS_PARAM ) | @@ -2474,7 +2492,7 @@ float64 float64_round_to_int( float64 a STATUS_PARAM ) | ||
2474 | return a; | 2492 | return a; |
2475 | } | 2493 | } |
2476 | if ( aExp < 0x3FF ) { | 2494 | if ( aExp < 0x3FF ) { |
2477 | - if ( (bits64) ( a<<1 ) == 0 ) return a; | 2495 | + if ( (bits64) ( float64_val(a)<<1 ) == 0 ) return a; |
2478 | STATUS(float_exception_flags) |= float_flag_inexact; | 2496 | STATUS(float_exception_flags) |= float_flag_inexact; |
2479 | aSign = extractFloat64Sign( a ); | 2497 | aSign = extractFloat64Sign( a ); |
2480 | switch ( STATUS(float_rounding_mode) ) { | 2498 | switch ( STATUS(float_rounding_mode) ) { |
@@ -2484,30 +2502,31 @@ float64 float64_round_to_int( float64 a STATUS_PARAM ) | @@ -2484,30 +2502,31 @@ float64 float64_round_to_int( float64 a STATUS_PARAM ) | ||
2484 | } | 2502 | } |
2485 | break; | 2503 | break; |
2486 | case float_round_down: | 2504 | case float_round_down: |
2487 | - return aSign ? LIT64( 0xBFF0000000000000 ) : 0; | 2505 | + return make_float64(aSign ? LIT64( 0xBFF0000000000000 ) : 0); |
2488 | case float_round_up: | 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 | return packFloat64( aSign, 0, 0 ); | 2510 | return packFloat64( aSign, 0, 0 ); |
2493 | } | 2511 | } |
2494 | lastBitMask = 1; | 2512 | lastBitMask = 1; |
2495 | lastBitMask <<= 0x433 - aExp; | 2513 | lastBitMask <<= 0x433 - aExp; |
2496 | roundBitsMask = lastBitMask - 1; | 2514 | roundBitsMask = lastBitMask - 1; |
2497 | - z = a; | 2515 | + z = float64_val(a); |
2498 | roundingMode = STATUS(float_rounding_mode); | 2516 | roundingMode = STATUS(float_rounding_mode); |
2499 | if ( roundingMode == float_round_nearest_even ) { | 2517 | if ( roundingMode == float_round_nearest_even ) { |
2500 | z += lastBitMask>>1; | 2518 | z += lastBitMask>>1; |
2501 | if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask; | 2519 | if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask; |
2502 | } | 2520 | } |
2503 | else if ( roundingMode != float_round_to_zero ) { | 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 | z += roundBitsMask; | 2523 | z += roundBitsMask; |
2506 | } | 2524 | } |
2507 | } | 2525 | } |
2508 | z &= ~ roundBitsMask; | 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,7 +2970,7 @@ float64 float64_sqrt( float64 a STATUS_PARAM ) | ||
2951 | return float64_default_nan; | 2970 | return float64_default_nan; |
2952 | } | 2971 | } |
2953 | if ( aExp == 0 ) { | 2972 | if ( aExp == 0 ) { |
2954 | - if ( aSig == 0 ) return 0; | 2973 | + if ( aSig == 0 ) return float64_zero; |
2955 | normalizeFloat64Subnormal( aSig, &aExp, &aSig ); | 2974 | normalizeFloat64Subnormal( aSig, &aExp, &aSig ); |
2956 | } | 2975 | } |
2957 | zExp = ( ( aExp - 0x3FF )>>1 ) + 0x3FE; | 2976 | zExp = ( ( aExp - 0x3FF )>>1 ) + 0x3FE; |
@@ -2982,6 +3001,7 @@ float64 float64_sqrt( float64 a STATUS_PARAM ) | @@ -2982,6 +3001,7 @@ float64 float64_sqrt( float64 a STATUS_PARAM ) | ||
2982 | 3001 | ||
2983 | int float64_eq( float64 a, float64 b STATUS_PARAM ) | 3002 | int float64_eq( float64 a, float64 b STATUS_PARAM ) |
2984 | { | 3003 | { |
3004 | + bits64 av, bv; | ||
2985 | 3005 | ||
2986 | if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) | 3006 | if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) |
2987 | || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) | 3007 | || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) |
@@ -2991,7 +3011,9 @@ int float64_eq( float64 a, float64 b STATUS_PARAM ) | @@ -2991,7 +3011,9 @@ int float64_eq( float64 a, float64 b STATUS_PARAM ) | ||
2991 | } | 3011 | } |
2992 | return 0; | 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,6 +3027,7 @@ int float64_eq( float64 a, float64 b STATUS_PARAM ) | ||
3005 | int float64_le( float64 a, float64 b STATUS_PARAM ) | 3027 | int float64_le( float64 a, float64 b STATUS_PARAM ) |
3006 | { | 3028 | { |
3007 | flag aSign, bSign; | 3029 | flag aSign, bSign; |
3030 | + bits64 av, bv; | ||
3008 | 3031 | ||
3009 | if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) | 3032 | if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) |
3010 | || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) | 3033 | || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) |
@@ -3014,8 +3037,10 @@ int float64_le( float64 a, float64 b STATUS_PARAM ) | @@ -3014,8 +3037,10 @@ int float64_le( float64 a, float64 b STATUS_PARAM ) | ||
3014 | } | 3037 | } |
3015 | aSign = extractFloat64Sign( a ); | 3038 | aSign = extractFloat64Sign( a ); |
3016 | bSign = extractFloat64Sign( b ); | 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,6 +3053,7 @@ int float64_le( float64 a, float64 b STATUS_PARAM ) | ||
3028 | int float64_lt( float64 a, float64 b STATUS_PARAM ) | 3053 | int float64_lt( float64 a, float64 b STATUS_PARAM ) |
3029 | { | 3054 | { |
3030 | flag aSign, bSign; | 3055 | flag aSign, bSign; |
3056 | + bits64 av, bv; | ||
3031 | 3057 | ||
3032 | if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) | 3058 | if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) |
3033 | || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) | 3059 | || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) |
@@ -3037,8 +3063,10 @@ int float64_lt( float64 a, float64 b STATUS_PARAM ) | @@ -3037,8 +3063,10 @@ int float64_lt( float64 a, float64 b STATUS_PARAM ) | ||
3037 | } | 3063 | } |
3038 | aSign = extractFloat64Sign( a ); | 3064 | aSign = extractFloat64Sign( a ); |
3039 | bSign = extractFloat64Sign( b ); | 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,6 +3079,7 @@ int float64_lt( float64 a, float64 b STATUS_PARAM ) | ||
3051 | 3079 | ||
3052 | int float64_eq_signaling( float64 a, float64 b STATUS_PARAM ) | 3080 | int float64_eq_signaling( float64 a, float64 b STATUS_PARAM ) |
3053 | { | 3081 | { |
3082 | + bits64 av, bv; | ||
3054 | 3083 | ||
3055 | if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) | 3084 | if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) |
3056 | || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) | 3085 | || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) |
@@ -3058,7 +3087,9 @@ int float64_eq_signaling( float64 a, float64 b STATUS_PARAM ) | @@ -3058,7 +3087,9 @@ int float64_eq_signaling( float64 a, float64 b STATUS_PARAM ) | ||
3058 | float_raise( float_flag_invalid STATUS_VAR); | 3087 | float_raise( float_flag_invalid STATUS_VAR); |
3059 | return 0; | 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,6 +3103,7 @@ int float64_eq_signaling( float64 a, float64 b STATUS_PARAM ) | ||
3072 | int float64_le_quiet( float64 a, float64 b STATUS_PARAM ) | 3103 | int float64_le_quiet( float64 a, float64 b STATUS_PARAM ) |
3073 | { | 3104 | { |
3074 | flag aSign, bSign; | 3105 | flag aSign, bSign; |
3106 | + bits64 av, bv; | ||
3075 | 3107 | ||
3076 | if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) | 3108 | if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) |
3077 | || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) | 3109 | || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) |
@@ -3083,8 +3115,10 @@ int float64_le_quiet( float64 a, float64 b STATUS_PARAM ) | @@ -3083,8 +3115,10 @@ int float64_le_quiet( float64 a, float64 b STATUS_PARAM ) | ||
3083 | } | 3115 | } |
3084 | aSign = extractFloat64Sign( a ); | 3116 | aSign = extractFloat64Sign( a ); |
3085 | bSign = extractFloat64Sign( b ); | 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,6 +3132,7 @@ int float64_le_quiet( float64 a, float64 b STATUS_PARAM ) | ||
3098 | int float64_lt_quiet( float64 a, float64 b STATUS_PARAM ) | 3132 | int float64_lt_quiet( float64 a, float64 b STATUS_PARAM ) |
3099 | { | 3133 | { |
3100 | flag aSign, bSign; | 3134 | flag aSign, bSign; |
3135 | + bits64 av, bv; | ||
3101 | 3136 | ||
3102 | if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) | 3137 | if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) |
3103 | || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) | 3138 | || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) |
@@ -3109,8 +3144,10 @@ int float64_lt_quiet( float64 a, float64 b STATUS_PARAM ) | @@ -3109,8 +3144,10 @@ int float64_lt_quiet( float64 a, float64 b STATUS_PARAM ) | ||
3109 | } | 3144 | } |
3110 | aSign = extractFloat64Sign( a ); | 3145 | aSign = extractFloat64Sign( a ); |
3111 | bSign = extractFloat64Sign( b ); | 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,12 +5347,14 @@ unsigned int float64_to_uint32_round_to_zero( float64 a STATUS_PARAM ) | ||
5310 | return res; | 5347 | return res; |
5311 | } | 5348 | } |
5312 | 5349 | ||
5350 | +/* FIXME: This looks broken. */ | ||
5313 | uint64_t float64_to_uint64 (float64 a STATUS_PARAM) | 5351 | uint64_t float64_to_uint64 (float64 a STATUS_PARAM) |
5314 | { | 5352 | { |
5315 | int64_t v; | 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 | return v - INT64_MIN; | 5359 | return v - INT64_MIN; |
5321 | } | 5360 | } |
@@ -5324,8 +5363,9 @@ uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM) | @@ -5324,8 +5363,9 @@ uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM) | ||
5324 | { | 5363 | { |
5325 | int64_t v; | 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 | return v - INT64_MIN; | 5370 | return v - INT64_MIN; |
5331 | } | 5371 | } |
@@ -5335,6 +5375,7 @@ INLINE int float ## s ## _compare_internal( float ## s a, float ## s b, \ | @@ -5335,6 +5375,7 @@ INLINE int float ## s ## _compare_internal( float ## s a, float ## s b, \ | ||
5335 | int is_quiet STATUS_PARAM ) \ | 5375 | int is_quiet STATUS_PARAM ) \ |
5336 | { \ | 5376 | { \ |
5337 | flag aSign, bSign; \ | 5377 | flag aSign, bSign; \ |
5378 | + bits ## s av, bv; \ | ||
5338 | \ | 5379 | \ |
5339 | if (( ( extractFloat ## s ## Exp( a ) == nan_exp ) && \ | 5380 | if (( ( extractFloat ## s ## Exp( a ) == nan_exp ) && \ |
5340 | extractFloat ## s ## Frac( a ) ) || \ | 5381 | extractFloat ## s ## Frac( a ) ) || \ |
@@ -5349,18 +5390,20 @@ INLINE int float ## s ## _compare_internal( float ## s a, float ## s b, \ | @@ -5349,18 +5390,20 @@ INLINE int float ## s ## _compare_internal( float ## s a, float ## s b, \ | ||
5349 | } \ | 5390 | } \ |
5350 | aSign = extractFloat ## s ## Sign( a ); \ | 5391 | aSign = extractFloat ## s ## Sign( a ); \ |
5351 | bSign = extractFloat ## s ## Sign( b ); \ | 5392 | bSign = extractFloat ## s ## Sign( b ); \ |
5393 | + av = float ## s ## _val(a); \ | ||
5394 | + bv = float ## s ## _val(a); \ | ||
5352 | if ( aSign != bSign ) { \ | 5395 | if ( aSign != bSign ) { \ |
5353 | - if ( (bits ## s) ( ( a | b )<<1 ) == 0 ) { \ | 5396 | + if ( (bits ## s) ( ( av | bv )<<1 ) == 0 ) { \ |
5354 | /* zero case */ \ | 5397 | /* zero case */ \ |
5355 | return float_relation_equal; \ | 5398 | return float_relation_equal; \ |
5356 | } else { \ | 5399 | } else { \ |
5357 | return 1 - (2 * aSign); \ | 5400 | return 1 - (2 * aSign); \ |
5358 | } \ | 5401 | } \ |
5359 | } else { \ | 5402 | } else { \ |
5360 | - if (a == b) { \ | 5403 | + if (av == bv) { \ |
5361 | return float_relation_equal; \ | 5404 | return float_relation_equal; \ |
5362 | } else { \ | 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,8 +111,31 @@ enum { | ||
111 | /*---------------------------------------------------------------------------- | 111 | /*---------------------------------------------------------------------------- |
112 | | Software IEC/IEEE floating-point types. | 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 | typedef uint32_t float32; | 132 | typedef uint32_t float32; |
115 | typedef uint64_t float64; | 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 | #ifdef FLOATX80 | 139 | #ifdef FLOATX80 |
117 | typedef struct { | 140 | typedef struct { |
118 | uint64_t low; | 141 | uint64_t low; |
@@ -248,14 +271,16 @@ float32 float32_scalbn( float32, int STATUS_PARAM ); | @@ -248,14 +271,16 @@ float32 float32_scalbn( float32, int STATUS_PARAM ); | ||
248 | 271 | ||
249 | INLINE float32 float32_abs(float32 a) | 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 | INLINE float32 float32_chs(float32 a) | 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 | | Software IEC/IEEE double-precision conversion routines. | 285 | | Software IEC/IEEE double-precision conversion routines. |
261 | *----------------------------------------------------------------------------*/ | 286 | *----------------------------------------------------------------------------*/ |
@@ -300,14 +325,16 @@ float64 float64_scalbn( float64, int STATUS_PARAM ); | @@ -300,14 +325,16 @@ float64 float64_scalbn( float64, int STATUS_PARAM ); | ||
300 | 325 | ||
301 | INLINE float64 float64_abs(float64 a) | 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 | INLINE float64 float64_chs(float64 a) | 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 | #ifdef FLOATX80 | 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,7 +38,7 @@ float64 float64_pol(float64 rFn,float64 rFm); | ||
38 | unsigned int DoubleCPDO(const unsigned int opcode) | 38 | unsigned int DoubleCPDO(const unsigned int opcode) |
39 | { | 39 | { |
40 | FPA11 *fpa11 = GET_FPA11(); | 40 | FPA11 *fpa11 = GET_FPA11(); |
41 | - float64 rFm, rFn = 0; | 41 | + float64 rFm, rFn = float64_zero; |
42 | unsigned int Fd, Fm, Fn, nRc = 1; | 42 | unsigned int Fd, Fm, Fn, nRc = 1; |
43 | 43 | ||
44 | //printk("DoubleCPDO(0x%08x)\n",opcode); | 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,7 +38,7 @@ float32 float32_pol(float32 rFn,float32 rFm); | ||
38 | unsigned int SingleCPDO(const unsigned int opcode) | 38 | unsigned int SingleCPDO(const unsigned int opcode) |
39 | { | 39 | { |
40 | FPA11 *fpa11 = GET_FPA11(); | 40 | FPA11 *fpa11 = GET_FPA11(); |
41 | - float32 rFm, rFn = 0; | 41 | + float32 rFm, rFn = float32_zero; |
42 | unsigned int Fd, Fm, Fn, nRc = 1; | 42 | unsigned int Fd, Fm, Fn, nRc = 1; |
43 | 43 | ||
44 | Fm = getFm(opcode); | 44 | Fm = getFm(opcode); |
@@ -128,13 +128,11 @@ unsigned int SingleCPDO(const unsigned int opcode) | @@ -128,13 +128,11 @@ unsigned int SingleCPDO(const unsigned int opcode) | ||
128 | break; | 128 | break; |
129 | 129 | ||
130 | case MNF_CODE: | 130 | case MNF_CODE: |
131 | - rFm ^= 0x80000000; | ||
132 | - fpa11->fpreg[Fd].fSingle = rFm; | 131 | + fpa11->fpreg[Fd].fSingle = float32_chs(rFm); |
133 | break; | 132 | break; |
134 | 133 | ||
135 | case ABS_CODE: | 134 | case ABS_CODE: |
136 | - rFm &= 0x7fffffff; | ||
137 | - fpa11->fpreg[Fd].fSingle = rFm; | 135 | + fpa11->fpreg[Fd].fSingle = float32_abs(rFm); |
138 | break; | 136 | break; |
139 | 137 | ||
140 | case RND_CODE: | 138 | case RND_CODE: |
target-m68k/helper.c
@@ -255,7 +255,7 @@ float64 helper_sub_cmpf64(CPUM68KState *env, float64 src0, float64 src1) | @@ -255,7 +255,7 @@ float64 helper_sub_cmpf64(CPUM68KState *env, float64 src0, float64 src1) | ||
255 | /* +/-inf compares equal against itself, but sub returns nan. */ | 255 | /* +/-inf compares equal against itself, but sub returns nan. */ |
256 | if (!float64_is_nan(src0) | 256 | if (!float64_is_nan(src0) |
257 | && !float64_is_nan(src1)) { | 257 | && !float64_is_nan(src1)) { |
258 | - res = 0; | 258 | + res = float64_zero; |
259 | if (float64_lt_quiet(src0, res, &env->fp_status)) | 259 | if (float64_lt_quiet(src0, res, &env->fp_status)) |
260 | res = float64_chs(res); | 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,10 +624,10 @@ void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec, | ||
624 | 624 | ||
625 | /* Complex FPU operations which may need stack space. */ | 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 | #define FLOAT_QNAN32 0x7fbfffff | 631 | #define FLOAT_QNAN32 0x7fbfffff |
632 | #define FLOAT_QNAN64 0x7ff7ffffffffffffULL | 632 | #define FLOAT_QNAN64 0x7ff7ffffffffffffULL |
633 | #define FLOAT_SNAN32 0x7fffffff | 633 | #define FLOAT_SNAN32 0x7fffffff |