Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(449)

Side by Side Diff: src/mips64/simulator-mips64.cc

Issue 2184843002: MIPS: Add NaN handling to floating point operators in simulators. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: rebased Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« src/mips/simulator-mips.cc ('K') | « src/mips/simulator-mips.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <limits.h> 5 #include <limits.h>
6 #include <stdarg.h> 6 #include <stdarg.h>
7 #include <stdlib.h> 7 #include <stdlib.h>
8 #include <cmath> 8 #include <cmath>
9 9
10 #if V8_TARGET_ARCH_MIPS64 10 #if V8_TARGET_ARCH_MIPS64
(...skipping 2346 matching lines...) Expand 10 before | Expand all | Expand 10 after
2357 result = a; 2357 result = a;
2358 } else if (FPAbs(b) > FPAbs(a)) { 2358 } else if (FPAbs(b) > FPAbs(a)) {
2359 result = b; 2359 result = b;
2360 } else { 2360 } else {
2361 result = a > b ? a : b; 2361 result = a > b ? a : b;
2362 } 2362 }
2363 } 2363 }
2364 return result; 2364 return result;
2365 } 2365 }
2366 2366
2367 enum class KeepSign : bool { no = false, yes };
2368
2369 template <typename T>
2370 T FPUCanonalizeNaNArg(T result, T arg, KeepSign keepSign = KeepSign::no);
2371
2372 template <>
2373 double FPUCanonalizeNaNArg(double result, double arg, KeepSign keepSign) {
2374 DCHECK(std::isnan(arg));
2375 double qNaN = std::numeric_limits<double>::quiet_NaN();
2376 if (keepSign == KeepSign::yes) {
2377 uint64_t resBits = bit_cast<uint64_t>(result);
2378 return resBits & Double::kSignMask ? -qNaN : qNaN;
2379 }
2380 return qNaN;
2381 }
2382
2383 template <>
2384 float FPUCanonalizeNaNArg(float result, float arg, KeepSign keepSign) {
2385 DCHECK(std::isnan(arg));
2386 float qNaN = std::numeric_limits<float>::quiet_NaN();
2387 if (keepSign == KeepSign::yes) {
2388 uint32_t resBits = bit_cast<uint32_t>(result);
2389 return resBits & kBinary32SignMask ? -qNaN : qNaN;
2390 }
2391 return qNaN;
2392 }
2393
2394 template <typename T>
2395 T FPUCanonalizeNaNArgs(T result, KeepSign keepSign, T first) {
2396 if (std::isnan(first)) {
2397 return FPUCanonalizeNaNArg(result, first, keepSign);
2398 }
2399 return result;
2400 }
2401
2402 template <typename T, typename... Args>
2403 T FPUCanonalizeNaNArgs(T result, KeepSign keepSign, T first, Args... args) {
2404 if (std::isnan(first)) {
2405 return FPUCanonalizeNaNArg(result, first, keepSign);
2406 }
2407 return FPUCanonalizeNaNArgs(result, keepSign, args...);
2408 }
2409
2410 template <typename Func, typename T, typename... Args>
2411 T FPUCanonalizeOperation(Func f, T first, Args... args) {
2412 return FPUCanonalizeOperation(f, KeepSign::no, first, args...);
2413 }
2414
2415 template <typename Func, typename T, typename... Args>
2416 T FPUCanonalizeOperation(Func f, KeepSign keepSign, T first, Args... args) {
2417 T result = f(first, args...);
2418 if (std::isnan(result)) {
2419 result = FPUCanonalizeNaNArgs(result, keepSign, first, args...);
2420 }
2421 return result;
2422 }
2423
2367 // Handle execution based on instruction types. 2424 // Handle execution based on instruction types.
2368 2425
2369 void Simulator::DecodeTypeRegisterSRsType() { 2426 void Simulator::DecodeTypeRegisterSRsType() {
2370 float fs, ft, fd; 2427 float fs, ft, fd;
2371 fs = get_fpu_register_float(fs_reg()); 2428 fs = get_fpu_register_float(fs_reg());
2372 ft = get_fpu_register_float(ft_reg()); 2429 ft = get_fpu_register_float(ft_reg());
2373 fd = get_fpu_register_float(fd_reg()); 2430 fd = get_fpu_register_float(fd_reg());
2374 int32_t ft_int = bit_cast<int32_t>(ft); 2431 int32_t ft_int = bit_cast<int32_t>(ft);
2375 int32_t fd_int = bit_cast<int32_t>(fd); 2432 int32_t fd_int = bit_cast<int32_t>(fd);
2376 uint32_t cc, fcsr_cc; 2433 uint32_t cc, fcsr_cc;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2409 result = lower; 2466 result = lower;
2410 break; 2467 break;
2411 } 2468 }
2412 set_fpu_register_float(fd_reg(), result); 2469 set_fpu_register_float(fd_reg(), result);
2413 if (result != fs) { 2470 if (result != fs) {
2414 set_fcsr_bit(kFCSRInexactFlagBit, true); 2471 set_fcsr_bit(kFCSRInexactFlagBit, true);
2415 } 2472 }
2416 break; 2473 break;
2417 } 2474 }
2418 case ADD_S: 2475 case ADD_S:
2419 set_fpu_register_float(fd_reg(), fs + ft); 2476 set_fpu_register_float(
2477 fd_reg(),
2478 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs + rhs; },
2479 fs, ft));
2420 break; 2480 break;
2421 case SUB_S: 2481 case SUB_S:
2422 set_fpu_register_float(fd_reg(), fs - ft); 2482 set_fpu_register_float(
2483 fd_reg(),
2484 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs - rhs; },
2485 fs, ft));
2423 break; 2486 break;
2424 case MADDF_S: 2487 case MADDF_S:
2425 DCHECK(kArchVariant == kMips64r6); 2488 DCHECK(kArchVariant == kMips64r6);
2426 set_fpu_register_float(fd_reg(), fd + (fs * ft)); 2489 set_fpu_register_float(fd_reg(), fd + (fs * ft));
2427 break; 2490 break;
2428 case MSUBF_S: 2491 case MSUBF_S:
2429 DCHECK(kArchVariant == kMips64r6); 2492 DCHECK(kArchVariant == kMips64r6);
2430 set_fpu_register_float(fd_reg(), fd - (fs * ft)); 2493 set_fpu_register_float(fd_reg(), fd - (fs * ft));
2431 break; 2494 break;
2432 case MUL_S: 2495 case MUL_S:
2433 set_fpu_register_float(fd_reg(), fs * ft); 2496 set_fpu_register_float(
2497 fd_reg(),
2498 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs * rhs; },
2499 fs, ft));
2434 break; 2500 break;
2435 case DIV_S: 2501 case DIV_S:
2436 set_fpu_register_float(fd_reg(), fs / ft); 2502 set_fpu_register_float(
2503 fd_reg(),
2504 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs / rhs; },
2505 fs, ft));
2437 break; 2506 break;
2438 case ABS_S: 2507 case ABS_S:
2439 set_fpu_register_float(fd_reg(), fabs(fs)); 2508 set_fpu_register_float(
2509 fd_reg(),
2510 FPUCanonalizeOperation([](float fs) { return FPAbs(fs); }, fs));
2440 break; 2511 break;
2441 case MOV_S: 2512 case MOV_S:
2442 set_fpu_register_float(fd_reg(), fs); 2513 set_fpu_register_float(fd_reg(), fs);
2443 break; 2514 break;
2444 case NEG_S: 2515 case NEG_S:
2445 set_fpu_register_float(fd_reg(), -fs); 2516 set_fpu_register_float(
2517 fd_reg(), FPUCanonalizeOperation([](float src) { return -src; },
2518 KeepSign::yes, fs));
2446 break; 2519 break;
2447 case SQRT_S: 2520 case SQRT_S:
2448 lazily_initialize_fast_sqrt(isolate_); 2521 set_fpu_register_float(
2449 set_fpu_register_float(fd_reg(), fast_sqrt(fs, isolate_)); 2522 fd_reg(),
2523 FPUCanonalizeOperation([](float src) { return std::sqrt(src); }, fs));
2450 break; 2524 break;
2451 case RSQRT_S: { 2525 case RSQRT_S:
2452 lazily_initialize_fast_sqrt(isolate_); 2526 set_fpu_register_float(
2453 float result = 1.0 / fast_sqrt(fs, isolate_); 2527 fd_reg(), FPUCanonalizeOperation(
2454 set_fpu_register_float(fd_reg(), result); 2528 [](float src) { return 1.0 / std::sqrt(src); }, fs));
2455 break; 2529 break;
2456 } 2530 case RECIP_S:
2457 case RECIP_S: { 2531 set_fpu_register_float(
2458 float result = 1.0 / fs; 2532 fd_reg(),
2459 set_fpu_register_float(fd_reg(), result); 2533 FPUCanonalizeOperation([](float src) { return 1.0 / src; }, fs));
2460 break; 2534 break;
2461 }
2462 case C_F_D: 2535 case C_F_D:
2463 set_fcsr_bit(fcsr_cc, false); 2536 set_fcsr_bit(fcsr_cc, false);
2464 break; 2537 break;
2465 case C_UN_D: 2538 case C_UN_D:
2466 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft)); 2539 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft));
2467 break; 2540 break;
2468 case C_EQ_D: 2541 case C_EQ_D:
2469 set_fcsr_bit(fcsr_cc, (fs == ft)); 2542 set_fcsr_bit(fcsr_cc, (fs == ft));
2470 break; 2543 break;
2471 case C_UEQ_D: 2544 case C_UEQ_D:
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
2820 break; 2893 break;
2821 case MIN: 2894 case MIN:
2822 DCHECK(kArchVariant == kMips64r6); 2895 DCHECK(kArchVariant == kMips64r6);
2823 set_fpu_register_double(fd_reg(), FPUMin(ft, fs)); 2896 set_fpu_register_double(fd_reg(), FPUMin(ft, fs));
2824 break; 2897 break;
2825 case MAX: 2898 case MAX:
2826 DCHECK(kArchVariant == kMips64r6); 2899 DCHECK(kArchVariant == kMips64r6);
2827 set_fpu_register_double(fd_reg(), FPUMax(ft, fs)); 2900 set_fpu_register_double(fd_reg(), FPUMax(ft, fs));
2828 break; 2901 break;
2829 case ADD_D: 2902 case ADD_D:
2830 set_fpu_register_double(fd_reg(), fs + ft); 2903 set_fpu_register_double(
2904 fd_reg(),
2905 FPUCanonalizeOperation(
2906 [](double lhs, double rhs) { return lhs + rhs; }, fs, ft));
2831 break; 2907 break;
2832 case SUB_D: 2908 case SUB_D:
2833 set_fpu_register_double(fd_reg(), fs - ft); 2909 set_fpu_register_double(
2910 fd_reg(),
2911 FPUCanonalizeOperation(
2912 [](double lhs, double rhs) { return lhs - rhs; }, fs, ft));
2834 break; 2913 break;
2835 case MADDF_D: 2914 case MADDF_D:
2836 DCHECK(kArchVariant == kMips64r6); 2915 DCHECK(kArchVariant == kMips64r6);
2837 set_fpu_register_double(fd_reg(), fd + (fs * ft)); 2916 set_fpu_register_double(fd_reg(), fd + (fs * ft));
2838 break; 2917 break;
2839 case MSUBF_D: 2918 case MSUBF_D:
2840 DCHECK(kArchVariant == kMips64r6); 2919 DCHECK(kArchVariant == kMips64r6);
2841 set_fpu_register_double(fd_reg(), fd - (fs * ft)); 2920 set_fpu_register_double(fd_reg(), fd - (fs * ft));
2842 break; 2921 break;
2843 case MUL_D: 2922 case MUL_D:
2844 set_fpu_register_double(fd_reg(), fs * ft); 2923 set_fpu_register_double(
2924 fd_reg(),
2925 FPUCanonalizeOperation(
2926 [](double lhs, double rhs) { return lhs * rhs; }, fs, ft));
2845 break; 2927 break;
2846 case DIV_D: 2928 case DIV_D:
2847 set_fpu_register_double(fd_reg(), fs / ft); 2929 set_fpu_register_double(
2930 fd_reg(),
2931 FPUCanonalizeOperation(
2932 [](double lhs, double rhs) { return lhs / rhs; }, fs, ft));
2848 break; 2933 break;
2849 case ABS_D: 2934 case ABS_D:
2850 set_fpu_register_double(fd_reg(), fabs(fs)); 2935 set_fpu_register_double(
2936 fd_reg(),
2937 FPUCanonalizeOperation([](double fs) { return FPAbs(fs); }, fs));
2851 break; 2938 break;
2852 case MOV_D: 2939 case MOV_D:
2853 set_fpu_register_double(fd_reg(), fs); 2940 set_fpu_register_double(fd_reg(), fs);
2854 break; 2941 break;
2855 case NEG_D: 2942 case NEG_D:
2856 set_fpu_register_double(fd_reg(), -fs); 2943 set_fpu_register_double(
2944 fd_reg(), FPUCanonalizeOperation([](double src) { return -src; },
2945 KeepSign::yes, fs));
2857 break; 2946 break;
2858 case SQRT_D: 2947 case SQRT_D:
2859 lazily_initialize_fast_sqrt(isolate_); 2948 set_fpu_register_double(
2860 set_fpu_register_double(fd_reg(), fast_sqrt(fs, isolate_)); 2949 fd_reg(),
2950 FPUCanonalizeOperation([](double fs) { return std::sqrt(fs); }, fs));
2861 break; 2951 break;
2862 case RSQRT_D: { 2952 case RSQRT_D:
2863 lazily_initialize_fast_sqrt(isolate_); 2953 set_fpu_register_double(
2864 double result = 1.0 / fast_sqrt(fs, isolate_); 2954 fd_reg(), FPUCanonalizeOperation(
2865 set_fpu_register_double(fd_reg(), result); 2955 [](double fs) { return 1.0 / std::sqrt(fs); }, fs));
2866 break; 2956 break;
2867 } 2957 case RECIP_D:
2868 case RECIP_D: { 2958 set_fpu_register_double(
2869 double result = 1.0 / fs; 2959 fd_reg(),
2870 set_fpu_register_double(fd_reg(), result); 2960 FPUCanonalizeOperation([](double fs) { return 1.0 / fs; }, fs));
2871 break; 2961 break;
2872 }
2873 case C_UN_D: 2962 case C_UN_D:
2874 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft)); 2963 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft));
2875 break; 2964 break;
2876 case C_EQ_D: 2965 case C_EQ_D:
2877 set_fcsr_bit(fcsr_cc, (fs == ft)); 2966 set_fcsr_bit(fcsr_cc, (fs == ft));
2878 break; 2967 break;
2879 case C_UEQ_D: 2968 case C_UEQ_D:
2880 set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft))); 2969 set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft)));
2881 break; 2970 break;
2882 case C_OLT_D: 2971 case C_OLT_D:
(...skipping 2095 matching lines...) Expand 10 before | Expand all | Expand 10 after
4978 } 5067 }
4979 5068
4980 5069
4981 #undef UNSUPPORTED 5070 #undef UNSUPPORTED
4982 } // namespace internal 5071 } // namespace internal
4983 } // namespace v8 5072 } // namespace v8
4984 5073
4985 #endif // USE_SIMULATOR 5074 #endif // USE_SIMULATOR
4986 5075
4987 #endif // V8_TARGET_ARCH_MIPS64 5076 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW
« src/mips/simulator-mips.cc ('K') | « src/mips/simulator-mips.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698