Bug 1147908 - IonMonkey: MIPS: Fix UDiv and UMod for double and merge them. r=rankov
authorHeiher <r@hev.cc>
Thu, 26 Mar 2015 08:13:00 -0400
changeset 266432 1338e3ef4d6ed5cd363be54658f5443d3967e684
parent 266431 f93153e7329e38d65c835dd463b32a043012de6f
child 266433 18bdc63a2ca08158d83e3d1bfc881b941f9c80e7
push id830
push userraliiev@mozilla.com
push dateFri, 19 Jun 2015 19:24:37 +0000
treeherdermozilla-release@932614382a68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrankov
bugs1147908
milestone39.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 1147908 - IonMonkey: MIPS: Fix UDiv and UMod for double and merge them. r=rankov
js/src/jit/mips/CodeGenerator-mips.cpp
js/src/jit/mips/CodeGenerator-mips.h
js/src/jit/mips/LIR-mips.h
js/src/jit/mips/LOpcodes-mips.h
js/src/jit/mips/Lowering-mips.cpp
--- a/js/src/jit/mips/CodeGenerator-mips.cpp
+++ b/js/src/jit/mips/CodeGenerator-mips.cpp
@@ -2015,70 +2015,48 @@ CodeGeneratorMIPS::visitAsmJSPassStackAr
         } else {
             masm.storeDouble(ToFloatRegister(ins->arg()).doubleOverlay(0),
                              Address(StackPointer, mir->spOffset()));
         }
     }
 }
 
 void
-CodeGeneratorMIPS::visitUDiv(LUDiv *ins)
-{
-    Register lhs = ToRegister(ins->lhs());
-    Register rhs = ToRegister(ins->rhs());
-    Register output = ToRegister(ins->output());
-
-    Label done;
-    if (ins->mir()->canBeDivideByZero()) {
-        if (ins->mir()->isTruncated()) {
-            Label notzero;
-            masm.ma_b(rhs, rhs, &notzero, Assembler::NonZero, ShortJump);
-            masm.move32(Imm32(0), output);
-            masm.ma_b(&done, ShortJump);
-            masm.bind(&notzero);
-        } else {
-            MOZ_ASSERT(ins->mir()->fallible());
-            bailoutCmp32(Assembler::Equal, rhs, Imm32(0), ins->snapshot());
-        }
-    }
-
-    masm.as_divu(lhs, rhs);
-    masm.as_mflo(output);
-
-    if (!ins->mir()->isTruncated())
-        bailoutCmp32(Assembler::LessThan, output, Imm32(0), ins->snapshot());
-
-    masm.bind(&done);
-}
-
-void
-CodeGeneratorMIPS::visitUMod(LUMod *ins)
+CodeGeneratorMIPS::visitUDivOrMod(LUDivOrMod *ins)
 {
     Register lhs = ToRegister(ins->lhs());
     Register rhs = ToRegister(ins->rhs());
     Register output = ToRegister(ins->output());
     Label done;
 
-    if (ins->mir()->canBeDivideByZero()) {
+    // Prevent divide by zero.
+    if (ins->canBeDivideByZero()) {
         if (ins->mir()->isTruncated()) {
             // Infinity|0 == 0
             Label notzero;
             masm.ma_b(rhs, rhs, &notzero, Assembler::NonZero, ShortJump);
             masm.move32(Imm32(0), output);
             masm.ma_b(&done, ShortJump);
             masm.bind(&notzero);
         } else {
-            MOZ_ASSERT(ins->mir()->fallible());
             bailoutCmp32(Assembler::Equal, rhs, Imm32(0), ins->snapshot());
         }
     }
 
     masm.as_divu(lhs, rhs);
     masm.as_mfhi(output);
 
+    // If the remainder is > 0, bailout since this must be a double.
+    if (ins->mir()->isDiv()) {
+        if (!ins->mir()->toDiv()->canTruncateRemainder())
+          bailoutCmp32(Assembler::NonZero, output, output, ins->snapshot());
+        // Get quotient
+        masm.as_mflo(output);
+    }
+
     if (!ins->mir()->isTruncated())
         bailoutCmp32(Assembler::LessThan, output, Imm32(0), ins->snapshot());
 
     masm.bind(&done);
 }
 
 void
 CodeGeneratorMIPS::visitEffectiveAddress(LEffectiveAddress *ins)
--- a/js/src/jit/mips/CodeGenerator-mips.h
+++ b/js/src/jit/mips/CodeGenerator-mips.h
@@ -268,18 +268,17 @@ class CodeGeneratorMIPS : public CodeGen
     void visitAsmJSLoadFFIFunc(LAsmJSLoadFFIFunc *ins);
 
     void visitAsmJSPassStackArg(LAsmJSPassStackArg *ins);
 
     void generateInvalidateEpilogue();
 
   protected:
     void visitEffectiveAddress(LEffectiveAddress *ins);
-    void visitUDiv(LUDiv *ins);
-    void visitUMod(LUMod *ins);
+    void visitUDivOrMod(LUDivOrMod *ins);
 
   public:
     // Unimplemented SIMD instructions
     void visitSimdSplatX4(LSimdSplatX4 *lir) { MOZ_CRASH("NYI"); }
     void visitInt32x4(LInt32x4 *ins) { MOZ_CRASH("NYI"); }
     void visitFloat32x4(LFloat32x4 *ins) { MOZ_CRASH("NYI"); }
     void visitSimdReinterpretCast(LSimdReinterpretCast *ins) { MOZ_CRASH("NYI"); }
     void visitSimdExtractElementI(LSimdExtractElementI *ins) { MOZ_CRASH("NYI"); }
--- a/js/src/jit/mips/LIR-mips.h
+++ b/js/src/jit/mips/LIR-mips.h
@@ -350,33 +350,30 @@ class LMulI : public LBinaryMath<0>
   public:
     LIR_HEADER(MulI);
 
     MMul *mir() {
         return mir_->toMul();
     }
 };
 
