qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

fpu/softfloat: Specialize on snan_bit_is_one

Only MIPS requires snan_bit_is_one to be variable. While we are
specializing softfloat behaviour, allow other targets to eliminate
this runtime check.

Cc: Aurelien Jarno <aurelien@aurel32.net>
Cc: Yongbok Kim <yongbok.kim@mips.com>
Cc: David Gibson <david@gibson.dropbear.id.au>
Cc: Alexander Graf <agraf@suse.de>
Cc: Guan Xuetao <gxt@mprc.pku.edu.cn>
Tested-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

+44 -30
+43 -25
fpu/softfloat-specialize.h
··· 79 79 * version 2 or later. See the COPYING file in the top-level directory. 80 80 */ 81 81 82 - #if defined(TARGET_XTENSA) 83 82 /* Define for architectures which deviate from IEEE in not supporting 84 83 * signaling NaNs (so all NaNs are treated as quiet). 85 84 */ 85 + #if defined(TARGET_XTENSA) 86 86 #define NO_SIGNALING_NANS 1 87 87 #endif 88 88 89 + /* Define how the architecture discriminates signaling NaNs. 90 + * This done with the most significant bit of the fraction. 91 + * In IEEE 754-1985 this was implementation defined, but in IEEE 754-2008 92 + * the msb must be zero. MIPS is (so far) unique in supporting both the 93 + * 2008 revision and backward compatibility with their original choice. 94 + * Thus for MIPS we must make the choice at runtime. 95 + */ 96 + static inline flag snan_bit_is_one(float_status *status) 97 + { 98 + #if defined(TARGET_MIPS) 99 + return status->snan_bit_is_one; 100 + #elif defined(TARGET_HPPA) || defined(TARGET_UNICORE32) || defined(TARGET_SH4) 101 + return 1; 102 + #else 103 + return 0; 104 + #endif 105 + } 106 + 89 107 /*---------------------------------------------------------------------------- 90 108 | For the deconstructed floating-point with fraction FRAC, return true 91 109 | if the fraction represents a signalling NaN; otherwise false. ··· 97 115 return false; 98 116 #else 99 117 flag msb = extract64(frac, DECOMPOSED_BINARY_POINT - 1, 1); 100 - return msb == status->snan_bit_is_one; 118 + return msb == snan_bit_is_one(status); 101 119 #endif 102 120 } 103 121 ··· 118 136 #elif defined(TARGET_HPPA) 119 137 frac = 1ULL << (DECOMPOSED_BINARY_POINT - 2); 120 138 #else 121 - if (status->snan_bit_is_one) { 139 + if (snan_bit_is_one(status)) { 122 140 frac = (1ULL << (DECOMPOSED_BINARY_POINT - 1)) - 1; 123 141 } else { 124 142 #if defined(TARGET_MIPS) ··· 151 169 a.frac &= ~(1ULL << (DECOMPOSED_BINARY_POINT - 1)); 152 170 a.frac |= 1ULL << (DECOMPOSED_BINARY_POINT - 2); 153 171 #else 154 - if (status->snan_bit_is_one) { 172 + if (snan_bit_is_one(status)) { 155 173 return parts_default_nan(status); 156 174 } else { 157 175 a.frac |= 1ULL << (DECOMPOSED_BINARY_POINT - 1); ··· 169 187 #if defined(TARGET_ARM) 170 188 return const_float16(0x7E00); 171 189 #else 172 - if (status->snan_bit_is_one) { 190 + if (snan_bit_is_one(status)) { 173 191 return const_float16(0x7DFF); 174 192 } else { 175 193 #if defined(TARGET_MIPS) ··· 195 213 #elif defined(TARGET_HPPA) 196 214 return const_float32(0x7FA00000); 197 215 #else 198 - if (status->snan_bit_is_one) { 216 + if (snan_bit_is_one(status)) { 199 217 return const_float32(0x7FBFFFFF); 200 218 } else { 201 219 #if defined(TARGET_MIPS) ··· 220 238 #elif defined(TARGET_HPPA) 221 239 return const_float64(LIT64(0x7FF4000000000000)); 222 240 #else 223 - if (status->snan_bit_is_one) { 241 + if (snan_bit_is_one(status)) { 224 242 return const_float64(LIT64(0x7FF7FFFFFFFFFFFF)); 225 243 } else { 226 244 #if defined(TARGET_MIPS) ··· 242 260 r.low = LIT64(0xFFFFFFFFFFFFFFFF); 243 261 r.high = 0x7FFF; 244 262 #else 245 - if (status->snan_bit_is_one) { 263 + if (snan_bit_is_one(status)) { 246 264 r.low = LIT64(0xBFFFFFFFFFFFFFFF); 247 265 r.high = 0x7FFF; 248 266 } else { ··· 274 292 { 275 293 float128 r; 276 294 277 - if (status->snan_bit_is_one) { 295 + if (snan_bit_is_one(status)) { 278 296 r.low = LIT64(0xFFFFFFFFFFFFFFFF); 279 297 r.high = LIT64(0x7FFF7FFFFFFFFFFF); 280 298 } else { ··· 319 337 return float16_is_any_nan(a_); 320 338 #else 321 339 uint16_t a = float16_val(a_); 322 - if (status->snan_bit_is_one) { 340 + if (snan_bit_is_one(status)) { 323 341 return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF); 324 342 } else { 325 343 return ((a & ~0x8000) >= 0x7C80); ··· 338 356 return 0; 339 357 #else 340 358 uint16_t a = float16_val(a_); 341 - if (status->snan_bit_is_one) { 359 + if (snan_bit_is_one(status)) { 342 360 return ((a & ~0x8000) >= 0x7C80); 343 361 } else { 344 362 return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF); ··· 356 374 #ifdef NO_SIGNALING_NANS 357 375 g_assert_not_reached(); 358 376 #else 359 - if (status->snan_bit_is_one) { 377 + if (snan_bit_is_one(status)) { 360 378 return float16_default_nan(status); 361 379 } else { 362 380 return a | (1 << 9); ··· 375 393 return float32_is_any_nan(a_); 376 394 #else 377 395 uint32_t a = float32_val(a_); 378 - if (status->snan_bit_is_one) { 396 + if (snan_bit_is_one(status)) { 379 397 return (((a >> 22) & 0x1FF) == 0x1FE) && (a & 0x003FFFFF); 380 398 } else { 381 399 return ((uint32_t)(a << 1) >= 0xFF800000); ··· 394 412 return 0; 395 413 #else 396 414 uint32_t a = float32_val(a_); 397 - if (status->snan_bit_is_one) { 415 + if (snan_bit_is_one(status)) { 398 416 return ((uint32_t)(a << 1) >= 0xFF800000); 399 417 } else { 400 418 return (((a >> 22) & 0x1FF) == 0x1FE) && (a & 0x003FFFFF); ··· 412 430 #ifdef NO_SIGNALING_NANS 413 431 g_assert_not_reached(); 414 432 #else 415 - if (status->snan_bit_is_one) { 433 + if (snan_bit_is_one(status)) { 416 434 # ifdef TARGET_HPPA 417 435 a &= ~0x00400000; 418 436 a |= 0x00200000; ··· 651 669 return 3; 652 670 } 653 671 654 - if (status->snan_bit_is_one) { 672 + if (snan_bit_is_one(status)) { 655 673 /* Prefer sNaN over qNaN, in the a, b, c order. */ 656 674 if (aIsSNaN) { 657 675 return 0; ··· 786 804 return float64_is_any_nan(a_); 787 805 #else 788 806 uint64_t a = float64_val(a_); 789 - if (status->snan_bit_is_one) { 807 + if (snan_bit_is_one(status)) { 790 808 return (((a >> 51) & 0xFFF) == 0xFFE) 791 809 && (a & 0x0007FFFFFFFFFFFFULL); 792 810 } else { ··· 806 824 return 0; 807 825 #else 808 826 uint64_t a = float64_val(a_); 809 - if (status->snan_bit_is_one) { 827 + if (snan_bit_is_one(status)) { 810 828 return ((a << 1) >= 0xFFF0000000000000ULL); 811 829 } else { 812 830 return (((a >> 51) & 0xFFF) == 0xFFE) ··· 825 843 #ifdef NO_SIGNALING_NANS 826 844 g_assert_not_reached(); 827 845 #else 828 - if (status->snan_bit_is_one) { 846 + if (snan_bit_is_one(status)) { 829 847 # ifdef TARGET_HPPA 830 848 a &= ~0x0008000000000000ULL; 831 849 a |= 0x0004000000000000ULL; ··· 942 960 #ifdef NO_SIGNALING_NANS 943 961 return floatx80_is_any_nan(a); 944 962 #else 945 - if (status->snan_bit_is_one) { 963 + if (snan_bit_is_one(status)) { 946 964 uint64_t aLow; 947 965 948 966 aLow = a.low & ~0x4000000000000000ULL; ··· 967 985 #ifdef NO_SIGNALING_NANS 968 986 return 0; 969 987 #else 970 - if (status->snan_bit_is_one) { 988 + if (snan_bit_is_one(status)) { 971 989 return ((a.high & 0x7FFF) == 0x7FFF) 972 990 && ((a.low << 1) >= 0x8000000000000000ULL); 973 991 } else { ··· 991 1009 #ifdef NO_SIGNALING_NANS 992 1010 g_assert_not_reached(); 993 1011 #else 994 - if (status->snan_bit_is_one) { 1012 + if (snan_bit_is_one(status)) { 995 1013 return floatx80_default_nan(status); 996 1014 } else { 997 1015 a.low |= LIT64(0xC000000000000000); ··· 1105 1123 #ifdef NO_SIGNALING_NANS 1106 1124 return float128_is_any_nan(a); 1107 1125 #else 1108 - if (status->snan_bit_is_one) { 1126 + if (snan_bit_is_one(status)) { 1109 1127 return (((a.high >> 47) & 0xFFFF) == 0xFFFE) 1110 1128 && (a.low || (a.high & 0x00007FFFFFFFFFFFULL)); 1111 1129 } else { ··· 1125 1143 #ifdef NO_SIGNALING_NANS 1126 1144 return 0; 1127 1145 #else 1128 - if (status->snan_bit_is_one) { 1146 + if (snan_bit_is_one(status)) { 1129 1147 return ((a.high << 1) >= 0xFFFF000000000000ULL) 1130 1148 && (a.low || (a.high & 0x0000FFFFFFFFFFFFULL)); 1131 1149 } else { ··· 1145 1163 #ifdef NO_SIGNALING_NANS 1146 1164 g_assert_not_reached(); 1147 1165 #else 1148 - if (status->snan_bit_is_one) { 1166 + if (snan_bit_is_one(status)) { 1149 1167 return float128_default_nan(status); 1150 1168 } else { 1151 1169 a.high |= LIT64(0x0000800000000000);
+1
include/fpu/softfloat-types.h
··· 173 173 /* should denormalised inputs go to zero and set the input_denormal flag? */ 174 174 flag flush_inputs_to_zero; 175 175 flag default_nan_mode; 176 + /* not always used -- see snan_bit_is_one() in softfloat-specialize.h */ 176 177 flag snan_bit_is_one; 177 178 } float_status; 178 179
-1
target/hppa/cpu.c
··· 141 141 cs->env_ptr = env; 142 142 cs->exception_index = -1; 143 143 cpu_hppa_loaded_fr0(env); 144 - set_snan_bit_is_one(true, &env->fp_status); 145 144 cpu_hppa_put_psw(env, PSW_W); 146 145 } 147 146
-1
target/ppc/fpu_helper.c
··· 3382 3382 xt.f128 = xb.f128; 3383 3383 } else if (float128_is_neg(xb.f128) && !float128_is_zero(xb.f128)) { 3384 3384 float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, 1); 3385 - set_snan_bit_is_one(0, &env->fp_status); 3386 3385 xt.f128 = float128_default_nan(&env->fp_status); 3387 3386 } 3388 3387 }
-1
target/sh4/cpu.c
··· 71 71 set_flush_to_zero(1, &env->fp_status); 72 72 #endif 73 73 set_default_nan_mode(1, &env->fp_status); 74 - set_snan_bit_is_one(1, &env->fp_status); 75 74 } 76 75 77 76 static void superh_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
-2
target/unicore32/cpu.c
··· 70 70 71 71 set_feature(env, UC32_HWCAP_CMOV); 72 72 set_feature(env, UC32_HWCAP_UCF64); 73 - set_snan_bit_is_one(1, &env->ucf64.fp_status); 74 73 } 75 74 76 75 static void uc32_any_cpu_initfn(Object *obj) ··· 83 82 84 83 set_feature(env, UC32_HWCAP_CMOV); 85 84 set_feature(env, UC32_HWCAP_UCF64); 86 - set_snan_bit_is_one(1, &env->ucf64.fp_status); 87 85 } 88 86 89 87 static void uc32_cpu_realizefn(DeviceState *dev, Error **errp)