Bug 1391248 - Crash mips32 simulator on instructions whose result is undefined under FR=0 mode. r=bbouvier
author"dragan.mladjenovic" <dragan.mladjenovic@rt-rk.com>
Thu, 24 Aug 2017 10:48:00 -0400
changeset 376606 220bc56b5036
parent 376605 e452433ec516
child 376607 3c6a4705b511
push id32387
push userryanvm@gmail.com
push dateFri, 25 Aug 2017 00:13:42 +0000
treeherdermozilla-central@3199bacd6b38 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbbouvier
bugs1391248
milestone57.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1391248 - Crash mips32 simulator on instructions whose result is undefined under FR=0 mode. r=bbouvier
js/src/jit/mips32/Simulator-mips32.cpp
--- a/js/src/jit/mips32/Simulator-mips32.cpp
+++ b/js/src/jit/mips32/Simulator-mips32.cpp
@@ -1447,37 +1447,23 @@ Simulator::setFpuRegister(int fpureg, in
 void
 Simulator::setFpuRegisterFloat(int fpureg, float value)
 {
     MOZ_ASSERT((fpureg >= 0) && (fpureg < Simulator::FPURegister::kNumFPURegisters));
     *mozilla::BitwiseCast<float*>(&FPUregisters_[fpureg]) = value;
 }
 
 void
-Simulator::setFpuRegisterFloat(int fpureg, int64_t value)
-{
-    setFpuRegister(fpureg, value & 0xffffffff);
-    setFpuRegister(fpureg + 1, value >> 32);
-}
-
-void
 Simulator::setFpuRegisterDouble(int fpureg, double value)
 {
     MOZ_ASSERT((fpureg >= 0) && (fpureg < Simulator::FPURegister::kNumFPURegisters)
            && ((fpureg % 2) == 0));
     *mozilla::BitwiseCast<double*>(&FPUregisters_[fpureg]) = value;
 }
 
-void
-Simulator::setFpuRegisterDouble(int fpureg, int64_t value)
-{
-    setFpuRegister(fpureg, value & 0xffffffff);
-    setFpuRegister(fpureg + 1, value >> 32);
-}
-
 // Get the register from the architecture state. This function does handle
 // the special case of accessing the PC register.
 int32_t
 Simulator::getRegister(int reg) const
 {
     MOZ_ASSERT((reg >= 0) && (reg < Register::kNumSimuRegisters));
     if (reg == 0)
         return 0;
@@ -2620,17 +2606,16 @@ Simulator::decodeTypeRegister(SimInstruc
             FPUregisters_[fs_reg] = registers_[rt_reg];
             break;
           case rs_mthc1:
             MOZ_CRASH();
             break;
           case rs_s:
             float f, ft_value, fs_value;
             uint32_t cc, fcsr_cc;
-            int64_t  i64;
             fs_value = getFpuRegisterFloat(fs_reg);
             ft_value = getFpuRegisterFloat(ft_reg);
             cc = instr->fcccValue();
             fcsr_cc = GetFCSRConditionBit(cc);
             switch (instr->functionFieldRaw()) {
               case ff_add_fmt:
                 setFpuRegisterFloat(fd_reg, fs_value + ft_value);
                 break;
@@ -2724,43 +2709,21 @@ Simulator::decodeTypeRegister(SimInstruc
                 float rounded = std::ceil(fs_value);
                 int32_t result = static_cast<int32_t>(rounded);
                 setFpuRegister(fd_reg, result);
                 if (setFCSRRoundError(fs_value, rounded)) {
                     setFpuRegister(fd_reg, kFPUInvalidResult);
                 }
                 break;
               }
-              case ff_cvt_l_fmt: {  // Mips32r2: Truncate float to 64-bit long-word.
-                float rounded = truncf(fs_value);
-                i64 = static_cast<int64_t>(rounded);
-                setFpuRegisterFloat(fd_reg, i64);
-                break;
-              }
-              case ff_round_l_fmt: {  // Mips32r2 instruction.
-                float rounded =
-                    fs_value > 0 ? std::floor(fs_value + 0.5) : std::ceil(fs_value - 0.5);
-                i64 = static_cast<int64_t>(rounded);
-                setFpuRegisterFloat(fd_reg, i64);
-                break;
-              }
-              case ff_trunc_l_fmt: {  // Mips32r2 instruction.
-                float rounded = truncf(fs_value);
-                i64 = static_cast<int64_t>(rounded);
-                setFpuRegisterFloat(fd_reg, i64);
-                break;
-              }
-              case ff_floor_l_fmt:  // Mips32r2 instruction.
-                i64 = static_cast<int64_t>(std::floor(fs_value));
-                setFpuRegisterFloat(fd_reg, i64);
-                break;
-              case ff_ceil_l_fmt:  // Mips32r2 instruction.
-                i64 = static_cast<int64_t>(std::ceil(fs_value));
-                setFpuRegisterFloat(fd_reg, i64);
-                break;
+              case ff_cvt_l_fmt:
+              case ff_round_l_fmt:
+              case ff_trunc_l_fmt:
+              case ff_floor_l_fmt:
+              case ff_ceil_l_fmt:
               case ff_cvt_ps_s:
               case ff_c_f_fmt:
                 MOZ_CRASH();
                 break;
               case ff_movf_fmt:
                 if (testFCSRBit(fcsr_cc)) {
                   setFpuRegisterFloat(fd_reg, getFpuRegisterFloat(fs_reg));
                 }
@@ -2888,43 +2851,21 @@ Simulator::decodeTypeRegister(SimInstruc
                 if (setFCSRRoundError(ds_value, rounded)) {
                     setFpuRegister(fd_reg, kFPUInvalidResult);
                 }
                 break;
               }
               case ff_cvt_s_fmt:  // Convert double to float (single).
                 setFpuRegisterFloat(fd_reg, static_cast<float>(ds_value));
                 break;
-              case ff_cvt_l_fmt: {  // Mips32r2: Truncate double to 64-bit long-word.
-                double rounded = trunc(ds_value);
-                i64 = static_cast<int64_t>(rounded);
-                setFpuRegisterDouble(fd_reg, i64);
-                break;
-              }
-              case ff_trunc_l_fmt: {  // Mips32r2 instruction.
-                double rounded = trunc(ds_value);
-                i64 = static_cast<int64_t>(rounded);
-                setFpuRegisterDouble(fd_reg, i64);
-                break;
-              }
-              case ff_round_l_fmt: {  // Mips32r2 instruction.
-                double rounded =
-                    ds_value > 0 ? std::floor(ds_value + 0.5) : std::ceil(ds_value - 0.5);
-                i64 = static_cast<int64_t>(rounded);
-                setFpuRegisterDouble(fd_reg, i64);
-                break;
-              }
-              case ff_floor_l_fmt:  // Mips32r2 instruction.
-                i64 = static_cast<int64_t>(std::floor(ds_value));
-                setFpuRegisterDouble(fd_reg, i64);
-                break;
-              case ff_ceil_l_fmt:  // Mips32r2 instruction.
-                i64 = static_cast<int64_t>(std::ceil(ds_value));
-                setFpuRegisterDouble(fd_reg, i64);
-                break;
+              case ff_cvt_l_fmt:
+              case ff_trunc_l_fmt:
+              case ff_round_l_fmt:
+              case ff_floor_l_fmt:
+              case ff_ceil_l_fmt:
               case ff_c_f_fmt:
                 MOZ_CRASH();
                 break;
               case ff_movf_fmt:
                 if (testFCSRBit(fcsr_cc)) {
                   setFpuRegisterDouble(fd_reg, getFpuRegisterDouble(fs_reg));
                 }
                 break;
@@ -2953,23 +2894,17 @@ Simulator::decodeTypeRegister(SimInstruc
                 setFpuRegisterDouble(fd_reg, static_cast<double>(alu_out));
                 break;
               default:
                 MOZ_CRASH();
             }
             break;
           case rs_l:
             switch (instr->functionFieldRaw()) {
-              case ff_cvt_d_fmt:  // Mips32r2 instruction.
-                // Watch the signs here, we want 2 32-bit vals
-                // to make a sign-64.
-                i64 = static_cast<uint32_t>(getFpuRegister(fs_reg));
-                i64 |= static_cast<int64_t>(getFpuRegister(fs_reg + 1)) << 32;
-                setFpuRegisterDouble(fd_reg, static_cast<double>(i64));
-                break;
+              case ff_cvt_d_fmt:
               case ff_cvt_s_fmt:
                 MOZ_CRASH();
                 break;
               default:
                 MOZ_CRASH();
             }
             break;
           case rs_ps: