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

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: Fix templates. 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
« no previous file with comments | « 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, typename std::enable_if<std::is_floating_point<T>::value,
2370 int>::type = 0>
2371 T FPUCanonalizeNaNArg(T result, T arg, KeepSign keepSign = KeepSign::no) {
2372 DCHECK(std::isnan(arg));
2373 T qNaN = std::numeric_limits<T>::quiet_NaN();
2374 if (keepSign == KeepSign::yes) {
2375 return std::copysign(qNaN, result);
2376 }
2377 return qNaN;
2378 }
2379
2380 template <typename T>
2381 T FPUCanonalizeNaNArgs(T result, KeepSign keepSign, T first) {
2382 if (std::isnan(first)) {
2383 return FPUCanonalizeNaNArg(result, first, keepSign);
2384 }
2385 return result;
2386 }
2387
2388 template <typename T, typename... Args>
2389 T FPUCanonalizeNaNArgs(T result, KeepSign keepSign, T first, Args... args) {
2390 if (std::isnan(first)) {
2391 return FPUCanonalizeNaNArg(result, first, keepSign);
2392 }
2393 return FPUCanonalizeNaNArgs(result, keepSign, args...);
2394 }
2395
2396 template <typename Func, typename T, typename... Args>
2397 T FPUCanonalizeOperation(Func f, T first, Args... args) {
2398 return FPUCanonalizeOperation(f, KeepSign::no, first, args...);
2399 }
2400
2401 template <typename Func, typename T, typename... Args>
2402 T FPUCanonalizeOperation(Func f, KeepSign keepSign, T first, Args... args) {
2403 T result = f(first, args...);
2404 if (std::isnan(result)) {
2405 result = FPUCanonalizeNaNArgs(result, keepSign, first, args...);
2406 }
2407 return result;
2408 }
2409
2367 // Handle execution based on instruction types. 2410 // Handle execution based on instruction types.
2368 2411
2369 void Simulator::DecodeTypeRegisterSRsType() { 2412 void Simulator::DecodeTypeRegisterSRsType() {
2370 float fs, ft, fd; 2413 float fs, ft, fd;
2371 fs = get_fpu_register_float(fs_reg()); 2414 fs = get_fpu_register_float(fs_reg());
2372 ft = get_fpu_register_float(ft_reg()); 2415 ft = get_fpu_register_float(ft_reg());
2373 fd = get_fpu_register_float(fd_reg()); 2416 fd = get_fpu_register_float(fd_reg());
2374 int32_t ft_int = bit_cast<int32_t>(ft); 2417 int32_t ft_int = bit_cast<int32_t>(ft);
2375 int32_t fd_int = bit_cast<int32_t>(fd); 2418 int32_t fd_int = bit_cast<int32_t>(fd);
2376 uint32_t cc, fcsr_cc; 2419 uint32_t cc, fcsr_cc;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2409 result = lower; 2452 result = lower;
2410 break; 2453 break;
2411 } 2454 }
2412 set_fpu_register_float(fd_reg(), result); 2455 set_fpu_register_float(fd_reg(), result);
2413 if (result != fs) { 2456 if (result != fs) {
2414 set_fcsr_bit(kFCSRInexactFlagBit, true); 2457 set_fcsr_bit(kFCSRInexactFlagBit, true);
2415 } 2458 }
2416 break; 2459 break;
2417 } 2460 }
2418 case ADD_S: 2461 case ADD_S:
2419 set_fpu_register_float(fd_reg(), fs + ft); 2462 set_fpu_register_float(
2463 fd_reg(),
2464 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs + rhs; },
2465 fs, ft));
2420 break; 2466 break;
2421 case SUB_S: 2467 case SUB_S:
2422 set_fpu_register_float(fd_reg(), fs - ft); 2468 set_fpu_register_float(
2469 fd_reg(),
2470 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs - rhs; },
2471 fs, ft));
2423 break; 2472 break;
2424 case MADDF_S: 2473 case MADDF_S:
2425 DCHECK(kArchVariant == kMips64r6); 2474 DCHECK(kArchVariant == kMips64r6);
2426 set_fpu_register_float(fd_reg(), fd + (fs * ft)); 2475 set_fpu_register_float(fd_reg(), fd + (fs * ft));
2427 break; 2476 break;
2428 case MSUBF_S: 2477 case MSUBF_S:
2429 DCHECK(kArchVariant == kMips64r6); 2478 DCHECK(kArchVariant == kMips64r6);
2430 set_fpu_register_float(fd_reg(), fd - (fs * ft)); 2479 set_fpu_register_float(fd_reg(), fd - (fs * ft));
2431 break; 2480 break;
2432 case MUL_S: 2481 case MUL_S:
2433 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));
2434 break; 2486 break;
2435 case DIV_S: 2487 case DIV_S:
2436 set_fpu_register_float(fd_reg(), fs / ft); 2488 set_fpu_register_float(
2489 fd_reg(),
2490 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs / rhs; },
2491 fs, ft));
2437 break; 2492 break;
2438 case ABS_S: 2493 case ABS_S:
2439 set_fpu_register_float(fd_reg(), fabs(fs)); 2494 set_fpu_register_float(
2495 fd_reg(),
2496 FPUCanonalizeOperation([](float fs) { return FPAbs(fs); }, fs));
2440 break; 2497 break;
2441 case MOV_S: 2498 case MOV_S:
2442 set_fpu_register_float(fd_reg(), fs); 2499 set_fpu_register_float(fd_reg(), fs);
2443 break; 2500 break;
2444 case NEG_S: 2501 case NEG_S:
2445 set_fpu_register_float(fd_reg(), -fs); 2502 set_fpu_register_float(
2503 fd_reg(), FPUCanonalizeOperation([](float src) { return -src; },
2504 KeepSign::yes, fs));
2446 break; 2505 break;
2447 case SQRT_S: 2506 case SQRT_S:
2448 lazily_initialize_fast_sqrt(isolate_); 2507 set_fpu_register_float(
2449 set_fpu_register_float(fd_reg(), fast_sqrt(fs, isolate_)); 2508 fd_reg(),
2509 FPUCanonalizeOperation([](float src) { return std::sqrt(src); }, fs));
2450 break; 2510 break;
2451 case RSQRT_S: { 2511 case RSQRT_S:
2452 lazily_initialize_fast_sqrt(isolate_); 2512 set_fpu_register_float(
2453 float result = 1.0 / fast_sqrt(fs, isolate_); 2513 fd_reg(), FPUCanonalizeOperation(
2454 set_fpu_register_float(fd_reg(), result); 2514 [](float src) { return 1.0 / std::sqrt(src); }, fs));
2455 break; 2515 break;
2456 } 2516 case RECIP_S:
2457 case RECIP_S: { 2517 set_fpu_register_float(
2458 float result = 1.0 / fs; 2518 fd_reg(),
2459 set_fpu_register_float(fd_reg(), result); 2519 FPUCanonalizeOperation([](float src) { return 1.0 / src; }, fs));
2460 break; 2520 break;
2461 }
2462 case C_F_D: 2521 case C_F_D:
2463 set_fcsr_bit(fcsr_cc, false); 2522 set_fcsr_bit(fcsr_cc, false);
2464 break; 2523 break;
2465 case C_UN_D: 2524 case C_UN_D:
2466 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft)); 2525 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft));
2467 break; 2526 break;
2468 case C_EQ_D: 2527 case C_EQ_D:
2469 set_fcsr_bit(fcsr_cc, (fs == ft)); 2528 set_fcsr_bit(fcsr_cc, (fs == ft));
2470 break; 2529 break;
2471 case C_UEQ_D: 2530 case C_UEQ_D:
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
2820 break; 2879 break;
2821 case MIN: 2880 case MIN:
2822 DCHECK(kArchVariant == kMips64r6); 2881 DCHECK(kArchVariant == kMips64r6);
2823 set_fpu_register_double(fd_reg(), FPUMin(ft, fs)); 2882 set_fpu_register_double(fd_reg(), FPUMin(ft, fs));
2824 break; 2883 break;
2825 case MAX: 2884 case MAX:
2826 DCHECK(kArchVariant == kMips64r6); 2885 DCHECK(kArchVariant == kMips64r6);
2827 set_fpu_register_double(fd_reg(), FPUMax(ft, fs)); 2886 set_fpu_register_double(fd_reg(), FPUMax(ft, fs));
2828 break; 2887 break;
2829 case ADD_D: 2888 case ADD_D:
2830 set_fpu_register_double(fd_reg(), fs + ft); 2889 set_fpu_register_double(
2890 fd_reg(),
2891 FPUCanonalizeOperation(
2892 [](double lhs, double rhs) { return lhs + rhs; }, fs, ft));
2831 break; 2893 break;
2832 case SUB_D: 2894 case SUB_D:
2833 set_fpu_register_double(fd_reg(), fs - ft); 2895 set_fpu_register_double(
2896 fd_reg(),
2897 FPUCanonalizeOperation(
2898 [](double lhs, double rhs) { return lhs - rhs; }, fs, ft));
2834 break; 2899 break;
2835 case MADDF_D: 2900 case MADDF_D:
2836 DCHECK(kArchVariant == kMips64r6); 2901 DCHECK(kArchVariant == kMips64r6);
2837 set_fpu_register_double(fd_reg(), fd + (fs * ft)); 2902 set_fpu_register_double(fd_reg(), fd + (fs * ft));
2838 break; 2903 break;
2839 case MSUBF_D: 2904 case MSUBF_D:
2840 DCHECK(kArchVariant == kMips64r6); 2905 DCHECK(kArchVariant == kMips64r6);
2841 set_fpu_register_double(fd_reg(), fd - (fs * ft)); 2906 set_fpu_register_double(fd_reg(), fd - (fs * ft));
2842 break; 2907 break;
2843 case MUL_D: 2908 case MUL_D:
2844 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));
2845 break; 2913 break;
2846 case DIV_D: 2914 case DIV_D:
2847 set_fpu_register_double(fd_reg(), fs / ft); 2915 set_fpu_register_double(
2916 fd_reg(),
2917 FPUCanonalizeOperation(
2918 [](double lhs, double rhs) { return lhs / rhs; }, fs, ft));
2848 break; 2919 break;
2849 case ABS_D: 2920 case ABS_D:
2850 set_fpu_register_double(fd_reg(), fabs(fs)); 2921 set_fpu_register_double(
2922 fd_reg(),
2923 FPUCanonalizeOperation([](double fs) { return FPAbs(fs); }, fs));
2851 break; 2924 break;
2852 case MOV_D: 2925 case MOV_D:
2853 set_fpu_register_double(fd_reg(), fs); 2926 set_fpu_register_double(fd_reg(), fs);
2854 break; 2927 break;
2855 case NEG_D: 2928 case NEG_D:
2856 set_fpu_register_double(fd_reg(), -fs); 2929 set_fpu_register_double(
2930 fd_reg(), FPUCanonalizeOperation([](double src) { return -src; },
2931 KeepSign::yes, fs));
2857 break; 2932 break;
2858 case SQRT_D: 2933 case SQRT_D:
2859 lazily_initialize_fast_sqrt(isolate_); 2934 set_fpu_register_double(
2860 set_fpu_register_double(fd_reg(), fast_sqrt(fs, isolate_)); 2935 fd_reg(),
2936 FPUCanonalizeOperation([](double fs) { return std::sqrt(fs); }, fs));
2861 break; 2937 break;
2862 case RSQRT_D: { 2938 case RSQRT_D:
2863 lazily_initialize_fast_sqrt(isolate_); 2939 set_fpu_register_double(
2864 double result = 1.0 / fast_sqrt(fs, isolate_); 2940 fd_reg(), FPUCanonalizeOperation(
2865 set_fpu_register_double(fd_reg(), result); 2941 [](double fs) { return 1.0 / std::sqrt(fs); }, fs));
2866 break; 2942 break;
2867 } 2943 case RECIP_D:
2868 case RECIP_D: { 2944 set_fpu_register_double(
2869 double result = 1.0 / fs; 2945 fd_reg(),
2870 set_fpu_register_double(fd_reg(), result); 2946 FPUCanonalizeOperation([](double fs) { return 1.0 / fs; }, fs));
2871 break; 2947 break;
2872 }
2873 case C_UN_D: 2948 case C_UN_D:
2874 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft)); 2949 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft));
2875 break; 2950 break;
2876 case C_EQ_D: 2951 case C_EQ_D:
2877 set_fcsr_bit(fcsr_cc, (fs == ft)); 2952 set_fcsr_bit(fcsr_cc, (fs == ft));
2878 break; 2953 break;
2879 case C_UEQ_D: 2954 case C_UEQ_D:
2880 set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft))); 2955 set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft)));
2881 break; 2956 break;
2882 case C_OLT_D: 2957 case C_OLT_D:
(...skipping 2095 matching lines...) Expand 10 before | Expand all | Expand 10 after
4978 } 5053 }
4979 5054
4980 5055
4981 #undef UNSUPPORTED 5056 #undef UNSUPPORTED
4982 } // namespace internal 5057 } // namespace internal
4983 } // namespace v8 5058 } // namespace v8
4984 5059
4985 #endif // USE_SIMULATOR 5060 #endif // USE_SIMULATOR
4986 5061
4987 #endif // V8_TARGET_ARCH_MIPS64 5062 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW
« no previous file with comments | « src/mips/simulator-mips.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698