Bug 1248859 - OdinMonkey: MIPS: Fix replace retargetWithOffset. r=arai
authorHeiher <r@hev.cc>
Wed, 17 Feb 2016 17:50:42 +0800
changeset 331599 b6287d1e98969a5af6cd82310dd38a30aa23856f
parent 331598 1378bf53b053c9b06e108d1c865428290d1e3d96
child 331600 43e61da8cc4394f48b6a98e65c2bc0a4842ea65a
push id11020
push userjolesen@mozilla.com
push dateWed, 17 Feb 2016 18:16:38 +0000
reviewersarai
bugs1248859
milestone47.0a1
Bug 1248859 - OdinMonkey: MIPS: Fix replace retargetWithOffset. r=arai --- js/src/jit/mips-shared/Assembler-mips-shared.cpp | 16 +++++++++++++- .../jit/mips-shared/CodeGenerator-mips-shared.cpp | 12 +++++------ .../jit/mips-shared/MacroAssembler-mips-shared.cpp | 25 ++++++++++++++++++++++ .../jit/mips-shared/MacroAssembler-mips-shared.h | 4 ++++ js/src/jit/mips32/MacroAssembler-mips32.cpp | 8 +++++++ js/src/jit/mips32/MacroAssembler-mips32.h | 5 +++++ js/src/jit/mips64/MacroAssembler-mips64.cpp | 9 ++++++++ js/src/jit/mips64/MacroAssembler-mips64.h | 5 +++++ 8 files changed, 77 insertions(+), 7 deletions(-)
js/src/jit/mips-shared/Assembler-mips-shared.cpp
js/src/jit/mips-shared/CodeGenerator-mips-shared.cpp
js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp
js/src/jit/mips-shared/MacroAssembler-mips-shared.h
js/src/jit/mips32/MacroAssembler-mips32.cpp
js/src/jit/mips32/MacroAssembler-mips32.h
js/src/jit/mips64/MacroAssembler-mips64.cpp
js/src/jit/mips64/MacroAssembler-mips64.h
--- a/js/src/jit/mips-shared/Assembler-mips-shared.cpp
+++ b/js/src/jit/mips-shared/Assembler-mips-shared.cpp
@@ -1324,17 +1324,31 @@ AssemblerMIPSShared::bind(Label* label, 
         } while (next != LabelBase::INVALID_OFFSET);
     }
     label->bind(dest.getOffset());
 }
 
 void
 AssemblerMIPSShared::bindLater(Label* label, wasm::JumpTarget target)
 {
-    MOZ_CRASH("NYI");
+    if (label->used()) {
+        int32_t next;
+
+        BufferOffset b(label);
+        do {
+            Instruction* inst = editSrc(b);
+
+            append(target, b.getOffset());
+            next = inst[1].encode();
+            inst[1].makeNop();
+
+            b = BufferOffset(next);
+        } while (next != LabelBase::INVALID_OFFSET);
+    }
+    label->reset();
 }
 
 void
 AssemblerMIPSShared::retarget(Label* label, Label* target)
 {
     if (label->used() && !oom()) {
         if (target->bound()) {
             bind(label, BufferOffset(target));
--- a/js/src/jit/mips-shared/CodeGenerator-mips-shared.cpp
+++ b/js/src/jit/mips-shared/CodeGenerator-mips-shared.cpp
@@ -1657,17 +1657,17 @@ CodeGeneratorMIPSShared::visitAsmJSLoadH
         if (size == 32)
             masm.loadFloat32(Address(GlobalReg, wasm::NaN32GlobalDataOffset - AsmJSGlobalRegBias),
                              ToFloatRegister(out));
         else
             masm.loadDouble(Address(GlobalReg, wasm::NaN64GlobalDataOffset - AsmJSGlobalRegBias),
                             ToFloatRegister(out));
     } else {
         if (mir->isAtomicAccess())
-            masm.ma_b(masm.asmOnOutOfBoundsLabel());
+            masm.ma_b(wasm::JumpTarget::OutOfBounds);
         else
             masm.move32(Imm32(0), ToRegister(out));
     }
     masm.bind(&done);
 
     memoryBarrier(mir->barrierAfter());
     masm.append(wasm::HeapAccess(bo.getOffset()));
 }
@@ -1745,17 +1745,17 @@ CodeGeneratorMIPSShared::visitAsmJSStore
     } else {
         masm.ma_store(ToRegister(value), BaseIndex(HeapReg, ptrReg, TimesOne),
                       static_cast<LoadStoreSize>(size), isSigned ? SignExtend : ZeroExtend);
     }
     masm.ma_b(&done, ShortJump);
     masm.bind(&outOfRange);
     // Offset is out of range.
     if (mir->isAtomicAccess())
