Bug 1204191 - IonMonkey: MIPS: Split shareable code to mips-shared in Lowering-mips32. r=nbp
authorHeiher <r@hev.cc>
Wed, 16 Sep 2015 06:53:27 +0800
changeset 296920 8e4da0532d8f3bdaafd38163a39925e69b08531f
parent 296919 25f22b3433e0e7ee53cfc264b4ac3647d83d902a
child 296921 9abb92bb199c469095d150e7b438a7f968bba990
push id962
push userjlund@mozilla.com
push dateFri, 04 Dec 2015 23:28:54 +0000
treeherdermozilla-release@23a2d286e80f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp
bugs1204191
milestone43.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 1204191 - IonMonkey: MIPS: Split shareable code to mips-shared in Lowering-mips32. r=nbp --- .../Lowering-mips-shared.cpp} | 264 +++---------- .../Lowering-mips-shared.h} | 28 +- js/src/jit/mips32/Lowering-mips32.cpp | 409 +-------------------- js/src/jit/mips32/Lowering-mips32.h | 73 +--- js/src/moz.build | 1 + 5 files changed, 63 insertions(+), 712 deletions(-) copy js/src/jit/{mips32/Lowering-mips32.cpp => mips-shared/Lowering-mips-shared.cpp} (50%) copy js/src/jit/{mips32/Lowering-mips32.h => mips-shared/Lowering-mips-shared.h} (79%)
js/src/jit/mips-shared/Lowering-mips-shared.cpp
js/src/jit/mips-shared/Lowering-mips-shared.h
js/src/jit/mips32/Lowering-mips32.cpp
js/src/jit/mips32/Lowering-mips32.h
js/src/moz.build
copy from js/src/jit/mips32/Lowering-mips32.cpp
copy to js/src/jit/mips-shared/Lowering-mips-shared.cpp
--- a/js/src/jit/mips32/Lowering-mips32.cpp
+++ b/js/src/jit/mips-shared/Lowering-mips-shared.cpp
@@ -1,249 +1,107 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+#include "jit/mips-shared/Lowering-mips-shared.h"
+
 #include "mozilla/MathAlgorithms.h"
 
-
-#include "jit/Lowering.h"
-#include "jit/mips32/Assembler-mips32.h"
 #include "jit/MIR.h"
 
 #include "jit/shared/Lowering-shared-inl.h"
 
 using namespace js;
 using namespace js::jit;
 
 using mozilla::FloorLog2;
 
-void
-LIRGeneratorMIPS::useBoxFixed(LInstruction* lir, size_t n, MDefinition* mir, Register reg1,
-                              Register reg2, bool useAtStart)
-{
-    MOZ_ASSERT(mir->type() == MIRType_Value);
-    MOZ_ASSERT(reg1 != reg2);
-
-    ensureDefined(mir);
-    lir->setOperand(n, LUse(reg1, mir->virtualRegister(), useAtStart));
-    lir->setOperand(n + 1, LUse(reg2, VirtualRegisterOfPayload(mir), useAtStart));
-}
-
 LAllocation
-LIRGeneratorMIPS::useByteOpRegister(MDefinition* mir)
+LIRGeneratorMIPSShared::useByteOpRegister(MDefinition* mir)
 {
     return useRegister(mir);
 }
 
 LAllocation
-LIRGeneratorMIPS::useByteOpRegisterOrNonDoubleConstant(MDefinition* mir)
+LIRGeneratorMIPSShared::useByteOpRegisterOrNonDoubleConstant(MDefinition* mir)
 {
     return useRegisterOrNonDoubleConstant(mir);
 }
 
 LDefinition
-LIRGeneratorMIPS::tempByteOpRegister()
+LIRGeneratorMIPSShared::tempByteOpRegister()
 {
     return temp();
 }
 
-void
-LIRGeneratorMIPS::visitBox(MBox* box)
-{
-    MDefinition* inner = box->getOperand(0);
-
-    // If the box wrapped a double, it needs a new register.
-    if (IsFloatingPointType(inner->type())) {
-        defineBox(new(alloc()) LBoxFloatingPoint(useRegisterAtStart(inner),
-                                                 tempCopy(inner, 0), inner->type()), box);
-        return;
-    }
-
-    if (box->canEmitAtUses()) {
-        emitAtUses(box);
-        return;
-    }
-
-    if (inner->isConstant()) {
-        defineBox(new(alloc()) LValue(inner->toConstant()->value()), box);
-        return;
-    }
-
-    LBox* lir = new(alloc()) LBox(use(inner), inner->type());
-
-    // Otherwise, we should not define a new register for the payload portion
-    // of the output, so bypass defineBox().
-    uint32_t vreg = getVirtualRegister();
-
-    // Note that because we're using BogusTemp(), we do not change the type of
-    // the definition. We also do not define the first output as "TYPE",
-    // because it has no corresponding payload at (vreg + 1). Also note that
-    // although we copy the input's original type for the payload half of the
-    // definition, this is only for clarity. BogusTemp() definitions are
-    // ignored.
-    lir->setDef(0, LDefinition(vreg, LDefinition::GENERAL));
-    lir->setDef(1, LDefinition::BogusTemp());
-    box->setVirtualRegister(vreg);
-    add(lir);
-}
-
-void
-LIRGeneratorMIPS::visitUnbox(MUnbox* unbox)
-{
-    MDefinition* inner = unbox->getOperand(0);
-
-    if (inner->type() == MIRType_ObjectOrNull) {
-        LUnboxObjectOrNull* lir = new(alloc()) LUnboxObjectOrNull(useRegisterAtStart(inner));
-        if (unbox->fallible())
-            assignSnapshot(lir, unbox->bailoutKind());
-        defineReuseInput(lir, unbox, 0);
-        return;
-    }
-
-    // An unbox on mips reads in a type tag (either in memory or a register) and
-    // a payload. Unlike most instructions consuming a box, we ask for the type
-    // second, so that the result can re-use the first input.
-    MOZ_ASSERT(inner->type() == MIRType_Value);
-
-    ensureDefined(inner);
-
-    if (IsFloatingPointType(unbox->type())) {
-        LUnboxFloatingPoint* lir = new(alloc()) LUnboxFloatingPoint(unbox->type());
-        if (unbox->fallible())
-            assignSnapshot(lir, unbox->bailoutKind());
-        useBox(lir, LUnboxFloatingPoint::Input, inner);
-        define(lir, unbox);
-        return;
-    }
-
-    // Swap the order we use the box pieces so we can re-use the payload
-    // register.
-    LUnbox* lir = new(alloc()) LUnbox;
-    lir->setOperand(0, usePayloadInRegisterAtStart(inner));
-    lir->setOperand(1, useType(inner, LUse::REGISTER));
-
-    if (unbox->fallible())
-        assignSnapshot(lir, unbox->bailoutKind());
-
-    // Types and payloads form two separate intervals. If the type becomes dead
-    // before the payload, it could be used as a Value without the type being
-    // recoverable. Unbox's purpose is to eagerly kill the definition of a type
-    // tag, so keeping both alive (for the purpose of gcmaps) is unappealing.
-    // Instead, we create a new virtual register.
-    defineReuseInput(lir, unbox, 0);
-}
-
-void
-LIRGeneratorMIPS::visitReturn(MReturn* ret)
-{
-    MDefinition* opd = ret->getOperand(0);
-    MOZ_ASSERT(opd->type() == MIRType_Value);
-
-    LReturn* ins = new(alloc()) LReturn;
-    ins->setOperand(0, LUse(JSReturnReg_Type));
-    ins->setOperand(1, LUse(JSReturnReg_Data));
-    fillBoxUses(ins, 0, opd);
-    add(ins);
-}
-
 // x = !y
 void
