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 | ... | ... |