-        masm.ma_b(masm.asmOnOutOfBoundsLabel());
+        masm.ma_b(wasm::JumpTarget::OutOfBounds);
     masm.bind(&done);
 
     memoryBarrier(mir->barrierAfter());
     masm.append(wasm::HeapAccess(bo.getOffset()));
 }
 
 void
 CodeGeneratorMIPSShared::visitAsmJSCompareExchangeHeap(LAsmJSCompareExchangeHeap* ins)
@@ -1772,17 +1772,17 @@ CodeGeneratorMIPSShared::visitAsmJSCompa
     Register valueTemp = ToRegister(ins->valueTemp());
     Register offsetTemp = ToRegister(ins->offsetTemp());
     Register maskTemp = ToRegister(ins->maskTemp());
 
     uint32_t maybeCmpOffset = 0;
     if (mir->needsBoundsCheck()) {
         BufferOffset bo = masm.ma_BoundsCheck(ScratchRegister);
         maybeCmpOffset = bo.getOffset();
-        masm.ma_b(ptrReg, ScratchRegister, masm.asmOnOutOfBoundsLabel(), Assembler::AboveOrEqual);
+        masm.ma_b(ptrReg, ScratchRegister, wasm::JumpTarget::OutOfBounds, Assembler::AboveOrEqual);
     }
     masm.compareExchangeToTypedIntArray(vt == Scalar::Uint32 ? Scalar::Int32 : vt,
                                         srcAddr, oldval, newval, InvalidReg,
                                         valueTemp, offsetTemp, maskTemp,
                                         ToAnyRegister(ins->output()));
     if (mir->needsBoundsCheck())
         masm.append(wasm::HeapAccess(maybeCmpOffset));
 }
@@ -1800,17 +1800,17 @@ CodeGeneratorMIPSShared::visitAsmJSAtomi
     Register valueTemp = ToRegister(ins->valueTemp());
     Register offsetTemp = ToRegister(ins->offsetTemp());
     Register maskTemp = ToRegister(ins->maskTemp());
 
     uint32_t maybeCmpOffset = 0;
     if (mir->needsBoundsCheck()) {
         BufferOffset bo = masm.ma_BoundsCheck(ScratchRegister);
         maybeCmpOffset = bo.getOffset();
-        masm.ma_b(ptrReg, ScratchRegister, masm.asmOnOutOfBoundsLabel(), Assembler::AboveOrEqual);
+        masm.ma_b(ptrReg, ScratchRegister, wasm::JumpTarget::OutOfBounds, Assembler::AboveOrEqual);
     }
     masm.atomicExchangeToTypedIntArray(vt == Scalar::Uint32 ? Scalar::Int32 : vt,
                                        srcAddr, value, InvalidReg, valueTemp,
                                        offsetTemp, maskTemp, ToAnyRegister(ins->output()));
     if (mir->needsBoundsCheck())
         masm.append(wasm::HeapAccess(maybeCmpOffset));
 }
 