-LIRGeneratorMIPS::lowerForALU(LInstructionHelper<1, 1, 0>* ins,
-                              MDefinition* mir, MDefinition* input)
+LIRGeneratorMIPSShared::lowerForALU(LInstructionHelper<1, 1, 0>* ins,
+                                    MDefinition* mir, MDefinition* input)
 {
     ins->setOperand(0, useRegister(input));
     define(ins, mir, LDefinition(LDefinition::TypeFrom(mir->type()), LDefinition::REGISTER));
 }
 
 // z = x+y
 void
-LIRGeneratorMIPS::lowerForALU(LInstructionHelper<1, 2, 0>* ins, MDefinition* mir,
-                              MDefinition* lhs, MDefinition* rhs)
+LIRGeneratorMIPSShared::lowerForALU(LInstructionHelper<1, 2, 0>* ins, MDefinition* mir,
+                                    MDefinition* lhs, MDefinition* rhs)
 {
     ins->setOperand(0, useRegister(lhs));
     ins->setOperand(1, useRegisterOrConstant(rhs));
     define(ins, mir, LDefinition(LDefinition::TypeFrom(mir->type()), LDefinition::REGISTER));
 }
 
 void
-LIRGeneratorMIPS::lowerForFPU(LInstructionHelper<1, 1, 0>* ins, MDefinition* mir,
-                              MDefinition* input)
+LIRGeneratorMIPSShared::lowerForFPU(LInstructionHelper<1, 1, 0>* ins, MDefinition* mir,
+                                    MDefinition* input)
 {
     ins->setOperand(0, useRegister(input));
     define(ins, mir, LDefinition(LDefinition::TypeFrom(mir->type()), LDefinition::REGISTER));
 }
 
 template<size_t Temps>
 void
-LIRGeneratorMIPS::lowerForFPU(LInstructionHelper<1, 2, Temps>* ins, MDefinition* mir,
-                              MDefinition* lhs, MDefinition* rhs)
+LIRGeneratorMIPSShared::lowerForFPU(LInstructionHelper<1, 2, Temps>* ins, MDefinition* mir,
+                                    MDefinition* lhs, MDefinition* rhs)
 {
     ins->setOperand(0, useRegister(lhs));
     ins->setOperand(1, useRegister(rhs));
     define(ins, mir, LDefinition(LDefinition::TypeFrom(mir->type()), LDefinition::REGISTER));
 }
 
-template void LIRGeneratorMIPS::lowerForFPU(LInstructionHelper<1, 2, 0>* ins, MDefinition* mir,
-                                            MDefinition* lhs, MDefinition* rhs);
-template void LIRGeneratorMIPS::lowerForFPU(LInstructionHelper<1, 2, 1>* ins, MDefinition* mir,
-                                            MDefinition* lhs, MDefinition* rhs);
+template void LIRGeneratorMIPSShared::lowerForFPU(LInstructionHelper<1, 2, 0>* ins, MDefinition* mir,
+                                                  MDefinition* lhs, MDefinition* rhs);
+template void LIRGeneratorMIPSShared::lowerForFPU(LInstructionHelper<1, 2, 1>* ins, MDefinition* mir,
+                                                  MDefinition* lhs, MDefinition* rhs);
 
 void
-LIRGeneratorMIPS::lowerForBitAndAndBranch(LBitAndAndBranch* baab, MInstruction* mir,
-                                          MDefinition* lhs, MDefinition* rhs)
+LIRGeneratorMIPSShared::lowerForBitAndAndBranch(LBitAndAndBranch* baab, MInstruction* mir,
+                                                MDefinition* lhs, MDefinition* rhs)
 {
     baab->setOperand(0, useRegisterAtStart(lhs));
     baab->setOperand(1, useRegisterOrConstantAtStart(rhs));
     add(baab, mir);
 }
 
 void
-LIRGeneratorMIPS::defineUntypedPhi(MPhi* phi, size_t lirIndex)
-{
-    LPhi* type = current->getPhi(lirIndex + VREG_TYPE_OFFSET);
-    LPhi* payload = current->getPhi(lirIndex + VREG_DATA_OFFSET);
-
-    uint32_t typeVreg = getVirtualRegister();
-    phi->setVirtualRegister(typeVreg);
-
-    uint32_t payloadVreg = getVirtualRegister();
-    MOZ_ASSERT(typeVreg + 1 == payloadVreg);
-
-    type->setDef(0, LDefinition(typeVreg, LDefinition::TYPE));
-    payload->setDef(0, LDefinition(payloadVreg, LDefinition::PAYLOAD));
-    annotate(type);
-    annotate(payload);
-}
-
-void
-LIRGeneratorMIPS::lowerUntypedPhiInput(MPhi* phi, uint32_t inputPosition,
-                                       LBlock* block, size_t lirIndex)
-{
-    MDefinition* operand = phi->getOperand(inputPosition);
-    LPhi* type = block->getPhi(lirIndex + VREG_TYPE_OFFSET);
-    LPhi* payload = block->getPhi(lirIndex + VREG_DATA_OFFSET);
-    type->setOperand(inputPosition, LUse(operand->virtualRegister() + VREG_TYPE_OFFSET,
-                                         LUse::ANY));
-    payload->setOperand(inputPosition, LUse(VirtualRegisterOfPayload(operand), LUse::ANY));
-}
-
-void
-LIRGeneratorMIPS::lowerForShift(LInstructionHelper<1, 2, 0>* ins, MDefinition* mir,
-                                MDefinition* lhs, MDefinition* rhs)
+LIRGeneratorMIPSShared::lowerForShift(LInstructionHelper<1, 2, 0>* ins, MDefinition* mir,
+                                      MDefinition* lhs, MDefinition* rhs)
 {
     ins->setOperand(0, useRegister(lhs));
     ins->setOperand(1, useRegisterOrConstant(rhs));
     define(ins, mir);
 }
 
 void
-LIRGeneratorMIPS::lowerDivI(MDiv* div)
+LIRGeneratorMIPSShared::lowerDivI(MDiv* div)
 {
     if (div->isUnsigned()) {
         lowerUDiv(div);
         return;
     }
 
     // Division instructions are slow. Division by constant denominators can be
     // rewritten to use other instructions.
@@ -266,27 +124,27 @@ LIRGeneratorMIPS::lowerDivI(MDiv* div)
 
     LDivI* lir = new(alloc()) LDivI(useRegister(div->lhs()), useRegister(div->rhs()), temp());
     if (div->fallible())
         assignSnapshot(lir, Bailout_DoubleOutput);
     define(lir, div);
 }
 
 void
-LIRGeneratorMIPS::lowerMulI(MMul* mul, MDefinition* lhs, MDefinition* rhs)
+LIRGeneratorMIPSShared::lowerMulI(MMul* mul, MDefinition* lhs, MDefinition* rhs)
 {
     LMulI* lir = new(alloc()) LMulI;
     if (mul->fallible())
         assignSnapshot(lir, Bailout_DoubleOutput);
 
     lowerForALU(lir, mul, lhs, rhs);
 }
 
 void
