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

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

Issue 1668143002: MIPS: Fix FPU min, max, mina, maxa in simulator. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 10 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/mips64/simulator-mips64.h ('k') | test/cctest/test-assembler-mips.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_MIPS64 10 #if V8_TARGET_ARCH_MIPS64
(...skipping 2314 matching lines...) Expand 10 before | Expand all | Expand 10 after
2325 } 2325 }
2326 } 2326 }
2327 } 2327 }
2328 2328
2329 2329
2330 void Simulator::SignalException(Exception e) { 2330 void Simulator::SignalException(Exception e) {
2331 V8_Fatal(__FILE__, __LINE__, "Error: Exception %i raised.", 2331 V8_Fatal(__FILE__, __LINE__, "Error: Exception %i raised.",
2332 static_cast<int>(e)); 2332 static_cast<int>(e));
2333 } 2333 }
2334 2334
2335 template <typename T>
2336 T FPAbs(T a);
2337
2338 template <>
2339 double FPAbs<double>(double a) {
2340 return fabs(a);
2341 }
2342
2343 template <>
2344 float FPAbs<float>(float a) {
2345 return fabsf(a);
2346 }
2347
2348 template <typename T>
2349 bool Simulator::FPUProcessNaNsAndZeros(T a, T b, IsMin min, T& result) {
2350 if (std::isnan(a) && std::isnan(b)) {
2351 result = a;
2352 } else if (std::isnan(a)) {
2353 result = b;
2354 } else if (std::isnan(b)) {
2355 result = a;
2356 } else if (b == a) {
2357 // Handle -0.0 == 0.0 case.
2358 // std::signbit() returns int 0 or 1 so substracting IsMin::kMax negates the
2359 // result.
2360 result = std::signbit(b) - static_cast<int>(min) ? b : a;
2361 } else {
2362 return false;
2363 }
2364 return true;
2365 }
2366
2367 template <typename T>
2368 T Simulator::FPUMin(T a, T b) {
2369 T result;
2370 if (FPUProcessNaNsAndZeros(a, b, IsMin::kMin, result)) {
2371 return result;
2372 } else {
2373 return b < a ? b : a;
2374 }
2375 }
2376
2377 template <typename T>
2378 T Simulator::FPUMax(T a, T b) {
2379 T result;
2380 if (FPUProcessNaNsAndZeros(a, b, IsMin::kMax, result)) {
2381 return result;
2382 } else {
2383 return b > a ? b : a;
2384 }
2385 }
2386
2387 template <typename T>
2388 T Simulator::FPUMinA(T a, T b) {
2389 T result;
2390 if (!FPUProcessNaNsAndZeros(a, b, IsMin::kMin, result)) {
2391 if (FPAbs(a) < FPAbs(b)) {
2392 result = a;
2393 } else if (FPAbs(b) < FPAbs(a)) {
2394 result = b;
2395 } else {
2396 result = a < b ? a : b;
2397 }
2398 }
2399 return result;
2400 }
2401
2402 template <typename T>
2403 T Simulator::FPUMaxA(T a, T b) {
2404 T result;
2405 if (!FPUProcessNaNsAndZeros(a, b, IsMin::kMin, result)) {
2406 if (FPAbs(a) > FPAbs(b)) {
2407 result = a;
2408 } else if (FPAbs(b) > FPAbs(a)) {
2409 result = b;
2410 } else {
2411 result = a > b ? a : b;
2412 }
2413 }
2414 return result;
2415 }
2335 2416
2336 // Handle execution based on instruction types. 2417 // Handle execution based on instruction types.
2337 2418
2338 void Simulator::DecodeTypeRegisterSRsType() { 2419 void Simulator::DecodeTypeRegisterSRsType() {
2339 float fs, ft, fd; 2420 float fs, ft, fd;
2340 fs = get_fpu_register_float(fs_reg()); 2421 fs = get_fpu_register_float(fs_reg());
2341 ft = get_fpu_register_float(ft_reg()); 2422 ft = get_fpu_register_float(ft_reg());
2342 fd = get_fpu_register_float(fd_reg()); 2423 fd = get_fpu_register_float(fd_reg());
2343 int32_t ft_int = bit_cast<int32_t>(ft); 2424 int32_t ft_int = bit_cast<int32_t>(ft);
2344 int32_t fd_int = bit_cast<int32_t>(fd); 2425 int32_t fd_int = bit_cast<int32_t>(fd);
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
2609 float rounded = ceil(fs); 2690 float rounded = ceil(fs);
2610 int64_t result = static_cast<int64_t>(rounded); 2691 int64_t result = static_cast<int64_t>(rounded);
2611 set_fpu_register(fd_reg(), result); 2692 set_fpu_register(fd_reg(), result);
2612 if (set_fcsr_round64_error(fs, rounded)) { 2693 if (set_fcsr_round64_error(fs, rounded)) {
2613 set_fpu_register_invalid_result64(fs, rounded); 2694 set_fpu_register_invalid_result64(fs, rounded);
2614 } 2695 }
2615 break; 2696 break;
2616 } 2697 }
2617 case MINA: 2698 case MINA:
2618 DCHECK(kArchVariant == kMips64r6); 2699 DCHECK(kArchVariant == kMips64r6);
2619 fs = get_fpu_register_float(fs_reg()); 2700 set_fpu_register_float(fd_reg(), FPUMinA(ft, fs));
2620 if (std::isnan(fs) && std::isnan(ft)) {
2621 set_fpu_register_float(fd_reg(), fs);
2622 } else if (std::isnan(fs) && !std::isnan(ft)) {
2623 set_fpu_register_float(fd_reg(), ft);
2624 } else if (!std::isnan(fs) && std::isnan(ft)) {
2625 set_fpu_register_float(fd_reg(), fs);
2626 } else {
2627 float result;
2628 if (fabs(fs) > fabs(ft)) {
2629 result = ft;
2630 } else if (fabs(fs) < fabs(ft)) {
2631 result = fs;
2632 } else {
2633 result = (fs < ft ? fs : ft);
2634 }
2635 set_fpu_register_float(fd_reg(), result);
2636 }
2637 break; 2701 break;
2638 case MAXA: 2702 case MAXA:
2639 DCHECK(kArchVariant == kMips64r6); 2703 DCHECK(kArchVariant == kMips64r6);
2640 fs = get_fpu_register_float(fs_reg()); 2704 set_fpu_register_float(fd_reg(), FPUMaxA(ft, fs));
2641 if (std::isnan(fs) && std::isnan(ft)) {
2642 set_fpu_register_float(fd_reg(), fs);
2643 } else if (std::isnan(fs) && !std::isnan(ft)) {
2644 set_fpu_register_float(fd_reg(), ft);
2645 } else if (!std::isnan(fs) && std::isnan(ft)) {
2646 set_fpu_register_float(fd_reg(), fs);
2647 } else {
2648 float result;
2649 if (fabs(fs) < fabs(ft)) {
2650 result = ft;
2651 } else if (fabs(fs) > fabs(ft)) {
2652 result = fs;
2653 } else {
2654 result = (fs > ft ? fs : ft);
2655 }
2656 set_fpu_register_float(fd_reg(), result);
2657 }
2658 break; 2705 break;
2659 case MIN: 2706 case MIN:
2660 DCHECK(kArchVariant == kMips64r6); 2707 DCHECK(kArchVariant == kMips64r6);
2661 fs = get_fpu_register_float(fs_reg()); 2708 set_fpu_register_float(fd_reg(), FPUMin(ft, fs));
2662 if (std::isnan(fs) && std::isnan(ft)) {
2663 set_fpu_register_float(fd_reg(), fs);
2664 } else if (std::isnan(fs) && !std::isnan(ft)) {
2665 set_fpu_register_float(fd_reg(), ft);
2666 } else if (!std::isnan(fs) && std::isnan(ft)) {
2667 set_fpu_register_float(fd_reg(), fs);
2668 } else {
2669 set_fpu_register_float(fd_reg(), (fs >= ft) ? ft : fs);
2670 }
2671 break; 2709 break;
2672 case MAX: 2710 case MAX:
2673 DCHECK(kArchVariant == kMips64r6); 2711 DCHECK(kArchVariant == kMips64r6);
2674 fs = get_fpu_register_float(fs_reg()); 2712 set_fpu_register_float(fd_reg(), FPUMax(ft, fs));
2675 if (std::isnan(fs) && std::isnan(ft)) {
2676 set_fpu_register_float(fd_reg(), fs);
2677 } else if (std::isnan(fs) && !std::isnan(ft)) {
2678 set_fpu_register_float(fd_reg(), ft);
2679 } else if (!std::isnan(fs) && std::isnan(ft)) {
2680 set_fpu_register_float(fd_reg(), fs);
2681 } else {
2682 set_fpu_register_float(fd_reg(), (fs <= ft) ? ft : fs);
2683 }
2684 break; 2713 break;
2685 case SEL: 2714 case SEL:
2686 DCHECK(kArchVariant == kMips64r6); 2715 DCHECK(kArchVariant == kMips64r6);
2687 set_fpu_register_float(fd_reg(), (fd_int & 0x1) == 0 ? fs : ft); 2716 set_fpu_register_float(fd_reg(), (fd_int & 0x1) == 0 ? fs : ft);
2688 break; 2717 break;
2689 case SELEQZ_C: 2718 case SELEQZ_C:
2690 DCHECK(kArchVariant == kMips64r6); 2719 DCHECK(kArchVariant == kMips64r6);
2691 set_fpu_register_float(fd_reg(), (ft_int & 0x1) == 0 2720 set_fpu_register_float(fd_reg(), (ft_int & 0x1) == 0
2692 ? get_fpu_register_float(fs_reg()) 2721 ? get_fpu_register_float(fs_reg())
2693 : 0.0); 2722 : 0.0);
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
2818 // MOVT.D 2847 // MOVT.D
2819 if (test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg(), fs); 2848 if (test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg(), fs);
2820 } else { 2849 } else {
2821 // MOVF.D 2850 // MOVF.D
2822 if (!test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg(), fs); 2851 if (!test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg(), fs);
2823 } 2852 }
2824 break; 2853 break;
2825 } 2854 }
2826 case MINA: 2855 case MINA:
2827 DCHECK(kArchVariant == kMips64r6); 2856 DCHECK(kArchVariant == kMips64r6);
2828 fs = get_fpu_register_double(fs_reg()); 2857 set_fpu_register_double(fd_reg(), FPUMinA(ft, fs));
2829 if (std::isnan(fs) && std::isnan(ft)) {
2830 set_fpu_register_double(fd_reg(), fs);
2831 } else if (std::isnan(fs) && !std::isnan(ft)) {
2832 set_fpu_register_double(fd_reg(), ft);
2833 } else if (!std::isnan(fs) && std::isnan(ft)) {
2834 set_fpu_register_double(fd_reg(), fs);
2835 } else {
2836 double result;
2837 if (fabs(fs) > fabs(ft)) {
2838 result = ft;
2839 } else if (fabs(fs) < fabs(ft)) {
2840 result = fs;
2841 } else {
2842 result = (fs < ft ? fs : ft);
2843 }
2844 set_fpu_register_double(fd_reg(), result);
2845 }
2846 break; 2858 break;
2847 case MAXA: 2859 case MAXA:
2848 DCHECK(kArchVariant == kMips64r6); 2860 DCHECK(kArchVariant == kMips64r6);
2849 fs = get_fpu_register_double(fs_reg()); 2861 set_fpu_register_double(fd_reg(), FPUMaxA(ft, fs));
2850 if (std::isnan(fs) && std::isnan(ft)) {
2851 set_fpu_register_double(fd_reg(), fs);
2852 } else if (std::isnan(fs) && !std::isnan(ft)) {
2853 set_fpu_register_double(fd_reg(), ft);
2854 } else if (!std::isnan(fs) && std::isnan(ft)) {
2855 set_fpu_register_double(fd_reg(), fs);
2856 } else {
2857 double result;
2858 if (fabs(fs) < fabs(ft)) {
2859 result = ft;
2860 } else if (fabs(fs) > fabs(ft)) {
2861 result = fs;
2862 } else {
2863 result = (fs > ft ? fs : ft);
2864 }
2865 set_fpu_register_double(fd_reg(), result);
2866 }
2867 break; 2862 break;
2868 case MIN: 2863 case MIN:
2869 DCHECK(kArchVariant == kMips64r6); 2864 DCHECK(kArchVariant == kMips64r6);
2870 fs = get_fpu_register_double(fs_reg()); 2865 set_fpu_register_double(fd_reg(), FPUMin(ft, fs));
2871 if (std::isnan(fs) && std::isnan(ft)) {
2872 set_fpu_register_double(fd_reg(), fs);
2873 } else if (std::isnan(fs) && !std::isnan(ft)) {
2874 set_fpu_register_double(fd_reg(), ft);
2875 } else if (!std::isnan(fs) && std::isnan(ft)) {
2876 set_fpu_register_double(fd_reg(), fs);
2877 } else {
2878 set_fpu_register_double(fd_reg(), (fs >= ft) ? ft : fs);
2879 }
2880 break; 2866 break;
2881 case MAX: 2867 case MAX:
2882 DCHECK(kArchVariant == kMips64r6); 2868 DCHECK(kArchVariant == kMips64r6);
2883 fs = get_fpu_register_double(fs_reg()); 2869 set_fpu_register_double(fd_reg(), FPUMax(ft, fs));
2884 if (std::isnan(fs) && std::isnan(ft)) {
2885 set_fpu_register_double(fd_reg(), fs);
2886 } else if (std::isnan(fs) && !std::isnan(ft)) {
2887 set_fpu_register_double(fd_reg(), ft);
2888 } else if (!std::isnan(fs) && std::isnan(ft)) {
2889 set_fpu_register_double(fd_reg(), fs);
2890 } else {
2891 set_fpu_register_double(fd_reg(), (fs <= ft) ? ft : fs);
2892 }
2893 break; 2870 break;
2894 case ADD_D: 2871 case ADD_D:
2895 set_fpu_register_double(fd_reg(), fs + ft); 2872 set_fpu_register_double(fd_reg(), fs + ft);
2896 break; 2873 break;
2897 case SUB_D: 2874 case SUB_D:
2898 set_fpu_register_double(fd_reg(), fs - ft); 2875 set_fpu_register_double(fd_reg(), fs - ft);
2899 break; 2876 break;
2900 case MUL_D: 2877 case MUL_D:
2901 set_fpu_register_double(fd_reg(), fs * ft); 2878 set_fpu_register_double(fd_reg(), fs * ft);
2902 break; 2879 break;
(...skipping 1980 matching lines...) Expand 10 before | Expand all | Expand 10 after
4883 } 4860 }
4884 4861
4885 4862
4886 #undef UNSUPPORTED 4863 #undef UNSUPPORTED
4887 } // namespace internal 4864 } // namespace internal
4888 } // namespace v8 4865 } // namespace v8
4889 4866
4890 #endif // USE_SIMULATOR 4867 #endif // USE_SIMULATOR
4891 4868
4892 #endif // V8_TARGET_ARCH_MIPS64 4869 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW
« no previous file with comments | « src/mips64/simulator-mips64.h ('k') | test/cctest/test-assembler-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698