Bug 1393723 - Fix wasm i64 shifts/rotates on mips32. r=lth
authorDragan Mladjenovic <dragan.mladjenovic@rt-rk.com>
Tue, 29 Aug 2017 00:47:00 -0400
changeset 377602 27ce9e7b7648
parent 377601 6079341dccb2
child 377603 540cd433f474
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 wasm i64 shifts/rotates 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/MacroAssembler-mips32-inl.h
--- a/js/src/jit/mips-shared/CodeGenerator-mips-shared.cpp
+++ b/js/src/jit/mips-shared/CodeGenerator-mips-shared.cpp
@@ -1004,22 +1004,28 @@ CodeGeneratorMIPSShared::visitRotateI64(
 {
     MRotate* mir = lir->mir();
     LAllocation* count = lir->count();
 
     Register64 input = ToRegister64(lir->input());
     Register64 output = ToOutRegister64(lir);
     Register temp = ToTempRegisterOrInvalid(lir->temp());
 
+#ifdef JS_CODEGEN_MIPS64
     MOZ_ASSERT(input == output);
+#endif
 
     if (count->isConstant()) {
         int32_t c = int32_t(count->toConstant()->toInt64() & 0x3F);
-        if (!c)
+        if (!c) {
+#ifdef JS_CODEGEN_MIPS32
+            masm.move64(input, output);
+#endif
             return;
+        }
         if (mir->isLeftRotate())
             masm.rotateLeft64(Imm32(c), input, output, temp);
         else
             masm.rotateRight64(Imm32(c), input, output, temp);
     } else {
         if (mir->isLeftRotate())
             masm.rotateLeft64(ToRegister(count), input, output, temp);
         else
--- a/js/src/jit/mips-shared/Lowering-mips-shared.cpp
+++ b/js/src/jit/mips-shared/Lowering-mips-shared.cpp
@@ -99,28 +99,41 @@ LIRGeneratorMIPSShared::lowerForMulInt64
     defineInt64ReuseInput(ins, mir, 0);
 }
 
 template<size_t Temps>
 void
 LIRGeneratorMIPSShared::lowerForShiftInt64(LInstructionHelper<INT64_PIECES, INT64_PIECES + 1, Temps>* ins,
                                            MDefinition* mir, MDefinition* lhs, MDefinition* rhs)
 {
+#ifdef JS_CODEGEN_MIPS32
+    if (mir->isRotate()) {
+        if (!rhs->isConstant())
+            ins->setTemp(0, temp());
+        ins->setInt64Operand(0, useInt64Register(lhs));
+    } else {
+        ins->setInt64Operand(0, useInt64RegisterAtStart(lhs));
+    }
+#else
     ins->setInt64Operand(0, useInt64RegisterAtStart(lhs));
-#if defined(JS_NUNBOX32)
-    if (mir->isRotate())
-        ins->setTemp(0, temp());
 #endif
 
     static_assert(LShiftI64::Rhs == INT64_PIECES, "Assume Rhs is located at INT64_PIECES.");
     static_assert(LRotateI64::Count == INT64_PIECES, "Assume Count is located at INT64_PIECES.");
 
     ins->setOperand(INT64_PIECES, useRegisterOrConstant(rhs));
 
+#ifdef JS_CODEGEN_MIPS32
+    if (mir->isRotate())
+        defineInt64(ins, mir);
+    else
+        defineInt64ReuseInput(ins, mir, 0);
+#else
     defineInt64ReuseInput(ins, mir, 0);
+#endif
 }
 
 template void LIRGeneratorMIPSShared::lowerForShiftInt64(
     LInstructionHelper<INT64_PIECES, INT64_PIECES+1, 0>* ins, MDefinition* mir,
     MDefinition* lhs, MDefinition* rhs);
 template void LIRGeneratorMIPSShared::lowerForShiftInt64(
     LInstructionHelper<INT64_PIECES, INT64_PIECES+1, 1>* ins, MDefinition* mir,
     MDefinition* lhs, MDefinition* rhs);
--- a/js/src/jit/mips32/MacroAssembler-mips32-inl.h
+++ b/js/src/jit/mips32/MacroAssembler-mips32-inl.h
@@ -436,16 +436,18 @@ MacroAssembler::rshift64(Imm32 imm, Regi
 
 void
 MacroAssembler::rshift64(Register unmaskedShift, Register64 dest)
 {
     Label done, less;
     ScratchRegisterScope shift(*this);
 
     ma_and(shift, unmaskedShift, Imm32(0x3f));
+    ma_b(shift, Imm32(0), &done, Equal);
+
     ma_srl(dest.low, dest.low, shift);
     ma_subu(shift, shift, Imm32(32));
     ma_b(shift, Imm32(0), &less, LessThan);
 
     ma_srl(dest.low, dest.high, shift);
     move32(Imm32(0), dest.high);
     ma_b(&done);
 
@@ -482,16 +484,17 @@ MacroAssembler::rshift64Arithmetic(Imm32
 
 void
 MacroAssembler::rshift64Arithmetic(Register unmaskedShift, Register64 dest)
 {
     Label done, less;
 
     ScratchRegisterScope shift(*this);
     ma_and(shift, unmaskedShift, Imm32(0x3f));
+    ma_b(shift, Imm32(0), &done, Equal);
 
     ma_srl(dest.low, dest.low, shift);
     ma_subu(shift, shift, Imm32(32));
     ma_b(shift, Imm32(0), &less, LessThan);
 
     ma_sra(dest.low, dest.high, shift);
     as_sra(dest.high, dest.high, 31);
     ma_b(&done);
@@ -543,22 +546,23 @@ MacroAssembler::rotateLeft64(Imm32 count
 }
 
 void
 MacroAssembler::rotateLeft64(Register shift, Register64 src, Register64 dest, Register temp)
 {
     MOZ_ASSERT(temp != src.low && temp != src.high);
     MOZ_ASSERT(shift != src.low && shift != src.high);
     MOZ_ASSERT(temp != InvalidReg);
+    MOZ_ASSERT(src != dest);
 
     ScratchRegisterScope shift_value(*this);
-    Label high, done, zero;
-
+    Label high, swap, done, zero;
     ma_and(temp, shift, Imm32(0x3f));
-    ma_b(temp, Imm32(32), &high, GreaterThanOrEqual);
+    ma_b(temp, Imm32(32), &swap, Equal);
+    ma_b(temp, Imm32(32), &high, GreaterThan);
 
     // high = high << shift | low >> 32 - shift
     // low = low << shift | high >> 32 - shift
     ma_sll(dest.high, src.high, temp);
     ma_b(temp, Imm32(0), &zero, Equal);
     ma_li(SecondScratchReg, Imm32(32));
     as_subu(shift_value, SecondScratchReg, temp);
 
@@ -569,17 +573,21 @@ MacroAssembler::rotateLeft64(Register sh
     ma_srl(SecondScratchReg, src.high, shift_value);
     as_or(dest.low, dest.low, SecondScratchReg);
     ma_b(&done);
 
     bind(&zero);
     ma_move(dest.low, src.low);
     ma_move(dest.high, src.high);
     ma_b(&done);
-
+    bind(&swap);
+    ma_move(SecondScratchReg, src.low);
+    ma_move(dest.low, src.high);
+    ma_move(dest.high, SecondScratchReg);
+    ma_b(&done);
     // A 32 - 64 shift is a 0 - 32 shift in the other direction.
     bind(&high);
     ma_and(shift, shift, Imm32(0x3f));
     ma_li(SecondScratchReg, Imm32(64));
     as_subu(temp, SecondScratchReg, shift);
 
     ma_srl(dest.high, src.high, temp);
     ma_li(SecondScratchReg, Imm32(32));
@@ -626,22 +634,24 @@ MacroAssembler::rotateRight64(Imm32 coun
 }
 
 void
 MacroAssembler::rotateRight64(Register shift, Register64 src, Register64 dest, Register temp)
 {
     MOZ_ASSERT(temp != src.low && temp != src.high);
     MOZ_ASSERT(shift != src.low && shift != src.high);
     MOZ_ASSERT(temp != InvalidReg);
+    MOZ_ASSERT(src != dest);
 
     ScratchRegisterScope shift_value(*this);
-    Label high, done, zero;
+    Label high, swap, done, zero;
 
     ma_and(temp, shift, Imm32(0x3f));
-    ma_b(temp, Imm32(32), &high, GreaterThanOrEqual);
+    ma_b(temp, Imm32(32), &swap, Equal);
+    ma_b(temp, Imm32(32), &high, GreaterThan);
 
     // high = high >> shift | low << 32 - shift
     // low = low >> shift | high << 32 - shift
     ma_srl(dest.high, src.high, temp);
     ma_b(temp, Imm32(0), &zero, Equal);
     ma_li(SecondScratchReg, Imm32(32));
     as_subu(shift_value, SecondScratchReg, temp);
 
@@ -656,17 +666,21 @@ MacroAssembler::rotateRight64(Register s
     as_or(dest.low, dest.low, SecondScratchReg);
 
     ma_b(&done);
 
     bind(&zero);
     ma_move(dest.low, src.low);
     ma_move(dest.high, src.high);
     ma_b(&done);
-
+    bind(&swap);
+    ma_move(SecondScratchReg, src.low);
+    ma_move(dest.low, src.high);
+    ma_move(dest.high, SecondScratchReg);
+    ma_b(&done);
     // A 32 - 64 shift is a 0 - 32 shift in the other direction.
     bind(&high);
     ma_and(shift, shift, Imm32(0x3f));
     ma_li(SecondScratchReg, Imm32(64));
     as_subu(temp, SecondScratchReg, shift);
 
     ma_sll(dest.high, src.high, temp);
     ma_li(SecondScratchReg, Imm32(32));