-LIRGeneratorMIPS::lowerModI(MMod* mod)
+LIRGeneratorMIPSShared::lowerModI(MMod* mod)
 {
     if (mod->isUnsigned()) {
         lowerUMod(mod);
         return;
     }
 
     if (mod->rhs()->isConstant()) {
         int32_t rhs = mod->rhs()->toConstant()->value().toInt32();
@@ -312,135 +170,135 @@ LIRGeneratorMIPS::lowerModI(MMod* mod)
                            temp(LDefinition::GENERAL));
 
     if (mod->fallible())
         assignSnapshot(lir, Bailout_DoubleOutput);
     define(lir, mod);
 }
 
 void
-LIRGeneratorMIPS::visitPowHalf(MPowHalf* ins)
+LIRGeneratorMIPSShared::visitPowHalf(MPowHalf* ins)
 {
     MDefinition* input = ins->input();
     MOZ_ASSERT(input->type() == MIRType_Double);
     LPowHalfD* lir = new(alloc()) LPowHalfD(useRegisterAtStart(input));
     defineReuseInput(lir, ins, 0);
 }
 
 LTableSwitch*
-LIRGeneratorMIPS::newLTableSwitch(const LAllocation& in, const LDefinition& inputCopy,
-                                  MTableSwitch* tableswitch)
+LIRGeneratorMIPSShared::newLTableSwitch(const LAllocation& in, const LDefinition& inputCopy,
+                                        MTableSwitch* tableswitch)
 {
     return new(alloc()) LTableSwitch(in, inputCopy, temp(), tableswitch);
 }
 
 LTableSwitchV*
-LIRGeneratorMIPS::newLTableSwitchV(MTableSwitch* tableswitch)
+LIRGeneratorMIPSShared::newLTableSwitchV(MTableSwitch* tableswitch)
 {
     return new(alloc()) LTableSwitchV(temp(), tempDouble(), temp(), tableswitch);
 }
 
 void
-LIRGeneratorMIPS::visitGuardShape(MGuardShape* ins)
+LIRGeneratorMIPSShared::visitGuardShape(MGuardShape* ins)
 {
     MOZ_ASSERT(ins->obj()->type() == MIRType_Object);
 
     LDefinition tempObj = temp(LDefinition::OBJECT);
     LGuardShape* guard = new(alloc()) LGuardShape(useRegister(ins->obj()), tempObj);
     assignSnapshot(guard, ins->bailoutKind());
     add(guard, ins);
     redefine(ins, ins->obj());
 }
 
 void
-LIRGeneratorMIPS::visitGuardObjectGroup(MGuardObjectGroup* ins)
+LIRGeneratorMIPSShared::visitGuardObjectGroup(MGuardObjectGroup* ins)
 {
     MOZ_ASSERT(ins->obj()->type() == MIRType_Object);
 
     LDefinition tempObj = temp(LDefinition::OBJECT);
     LGuardObjectGroup* guard = new(alloc()) LGuardObjectGroup(useRegister(ins->obj()), tempObj);
     assignSnapshot(guard, ins->bailoutKind());
     add(guard, ins);
     redefine(ins, ins->obj());
 }
 
 void
-LIRGeneratorMIPS::lowerUrshD(MUrsh* mir)
+LIRGeneratorMIPSShared::lowerUrshD(MUrsh* mir)
 {
     MDefinition* lhs = mir->lhs();
     MDefinition* rhs = mir->rhs();
 
     MOZ_ASSERT(lhs->type() == MIRType_Int32);
     MOZ_ASSERT(rhs->type() == MIRType_Int32);
 
     LUrshD* lir = new(alloc()) LUrshD(useRegister(lhs), useRegisterOrConstant(rhs), temp());
     define(lir, mir);
 }
 
 void
-LIRGeneratorMIPS::visitAsmJSNeg(MAsmJSNeg* ins)
+LIRGeneratorMIPSShared::visitAsmJSNeg(MAsmJSNeg* ins)
 {
     if (ins->type() == MIRType_Int32) {
         define(new(alloc()) LNegI(useRegisterAtStart(ins->input())), ins);
     } else if (ins->type() == MIRType_Float32) {
         define(new(alloc()) LNegF(useRegisterAtStart(ins->input())), ins);
     } else {
         MOZ_ASSERT(ins->type() == MIRType_Double);
         define(new(alloc()) LNegD(useRegisterAtStart(ins->input())), ins);
     }
 }
 
 void
-LIRGeneratorMIPS::lowerUDiv(MDiv* div)
+LIRGeneratorMIPSShared::lowerUDiv(MDiv* div)
 {
     MDefinition* lhs = div->getOperand(0);
     MDefinition* rhs = div->getOperand(1);
 
     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)
+LIRGeneratorMIPSShared::lowerUMod(MMod* mod)
 {
     MDefinition* lhs = mod->getOperand(0);
     MDefinition* rhs = mod->getOperand(1);
 
     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);
 }
 
 void
-LIRGeneratorMIPS::visitAsmJSUnsignedToDouble(MAsmJSUnsignedToDouble* ins)
+LIRGeneratorMIPSShared::visitAsmJSUnsignedToDouble(MAsmJSUnsignedToDouble* ins)
 {
     MOZ_ASSERT(ins->input()->type() == MIRType_Int32);
     LAsmJSUInt32ToDouble* lir = new(alloc()) LAsmJSUInt32ToDouble(useRegisterAtStart(ins->input()));
     define(lir, ins);
 }
 
 void
-LIRGeneratorMIPS::visitAsmJSUnsignedToFloat32(MAsmJSUnsignedToFloat32* ins)
+LIRGeneratorMIPSShared::visitAsmJSUnsignedToFloat32(MAsmJSUnsignedToFloat32* ins)
 {
     MOZ_ASSERT(ins->input()->type() == MIRType_Int32);
     LAsmJSUInt32ToFloat32* lir = new(alloc()) LAsmJSUInt32ToFloat32(useRegisterAtStart(ins->input()));
     define(lir, ins);
 }
 
 void
