Bug 1393723 - Fix handling of wasm div/mod/mul64 on mips32. r=lth
authorDragan Mladjenovic <dragan.mladjenovic@rt-rk.com>
Tue, 29 Aug 2017 00:48:00 -0400
changeset 377599 b71a2824c224
parent 377598 330e2e4db3a7
child 377600 fdb95175a737
push id32411
push userkwierso@gmail.com
push dateTue, 29 Aug 2017 23:14:35 +0000
treeherdermozilla-central@db7f19e26e57 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslth
bugs1393723
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 1393723 - Fix handling of wasm div/mod/mul64 on mips32. r=lth
js/src/jit/mips-shared/CodeGenerator-mips-shared.cpp
js/src/jit/mips-shared/Lowering-mips-shared.cpp
js/src/jit/mips32/Assembler-mips32.h
js/src/jit/mips32/CodeGenerator-mips32.cpp
js/src/jit/mips32/MacroAssembler-mips32-inl.h
--- a/js/src/jit/mips-shared/CodeGenerator-mips-shared.cpp
+++ b/js/src/jit/mips-shared/CodeGenerator-mips-shared.cpp
@@ -531,19 +531,16 @@ CodeGeneratorMIPSShared::visitMulI64(LMu
             masm.neg64(ToRegister64(lhs));
             return;
           case 0:
             masm.xor64(ToRegister64(lhs), ToRegister64(lhs));
             return;
           case 1:
             // nop
             return;
-          case 2:
-            masm.add64(ToRegister64(lhs), ToRegister64(lhs));
-            return;
           default:
             if (constant > 0) {
                 // Use shift if constant is power of 2.
                 int32_t shift = mozilla::FloorLog2(constant);
                 if (int64_t(1) << shift == constant) {
                     masm.lshift64(Imm32(shift), ToRegister64(lhs));
                     return;
                 }
--- a/js/src/jit/mips-shared/Lowering-mips-shared.cpp
+++ b/js/src/jit/mips-shared/Lowering-mips-shared.cpp
@@ -69,33 +69,35 @@ LIRGeneratorMIPSShared::lowerForALUInt64
                          lhs != rhs ? useInt64OrConstant(rhs) : useInt64OrConstantAtStart(rhs));
     defineInt64ReuseInput(ins, mir, 0);
 }
 
 void
 LIRGeneratorMIPSShared::lowerForMulInt64(LMulI64* ins, MMul* mir, MDefinition* lhs, MDefinition* rhs)
 {
     bool needsTemp = false;
+    bool cannotAliasRhs = false;
 
 #ifdef JS_CODEGEN_MIPS32
     needsTemp = true;
+    cannotAliasRhs = true;
     if (rhs->isConstant()) {
         int64_t constant = rhs->toConstant()->toInt64();
         int32_t shift = mozilla::FloorLog2(constant);
         // See special cases in CodeGeneratorMIPSShared::visitMulI64
         if (constant >= -1 && constant <= 2)
             needsTemp = false;
         if (int64_t(1) << shift == constant)
             needsTemp = false;
     }
 #endif
-
     ins->setInt64Operand(0, useInt64RegisterAtStart(lhs));
     ins->setInt64Operand(INT64_PIECES,
-                         lhs != rhs ? useInt64OrConstant(rhs) : useInt64OrConstantAtStart(rhs));
+                         (lhs != rhs || cannotAliasRhs) ? useInt64OrConstant(rhs) : useInt64OrConstantAtStart(rhs));
+
     if (needsTemp)
         ins->setTemp(0, temp());
 
     defineInt64ReuseInput(ins, mir, 0);
 }
 
 template<size_t Temps>
 void
--- a/js/src/jit/mips32/Assembler-mips32.h
+++ b/js/src/jit/mips32/Assembler-mips32.h
@@ -60,17 +60,17 @@ static constexpr Register WasmTlsReg = s
 // Registers used for asm.js/wasm table calls. These registers must be disjoint
 // from the ABI argument registers, WasmTlsReg and each other.
 static constexpr Register WasmTableCallScratchReg = ABINonArgReg0;
 static constexpr Register WasmTableCallSigReg = ABINonArgReg1;
 static constexpr Register WasmTableCallIndexReg = ABINonArgReg2;
 
 static constexpr Register JSReturnReg_Type = a3;
 static constexpr Register JSReturnReg_Data = a2;
