| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |