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

Side by Side Diff: src/mips/simulator-mips.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 | « no previous file | src/mips64/simulator-mips64.cc » ('j') | 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_MIPS 10 #if V8_TARGET_ARCH_MIPS
(...skipping 2348 matching lines...) Expand 10 before | Expand all | Expand 10 after
2359 result = a; 2359 result = a;
2360 } else if (FPAbs(b) > FPAbs(a)) { 2360 } else if (FPAbs(b) > FPAbs(a)) {
2361 result = b; 2361 result = b;
2362 } else { 2362 } else {
2363 result = a > b ? a : b; 2363 result = a > b ? a : b;
2364 } 2364 }
2365 } 2365 }
2366 return result; 2366 return result;
2367 } 2367 }
2368 2368
2369 enum class KeepSign : bool { no = false, yes };
2370
2371 template <typename T, typename std::enable_if<std::is_floating_point<T>::value,
2372 int>::type = 0>
2373 T FPUCanonalizeNaNArg(T result, T arg, KeepSign keepSign = KeepSign::no) {
2374 DCHECK(std::isnan(arg));
2375 T qNaN = std::numeric_limits<T>::quiet_NaN();
2376 if (keepSign == KeepSign::yes) {
2377 return std::copysign(qNaN, result);
2378 }
2379 return qNaN;
2380 }
2381
2382 template <typename T>
2383 T FPUCanonalizeNaNArgs(T result, KeepSign keepSign, T first) {
2384 if (std::isnan(first)) {
2385 return FPUCanonalizeNaNArg(result, first, keepSign);
2386 }
2387 return result;
2388 }
2389
2390 template <typename T, typename... Args>
2391 T FPUCanonalizeNaNArgs(T result, KeepSign keepSign, T first, Args... args) {
2392 if (std::isnan(first)) {
2393 return FPUCanonalizeNaNArg(result, first, keepSign);
2394 }
2395 return FPUCanonalizeNaNArgs(result, keepSign, args...);
2396 }
2397
2398 template <typename Func, typename T, typename... Args>
2399 T FPUCanonalizeOperation(Func f, T first, Args... args) {
2400 return FPUCanonalizeOperation(f, KeepSign::no, first, args...);
2401 }
2402
2403 template <typename Func, typename T, typename... Args>
2404 T FPUCanonalizeOperation(Func f, KeepSign keepSign, T first, Args... args) {
2405 T result = f(first, args...);
2406 if (std::isnan(result)) {
2407 result = FPUCanonalizeNaNArgs(result, keepSign, first, args...);
2408 }
2409 return result;
2410 }
2411
2369 // Handle execution based on instruction types. 2412 // Handle execution based on instruction types.
2370 2413
2371 void Simulator::DecodeTypeRegisterDRsType() { 2414 void Simulator::DecodeTypeRegisterDRsType() {
2372 double ft, fs, fd; 2415 double ft, fs, fd;
2373 uint32_t cc, fcsr_cc; 2416 uint32_t cc, fcsr_cc;
2374 int64_t i64; 2417 int64_t i64;
2375 fs = get_fpu_register_double(fs_reg()); 2418 fs = get_fpu_register_double(fs_reg());
2376 ft = (get_instr()->FunctionFieldRaw() != MOVF) 2419 ft = (get_instr()->FunctionFieldRaw() != MOVF)
2377 ? get_fpu_register_double(ft_reg()) 2420 ? get_fpu_register_double(ft_reg())
2378 : 0.0; 2421 : 0.0;
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
2470 break; 2513 break;
2471 case MINA: 2514 case MINA:
2472 DCHECK(IsMipsArchVariant(kMips32r6)); 2515 DCHECK(IsMipsArchVariant(kMips32r6));
2473 set_fpu_register_double(fd_reg(), FPUMinA(ft, fs)); 2516 set_fpu_register_double(fd_reg(), FPUMinA(ft, fs));
2474 break; 2517 break;
2475 case MAXA: 2518 case MAXA:
2476 DCHECK(IsMipsArchVariant(kMips32r6)); 2519 DCHECK(IsMipsArchVariant(kMips32r6));
2477 set_fpu_register_double(fd_reg(), FPUMaxA(ft, fs)); 2520 set_fpu_register_double(fd_reg(), FPUMaxA(ft, fs));
2478 break; 2521 break;
2479 case ADD_D: 2522 case ADD_D:
2480 set_fpu_register_double(fd_reg(), fs + ft); 2523 set_fpu_register_double(
2524 fd_reg(),
2525 FPUCanonalizeOperation(
2526 [](double lhs, double rhs) { return lhs + rhs; }, fs, ft));
2481 break; 2527 break;
2482 case SUB_D: 2528 case SUB_D:
2483 set_fpu_register_double(fd_reg(), fs - ft); 2529 set_fpu_register_double(
2530 fd_reg(),
2531 FPUCanonalizeOperation(
2532 [](double lhs, double rhs) { return lhs - rhs; }, fs, ft));
2484 break; 2533 break;
2485 case MADDF_D: 2534 case MADDF_D:
2486 DCHECK(IsMipsArchVariant(kMips32r6)); 2535 DCHECK(IsMipsArchVariant(kMips32r6));
2487 set_fpu_register_double(fd_reg(), fd + (fs * ft)); 2536 set_fpu_register_double(fd_reg(), fd + (fs * ft));
2488 break; 2537 break;
2489 case MSUBF_D: 2538 case MSUBF_D:
2490 DCHECK(IsMipsArchVariant(kMips32r6)); 2539 DCHECK(IsMipsArchVariant(kMips32r6));
2491 set_fpu_register_double(fd_reg(), fd - (fs * ft)); 2540 set_fpu_register_double(fd_reg(), fd - (fs * ft));
2492 break; 2541 break;
2493 case MUL_D: 2542 case MUL_D:
2494 set_fpu_register_double(fd_reg(), fs * ft); 2543 set_fpu_register_double(
2544 fd_reg(),
2545 FPUCanonalizeOperation(
2546 [](double lhs, double rhs) { return lhs * rhs; }, fs, ft));
2495 break; 2547 break;
2496 case DIV_D: 2548 case DIV_D:
2497 set_fpu_register_double(fd_reg(), fs / ft); 2549 set_fpu_register_double(
2550 fd_reg(),
2551 FPUCanonalizeOperation(
2552 [](double lhs, double rhs) { return lhs / rhs; }, fs, ft));
2498 break; 2553 break;
2499 case ABS_D: 2554 case ABS_D:
2500 set_fpu_register_double(fd_reg(), fabs(fs)); 2555 set_fpu_register_double(
2556 fd_reg(),
2557 FPUCanonalizeOperation([](double fs) { return FPAbs(fs); }, fs));
2501 break; 2558 break;
2502 case MOV_D: 2559 case MOV_D:
2503 set_fpu_register_double(fd_reg(), fs); 2560 set_fpu_register_double(fd_reg(), fs);
2504 break; 2561 break;
2505 case NEG_D: 2562 case NEG_D:
2506 set_fpu_register_double(fd_reg(), -fs); 2563 set_fpu_register_double(
2564 fd_reg(), FPUCanonalizeOperation([](double src) { return -src; },
2565 KeepSign::yes, fs));
2507 break; 2566 break;
2508 case SQRT_D: 2567 case SQRT_D:
2509 lazily_initialize_fast_sqrt(isolate_); 2568 set_fpu_register_double(
2510 set_fpu_register_double(fd_reg(), fast_sqrt(fs, isolate_)); 2569 fd_reg(),
2570 FPUCanonalizeOperation([](double fs) { return std::sqrt(fs); }, fs));
2511 break; 2571 break;
2512 case RSQRT_D: { 2572 case RSQRT_D:
2513 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 2573 set_fpu_register_double(
2514 lazily_initialize_fast_sqrt(isolate_); 2574 fd_reg(), FPUCanonalizeOperation(
2515 double result = 1.0 / fast_sqrt(fs, isolate_); 2575 [](double fs) { return 1.0 / std::sqrt(fs); }, fs));
2516 set_fpu_register_double(fd_reg(), result);
2517 break; 2576 break;
2518 } 2577 case RECIP_D:
2519 case RECIP_D: { 2578 set_fpu_register_double(
2520 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 2579 fd_reg(),
2521 double result = 1.0 / fs; 2580 FPUCanonalizeOperation([](double fs) { return 1.0 / fs; }, fs));
2522 set_fpu_register_double(fd_reg(), result);
2523 break; 2581 break;
2524 }
2525 case C_UN_D: 2582 case C_UN_D:
2526 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft)); 2583 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft));
2527 break; 2584 break;
2528 case C_EQ_D: 2585 case C_EQ_D:
2529 set_fcsr_bit(fcsr_cc, (fs == ft)); 2586 set_fcsr_bit(fcsr_cc, (fs == ft));
2530 break; 2587 break;
2531 case C_UEQ_D: 2588 case C_UEQ_D:
2532 set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft))); 2589 set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft)));
2533 break; 2590 break;
2534 case C_OLT_D: 2591 case C_OLT_D:
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
2883 result = lower; 2940 result = lower;
2884 break; 2941 break;
2885 } 2942 }
2886 set_fpu_register_float(fd_reg(), result); 2943 set_fpu_register_float(fd_reg(), result);
2887 if (result != fs) { 2944 if (result != fs) {
2888 set_fcsr_bit(kFCSRInexactFlagBit, true); 2945 set_fcsr_bit(kFCSRInexactFlagBit, true);
2889 } 2946 }
2890 break; 2947 break;
2891 } 2948 }
2892 case ADD_S: 2949 case ADD_S:
2893 set_fpu_register_float(fd_reg(), fs + ft); 2950 set_fpu_register_float(
2951 fd_reg(),
2952 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs + rhs; },
2953 fs, ft));
2894 break; 2954 break;
2895 case SUB_S: 2955 case SUB_S:
2896 set_fpu_register_float(fd_reg(), fs - ft); 2956 set_fpu_register_float(
2957 fd_reg(),
2958 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs - rhs; },
2959 fs, ft));
2897 break; 2960 break;
2898 case MADDF_S: 2961 case MADDF_S:
2899 DCHECK(IsMipsArchVariant(kMips32r6)); 2962 DCHECK(IsMipsArchVariant(kMips32r6));
2900 set_fpu_register_float(fd_reg(), fd + (fs * ft)); 2963 set_fpu_register_float(fd_reg(), fd + (fs * ft));
2901 break; 2964 break;
2902 case MSUBF_S: 2965 case MSUBF_S:
2903 DCHECK(IsMipsArchVariant(kMips32r6)); 2966 DCHECK(IsMipsArchVariant(kMips32r6));
2904 set_fpu_register_float(fd_reg(), fd - (fs * ft)); 2967 set_fpu_register_float(fd_reg(), fd - (fs * ft));
2905 break; 2968 break;
2906 case MUL_S: 2969 case MUL_S:
2907 set_fpu_register_float(fd_reg(), fs * ft); 2970 set_fpu_register_float(
2971 fd_reg(),
2972 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs * rhs; },
2973 fs, ft));
2908 break; 2974 break;
2909 case DIV_S: 2975 case DIV_S:
2910 set_fpu_register_float(fd_reg(), fs / ft); 2976 set_fpu_register_float(
2977 fd_reg(),
2978 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs / rhs; },
2979 fs, ft));
2911 break; 2980 break;
2912 case ABS_S: 2981 case ABS_S:
2913 set_fpu_register_float(fd_reg(), fabs(fs)); 2982 set_fpu_register_float(
2983 fd_reg(),
2984 FPUCanonalizeOperation([](float fs) { return FPAbs(fs); }, fs));
2914 break; 2985 break;
2915 case MOV_S: 2986 case MOV_S:
2916 set_fpu_register_float(fd_reg(), fs); 2987 set_fpu_register_float(fd_reg(), fs);
2917 break; 2988 break;
2918 case NEG_S: 2989 case NEG_S:
2919 set_fpu_register_float(fd_reg(), -fs); 2990 set_fpu_register_float(
2991 fd_reg(), FPUCanonalizeOperation([](float src) { return -src; },
2992 KeepSign::yes, fs));
2920 break; 2993 break;
2921 case SQRT_S: 2994 case SQRT_S:
2922 lazily_initialize_fast_sqrt(isolate_); 2995 set_fpu_register_float(
2923 set_fpu_register_float(fd_reg(), fast_sqrt(fs, isolate_)); 2996 fd_reg(),
2997 FPUCanonalizeOperation([](float src) { return std::sqrt(src); }, fs));
2924 break; 2998 break;
2925 case RSQRT_S: { 2999 case RSQRT_S:
2926 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 3000 set_fpu_register_float(
2927 lazily_initialize_fast_sqrt(isolate_); 3001 fd_reg(), FPUCanonalizeOperation(
2928 float result = 1.0 / fast_sqrt(fs, isolate_); 3002 [](float src) { return 1.0 / std::sqrt(src); }, fs));
2929 set_fpu_register_float(fd_reg(), result);
2930 break; 3003 break;
2931 } 3004 case RECIP_S:
2932 case RECIP_S: { 3005 set_fpu_register_float(
2933 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 3006 fd_reg(),
2934 float result = 1.0 / fs; 3007 FPUCanonalizeOperation([](float src) { return 1.0 / src; }, fs));
2935 set_fpu_register_float(fd_reg(), result);
2936 break; 3008 break;
2937 }
2938 case C_F_D: 3009 case C_F_D:
2939 set_fcsr_bit(fcsr_cc, false); 3010 set_fcsr_bit(fcsr_cc, false);
2940 break; 3011 break;
2941 case C_UN_D: 3012 case C_UN_D:
2942 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft)); 3013 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft));
2943 break; 3014 break;
2944 case C_EQ_D: 3015 case C_EQ_D:
2945 set_fcsr_bit(fcsr_cc, (fs == ft)); 3016 set_fcsr_bit(fcsr_cc, (fs == ft));
2946 break; 3017 break;
2947 case C_UEQ_D: 3018 case C_UEQ_D:
(...skipping 1678 matching lines...) Expand 10 before | Expand all | Expand 10 after
4626 4697
4627 4698
4628 #undef UNSUPPORTED 4699 #undef UNSUPPORTED
4629 4700
4630 } // namespace internal 4701 } // namespace internal
4631 } // namespace v8 4702 } // namespace v8
4632 4703
4633 #endif // USE_SIMULATOR 4704 #endif // USE_SIMULATOR
4634 4705
4635 #endif // V8_TARGET_ARCH_MIPS 4706 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « no previous file | src/mips64/simulator-mips64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698