-LIRGeneratorMIPS::visitAsmJSLoadHeap(MAsmJSLoadHeap* ins)
+LIRGeneratorMIPSShared::visitAsmJSLoadHeap(MAsmJSLoadHeap* ins)
 {
     MDefinition* ptr = ins->ptr();
     MOZ_ASSERT(ptr->type() == MIRType_Int32);
     LAllocation ptrAlloc;
 
     // For MIPS it is best to keep the 'ptr' in a register if a bounds check
     // is needed.
     if (ptr->isConstantValue() && !ins->needsBoundsCheck()) {
@@ -449,132 +307,114 @@ LIRGeneratorMIPS::visitAsmJSLoadHeap(MAs
         ptrAlloc = LAllocation(ptr->constantVp());
     } else
         ptrAlloc = useRegisterAtStart(ptr);
 
     define(new(alloc()) LAsmJSLoadHeap(ptrAlloc), ins);
 }
 
 void
-LIRGeneratorMIPS::visitAsmJSStoreHeap(MAsmJSStoreHeap* ins)
+LIRGeneratorMIPSShared::visitAsmJSStoreHeap(MAsmJSStoreHeap* ins)
 {
     MDefinition* ptr = ins->ptr();
     MOZ_ASSERT(ptr->type() == MIRType_Int32);
     LAllocation ptrAlloc;
 
     if (ptr->isConstantValue() && !ins->needsBoundsCheck()) {
         MOZ_ASSERT(ptr->constantValue().toInt32() >= 0);
         ptrAlloc = LAllocation(ptr->constantVp());
     } else
         ptrAlloc = useRegisterAtStart(ptr);
 
     add(new(alloc()) LAsmJSStoreHeap(ptrAlloc, useRegisterAtStart(ins->value())), ins);
 }
 
 void
-LIRGeneratorMIPS::visitAsmJSLoadFuncPtr(MAsmJSLoadFuncPtr* ins)
+LIRGeneratorMIPSShared::visitAsmJSLoadFuncPtr(MAsmJSLoadFuncPtr* ins)
 {
     define(new(alloc()) LAsmJSLoadFuncPtr(useRegister(ins->index())), ins);
 }
 
 void
-LIRGeneratorMIPS::lowerTruncateDToInt32(MTruncateToInt32* ins)
-{
-    MDefinition* opd = ins->input();
-    MOZ_ASSERT(opd->type() == MIRType_Double);
-
-    define(new(alloc()) LTruncateDToInt32(useRegister(opd), LDefinition::BogusTemp()), ins);
-}
-
-void
-LIRGeneratorMIPS::lowerTruncateFToInt32(MTruncateToInt32* ins)
-{
-    MDefinition* opd = ins->input();
-    MOZ_ASSERT(opd->type() == MIRType_Float32);
-
-    define(new(alloc()) LTruncateFToInt32(useRegister(opd), LDefinition::BogusTemp()), ins);
-}
-
-void
-LIRGeneratorMIPS::visitSubstr(MSubstr* ins)
+LIRGeneratorMIPSShared::visitSubstr(MSubstr* ins)
 {
     LSubstr* lir = new (alloc()) LSubstr(useRegister(ins->string()),
                                          useRegister(ins->begin()),
                                          useRegister(ins->length()),
                                          temp(),
                                          temp(),
                                          tempByteOpRegister());
     define(lir, ins);
     assignSafepoint(lir, ins);
 }
 
 void
-LIRGeneratorMIPS::visitStoreTypedArrayElementStatic(MStoreTypedArrayElementStatic* ins)
+LIRGeneratorMIPSShared::visitStoreTypedArrayElementStatic(MStoreTypedArrayElementStatic* ins)
 {
     MOZ_CRASH("NYI");
 }
 
 void
-LIRGeneratorMIPS::visitSimdBinaryArith(MSimdBinaryArith* ins)
+LIRGeneratorMIPSShared::visitSimdBinaryArith(MSimdBinaryArith* ins)
 {
     MOZ_CRASH("NYI");
 }
 
 void
-LIRGeneratorMIPS::visitSimdSelect(MSimdSelect* ins)
+LIRGeneratorMIPSShared::visitSimdSelect(MSimdSelect* ins)
 {
     MOZ_CRASH("NYI");
 }
 
 void
-LIRGeneratorMIPS::visitSimdSplatX4(MSimdSplatX4* ins)
+LIRGeneratorMIPSShared::visitSimdSplatX4(MSimdSplatX4* ins)
 {
     MOZ_CRASH("NYI");
 }
 
 void
-LIRGeneratorMIPS::visitSimdValueX4(MSimdValueX4* ins)
+LIRGeneratorMIPSShared::visitSimdValueX4(MSimdValueX4* ins)
 {
     MOZ_CRASH("NYI");
 }
 
 void
-LIRGeneratorMIPS::visitCompareExchangeTypedArrayElement(MCompareExchangeTypedArrayElement* ins)
+LIRGeneratorMIPSShared::visitCompareExchangeTypedArrayElement(MCompareExchangeTypedArrayElement* ins)
 {
     MOZ_CRASH("NYI");
 }
 
 void
-LIRGeneratorMIPS::visitAtomicExchangeTypedArrayElement(MAtomicExchangeTypedArrayElement* ins)
+LIRGeneratorMIPSShared::visitAtomicExchangeTypedArrayElement(MAtomicExchangeTypedArrayElement* ins)
 {
     MOZ_CRASH("NYI");
 }
 
 void
-LIRGeneratorMIPS::visitAsmJSCompareExchangeHeap(MAsmJSCompareExchangeHeap* ins)
+LIRGeneratorMIPSShared::visitAsmJSCompareExchangeHeap(MAsmJSCompareExchangeHeap* ins)
 {
     MOZ_CRASH("NYI");
 }
 
 void
-LIRGeneratorMIPS::visitAsmJSAtomicExchangeHeap(MAsmJSAtomicExchangeHeap* ins)
+LIRGeneratorMIPSShared::visitAsmJSAtomicExchangeHeap(MAsmJSAtomicExchangeHeap* ins)
 {
     MOZ_CRASH("NYI");
 }
 
 void
-LIRGeneratorMIPS::visitAsmJSAtomicBinopHeap(MAsmJSAtomicBinopHeap* ins)
+LIRGeneratorMIPSShared::visitAsmJSAtomicBinopHeap(MAsmJSAtomicBinopHeap* ins)
 {
     MOZ_CRASH("NYI");
 }
 
 void
-LIRGeneratorMIPS::visitAtomicTypedArrayElementBinop(MAtomicTypedArrayElementBinop* ins)
+LIRGeneratorMIPSShared::visitAtomicTypedArrayElementBinop(MAtomicTypedArrayElementBinop* ins)
 {
     MOZ_CRASH("NYI");
 }
 
 void
-LIRGeneratorMIPS::visitRandom(MRandom* ins)
+LIRGeneratorMIPSShared::visitRandom(MRandom* ins)
 {
     LRandom* lir = new(alloc()) LRandom(tempFixed(CallTempReg0), tempFixed(CallTempReg1));
     defineReturn(lir, ins);
 }
copy from js/src/jit/mips32/Lowering-mips32.h
copy to js/src/jit/mips-shared/Lowering-mips-shared.h
--- a/js/src/jit/mips32/Lowering-mips32.h
+++ b/js/src/jit/mips-shared/Lowering-mips-shared.h
@@ -1,49 +1,38 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#ifndef jit_mips32_Lowering_mips32_h
-#define jit_mips32_Lowering_mips32_h
+#ifndef jit_mips_shared_Lowering_mips_shared_h
+#define jit_mips_shared_Lowering_mips_shared_h
 
 #include "jit/shared/Lowering-shared.h"
 
 namespace js {
 namespace jit {
 
-class LIRGeneratorMIPS : public LIRGeneratorShared
+class LIRGeneratorMIPSShared : public LIRGeneratorShared
 {
   protected:
-    LIRGeneratorMIPS(MIRGenerator* gen, MIRGraph& graph, LIRGraph& lirGraph)
+    LIRGeneratorMIPSShared(MIRGenerator* gen, MIRGraph& graph, LIRGraph& lirGraph)
       : LIRGeneratorShared(gen, graph, lirGraph)
     { }
 
   protected:
-    // Adds a box input to an instruction, setting operand |n| to the type and
-    // |n+1| to the payload.
-    void useBoxFixed(LInstruction* lir, size_t n, MDefinition* mir, Register reg1, Register reg2,
-                     bool useAtStart = false);
-
     // x86 has constraints on what registers can be formatted for 1-byte
     // stores and loads; on MIPS all registers are okay.
     LAllocation useByteOpRegister(MDefinition* mir);
     LAllocation useByteOpRegisterOrNonDoubleConstant(MDefinition* mir);
     LDefinition tempByteOpRegister();
 
-    inline LDefinition tempToUnbox() {
-        return LDefinition::BogusTemp();
-    }
-
     bool needTempForPostBarrier() { return false; }
 
-    void lowerUntypedPhiInput(MPhi* phi, uint32_t inputPosition, LBlock* block, size_t lirIndex);
-    void defineUntypedPhi(MPhi* phi, size_t lirIndex);
     void lowerForShift(LInstructionHelper<1, 2, 0>* ins, MDefinition* mir, MDefinition* lhs,
                        MDefinition* rhs);
     void lowerUrshD(MUrsh* mir);
 
     void lowerForALU(LInstructionHelper<1, 1, 0>* ins, MDefinition* mir,
                      MDefinition* input);
     void lowerForALU(LInstructionHelper<1, 2, 0>* ins, MDefinition* mir,
                      MDefinition* lhs, MDefinition* rhs);
@@ -62,34 +51,29 @@ class LIRGeneratorMIPS : public LIRGener
     void lowerForCompFx4(LSimdBinaryCompFx4* ins, MSimdBinaryComp* mir,
                          MDefinition* lhs, MDefinition* rhs)
     {
         return lowerForFPU(ins, mir, lhs, rhs);
     }
 
     void lowerForBitAndAndBranch(LBitAndAndBranch* baab, MInstruction* mir,
                                  MDefinition* lhs, MDefinition* rhs);
-    void lowerTruncateDToInt32(MTruncateToInt32* ins);
-    void lowerTruncateFToInt32(MTruncateToInt32* ins);
     void lowerDivI(MDiv* div);
     void lowerModI(MMod* mod);
     void lowerMulI(MMul* mul, MDefinition* lhs, MDefinition* rhs);
     void lowerUDiv(MDiv* div);
     void lowerUMod(MMod* mod);
     void visitPowHalf(MPowHalf* ins);
     void visitAsmJSNeg(MAsmJSNeg* ins);
 
     LTableSwitch* newLTableSwitch(const LAllocation& in, const LDefinition& inputCopy,
                                   MTableSwitch* ins);
     LTableSwitchV* newLTableSwitchV(MTableSwitch* ins);
 
   public:
-    void visitBox(MBox* box);
-    void visitUnbox(MUnbox* unbox);
-    void visitReturn(MReturn* ret);
     void lowerPhi(MPhi* phi);
     void visitGuardShape(MGuardShape* ins);
     void visitGuardObjectGroup(MGuardObjectGroup* ins);
     void visitAsmJSUnsignedToDouble(MAsmJSUnsignedToDouble* ins);
     void visitAsmJSUnsignedToFloat32(MAsmJSUnsignedToFloat32* ins);
     void visitAsmJSLoadHeap(MAsmJSLoadHeap* ins);
     void visitAsmJSStoreHeap(MAsmJSStoreHeap* ins);
     void visitAsmJSCompareExchangeHeap(MAsmJSCompareExchangeHeap* ins);
@@ -103,14 +87,12 @@ class LIRGeneratorMIPS : public LIRGener
     void visitSimdValueX4(MSimdValueX4* ins);
     void visitCompareExchangeTypedArrayElement(MCompareExchangeTypedArrayElement* ins);
     void visitAtomicExchangeTypedArrayElement(MAtomicExchangeTypedArrayElement* ins);
     void visitAtomicTypedArrayElementBinop(MAtomicTypedArrayElementBinop* ins);
     void visitSubstr(MSubstr* ins);
     void visitRandom(MRandom* ins);
 };
 
-typedef LIRGeneratorMIPS LIRGeneratorSpecific;
-
 } // namespace jit
 } // namespace js
 
-#endif /* jit_mips32_Lowering_mips32_h */
+#endif /* jit_mips_shared_Lowering_mips_shared_h */
--- a/js/src/jit/mips32/Lowering-mips32.cpp
+++ b/js/src/jit/mips32/Lowering-mips32.cpp
@@ -1,58 +1,37 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "mozilla/MathAlgorithms.h"
-
+#include "jit/mips32/Lowering-mips32.h"
 
-#include "jit/Lowering.h"
 #include "jit/mips32/Assembler-mips32.h"
+
 #include "jit/MIR.h"
 
 #include "jit/shared/Lowering-shared-inl.h"
 
 using namespace js;
 using namespace js::jit;
 
-using mozilla::FloorLog2;
-
 void
 LIRGeneratorMIPS::useBoxFixed(LInstruction* lir, size_t n, MDefinition* mir, Register reg1,
                               Register reg2, bool useAtStart)
 {
     MOZ_ASSERT(mir->type() == MIRType_Value);
     MOZ_ASSERT(reg1 != reg2);
 
     ensureDefined(mir);
     lir->setOperand(n, LUse(reg1, mir->virtualRegister(), useAtStart));
     lir->setOperand(n + 1, LUse(reg2, VirtualRegisterOfPayload(mir), useAtStart));
 }
 
-LAllocation
-LIRGeneratorMIPS::useByteOpRegister(MDefinition* mir)
-{
-    return useRegister(mir);
-}
-
-LAllocation
-LIRGeneratorMIPS::useByteOpRegisterOrNonDoubleConstant(MDefinition* mir)
-{
-    return useRegisterOrNonDoubleConstant(mir);
-}
-
-LDefinition
-LIRGeneratorMIPS::tempByteOpRegister()
-{
-    return temp();
-}
-
 void
 LIRGeneratorMIPS::visitBox(MBox* box)
 {
     MDefinition* inner = box->getOperand(0);
 
     // If the box wrapped a double, it needs a new register.
     if (IsFloatingPointType(inner->type())) {
         defineBox(new(alloc()) LBoxFloatingPoint(useRegisterAtStart(inner),
@@ -142,67 +121,16 @@ LIRGeneratorMIPS::visitReturn(MReturn* r
 
     LReturn* ins = new(alloc()) LReturn;
     ins->setOperand(0, LUse(JSReturnReg_Type));
     ins->setOperand(1, LUse(JSReturnReg_Data));
     fillBoxUses(ins, 0, opd);
     add(ins);
 }
 
-// x = !y
-void
-LIRGeneratorMIPS::lowerForALU(LInstructionHelper<1, 1, 0>* ins,
-                              MDefinition* mir, MDefinition* input)
-{
-    ins->setOperand(0, useRegister(input));
-    define(ins, mir, LDefinition(LDefinition::TypeFrom(mir->type()), LDefinition::REGISTER));
-}
-
-// z = x+y
-void
-LIRGeneratorMIPS::lowerForALU(LInstructionHelper<1, 2, 0>* ins, MDefinition* mir,
-                              MDefinition* lhs, MDefinition* rhs)
-{
-    ins->setOperand(0, useRegister(lhs));
-    ins->setOperand(1, useRegisterOrConstant(rhs));
-    define(ins, mir, LDefinition(LDefinition::TypeFrom(mir->type()), LDefinition::REGISTER));
-}
-
-void
-LIRGeneratorMIPS::lowerForFPU(LInstructionHelper<1, 1, 0>* ins, MDefinition* mir,
-                              MDefinition* input)
-{
-    ins->setOperand(0, useRegister(input));
-    define(ins, mir, LDefinition(LDefinition::TypeFrom(mir->type()), LDefinition::REGISTER));
-}
-
-template<size_t Temps>
-void
-LIRGeneratorMIPS::lowerForFPU(LInstructionHelper<1, 2, Temps>* ins, MDefinition* mir,
-                              MDefinition* lhs, MDefinition* rhs)
-{
-    ins->setOperand(0, useRegister(lhs));
-    ins->setOperand(1, useRegister(rhs));
-    define(ins, mir, LDefinition(LDefinition::TypeFrom(mir->type()), LDefinition::REGISTER));
-}
-
-template void LIRGeneratorMIPS::lowerForFPU(LInstructionHelper<1, 2, 0>* ins, MDefinition* mir,
-                                            MDefinition* lhs, MDefinition* rhs);
-template void LIRGeneratorMIPS::lowerForFPU(LInstructionHelper<1, 2, 1>* ins, MDefinition* mir,
-                                            MDefinition* lhs, MDefinition* rhs);
-
-void
-LIRGeneratorMIPS::lowerForBitAndAndBranch(LBitAndAndBranch* baab, MInstruction* mir,
-                                          MDefinition* lhs, MDefinition* rhs)
-{
-    baab->setOperand(0, useRegisterAtStart(lhs));
-    baab->setOperand(1, useRegisterOrConstantAtStart(rhs));
-    add(baab, mir);
-}
-
 void
 LIRGeneratorMIPS::defineUntypedPhi(MPhi* phi, size_t lirIndex)
 {
     LPhi* type = current->getPhi(lirIndex + VREG_TYPE_OFFSET);
     LPhi* payload = current->getPhi(lirIndex + VREG_DATA_OFFSET);
 
     uint32_t typeVreg = getVirtualRegister();
     phi->setVirtualRegister(typeVreg);
@@ -224,357 +152,24 @@ LIRGeneratorMIPS::lowerUntypedPhiInput(M
     LPhi* type = block->getPhi(lirIndex + VREG_TYPE_OFFSET);
     LPhi* payload = block->getPhi(lirIndex + VREG_DATA_OFFSET);
     type->setOperand(inputPosition, LUse(operand->virtualRegister() + VREG_TYPE_OFFSET,
                                          LUse::ANY));
     payload->setOperand(inputPosition, LUse(VirtualRegisterOfPayload(operand), LUse::ANY));
 }
 
 void
-LIRGeneratorMIPS::lowerForShift(LInstructionHelper<1, 2, 0>* ins, MDefinition* mir,
-                                MDefinition* lhs, MDefinition* rhs)
-{
-    ins->setOperand(0, useRegister(lhs));
-    ins->setOperand(1, useRegisterOrConstant(rhs));
-    define(ins, mir);
-}
-
-void
-LIRGeneratorMIPS::lowerDivI(MDiv* div)
-{
-    if (div->isUnsigned()) {
-        lowerUDiv(div);
-        return;
-    }
-
-    // Division instructions are slow. Division by constant denominators can be
-    // rewritten to use other instructions.
-    if (div->rhs()->isConstant()) {
-        int32_t rhs = div->rhs()->toConstant()->value().toInt32();
-        // Check for division by a positive power of two, which is an easy and
-        // important case to optimize. Note that other optimizations are also
-        // possible; division by negative powers of two can be optimized in a
-        // similar manner as positive powers of two, and division by other
-        // constants can be optimized by a reciprocal multiplication technique.
-        int32_t shift = FloorLog2(rhs);
-        if (rhs > 0 && 1 << shift == rhs) {
-            LDivPowTwoI* lir = new(alloc()) LDivPowTwoI(useRegister(div->lhs()), shift, temp());
-            if (div->fallible())
-                assignSnapshot(lir, Bailout_DoubleOutput);
-            define(lir, div);
-            return;
-        }
-    }
-
-    LDivI* lir = new(alloc()) LDivI(useRegister(div->lhs()), useRegister(div->rhs()), temp());
-    if (div->fallible())
-        assignSnapshot(lir, Bailout_DoubleOutput);
-    define(lir, div);
-}
-
-void
-LIRGeneratorMIPS::lowerMulI(MMul* mul, MDefinition* lhs, MDefinition* rhs)
-{
-    LMulI* lir = new(alloc()) LMulI;
-    if (mul->fallible())
-        assignSnapshot(lir, Bailout_DoubleOutput);
-
-    lowerForALU(lir, mul, lhs, rhs);
-}
-
-void
-LIRGeneratorMIPS::lowerModI(MMod* mod)
-{
-    if (mod->isUnsigned()) {
-        lowerUMod(mod);
-        return;
-    }
-
-    if (mod->rhs()->isConstant()) {
-        int32_t rhs = mod->rhs()->toConstant()->value().toInt32();
-        int32_t shift = FloorLog2(rhs);
-        if (rhs > 0 && 1 << shift == rhs) {
-            LModPowTwoI* lir = new(alloc()) LModPowTwoI(useRegister(mod->lhs()), shift);
-            if (mod->fallible())
-                assignSnapshot(lir, Bailout_DoubleOutput);
-            define(lir, mod);
-            return;
-        } else if (shift < 31 && (1 << (shift + 1)) - 1 == rhs) {
-            LModMaskI* lir = new(alloc()) LModMaskI(useRegister(mod->lhs()),
-                                                    temp(LDefinition::GENERAL),
-                                                    temp(LDefinition::GENERAL),
-                                                    shift + 1);
-            if (mod->fallible())
-                assignSnapshot(lir, Bailout_DoubleOutput);
-            define(lir, mod);
-            return;
-        }
-    }
-    LModI* lir = new(alloc()) LModI(useRegister(mod->lhs()), useRegister(mod->rhs()),
-                           temp(LDefinition::GENERAL));
-
-    if (mod->fallible())
-        assignSnapshot(lir, Bailout_DoubleOutput);
-    define(lir, mod);
-}
-
-void
-LIRGeneratorMIPS::visitPowHalf(MPowHalf* ins)
-{
-    MDefinition* input = ins->input();
-    MOZ_ASSERT(input->type() == MIRType_Double);
-    LPowHalfD* lir = new(alloc()) LPowHalfD(useRegisterAtStart(input));
-    defineReuseInput(lir, ins, 0);
-}
-
-LTableSwitch*
-LIRGeneratorMIPS::newLTableSwitch(const LAllocation& in, const LDefinition& inputCopy,
-                                  MTableSwitch* tableswitch)
-{
-    return new(alloc()) LTableSwitch(in, inputCopy, temp(), tableswitch);
-}
-
-LTableSwitchV*
-LIRGeneratorMIPS::newLTableSwitchV(MTableSwitch* tableswitch)
-{
-    return new(alloc()) LTableSwitchV(temp(), tempDouble(), temp(), tableswitch);
-}
-
-void
-LIRGeneratorMIPS::visitGuardShape(MGuardShape* ins)
-{
-    MOZ_ASSERT(ins->obj()->type() == MIRType_Object);
-
-    LDefinition tempObj = temp(LDefinition::OBJECT);
-    LGuardShape* guard = new(alloc()) LGuardShape(useRegister(ins->obj()), tempObj);
-    assignSnapshot(guard, ins->bailoutKind());
-    add(guard, ins);
-    redefine(ins, ins->obj());
-}
-
-void
-LIRGeneratorMIPS::visitGuardObjectGroup(MGuardObjectGroup* ins)
-{
-    MOZ_ASSERT(ins->obj()->type() == MIRType_Object);
-
-    LDefinition tempObj = temp(LDefinition::OBJECT);
-    LGuardObjectGroup* guard = new(alloc()) LGuardObjectGroup(useRegister(ins->obj()), tempObj);
-    assignSnapshot(guard, ins->bailoutKind());
-    add(guard, ins);
-    redefine(ins, ins->obj());
-}
-
-void
-LIRGeneratorMIPS::lowerUrshD(MUrsh* mir)
-{
-    MDefinition* lhs = mir->lhs();
-    MDefinition* rhs = mir->rhs();
-
-    MOZ_ASSERT(lhs->type() == MIRType_Int32);
-    MOZ_ASSERT(rhs->type() == MIRType_Int32);
-
-    LUrshD* lir = new(alloc()) LUrshD(useRegister(lhs), useRegisterOrConstant(rhs), temp());
-    define(lir, mir);
-}
-
-void
-LIRGeneratorMIPS::visitAsmJSNeg(MAsmJSNeg* ins)
-{
-    if (ins->type() == MIRType_Int32) {
-        define(new(alloc()) LNegI(useRegisterAtStart(ins->input())), ins);
-    } else if (ins->type() == MIRType_Float32) {
-        define(new(alloc()) LNegF(useRegisterAtStart(ins->input())), ins);
-    } else {
-        MOZ_ASSERT(ins->type() == MIRType_Double);
-        define(new(alloc()) LNegD(useRegisterAtStart(ins->input())), ins);
-    }
-}
-
-void
-LIRGeneratorMIPS::lowerUDiv(MDiv* div)
-{
-    MDefinition* lhs = div->getOperand(0);
-    MDefinition* rhs = div->getOperand(1);
-
-    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);
-
-    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);
-}
-
-void
-LIRGeneratorMIPS::visitAsmJSUnsignedToDouble(MAsmJSUnsignedToDouble* ins)
-{
-    MOZ_ASSERT(ins->input()->type() == MIRType_Int32);
-    LAsmJSUInt32ToDouble* lir = new(alloc()) LAsmJSUInt32ToDouble(useRegisterAtStart(ins->input()));
-    define(lir, ins);
-}
-
-void
-LIRGeneratorMIPS::visitAsmJSUnsignedToFloat32(MAsmJSUnsignedToFloat32* ins)
-{
-    MOZ_ASSERT(ins->input()->type() == MIRType_Int32);
-    LAsmJSUInt32ToFloat32* lir = new(alloc()) LAsmJSUInt32ToFloat32(useRegisterAtStart(ins->input()));
-    define(lir, ins);
-}
-
-void
-LIRGeneratorMIPS::visitAsmJSLoadHeap(MAsmJSLoadHeap* ins)
-{
-    MDefinition* ptr = ins->ptr();
-    MOZ_ASSERT(ptr->type() == MIRType_Int32);
-    LAllocation ptrAlloc;
-
-    // For MIPS it is best to keep the 'ptr' in a register if a bounds check
-    // is needed.
-    if (ptr->isConstantValue() && !ins->needsBoundsCheck()) {
-        // A bounds check is only skipped for a positive index.
-        MOZ_ASSERT(ptr->constantValue().toInt32() >= 0);
-        ptrAlloc = LAllocation(ptr->constantVp());
-    } else
-        ptrAlloc = useRegisterAtStart(ptr);
-
-    define(new(alloc()) LAsmJSLoadHeap(ptrAlloc), ins);
-}
-
-void
-LIRGeneratorMIPS::visitAsmJSStoreHeap(MAsmJSStoreHeap* ins)
-{
-    MDefinition* ptr = ins->ptr();
-    MOZ_ASSERT(ptr->type() == MIRType_Int32);
-    LAllocation ptrAlloc;
-
-    if (ptr->isConstantValue() && !ins->needsBoundsCheck()) {
-        MOZ_ASSERT(ptr->constantValue().toInt32() >= 0);
-        ptrAlloc = LAllocation(ptr->constantVp());
-    } else
-        ptrAlloc = useRegisterAtStart(ptr);
-
-    add(new(alloc()) LAsmJSStoreHeap(ptrAlloc, useRegisterAtStart(ins->value())), ins);
-}
-
-void
-LIRGeneratorMIPS::visitAsmJSLoadFuncPtr(MAsmJSLoadFuncPtr* ins)
-{
-    define(new(alloc()) LAsmJSLoadFuncPtr(useRegister(ins->index())), ins);
-}
-
-void
 LIRGeneratorMIPS::lowerTruncateDToInt32(MTruncateToInt32* ins)
 {
     MDefinition* opd = ins->input();
     MOZ_ASSERT(opd->type() == MIRType_Double);
 
     define(new(alloc()) LTruncateDToInt32(useRegister(opd), LDefinition::BogusTemp()), ins);
 }
 
 void
 LIRGeneratorMIPS::lowerTruncateFToInt32(MTruncateToInt32* ins)
 {
     MDefinition* opd = ins->input();
     MOZ_ASSERT(opd->type() == MIRType_Float32);
 
     define(new(alloc()) LTruncateFToInt32(useRegister(opd), LDefinition::BogusTemp()), ins);
 }
-
-void
-LIRGeneratorMIPS::visitSubstr(MSubstr* ins)
-{
-    LSubstr* lir = new (alloc()) LSubstr(useRegister(ins->string()),
-                                         useRegister(ins->begin()),
-                                         useRegister(ins->length()),
-                                         temp(),
-                                         temp(),
-                                         tempByteOpRegister());
-    define(lir, ins);
-    assignSafepoint(lir, ins);
-}
-
-void
-LIRGeneratorMIPS::visitStoreTypedArrayElementStatic(MStoreTypedArrayElementStatic* ins)
-{
-    MOZ_CRASH("NYI");
-}
-
-void
-LIRGeneratorMIPS::visitSimdBinaryArith(MSimdBinaryArith* ins)
-{
-    MOZ_CRASH("NYI");
-}
-
-void
-LIRGeneratorMIPS::visitSimdSelect(MSimdSelect* ins)
-{
-    MOZ_CRASH("NYI");
-}
-
-void
-LIRGeneratorMIPS::visitSimdSplatX4(MSimdSplatX4* ins)
-{
-    MOZ_CRASH("NYI");
-}
-
-void
-LIRGeneratorMIPS::visitSimdValueX4(MSimdValueX4* ins)
-{
-    MOZ_CRASH("NYI");
-}
-
-void
-LIRGeneratorMIPS::visitCompareExchangeTypedArrayElement(MCompareExchangeTypedArrayElement* ins)
-{
-    MOZ_CRASH("NYI");
-}
-
-void
-LIRGeneratorMIPS::visitAtomicExchangeTypedArrayElement(MAtomicExchangeTypedArrayElement* ins)
-{
-    MOZ_CRASH("NYI");
-}
-
-void
-LIRGeneratorMIPS::visitAsmJSCompareExchangeHeap(MAsmJSCompareExchangeHeap* ins)
-{
-    MOZ_CRASH("NYI");
-}
-
-void
-LIRGeneratorMIPS::visitAsmJSAtomicExchangeHeap(MAsmJSAtomicExchangeHeap* ins)
-{
-    MOZ_CRASH("NYI");
-}
-
-void
-LIRGeneratorMIPS::visitAsmJSAtomicBinopHeap(MAsmJSAtomicBinopHeap* ins)
-{
-    MOZ_CRASH("NYI");
-}
-
-void
-LIRGeneratorMIPS::visitAtomicTypedArrayElementBinop(MAtomicTypedArrayElementBinop* ins)
-{
-    MOZ_CRASH("NYI");
-}
-
-void
-LIRGeneratorMIPS::visitRandom(MRandom* ins)
-{
-    LRandom* lir = new(alloc()) LRandom(tempFixed(CallTempReg0), tempFixed(CallTempReg1));
-    defineReturn(lir, ins);
-}
--- a/js/src/jit/mips32/Lowering-mips32.h
+++ b/js/src/jit/mips32/Lowering-mips32.h
@@ -2,115 +2,48 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef jit_mips32_Lowering_mips32_h
 #define jit_mips32_Lowering_mips32_h
 
-#include "jit/shared/Lowering-shared.h"
+#include "jit/mips-shared/Lowering-mips-shared.h"
 
 namespace js {
 namespace jit {
 
-class LIRGeneratorMIPS : public LIRGeneratorShared
+class LIRGeneratorMIPS : public LIRGeneratorMIPSShared
 {
   protected:
     LIRGeneratorMIPS(MIRGenerator* gen, MIRGraph& graph, LIRGraph& lirGraph)
-      : LIRGeneratorShared(gen, graph, lirGraph)
+      : LIRGeneratorMIPSShared(gen, graph, lirGraph)
     { }
 
   protected:
     // Adds a box input to an instruction, setting operand |n| to the type and
     // |n+1| to the payload.
     void useBoxFixed(LInstruction* lir, size_t n, MDefinition* mir, Register reg1, Register reg2,
                      bool useAtStart = false);
 
-    // x86 has constraints on what registers can be formatted for 1-byte
-    // stores and loads; on MIPS all registers are okay.
-    LAllocation useByteOpRegister(MDefinition* mir);
-    LAllocation useByteOpRegisterOrNonDoubleConstant(MDefinition* mir);
-    LDefinition tempByteOpRegister();
-
     inline LDefinition tempToUnbox() {
         return LDefinition::BogusTemp();
     }
 
-    bool needTempForPostBarrier() { return false; }
-
     void lowerUntypedPhiInput(MPhi* phi, uint32_t inputPosition, LBlock* block, size_t lirIndex);
     void defineUntypedPhi(MPhi* phi, size_t lirIndex);
-    void lowerForShift(LInstructionHelper<1, 2, 0>* ins, MDefinition* mir, MDefinition* lhs,
-                       MDefinition* rhs);
-    void lowerUrshD(MUrsh* mir);
 
-    void lowerForALU(LInstructionHelper<1, 1, 0>* ins, MDefinition* mir,
-                     MDefinition* input);
-    void lowerForALU(LInstructionHelper<1, 2, 0>* ins, MDefinition* mir,
-                     MDefinition* lhs, MDefinition* rhs);
-
-    void lowerForFPU(LInstructionHelper<1, 1, 0>* ins, MDefinition* mir,
-                     MDefinition* src);
-    template<size_t Temps>
-    void lowerForFPU(LInstructionHelper<1, 2, Temps>* ins, MDefinition* mir,
-                     MDefinition* lhs, MDefinition* rhs);
-
-    void lowerForCompIx4(LSimdBinaryCompIx4* ins, MSimdBinaryComp* mir,
-                         MDefinition* lhs, MDefinition* rhs)
-    {
-        return lowerForFPU(ins, mir, lhs, rhs);
-    }
-    void lowerForCompFx4(LSimdBinaryCompFx4* ins, MSimdBinaryComp* mir,
-                         MDefinition* lhs, MDefinition* rhs)
-    {
-        return lowerForFPU(ins, mir, lhs, rhs);
-    }
-
-    void lowerForBitAndAndBranch(LBitAndAndBranch* baab, MInstruction* mir,
-                                 MDefinition* lhs, MDefinition* rhs);
     void lowerTruncateDToInt32(MTruncateToInt32* ins);
     void lowerTruncateFToInt32(MTruncateToInt32* ins);
-    void lowerDivI(MDiv* div);
-    void lowerModI(MMod* mod);
-    void lowerMulI(MMul* mul, MDefinition* lhs, MDefinition* rhs);
-    void lowerUDiv(MDiv* div);
-    void lowerUMod(MMod* mod);
-    void visitPowHalf(MPowHalf* ins);
-    void visitAsmJSNeg(MAsmJSNeg* ins);
-
-    LTableSwitch* newLTableSwitch(const LAllocation& in, const LDefinition& inputCopy,
-                                  MTableSwitch* ins);
-    LTableSwitchV* newLTableSwitchV(MTableSwitch* ins);
 
   public:
     void visitBox(MBox* box);
     void visitUnbox(MUnbox* unbox);
     void visitReturn(MReturn* ret);
-    void lowerPhi(MPhi* phi);
-    void visitGuardShape(MGuardShape* ins);
-    void visitGuardObjectGroup(MGuardObjectGroup* ins);
-    void visitAsmJSUnsignedToDouble(MAsmJSUnsignedToDouble* ins);
-    void visitAsmJSUnsignedToFloat32(MAsmJSUnsignedToFloat32* ins);
-    void visitAsmJSLoadHeap(MAsmJSLoadHeap* ins);
-    void visitAsmJSStoreHeap(MAsmJSStoreHeap* ins);
-    void visitAsmJSCompareExchangeHeap(MAsmJSCompareExchangeHeap* ins);
-    void visitAsmJSAtomicExchangeHeap(MAsmJSAtomicExchangeHeap* ins);
-    void visitAsmJSAtomicBinopHeap(MAsmJSAtomicBinopHeap* ins);
-    void visitAsmJSLoadFuncPtr(MAsmJSLoadFuncPtr* ins);
-    void visitStoreTypedArrayElementStatic(MStoreTypedArrayElementStatic* ins);
-    void visitSimdBinaryArith(MSimdBinaryArith* ins);
-    void visitSimdSelect(MSimdSelect* ins);
-    void visitSimdSplatX4(MSimdSplatX4* ins);
-    void visitSimdValueX4(MSimdValueX4* ins);
-    void visitCompareExchangeTypedArrayElement(MCompareExchangeTypedArrayElement* ins);
-    void visitAtomicExchangeTypedArrayElement(MAtomicExchangeTypedArrayElement* ins);
-    void visitAtomicTypedArrayElementBinop(MAtomicTypedArrayElementBinop* ins);
-    void visitSubstr(MSubstr* ins);
-    void visitRandom(MRandom* ins);
 };
 
 typedef LIRGeneratorMIPS LIRGeneratorSpecific;
 
 } // namespace jit
 } // namespace js
 
 #endif /* jit_mips32_Lowering_mips32_h */
--- a/js/src/moz.build
+++ b/js/src/moz.build
@@ -463,16 +463,17 @@ elif CONFIG['JS_CODEGEN_ARM64']:
             'jit/arm64/vixl/Debugger-vixl.cpp',
             'jit/arm64/vixl/MozSimulator-vixl.cpp',
             'jit/arm64/vixl/Simulator-vixl.cpp'
         ]
 elif CONFIG['JS_CODEGEN_MIPS32']:
     UNIFIED_SOURCES += [
         'jit/mips-shared/Architecture-mips-shared.cpp',
         'jit/mips-shared/Assembler-mips-shared.cpp',
+        'jit/mips-shared/Lowering-mips-shared.cpp',
     ]
     if CONFIG['JS_CODEGEN_MIPS32']:
         UNIFIED_SOURCES += [
             'jit/mips32/Architecture-mips32.cpp',
             'jit/mips32/Assembler-mips32.cpp',
             'jit/mips32/Bailouts-mips32.cpp',
             'jit/mips32/BaselineCompiler-mips32.cpp',
             'jit/mips32/BaselineIC-mips32.cpp',