-class LUDiv : public LBinaryMath<0>
+class LUDivOrMod : public LBinaryMath<0>
 {
   public:
-    LIR_HEADER(UDiv);
-
-    MDiv *mir() {
-        return mir_->toDiv();
-    }
-};
+    LIR_HEADER(UDivOrMod);
 
-class LUMod : public LBinaryMath<0>
-{
-  public:
-    LIR_HEADER(UMod);
+    MBinaryArithInstruction *mir() const {
+        MOZ_ASSERT(mir_->isDiv() || mir_->isMod());
+        return static_cast<MBinaryArithInstruction *>(mir_);
+    }
 
-    MMod *mir() {
-        return mir_->toMod();
+    bool canBeDivideByZero() const {
+        if (mir_->isMod())
+            return mir_->toMod()->canBeDivideByZero();
+        return mir_->toDiv()->canBeDivideByZero();
     }
 };
 
 class LAsmJSLoadFuncPtr : public LInstructionHelper<1, 1, 0>
 {
   public:
     LIR_HEADER(AsmJSLoadFuncPtr);
     LAsmJSLoadFuncPtr(const LAllocation &index) {
--- a/js/src/jit/mips/LOpcodes-mips.h
+++ b/js/src/jit/mips/LOpcodes-mips.h
@@ -15,13 +15,12 @@
     _(DivI)                     \
     _(DivPowTwoI)               \
     _(ModI)                     \
     _(ModPowTwoI)               \
     _(ModMaskI)                 \
     _(PowHalfD)                 \
     _(AsmJSUInt32ToDouble)      \
     _(AsmJSUInt32ToFloat32)     \
-    _(UDiv)                     \
-    _(UMod)                     \
+    _(UDivOrMod)                \
     _(AsmJSLoadFuncPtr)
 
 #endif // jit_mips_LOpcodes_mips_h__
--- a/js/src/jit/mips/Lowering-mips.cpp
+++ b/js/src/jit/mips/Lowering-mips.cpp
@@ -414,32 +414,32 @@ LIRGeneratorMIPS::visitAsmJSNeg(MAsmJSNe
 }
 
 void
 LIRGeneratorMIPS::lowerUDiv(MDiv *div)
 {
     MDefinition *lhs = div->getOperand(0);
     MDefinition *rhs = div->getOperand(1);
 
-    LUDiv *lir = new(alloc()) LUDiv;
+    LUDivOrMod *lir = new(alloc()) LUDivOrMod;
     lir->setOperand(0, useRegister(lhs));
     lir->setOperand(1, useRegister(rhs));
     if (div->fallible())
         assignSnapshot(lir, Bailout_DoubleOutput);
 
     define(lir, div);
 }
 
 void
 LIRGeneratorMIPS::lowerUMod(MMod *mod)
 {
     MDefinition *lhs = mod->getOperand(0);
     MDefinition *rhs = mod->getOperand(1);
 
-    LUMod *lir = new(alloc()) LUMod;
+    LUDivOrMod *lir = new(alloc()) LUDivOrMod;
     lir->setOperand(0, useRegister(lhs));
     lir->setOperand(1, useRegister(rhs));
     if (mod->fallible())
         assignSnapshot(lir, Bailout_DoubleOutput);
 
     define(lir, mod);
 }