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

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

Issue 14109010: ARM: Enable VFP default NaN mode (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Address review comments Created 7 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « src/arm/simulator-arm.h ('k') | src/arm/stub-cache-arm.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 755 matching lines...) Expand 10 before | Expand all | Expand 10 after
766 // even though s_registers_ & d_registers_ share the same 766 // even though s_registers_ & d_registers_ share the same
767 // physical registers in the target. 767 // physical registers in the target.
768 for (int i = 0; i < num_d_registers * 2; i++) { 768 for (int i = 0; i < num_d_registers * 2; i++) {
769 vfp_registers_[i] = 0; 769 vfp_registers_[i] = 0;
770 } 770 }
771 n_flag_FPSCR_ = false; 771 n_flag_FPSCR_ = false;
772 z_flag_FPSCR_ = false; 772 z_flag_FPSCR_ = false;
773 c_flag_FPSCR_ = false; 773 c_flag_FPSCR_ = false;
774 v_flag_FPSCR_ = false; 774 v_flag_FPSCR_ = false;
775 FPSCR_rounding_mode_ = RZ; 775 FPSCR_rounding_mode_ = RZ;
776 FPSCR_default_NaN_mode_ = true;
776 777
777 inv_op_vfp_flag_ = false; 778 inv_op_vfp_flag_ = false;
778 div_zero_vfp_flag_ = false; 779 div_zero_vfp_flag_ = false;
779 overflow_vfp_flag_ = false; 780 overflow_vfp_flag_ = false;
780 underflow_vfp_flag_ = false; 781 underflow_vfp_flag_ = false;
781 inexact_vfp_flag_ = false; 782 inexact_vfp_flag_ = false;
782 783
783 // The sp is initialized to point to the bottom (high address) of the 784 // The sp is initialized to point to the bottom (high address) of the
784 // allocated stack area. To be safe in potential stack underflows we leave 785 // allocated stack area. To be safe in potential stack underflows we leave
785 // some buffer below. 786 // some buffer below.
(...skipping 1075 matching lines...) Expand 10 before | Expand all | Expand 10 after
1861 } else { 1862 } else {
1862 // This is not a valid svc code. 1863 // This is not a valid svc code.
1863 UNREACHABLE(); 1864 UNREACHABLE();
1864 break; 1865 break;
1865 } 1866 }
1866 } 1867 }
1867 } 1868 }
1868 } 1869 }
1869 1870
1870 1871
1872 double Simulator::canonicalizeNaN(double value) {
1873 return (FPSCR_default_NaN_mode_ && isnan(value)) ?
1874 FixedDoubleArray::canonical_not_the_hole_nan_as_double(): value;
ulan 2013/04/15 15:00:56 Add space before ":".
1875 }
1876
1871 // Stop helper functions. 1877 // Stop helper functions.
1872 bool Simulator::isStopInstruction(Instruction* instr) { 1878 bool Simulator::isStopInstruction(Instruction* instr) {
1873 return (instr->Bits(27, 24) == 0xF) && (instr->SvcValue() >= kStopCode); 1879 return (instr->Bits(27, 24) == 0xF) && (instr->SvcValue() >= kStopCode);
1874 } 1880 }
1875 1881
1876 1882
1877 bool Simulator::isWatchedStop(uint32_t code) { 1883 bool Simulator::isWatchedStop(uint32_t code) {
1878 ASSERT(code <= kMaxStopCode); 1884 ASSERT(code <= kMaxStopCode);
1879 return code < kNumOfWatchedStops; 1885 return code < kNumOfWatchedStops;
1880 } 1886 }
(...skipping 840 matching lines...) Expand 10 before | Expand all | Expand 10 after
2721 set_d_register_from_double(d, get_double_from_d_register(m)); 2727 set_d_register_from_double(d, get_double_from_d_register(m));
2722 } else { 2728 } else {
2723 int m = instr->VFPMRegValue(kSinglePrecision); 2729 int m = instr->VFPMRegValue(kSinglePrecision);
2724 int d = instr->VFPDRegValue(kSinglePrecision); 2730 int d = instr->VFPDRegValue(kSinglePrecision);
2725 set_s_register_from_float(d, get_float_from_s_register(m)); 2731 set_s_register_from_float(d, get_float_from_s_register(m));
2726 } 2732 }
2727 } else if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x3)) { 2733 } else if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x3)) {
2728 // vabs 2734 // vabs
2729 double dm_value = get_double_from_d_register(vm); 2735 double dm_value = get_double_from_d_register(vm);
2730 double dd_value = fabs(dm_value); 2736 double dd_value = fabs(dm_value);
2737 dd_value = canonicalizeNaN(dd_value);
2731 set_d_register_from_double(vd, dd_value); 2738 set_d_register_from_double(vd, dd_value);
2732 } else if ((instr->Opc2Value() == 0x1) && (instr->Opc3Value() == 0x1)) { 2739 } else if ((instr->Opc2Value() == 0x1) && (instr->Opc3Value() == 0x1)) {
2733 // vneg 2740 // vneg
2734 double dm_value = get_double_from_d_register(vm); 2741 double dm_value = get_double_from_d_register(vm);
2735 double dd_value = -dm_value; 2742 double dd_value = -dm_value;
2743 dd_value = canonicalizeNaN(dd_value);
2736 set_d_register_from_double(vd, dd_value); 2744 set_d_register_from_double(vd, dd_value);
2737 } else if ((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3)) { 2745 } else if ((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3)) {
2738 DecodeVCVTBetweenDoubleAndSingle(instr); 2746 DecodeVCVTBetweenDoubleAndSingle(instr);
2739 } else if ((instr->Opc2Value() == 0x8) && (instr->Opc3Value() & 0x1)) { 2747 } else if ((instr->Opc2Value() == 0x8) && (instr->Opc3Value() & 0x1)) {
2740 DecodeVCVTBetweenFloatingPointAndInteger(instr); 2748 DecodeVCVTBetweenFloatingPointAndInteger(instr);
2741 } else if (((instr->Opc2Value() >> 1) == 0x6) && 2749 } else if (((instr->Opc2Value() >> 1) == 0x6) &&
2742 (instr->Opc3Value() & 0x1)) { 2750 (instr->Opc3Value() & 0x1)) {
2743 DecodeVCVTBetweenFloatingPointAndInteger(instr); 2751 DecodeVCVTBetweenFloatingPointAndInteger(instr);
2744 } else if (((instr->Opc2Value() == 0x4) || (instr->Opc2Value() == 0x5)) && 2752 } else if (((instr->Opc2Value() == 0x4) || (instr->Opc2Value() == 0x5)) &&
2745 (instr->Opc3Value() & 0x1)) { 2753 (instr->Opc3Value() & 0x1)) {
2746 DecodeVCMP(instr); 2754 DecodeVCMP(instr);
2747 } else if (((instr->Opc2Value() == 0x1)) && (instr->Opc3Value() == 0x3)) { 2755 } else if (((instr->Opc2Value() == 0x1)) && (instr->Opc3Value() == 0x3)) {
2748 // vsqrt 2756 // vsqrt
2749 double dm_value = get_double_from_d_register(vm); 2757 double dm_value = get_double_from_d_register(vm);
2750 double dd_value = sqrt(dm_value); 2758 double dd_value = sqrt(dm_value);
2759 dd_value = canonicalizeNaN(dd_value);
2751 set_d_register_from_double(vd, dd_value); 2760 set_d_register_from_double(vd, dd_value);
2752 } else if (instr->Opc3Value() == 0x0) { 2761 } else if (instr->Opc3Value() == 0x0) {
2753 // vmov immediate. 2762 // vmov immediate.
2754 if (instr->SzValue() == 0x1) { 2763 if (instr->SzValue() == 0x1) {
2755 set_d_register_from_double(vd, instr->DoubleImmedVmov()); 2764 set_d_register_from_double(vd, instr->DoubleImmedVmov());
2756 } else { 2765 } else {
2757 UNREACHABLE(); // Not used by v8. 2766 UNREACHABLE(); // Not used by v8.
2758 } 2767 }
2759 } else { 2768 } else {
2760 UNREACHABLE(); // Not used by V8. 2769 UNREACHABLE(); // Not used by V8.
2761 } 2770 }
2762 } else if (instr->Opc1Value() == 0x3) { 2771 } else if (instr->Opc1Value() == 0x3) {
2763 if (instr->SzValue() != 0x1) { 2772 if (instr->SzValue() != 0x1) {
2764 UNREACHABLE(); // Not used by V8. 2773 UNREACHABLE(); // Not used by V8.
2765 } 2774 }
2766 2775
2767 if (instr->Opc3Value() & 0x1) { 2776 if (instr->Opc3Value() & 0x1) {
2768 // vsub 2777 // vsub
2769 double dn_value = get_double_from_d_register(vn); 2778 double dn_value = get_double_from_d_register(vn);
2770 double dm_value = get_double_from_d_register(vm); 2779 double dm_value = get_double_from_d_register(vm);
2771 double dd_value = dn_value - dm_value; 2780 double dd_value = dn_value - dm_value;
2781 dd_value = canonicalizeNaN(dd_value);
2772 set_d_register_from_double(vd, dd_value); 2782 set_d_register_from_double(vd, dd_value);
2773 } else { 2783 } else {
2774 // vadd 2784 // vadd
2775 double dn_value = get_double_from_d_register(vn); 2785 double dn_value = get_double_from_d_register(vn);
2776 double dm_value = get_double_from_d_register(vm); 2786 double dm_value = get_double_from_d_register(vm);
2777 double dd_value = dn_value + dm_value; 2787 double dd_value = dn_value + dm_value;
2788 dd_value = canonicalizeNaN(dd_value);
2778 set_d_register_from_double(vd, dd_value); 2789 set_d_register_from_double(vd, dd_value);
2779 } 2790 }
2780 } else if ((instr->Opc1Value() == 0x2) && !(instr->Opc3Value() & 0x1)) { 2791 } else if ((instr->Opc1Value() == 0x2) && !(instr->Opc3Value() & 0x1)) {
2781 // vmul 2792 // vmul
2782 if (instr->SzValue() != 0x1) { 2793 if (instr->SzValue() != 0x1) {
2783 UNREACHABLE(); // Not used by V8. 2794 UNREACHABLE(); // Not used by V8.
2784 } 2795 }
2785 2796
2786 double dn_value = get_double_from_d_register(vn); 2797 double dn_value = get_double_from_d_register(vn);
2787 double dm_value = get_double_from_d_register(vm); 2798 double dm_value = get_double_from_d_register(vm);
2788 double dd_value = dn_value * dm_value; 2799 double dd_value = dn_value * dm_value;
2800 dd_value = canonicalizeNaN(dd_value);
2789 set_d_register_from_double(vd, dd_value); 2801 set_d_register_from_double(vd, dd_value);
2790 } else if ((instr->Opc1Value() == 0x0)) { 2802 } else if ((instr->Opc1Value() == 0x0)) {
2791 // vmla, vmls 2803 // vmla, vmls
2792 const bool is_vmls = (instr->Opc3Value() & 0x1); 2804 const bool is_vmls = (instr->Opc3Value() & 0x1);
2793 2805
2794 if (instr->SzValue() != 0x1) { 2806 if (instr->SzValue() != 0x1) {
2795 UNREACHABLE(); // Not used by V8. 2807 UNREACHABLE(); // Not used by V8.
2796 } 2808 }
2797 2809
2798 const double dd_val = get_double_from_d_register(vd); 2810 const double dd_val = get_double_from_d_register(vd);
2799 const double dn_val = get_double_from_d_register(vn); 2811 const double dn_val = get_double_from_d_register(vn);
2800 const double dm_val = get_double_from_d_register(vm); 2812 const double dm_val = get_double_from_d_register(vm);
2801 2813
2802 // Note: we do the mul and add/sub in separate steps to avoid getting a 2814 // Note: we do the mul and add/sub in separate steps to avoid getting a
2803 // result with too high precision. 2815 // result with too high precision.
2804 set_d_register_from_double(vd, dn_val * dm_val); 2816 set_d_register_from_double(vd, dn_val * dm_val);
2805 if (is_vmls) { 2817 if (is_vmls) {
2806 set_d_register_from_double(vd, dd_val - get_double_from_d_register(vd)); 2818 set_d_register_from_double(
2819 vd,
2820 canonicalizeNaN(dd_val - get_double_from_d_register(vd)));
2807 } else { 2821 } else {
2808 set_d_register_from_double(vd, dd_val + get_double_from_d_register(vd)); 2822 set_d_register_from_double(
2823 vd,
2824 canonicalizeNaN(dd_val + get_double_from_d_register(vd)));
2809 } 2825 }
2810 } else if ((instr->Opc1Value() == 0x4) && !(instr->Opc3Value() & 0x1)) { 2826 } else if ((instr->Opc1Value() == 0x4) && !(instr->Opc3Value() & 0x1)) {
2811 // vdiv 2827 // vdiv
2812 if (instr->SzValue() != 0x1) { 2828 if (instr->SzValue() != 0x1) {
2813 UNREACHABLE(); // Not used by V8. 2829 UNREACHABLE(); // Not used by V8.
2814 } 2830 }
2815 2831
2816 double dn_value = get_double_from_d_register(vn); 2832 double dn_value = get_double_from_d_register(vn);
2817 double dm_value = get_double_from_d_register(vm); 2833 double dm_value = get_double_from_d_register(vm);
2818 double dd_value = dn_value / dm_value; 2834 double dd_value = dn_value / dm_value;
2819 div_zero_vfp_flag_ = (dm_value == 0); 2835 div_zero_vfp_flag_ = (dm_value == 0);
2836 dd_value = canonicalizeNaN(dd_value);
2820 set_d_register_from_double(vd, dd_value); 2837 set_d_register_from_double(vd, dd_value);
2821 } else { 2838 } else {
2822 UNIMPLEMENTED(); // Not used by V8. 2839 UNIMPLEMENTED(); // Not used by V8.
2823 } 2840 }
2824 } else { 2841 } else {
2825 if ((instr->VCValue() == 0x0) && 2842 if ((instr->VCValue() == 0x0) &&
2826 (instr->VAValue() == 0x0)) { 2843 (instr->VAValue() == 0x0)) {
2827 DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(instr); 2844 DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(instr);
2828 } else if ((instr->VLValue() == 0x0) && 2845 } else if ((instr->VLValue() == 0x0) &&
2829 (instr->VCValue() == 0x1) && 2846 (instr->VCValue() == 0x1) &&
(...skipping 13 matching lines...) Expand all
2843 // vmrs 2860 // vmrs
2844 uint32_t rt = instr->RtValue(); 2861 uint32_t rt = instr->RtValue();
2845 if (rt == 0xF) { 2862 if (rt == 0xF) {
2846 Copy_FPSCR_to_APSR(); 2863 Copy_FPSCR_to_APSR();
2847 } else { 2864 } else {
2848 // Emulate FPSCR from the Simulator flags. 2865 // Emulate FPSCR from the Simulator flags.
2849 uint32_t fpscr = (n_flag_FPSCR_ << 31) | 2866 uint32_t fpscr = (n_flag_FPSCR_ << 31) |
2850 (z_flag_FPSCR_ << 30) | 2867 (z_flag_FPSCR_ << 30) |
2851 (c_flag_FPSCR_ << 29) | 2868 (c_flag_FPSCR_ << 29) |
2852 (v_flag_FPSCR_ << 28) | 2869 (v_flag_FPSCR_ << 28) |
2870 (FPSCR_default_NaN_mode_ << 25) |
2853 (inexact_vfp_flag_ << 4) | 2871 (inexact_vfp_flag_ << 4) |
2854 (underflow_vfp_flag_ << 3) | 2872 (underflow_vfp_flag_ << 3) |
2855 (overflow_vfp_flag_ << 2) | 2873 (overflow_vfp_flag_ << 2) |
2856 (div_zero_vfp_flag_ << 1) | 2874 (div_zero_vfp_flag_ << 1) |
2857 (inv_op_vfp_flag_ << 0) | 2875 (inv_op_vfp_flag_ << 0) |
2858 (FPSCR_rounding_mode_); 2876 (FPSCR_rounding_mode_);
2859 set_register(rt, fpscr); 2877 set_register(rt, fpscr);
2860 } 2878 }
2861 } else if ((instr->VLValue() == 0x0) && 2879 } else if ((instr->VLValue() == 0x0) &&
2862 (instr->VCValue() == 0x0) && 2880 (instr->VCValue() == 0x0) &&
2863 (instr->VAValue() == 0x7) && 2881 (instr->VAValue() == 0x7) &&
2864 (instr->Bits(19, 16) == 0x1)) { 2882 (instr->Bits(19, 16) == 0x1)) {
2865 // vmsr 2883 // vmsr
2866 uint32_t rt = instr->RtValue(); 2884 uint32_t rt = instr->RtValue();
2867 if (rt == pc) { 2885 if (rt == pc) {
2868 UNREACHABLE(); 2886 UNREACHABLE();
2869 } else { 2887 } else {
2870 uint32_t rt_value = get_register(rt); 2888 uint32_t rt_value = get_register(rt);
2871 n_flag_FPSCR_ = (rt_value >> 31) & 1; 2889 n_flag_FPSCR_ = (rt_value >> 31) & 1;
2872 z_flag_FPSCR_ = (rt_value >> 30) & 1; 2890 z_flag_FPSCR_ = (rt_value >> 30) & 1;
2873 c_flag_FPSCR_ = (rt_value >> 29) & 1; 2891 c_flag_FPSCR_ = (rt_value >> 29) & 1;
2874 v_flag_FPSCR_ = (rt_value >> 28) & 1; 2892 v_flag_FPSCR_ = (rt_value >> 28) & 1;
2893 FPSCR_default_NaN_mode_ = (rt_value >> 25) & 1;
2875 inexact_vfp_flag_ = (rt_value >> 4) & 1; 2894 inexact_vfp_flag_ = (rt_value >> 4) & 1;
2876 underflow_vfp_flag_ = (rt_value >> 3) & 1; 2895 underflow_vfp_flag_ = (rt_value >> 3) & 1;
2877 overflow_vfp_flag_ = (rt_value >> 2) & 1; 2896 overflow_vfp_flag_ = (rt_value >> 2) & 1;
2878 div_zero_vfp_flag_ = (rt_value >> 1) & 1; 2897 div_zero_vfp_flag_ = (rt_value >> 1) & 1;
2879 inv_op_vfp_flag_ = (rt_value >> 0) & 1; 2898 inv_op_vfp_flag_ = (rt_value >> 0) & 1;
2880 FPSCR_rounding_mode_ = 2899 FPSCR_rounding_mode_ =
2881 static_cast<VFPRoundingMode>((rt_value) & kVFPRoundingModeMask); 2900 static_cast<VFPRoundingMode>((rt_value) & kVFPRoundingModeMask);
2882 } 2901 }
2883 } else { 2902 } else {
2884 UNIMPLEMENTED(); // Not used by V8. 2903 UNIMPLEMENTED(); // Not used by V8.
(...skipping 585 matching lines...) Expand 10 before | Expand all | Expand 10 after
3470 uintptr_t address = *stack_slot; 3489 uintptr_t address = *stack_slot;
3471 set_register(sp, current_sp + sizeof(uintptr_t)); 3490 set_register(sp, current_sp + sizeof(uintptr_t));
3472 return address; 3491 return address;
3473 } 3492 }
3474 3493
3475 } } // namespace v8::internal 3494 } } // namespace v8::internal
3476 3495
3477 #endif // USE_SIMULATOR 3496 #endif // USE_SIMULATOR
3478 3497
3479 #endif // V8_TARGET_ARCH_ARM 3498 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/simulator-arm.h ('k') | src/arm/stub-cache-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698