-static constexpr Register64 ReturnReg64(InvalidReg, InvalidReg);
+static constexpr Register64 ReturnReg64(v1, v0);
 static constexpr FloatRegister ReturnFloat32Reg = { FloatRegisters::f0, FloatRegister::Single };
 static constexpr FloatRegister ReturnDoubleReg = { FloatRegisters::f0, FloatRegister::Double };
 static constexpr FloatRegister ScratchFloat32Reg = { FloatRegisters::f18, FloatRegister::Single };
 static constexpr FloatRegister ScratchDoubleReg = { FloatRegisters::f18, FloatRegister::Double };
 static constexpr FloatRegister SecondScratchFloat32Reg = { FloatRegisters::f16, FloatRegister::Single };
 static constexpr FloatRegister SecondScratchDoubleReg = { FloatRegisters::f16, FloatRegister::Double };
 
 struct ScratchDoubleScope : public AutoFloatRegisterScope
--- a/js/src/jit/mips32/CodeGenerator-mips32.cpp
+++ b/js/src/jit/mips32/CodeGenerator-mips32.cpp
@@ -391,17 +391,17 @@ CodeGeneratorMIPS::visitDivOrModI64(LDiv
             masm.xor64(output, output);
         } else {
             masm.jump(trap(lir, wasm::Trap::IntegerOverflow));
         }
         masm.jump(&done);
         masm.bind(&notmin);
     }
 
-    masm.setupUnalignedABICall(temp);
+    masm.setupWasmABICall();
     masm.passABIArg(lhs.high);
     masm.passABIArg(lhs.low);
     masm.passABIArg(rhs.high);
     masm.passABIArg(rhs.low);
 
     MOZ_ASSERT(gen->compilingWasm());
     if (lir->mir()->isMod())
         masm.callWithABI(lir->bytecodeOffset(), wasm::SymbolicAddress::ModI64);
@@ -430,17 +430,17 @@ CodeGeneratorMIPS::visitUDivOrModI64(LUD
         regs.take(rhs.high);
     }
     Register temp = regs.takeAny();
 
     // Prevent divide by zero.
     if (lir->canBeDivideByZero())
         masm.branchTest64(Assembler::Zero, rhs, rhs, temp, trap(lir, wasm::Trap::IntegerDivideByZero));
 
-    masm.setupUnalignedABICall(temp);
+    masm.setupWasmABICall();
     masm.passABIArg(lhs.high);
     masm.passABIArg(lhs.low);
     masm.passABIArg(rhs.high);
     masm.passABIArg(rhs.low);
 
     MOZ_ASSERT(gen->compilingWasm());
     if (lir->mir()->isMod())
         masm.callWithABI(lir->bytecodeOffset(), wasm::SymbolicAddress::UModI64);
--- a/js/src/jit/mips32/MacroAssembler-mips32-inl.h
+++ b/js/src/jit/mips32/MacroAssembler-mips32-inl.h
@@ -136,16 +136,18 @@ void
 MacroAssembler::addPtr(ImmWord imm, Register dest)
 {
     addPtr(Imm32(imm.value), dest);
 }
 
 void
 MacroAssembler::add64(Register64 src, Register64 dest)
 {
+    MOZ_ASSERT(dest.low != src.low);
+
     as_addu(dest.low, dest.low, src.low);
     as_sltu(ScratchRegister, dest.low, src.low);
     as_addu(dest.high, dest.high, src.high);
     as_addu(dest.high, dest.high, ScratchRegister);
 }
 
 void
 MacroAssembler::add64(Imm32 imm, Register64 dest)
@@ -185,16 +187,20 @@ void
 MacroAssembler::subPtr(Imm32 imm, Register dest)
 {
     ma_subu(dest, dest, imm);
 }
 
 void
 MacroAssembler::sub64(Register64 src, Register64 dest)
 {
+    MOZ_ASSERT(dest.low != src.high);
+    MOZ_ASSERT(dest.high != src.low);
+    MOZ_ASSERT(dest.high != src.high);
+
     as_sltu(ScratchRegister, dest.low, src.low);
     as_subu(dest.high, dest.high, ScratchRegister);
     as_subu(dest.low, dest.low, src.low);
     as_subu(dest.high, dest.high, src.high);
 }
 
 void
 MacroAssembler::sub64(Imm64 imm, Register64 dest)