@@ -1831,17 +1831,17 @@ CodeGeneratorMIPSShared::visitAsmJSAtomi
     AtomicOp op = mir->operation();
 
     BaseIndex srcAddr(HeapReg, ptrReg, TimesOne);
 
     uint32_t maybeCmpOffset = 0;
     if (mir->needsBoundsCheck()) {
         BufferOffset bo = masm.ma_BoundsCheck(ScratchRegister);
         maybeCmpOffset = bo.getOffset();
-        masm.ma_b(ptrReg, ScratchRegister, masm.asmOnOutOfBoundsLabel(), Assembler::AboveOrEqual);
+        masm.ma_b(ptrReg, ScratchRegister, wasm::JumpTarget::OutOfBounds, Assembler::AboveOrEqual);
     }
     if (value->isConstant())
         atomicBinopToTypedIntArray(op, vt == Scalar::Uint32 ? Scalar::Int32 : vt,
                                    Imm32(ToInt32(value)), srcAddr, flagTemp, InvalidReg,
                                    valueTemp, offsetTemp, maskTemp,
                                    ToAnyRegister(ins->output()));
     else
         atomicBinopToTypedIntArray(op, vt == Scalar::Uint32 ? Scalar::Int32 : vt,
@@ -1869,17 +1869,17 @@ CodeGeneratorMIPSShared::visitAsmJSAtomi
     AtomicOp op = mir->operation();
 
     BaseIndex srcAddr(HeapReg, ptrReg, TimesOne);
 
     uint32_t maybeCmpOffset = 0;
     if (mir->needsBoundsCheck()) {
         BufferOffset bo = masm.ma_BoundsCheck(ScratchRegister);
         maybeCmpOffset = bo.getOffset();
-        masm.ma_b(ptrReg, ScratchRegister, masm.asmOnOutOfBoundsLabel(), Assembler::AboveOrEqual);
+        masm.ma_b(ptrReg, ScratchRegister, wasm::JumpTarget::OutOfBounds, Assembler::AboveOrEqual);
     }
 
     if (value->isConstant())
         atomicBinopToTypedIntArray(op, vt, Imm32(ToInt32(value)), srcAddr, flagTemp,
                                    valueTemp, offsetTemp, maskTemp);
     else
         atomicBinopToTypedIntArray(op, vt, ToRegister(value), srcAddr, flagTemp,
                                    valueTemp, offsetTemp, maskTemp);
--- a/js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp
+++ b/js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp
@@ -436,22 +436,47 @@ MacroAssemblerMIPSShared::ma_b(Register 
 }
 
 void
 MacroAssemblerMIPSShared::ma_b(Register lhs, ImmPtr imm, Label* l, Condition c, JumpKind jumpKind)
 {
     asMasm().ma_b(lhs, ImmWord(uintptr_t(imm.value)), l, c, jumpKind);
 }
 
+template <typename T>
+void
+MacroAssemblerMIPSShared::ma_b(Register lhs, T rhs, wasm::JumpTarget target, Condition c,
+                               JumpKind jumpKind)
+{
+    Label label;
+    ma_b(lhs, rhs, &label, c, jumpKind);
+    bindLater(&label, target);
+}
+
+template void MacroAssemblerMIPSShared::ma_b<Register>(Register lhs, Register rhs,
+                                                       wasm::JumpTarget target, Condition c,
+                                                       JumpKind jumpKind);
+template void MacroAssemblerMIPSShared::ma_b<ImmTag>(Register lhs, ImmTag rhs,
+                                                       wasm::JumpTarget target, Condition c,
+                                                       JumpKind jumpKind);
+
 void
 MacroAssemblerMIPSShared::ma_b(Label* label, JumpKind jumpKind)
 {
     asMasm().branchWithCode(getBranchCode(BranchIsJump), label, jumpKind);
 }
 
+void
+MacroAssemblerMIPSShared::ma_b(wasm::JumpTarget target, JumpKind jumpKind)
+{
+    Label label;
+    asMasm().branchWithCode(getBranchCode(BranchIsJump), &label, jumpKind);
+    bindLater(&label, target);
+}
+
 Assembler::Condition
 MacroAssemblerMIPSShared::ma_cmp(Register scratch, Register lhs, Register rhs, Condition c)
 {
     switch (c) {
       case Above:
         // bgtu s,t,label =>
         //   sltu at,t,s
         //   bne at,$zero,offs
--- a/js/src/jit/mips-shared/MacroAssembler-mips-shared.h
+++ b/js/src/jit/mips-shared/MacroAssembler-mips-shared.h
@@ -135,18 +135,22 @@ class MacroAssemblerMIPSShared : public 
     void ma_b(Register lhs, Register rhs, Label* l, Condition c, JumpKind jumpKind = LongJump);
     void ma_b(Register lhs, Imm32 imm, Label* l, Condition c, JumpKind jumpKind = LongJump);
     void ma_b(Register lhs, ImmPtr imm, Label* l, Condition c, JumpKind jumpKind = LongJump);
     void ma_b(Register lhs, ImmGCPtr imm, Label* l, Condition c, JumpKind jumpKind = LongJump) {
         MOZ_ASSERT(lhs != ScratchRegister);
         ma_li(ScratchRegister, imm);
         ma_b(lhs, ScratchRegister, l, c, jumpKind);
     }
+    template <typename T>
+    void ma_b(Register lhs, T rhs, wasm::JumpTarget target, Condition c,
+              JumpKind jumpKind = LongJump);
 
     void ma_b(Label* l, JumpKind jumpKind = LongJump);
+    void ma_b(wasm::JumpTarget target, JumpKind jumpKind = LongJump);
 
     // fp instructions
     void ma_lis(FloatRegister dest, float value);
     void ma_liNegZero(FloatRegister dest);
 
     void ma_sd(FloatRegister fd, BaseIndex address);
     void ma_ss(FloatRegister fd, BaseIndex address);
 
--- a/js/src/jit/mips32/MacroAssembler-mips32.cpp
+++ b/js/src/jit/mips32/MacroAssembler-mips32.cpp
@@ -1388,16 +1388,24 @@ MacroAssemblerMIPSCompat::branchTestNumb
 
 void
 MacroAssemblerMIPSCompat::branchTestMagic(Condition cond, const ValueOperand& value, Label* label)
 {
     branchTestMagic(cond, value.typeReg(), label);
 }
 
 void
+MacroAssemblerMIPSCompat::branchTestMagic(Condition cond, const ValueOperand& value,
+                                          wasm::JumpTarget target)
+{
+    MOZ_ASSERT(cond == Equal || cond == NotEqual);
+    ma_b(value.typeReg(), ImmTag(JSVAL_TAG_MAGIC), target, cond);
+}
+
+void
 MacroAssemblerMIPSCompat::branchTestMagic(Condition cond, Register tag, Label* label)
 {
     MOZ_ASSERT(cond == Equal || cond == NotEqual);
     ma_b(tag, ImmTag(JSVAL_TAG_MAGIC), label, cond);
 }
 
 void
 MacroAssemblerMIPSCompat::branchTestMagic(Condition cond, const Address& address, Label* label)
--- a/js/src/jit/mips32/MacroAssembler-mips32.h
+++ b/js/src/jit/mips32/MacroAssembler-mips32.h
@@ -291,16 +291,20 @@ class MacroAssemblerMIPSCompat : public 
         as_jr(ScratchRegister);
         as_nop();
     }
 
     void jump(JitCode* code) {
         branch(code);
     }
 
+    void jump(wasm::JumpTarget target) {
+        ma_b(target);
+    }
+
     void negl(Register reg) {
         ma_negu(reg, reg);
     }
 
     // Returns the register containing the type tag.
     Register splitTagForTest(const ValueOperand& value) {
         return value.typeReg();
     }
@@ -412,16 +416,17 @@ class MacroAssemblerMIPSCompat : public 
     void branchTestUndefined(Condition cond, const BaseIndex& src, Label* label);
     void branchTestUndefined(Condition cond, const Address& address, Label* label);
     void testUndefinedSet(Condition cond, const ValueOperand& value, Register dest);
 
     void branchTestNumber(Condition cond, const ValueOperand& value, Label* label);
     void branchTestNumber(Condition cond, Register tag, Label* label);
 
     void branchTestMagic(Condition cond, const ValueOperand& value, Label* label);
+    void branchTestMagic(Condition cond, const ValueOperand& value, wasm::JumpTarget target);
     void branchTestMagic(Condition cond, Register tag, Label* label);
     void branchTestMagic(Condition cond, const Address& address, Label* label);
     void branchTestMagic(Condition cond, const BaseIndex& src, Label* label);
 
     void branchTestMagicValue(Condition cond, const ValueOperand& val, JSWhyMagic why,
                               Label* label) {
         MOZ_ASSERT(cond == Equal || cond == NotEqual);
         branchTestValue(cond, val, MagicValue(why), label);
--- a/js/src/jit/mips64/MacroAssembler-mips64.cpp
+++ b/js/src/jit/mips64/MacroAssembler-mips64.cpp
@@ -1527,16 +1527,25 @@ MacroAssemblerMIPS64Compat::branchTestNu
 void
 MacroAssemblerMIPS64Compat::branchTestMagic(Condition cond, const ValueOperand& value, Label* label)
 {
     splitTag(value, SecondScratchReg);
     branchTestMagic(cond, SecondScratchReg, label);
 }
 
 void
+MacroAssemblerMIPS64Compat::branchTestMagic(Condition cond, const ValueOperand& value,
+                                            wasm::JumpTarget target)
+{
+    MOZ_ASSERT(cond == Equal || cond == NotEqual);
+    splitTag(value, SecondScratchReg);
+    ma_b(SecondScratchReg, ImmTag(JSVAL_TAG_MAGIC), target, cond);
+}
+
+void
 MacroAssemblerMIPS64Compat::branchTestMagic(Condition cond, Register tag, Label* label)
 {
     MOZ_ASSERT(cond == Equal || cond == NotEqual);
     ma_b(tag, ImmTag(JSVAL_TAG_MAGIC), label, cond);
 }
 
 void
 MacroAssemblerMIPS64Compat::branchTestMagic(Condition cond, const Address& address, Label* label)
--- a/js/src/jit/mips64/MacroAssembler-mips64.h
+++ b/js/src/jit/mips64/MacroAssembler-mips64.h
@@ -314,16 +314,20 @@ class MacroAssemblerMIPS64Compat : publi
         as_jr(ScratchRegister);
         as_nop();
     }
 
     void jump(JitCode* code) {
         branch(code);
     }
 
+    void jump(wasm::JumpTarget target) {
+        ma_b(target);
+    }
+
     void splitTag(Register src, Register dest) {
         ma_dsrl(dest, src, Imm32(JSVAL_TAG_SHIFT));
     }
 
     void splitTag(const ValueOperand& operand, Register dest) {
         splitTag(operand.valueReg(), dest);
     }
 
@@ -453,16 +457,17 @@ class MacroAssemblerMIPS64Compat : publi
     void branchTestUndefined(Condition cond, const BaseIndex& src, Label* label);
     void branchTestUndefined(Condition cond, const Address& address, Label* label);
     void testUndefinedSet(Condition cond, const ValueOperand& value, Register dest);
 
     void branchTestNumber(Condition cond, const ValueOperand& value, Label* label);
     void branchTestNumber(Condition cond, Register tag, Label* label);
 
     void branchTestMagic(Condition cond, const ValueOperand& value, Label* label);
+    void branchTestMagic(Condition cond, const ValueOperand& value, wasm::JumpTarget target);
     void branchTestMagic(Condition cond, Register tag, Label* label);
     void branchTestMagic(Condition cond, const Address& address, Label* label);
     void branchTestMagic(Condition cond, const BaseIndex& src, Label* label);
 
     void branchTestMagicValue(Condition cond, const ValueOperand& val, JSWhyMagic why,
                               Label* label) {
         MOZ_ASSERT(cond == Equal || cond == NotEqual);
         branchTestValue(cond, val, MagicValue(why), label);