Bug 1205134 - IonMonkey: MIPS: Split shareable code to mips-shared in MacroAssembler-mips32. r=lth f=nbp
authorHeiher <r@hev.cc>
Tue, 27 Oct 2015 18:21:31 +0800
changeset 304825 11969330ba7e37bdf58a86fd15600cc3041f4c4b
parent 304824 7f2e1b5e5d96382502ca41163026e1fcbb4b0c23
child 304826 0dd4a8dd56181365169aee7c6928cca302f9baf2
push id1001
push userraliiev@mozilla.com
push dateMon, 18 Jan 2016 19:06:03 +0000
treeherdermozilla-release@8b89261f3ac4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslth
bugs1205134
milestone44.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 1205134 - IonMonkey: MIPS: Split shareable code to mips-shared in MacroAssembler-mips32. r=lth f=nbp --- .../MacroAssembler-mips-shared.cpp} | 2977 +------------------- .../MacroAssembler-mips-shared.h} | 1236 +------- js/src/jit/mips32/MacroAssembler-mips32.cpp | 766 ----- js/src/jit/mips32/MacroAssembler-mips32.h | 158 +- js/src/moz.build | 1 + 5 files changed, 118 insertions(+), 5020 deletions(-) copy js/src/jit/{mips32/MacroAssembler-mips32.cpp => mips-shared/MacroAssembler-mips-shared.cpp} (14%) copy js/src/jit/{mips32/MacroAssembler-mips32.h => mips-shared/MacroAssembler-mips-shared.h} (11%)
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/moz.build
copy from js/src/jit/mips32/MacroAssembler-mips32.cpp
copy to js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp
--- a/js/src/jit/mips32/MacroAssembler-mips32.cpp
+++ b/js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp
@@ -1,690 +1,290 @@
 /* -*- 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/mips32/MacroAssembler-mips32.h"
-
-#include "mozilla/DebugOnly.h"
-#include "mozilla/MathAlgorithms.h"
-
-#include "jit/Bailouts.h"
-#include "jit/BaselineFrame.h"
-#include "jit/JitFrames.h"
-#include "jit/MacroAssembler.h"
-#include "jit/mips32/Simulator-mips32.h"
-#include "jit/MoveEmitter.h"
-#include "jit/SharedICRegisters.h"
-
-#include "jit/MacroAssembler-inl.h"
+#include "jit/mips-shared/MacroAssembler-mips-shared.h"
 
 using namespace js;
 using namespace jit;
 
-using mozilla::Abs;
-
-static const int32_t PAYLOAD_OFFSET = NUNBOX32_PAYLOAD_OFFSET;
-static const int32_t TAG_OFFSET = NUNBOX32_TYPE_OFFSET;
-
-static_assert(sizeof(intptr_t) == 4, "Not 64-bit clean.");
-
 void
-MacroAssemblerMIPSCompat::convertBoolToInt32(Register src, Register dest)
-{
-    // Note that C++ bool is only 1 byte, so zero extend it to clear the
-    // higher-order bits.
-    ma_and(dest, src, Imm32(0xff));
-}
-
-void
-MacroAssemblerMIPSCompat::convertInt32ToDouble(Register src, FloatRegister dest)
-{
-    as_mtc1(src, dest);
-    as_cvtdw(dest, dest);
-}
-
-void
-MacroAssemblerMIPSCompat::convertInt32ToDouble(const Address& src, FloatRegister dest)
-{
-    ma_ls(dest, src);
-    as_cvtdw(dest, dest);
-}
-
-void
-MacroAssemblerMIPSCompat::convertInt32ToDouble(const BaseIndex& src, FloatRegister dest)
-{
-    computeScaledAddress(src, ScratchRegister);
-    convertInt32ToDouble(Address(ScratchRegister, src.offset), dest);
-}
-
-void
-MacroAssemblerMIPSCompat::convertUInt32ToDouble(Register src, FloatRegister dest)
-{
-    // We use SecondScratchDoubleReg because MacroAssembler::loadFromTypedArray
-    // calls with ScratchDoubleReg as dest.
-    MOZ_ASSERT(dest != SecondScratchDoubleReg);
-
-    // Subtract INT32_MIN to get a positive number
-    ma_subu(ScratchRegister, src, Imm32(INT32_MIN));
-
-    // Convert value
-    as_mtc1(ScratchRegister, dest);
-    as_cvtdw(dest, dest);
-
-    // Add unsigned value of INT32_MIN
-    ma_lid(SecondScratchDoubleReg, 2147483648.0);
-    as_addd(dest, dest, SecondScratchDoubleReg);
-}
-
-void
-MacroAssemblerMIPSCompat::mul64(Imm64 imm, const Register64& dest)
-{
-    // LOW32  = LOW(LOW(dest) * LOW(imm));
-    // HIGH32 = LOW(HIGH(dest) * LOW(imm)) [multiply imm into upper bits]
-    //        + LOW(LOW(dest) * HIGH(imm)) [multiply dest into upper bits]
-    //        + HIGH(LOW(dest) * LOW(imm)) [carry]
-
-    // HIGH(dest) = LOW(HIGH(dest) * LOW(imm));
-    ma_li(ScratchRegister, Imm32(imm.value & LOW_32_MASK));
-    as_multu(dest.high, ScratchRegister);
-    as_mflo(dest.high);
-
-    // mfhi:mflo = LOW(dest) * LOW(imm);
-    as_multu(dest.low, ScratchRegister);
-
-    // HIGH(dest) += mfhi;
-    as_mfhi(ScratchRegister);
-    as_addu(dest.high, dest.high, ScratchRegister);
-
-    if (((imm.value >> 32) & LOW_32_MASK) == 5) {
-        // Optimized case for Math.random().
-
-        // HIGH(dest) += LOW(LOW(dest) * HIGH(imm));
-        as_sll(ScratchRegister, dest.low, 2);
-        as_addu(ScratchRegister, ScratchRegister, dest.low);
-        as_addu(dest.high, dest.high, ScratchRegister);
-
-        // LOW(dest) = mflo;
-        as_mflo(dest.low);
-    } else {
-        // tmp = mflo
-        as_mflo(SecondScratchReg);
-
-        // HIGH(dest) += LOW(LOW(dest) * HIGH(imm));
-        ma_li(ScratchRegister, Imm32((imm.value >> 32) & LOW_32_MASK));
-        as_multu(dest.low, ScratchRegister);
-        as_mflo(ScratchRegister);
-        as_addu(dest.high, dest.high, ScratchRegister);
-
-        // LOW(dest) = tmp;
-        ma_move(dest.low, SecondScratchReg);
-    }
-}
-
-static const double TO_DOUBLE_HIGH_SCALE = 0x100000000;
-
-void
-MacroAssemblerMIPSCompat::convertUInt64ToDouble(Register64 src, Register temp, FloatRegister dest)
-{
-    convertUInt32ToDouble(src.high, dest);
-    loadConstantDouble(TO_DOUBLE_HIGH_SCALE, ScratchDoubleReg);
-    mulDouble(ScratchDoubleReg, dest);
-    convertUInt32ToDouble(src.low, ScratchDoubleReg);
-    addDouble(ScratchDoubleReg, dest);
-}
-
-void
-MacroAssemblerMIPSCompat::convertUInt32ToFloat32(Register src, FloatRegister dest)
-{
-    Label positive, done;
-    ma_b(src, src, &positive, NotSigned, ShortJump);
-
-    // We cannot do the same as convertUInt32ToDouble because float32 doesn't
-    // have enough precision.
-    convertUInt32ToDouble(src, dest);
-    convertDoubleToFloat32(dest, dest);
-    ma_b(&done, ShortJump);
-
-    bind(&positive);
-    convertInt32ToFloat32(src, dest);
-
-    bind(&done);
-}
-
-void
-MacroAssemblerMIPSCompat::convertDoubleToFloat32(FloatRegister src, FloatRegister dest)
-{
-    as_cvtsd(dest, src);
-}
-
-// Convert the floating point value to an integer, if it did not fit, then it
-// was clamped to INT32_MIN/INT32_MAX, and we can test it.
-// NOTE: if the value really was supposed to be INT32_MAX / INT32_MIN then it
-// will be wrong.
-void
-MacroAssemblerMIPSCompat::branchTruncateDouble(FloatRegister src, Register dest,
-                                         Label* fail)
-{
-    Label test, success;
-    as_truncwd(ScratchDoubleReg, src);
-    as_mfc1(dest, ScratchDoubleReg);
-
-    ma_b(dest, Imm32(INT32_MAX), fail, Assembler::Equal);
-    ma_b(dest, Imm32(INT32_MIN), fail, Assembler::Equal);
-}
-
-// Checks whether a double is representable as a 32-bit integer. If so, the
-// integer is written to the output register. Otherwise, a bailout is taken to
-// the given snapshot. This function overwrites the scratch float register.
-void
-MacroAssemblerMIPSCompat::convertDoubleToInt32(FloatRegister src, Register dest,
-                                         Label* fail, bool negativeZeroCheck)
-{
-    // Convert double to int, then convert back and check if we have the
-    // same number.
-    as_cvtwd(ScratchDoubleReg, src);
-    as_mfc1(dest, ScratchDoubleReg);
-    as_cvtdw(ScratchDoubleReg, ScratchDoubleReg);
-    ma_bc1d(src, ScratchDoubleReg, fail, Assembler::DoubleNotEqualOrUnordered);
-
-    if (negativeZeroCheck) {
-        Label notZero;
-        ma_b(dest, Imm32(0), &notZero, Assembler::NotEqual, ShortJump);
-        // Test and bail for -0.0, when integer result is 0
-        // Move the top word of the double into the output reg, if it is
-        // non-zero, then the original value was -0.0
-        moveFromDoubleHi(src, dest);
-        ma_b(dest, Imm32(INT32_MIN), fail, Assembler::Equal);
-        bind(&notZero);
-    }
-}
-
-// Checks whether a float32 is representable as a 32-bit integer. If so, the
-// integer is written to the output register. Otherwise, a bailout is taken to
-// the given snapshot. This function overwrites the scratch float register.
-void
-MacroAssemblerMIPSCompat::convertFloat32ToInt32(FloatRegister src, Register dest,
-                                          Label* fail, bool negativeZeroCheck)
-{
-    // Converting the floating point value to an integer and then converting it
-    // back to a float32 would not work, as float to int32 conversions are
-    // clamping (e.g. float(INT32_MAX + 1) would get converted into INT32_MAX
-    // and then back to float(INT32_MAX + 1)).  If this ever happens, we just
-    // bail out.
-    as_cvtws(ScratchFloat32Reg, src);
-    as_mfc1(dest, ScratchFloat32Reg);
-    as_cvtsw(ScratchFloat32Reg, ScratchFloat32Reg);
-    ma_bc1s(src, ScratchFloat32Reg, fail, Assembler::DoubleNotEqualOrUnordered);
-
-    // Bail out in the clamped cases.
-    ma_b(dest, Imm32(INT32_MAX), fail, Assembler::Equal);
-
-    if (negativeZeroCheck) {
-        Label notZero;
-        ma_b(dest, Imm32(0), &notZero, Assembler::NotEqual, ShortJump);
-        // Test and bail for -0.0, when integer result is 0
-        // Move the top word of the double into the output reg,
-        // if it is non-zero, then the original value was -0.0
-        moveFromDoubleHi(src, dest);
-        ma_b(dest, Imm32(INT32_MIN), fail, Assembler::Equal);
-        bind(&notZero);
-    }
-}
-
-void
-MacroAssemblerMIPSCompat::convertFloat32ToDouble(FloatRegister src, FloatRegister dest)
-{
-    as_cvtds(dest, src);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTruncateFloat32(FloatRegister src, Register dest,
-                                          Label* fail)
-{
-    Label test, success;
-    as_truncws(ScratchFloat32Reg, src);
-    as_mfc1(dest, ScratchFloat32Reg);
-
-    ma_b(dest, Imm32(INT32_MAX), fail, Assembler::Equal);
-}
-
-void
-MacroAssemblerMIPSCompat::convertInt32ToFloat32(Register src, FloatRegister dest)
-{
-    as_mtc1(src, dest);
-    as_cvtsw(dest, dest);
-}
-
-void
-MacroAssemblerMIPSCompat::convertInt32ToFloat32(const Address& src, FloatRegister dest)
-{
-    ma_ls(dest, src);
-    as_cvtsw(dest, dest);
-}
-
-void
-MacroAssemblerMIPSCompat::addDouble(FloatRegister src, FloatRegister dest)
-{
-    as_addd(dest, dest, src);
-}
-
-void
-MacroAssemblerMIPSCompat::subDouble(FloatRegister src, FloatRegister dest)
-{
-    as_subd(dest, dest, src);
-}
-
-void
-MacroAssemblerMIPSCompat::mulDouble(FloatRegister src, FloatRegister dest)
-{
-    as_muld(dest, dest, src);
-}
-
-void
-MacroAssemblerMIPSCompat::divDouble(FloatRegister src, FloatRegister dest)
-{
-    as_divd(dest, dest, src);
-}
-
-void
-MacroAssemblerMIPSCompat::negateDouble(FloatRegister reg)
-{
-    as_negd(reg, reg);
-}
-
-void
-MacroAssemblerMIPSCompat::inc64(AbsoluteAddress dest)
-{
-    ma_li(ScratchRegister, Imm32((int32_t)dest.addr));
-    as_lw(SecondScratchReg, ScratchRegister, 0);
-
-    as_addiu(SecondScratchReg, SecondScratchReg, 1);
-    as_sw(SecondScratchReg, ScratchRegister, 0);
-
-    as_sltiu(SecondScratchReg, SecondScratchReg, 1);
-    as_lw(ScratchRegister, ScratchRegister, 4);
-
-    as_addu(SecondScratchReg, ScratchRegister, SecondScratchReg);
-
-    ma_li(ScratchRegister, Imm32((int32_t)dest.addr));
-    as_sw(SecondScratchReg, ScratchRegister, 4);
-}
-
-void
-MacroAssemblerMIPS::ma_move(Register rd, Register rs)
+MacroAssemblerMIPSShared::ma_move(Register rd, Register rs)
 {
     as_or(rd, rs, zero);
 }
 
 void
-MacroAssemblerMIPS::ma_li(Register dest, ImmGCPtr ptr)
+MacroAssemblerMIPSShared::ma_li(Register dest, ImmGCPtr ptr)
 {
     writeDataRelocation(ptr);
-    ma_liPatchable(dest, ImmPtr(ptr.value));
+    asMasm().ma_liPatchable(dest, ImmPtr(ptr.value));
 }
 
 void
-MacroAssemblerMIPS::ma_li(Register dest, AbsoluteLabel* label)
-{
-    MOZ_ASSERT(!label->bound());
-    // Thread the patch list through the unpatched address word in the
-    // instruction stream.
-    BufferOffset bo = m_buffer.nextOffset();
-    ma_liPatchable(dest, Imm32(label->prev()));
-    label->setPrev(bo.getOffset());
-}
-
-void
-MacroAssemblerMIPS::ma_li(Register dest, Imm32 imm)
+MacroAssemblerMIPSShared::ma_li(Register dest, Imm32 imm)
 {
     if (Imm16::IsInSignedRange(imm.value)) {
         as_addiu(dest, zero, imm.value);
     } else if (Imm16::IsInUnsignedRange(imm.value)) {
         as_ori(dest, zero, Imm16::Lower(imm).encode());
     } else if (Imm16::Lower(imm).encode() == 0) {
         as_lui(dest, Imm16::Upper(imm).encode());
     } else {
         as_lui(dest, Imm16::Upper(imm).encode());
         as_ori(dest, dest, Imm16::Lower(imm).encode());
     }
 }
 
-void
-MacroAssemblerMIPS::ma_li(Register dest, ImmWord imm)
-{
-    ma_li(dest, Imm32(uint32_t(imm.value)));
-}
-
-// This method generates lui and ori instruction pair that can be modified by
-// UpdateLuiOriValue, either during compilation (eg. Assembler::bind), or
-// during execution (eg. jit::PatchJump).
-void
-MacroAssemblerMIPS::ma_liPatchable(Register dest, Imm32 imm)
-{
-    m_buffer.ensureSpace(2 * sizeof(uint32_t));
-    as_lui(dest, Imm16::Upper(imm).encode());
-    as_ori(dest, dest, Imm16::Lower(imm).encode());
-}
-
-void
-MacroAssemblerMIPS::ma_liPatchable(Register dest, ImmPtr imm)
-{
-    ma_liPatchable(dest, ImmWord(uintptr_t(imm.value)));
-}
-
-void
-MacroAssemblerMIPS::ma_liPatchable(Register dest, ImmWord imm)
-{
-    ma_liPatchable(dest, Imm32(int32_t(imm.value)));
-}
-
 // Shifts
 void
-MacroAssemblerMIPS::ma_sll(Register rd, Register rt, Imm32 shift)
+MacroAssemblerMIPSShared::ma_sll(Register rd, Register rt, Imm32 shift)
 {
     as_sll(rd, rt, shift.value % 32);
 }
 void
-MacroAssemblerMIPS::ma_srl(Register rd, Register rt, Imm32 shift)
+MacroAssemblerMIPSShared::ma_srl(Register rd, Register rt, Imm32 shift)
 {
     as_srl(rd, rt, shift.value % 32);
 }
 
 void
-MacroAssemblerMIPS::ma_sra(Register rd, Register rt, Imm32 shift)
+MacroAssemblerMIPSShared::ma_sra(Register rd, Register rt, Imm32 shift)
 {
     as_sra(rd, rt, shift.value % 32);
 }
 
 void
-MacroAssemblerMIPS::ma_ror(Register rd, Register rt, Imm32 shift)
+MacroAssemblerMIPSShared::ma_ror(Register rd, Register rt, Imm32 shift)
 {
     as_rotr(rd, rt, shift.value % 32);
 }
 
 void
-MacroAssemblerMIPS::ma_rol(Register rd, Register rt, Imm32 shift)
+MacroAssemblerMIPSShared::ma_rol(Register rd, Register rt, Imm32 shift)
 {
     as_rotr(rd, rt, 32 - (shift.value % 32));
 }
 
 void
-MacroAssemblerMIPS::ma_sll(Register rd, Register rt, Register shift)
+MacroAssemblerMIPSShared::ma_sll(Register rd, Register rt, Register shift)
 {
     as_sllv(rd, rt, shift);
 }
 
 void
-MacroAssemblerMIPS::ma_srl(Register rd, Register rt, Register shift)
+MacroAssemblerMIPSShared::ma_srl(Register rd, Register rt, Register shift)
 {
     as_srlv(rd, rt, shift);
 }
 
 void
-MacroAssemblerMIPS::ma_sra(Register rd, Register rt, Register shift)
+MacroAssemblerMIPSShared::ma_sra(Register rd, Register rt, Register shift)
 {
     as_srav(rd, rt, shift);
 }
 
 void
-MacroAssemblerMIPS::ma_ror(Register rd, Register rt, Register shift)
+MacroAssemblerMIPSShared::ma_ror(Register rd, Register rt, Register shift)
 {
     as_rotrv(rd, rt, shift);
 }
 
 void
-MacroAssemblerMIPS::ma_rol(Register rd, Register rt, Register shift)
+MacroAssemblerMIPSShared::ma_rol(Register rd, Register rt, Register shift)
 {
     ma_negu(ScratchRegister, shift);
     as_rotrv(rd, rt, ScratchRegister);
 }
 
 void
-MacroAssemblerMIPS::ma_negu(Register rd, Register rs)
+MacroAssemblerMIPSShared::ma_negu(Register rd, Register rs)
 {
     as_subu(rd, zero, rs);
 }
 
 void
-MacroAssemblerMIPS::ma_not(Register rd, Register rs)
+MacroAssemblerMIPSShared::ma_not(Register rd, Register rs)
 {
     as_nor(rd, rs, zero);
 }
 
 // And.
 void
-MacroAssemblerMIPS::ma_and(Register rd, Register rs)
+MacroAssemblerMIPSShared::ma_and(Register rd, Register rs)
 {
     as_and(rd, rd, rs);
 }
 
 void
-MacroAssemblerMIPS::ma_and(Register rd, Imm32 imm)
+MacroAssemblerMIPSShared::ma_and(Register rd, Imm32 imm)
 {
     ma_and(rd, rd, imm);
 }
 
 void
-MacroAssemblerMIPS::ma_and(Register rd, Register rs, Imm32 imm)
+MacroAssemblerMIPSShared::ma_and(Register rd, Register rs, Imm32 imm)
 {
     if (Imm16::IsInUnsignedRange(imm.value)) {
         as_andi(rd, rs, imm.value);
     } else {
         ma_li(ScratchRegister, imm);
         as_and(rd, rs, ScratchRegister);
     }
 }
 
 // Or.
 void
-MacroAssemblerMIPS::ma_or(Register rd, Register rs)
+MacroAssemblerMIPSShared::ma_or(Register rd, Register rs)
 {
     as_or(rd, rd, rs);
 }
 
 void
-MacroAssemblerMIPS::ma_or(Register rd, Imm32 imm)
+MacroAssemblerMIPSShared::ma_or(Register rd, Imm32 imm)
 {
     ma_or(rd, rd, imm);
 }
 
 void
-MacroAssemblerMIPS::ma_or(Register rd, Register rs, Imm32 imm)
+MacroAssemblerMIPSShared::ma_or(Register rd, Register rs, Imm32 imm)
 {
     if (Imm16::IsInUnsignedRange(imm.value)) {
         as_ori(rd, rs, imm.value);
     } else {
         ma_li(ScratchRegister, imm);
         as_or(rd, rs, ScratchRegister);
     }
 }
 
 // xor
 void
-MacroAssemblerMIPS::ma_xor(Register rd, Register rs)
+MacroAssemblerMIPSShared::ma_xor(Register rd, Register rs)
 {
     as_xor(rd, rd, rs);
 }
 
 void
-MacroAssemblerMIPS::ma_xor(Register rd, Imm32 imm)
+MacroAssemblerMIPSShared::ma_xor(Register rd, Imm32 imm)
 {
     ma_xor(rd, rd, imm);
 }
 
 void
-MacroAssemblerMIPS::ma_xor(Register rd, Register rs, Imm32 imm)
+MacroAssemblerMIPSShared::ma_xor(Register rd, Register rs, Imm32 imm)
 {
     if (Imm16::IsInUnsignedRange(imm.value)) {
         as_xori(rd, rs, imm.value);
     } else {
         ma_li(ScratchRegister, imm);
         as_xor(rd, rs, ScratchRegister);
     }
 }
 
 // Arithmetic-based ops.
 
 // Add.
 void
-MacroAssemblerMIPS::ma_addu(Register rd, Register rs, Imm32 imm)
+MacroAssemblerMIPSShared::ma_addu(Register rd, Register rs, Imm32 imm)
 {
     if (Imm16::IsInSignedRange(imm.value)) {
         as_addiu(rd, rs, imm.value);
     } else {
         ma_li(ScratchRegister, imm);
         as_addu(rd, rs, ScratchRegister);
     }
 }
 
 void
-MacroAssemblerMIPS::ma_addu(Register rd, Register rs)
+MacroAssemblerMIPSShared::ma_addu(Register rd, Register rs)
 {
     as_addu(rd, rd, rs);
 }
 
 void
-MacroAssemblerMIPS::ma_addu(Register rd, Imm32 imm)
+MacroAssemblerMIPSShared::ma_addu(Register rd, Imm32 imm)
 {
     ma_addu(rd, rd, imm);
 }
 
-void
-MacroAssemblerMIPS::ma_addTestOverflow(Register rd, Register rs, Register rt, Label* overflow)
-{
-    Label goodAddition;
-    as_addu(rd, rs, rt);
-
-    as_xor(ScratchRegister, rs, rt); // If different sign, no overflow
-    ma_b(ScratchRegister, Imm32(0), &goodAddition, Assembler::LessThan, ShortJump);
-
-    // If different sign, then overflow
-    as_xor(ScratchRegister, rs, rd);
-    ma_b(ScratchRegister, Imm32(0), overflow, Assembler::LessThan);
-
-    bind(&goodAddition);
-}
-
-void
-MacroAssemblerMIPS::ma_addTestOverflow(Register rd, Register rs, Imm32 imm, Label* overflow)
-{
-    // Check for signed range because of as_addiu
-    // Check for unsigned range because of as_xori
-    if (Imm16::IsInSignedRange(imm.value) && Imm16::IsInUnsignedRange(imm.value)) {
-        Label goodAddition;
-        as_addiu(rd, rs, imm.value);
-
-        // If different sign, no overflow
-        as_xori(ScratchRegister, rs, imm.value);
-        ma_b(ScratchRegister, Imm32(0), &goodAddition, Assembler::LessThan, ShortJump);
-
-        // If different sign, then overflow
-        as_xor(ScratchRegister, rs, rd);
-        ma_b(ScratchRegister, Imm32(0), overflow, Assembler::LessThan);
-
-        bind(&goodAddition);
-    } else {
-        ma_li(ScratchRegister, imm);
-        ma_addTestOverflow(rd, rs, ScratchRegister, overflow);
-    }
-}
-
 // Subtract.
 void
-MacroAssemblerMIPS::ma_subu(Register rd, Register rs, Imm32 imm)
+MacroAssemblerMIPSShared::ma_subu(Register rd, Register rs, Imm32 imm)
 {
     if (Imm16::IsInSignedRange(-imm.value)) {
         as_addiu(rd, rs, -imm.value);
     } else {
         ma_li(ScratchRegister, imm);
         as_subu(rd, rs, ScratchRegister);
     }
 }
 
 void
-MacroAssemblerMIPS::ma_subu(Register rd, Imm32 imm)
+MacroAssemblerMIPSShared::ma_subu(Register rd, Imm32 imm)
 {
     ma_subu(rd, rd, imm);
 }
 
 void
-MacroAssemblerMIPS::ma_subTestOverflow(Register rd, Register rs, Register rt, Label* overflow)
-{
-    Label goodSubtraction;
-    // Use second scratch. The instructions generated by ma_b don't use the
-    // second scratch register.
-    as_subu(rd, rs, rt);
-
-    as_xor(ScratchRegister, rs, rt); // If same sign, no overflow
-    ma_b(ScratchRegister, Imm32(0), &goodSubtraction, Assembler::GreaterThanOrEqual, ShortJump);
-
-    // If different sign, then overflow
-    as_xor(ScratchRegister, rs, rd);
-    ma_b(ScratchRegister, Imm32(0), overflow, Assembler::LessThan);
-
-    bind(&goodSubtraction);
-}
-
-void
-MacroAssemblerMIPS::ma_subTestOverflow(Register rd, Register rs, Imm32 imm, Label* overflow)
+MacroAssemblerMIPSShared::ma_subTestOverflow(Register rd, Register rs, Imm32 imm, Label* overflow)
 {
     if (imm.value != INT32_MIN) {
-        ma_addTestOverflow(rd, rs, Imm32(-imm.value), overflow);
+        asMasm().ma_addTestOverflow(rd, rs, Imm32(-imm.value), overflow);
     } else {
         ma_li(ScratchRegister, Imm32(imm.value));
-        ma_subTestOverflow(rd, rs, ScratchRegister, overflow);
+        asMasm().ma_subTestOverflow(rd, rs, ScratchRegister, overflow);
     }
 }
 
 void
-MacroAssemblerMIPS::ma_mult(Register rs, Imm32 imm)
+MacroAssemblerMIPSShared::ma_mult(Register rs, Imm32 imm)
 {
     ma_li(ScratchRegister, imm);
     as_mult(rs, ScratchRegister);
 }
 
 void
-MacroAssemblerMIPS::ma_mul_branch_overflow(Register rd, Register rs, Register rt, Label* overflow)
+MacroAssemblerMIPSShared::ma_mul_branch_overflow(Register rd, Register rs, Register rt, Label* overflow)
 {
     as_mult(rs, rt);
     as_mflo(rd);
     as_sra(ScratchRegister, rd, 31);
     as_mfhi(SecondScratchReg);
     ma_b(ScratchRegister, SecondScratchReg, overflow, Assembler::NotEqual);
 }
 
 void
-MacroAssemblerMIPS::ma_mul_branch_overflow(Register rd, Register rs, Imm32 imm, Label* overflow)
+MacroAssemblerMIPSShared::ma_mul_branch_overflow(Register rd, Register rs, Imm32 imm, Label* overflow)
 {
     ma_li(ScratchRegister, imm);
     ma_mul_branch_overflow(rd, rs, ScratchRegister, overflow);
 }
 
 void
-MacroAssemblerMIPS::ma_div_branch_overflow(Register rd, Register rs, Register rt, Label* overflow)
+MacroAssemblerMIPSShared::ma_div_branch_overflow(Register rd, Register rs, Register rt, Label* overflow)
 {
     as_div(rs, rt);
     as_mflo(rd);
     as_mfhi(ScratchRegister);
     ma_b(ScratchRegister, ScratchRegister, overflow, Assembler::NonZero);
 }
 
 void
-MacroAssemblerMIPS::ma_div_branch_overflow(Register rd, Register rs, Imm32 imm, Label* overflow)
+MacroAssemblerMIPSShared::ma_div_branch_overflow(Register rd, Register rs, Imm32 imm, Label* overflow)
 {
     ma_li(ScratchRegister, imm);
     ma_div_branch_overflow(rd, rs, ScratchRegister, overflow);
 }
 
 void
-MacroAssemblerMIPS::ma_mod_mask(Register src, Register dest, Register hold, Register remain,
-                                int32_t shift, Label* negZero)
+MacroAssemblerMIPSShared::ma_mod_mask(Register src, Register dest, Register hold, Register remain,
+                                      int32_t shift, Label* negZero)
 {
     // MATH:
     // We wish to compute x % (1<<y) - 1 for a known constant, y.
     // First, let b = (1<<y) and C = (1<<y)-1, then think of the 32 bit
     // dividend as a number in base b, namely
     // c_0*1 + c_1*b + c_2*b^2 ... c_n*b^n
     // now, since both addition and multiplication commute with modulus,
     // x % C == (c_0 + c_1*b + ... + c_n*b^n) % C ==
@@ -749,357 +349,105 @@ MacroAssemblerMIPS::ma_mod_mask(Register
     }
 
     bind(&done);
 }
 
 // Memory.
 
 void
-MacroAssemblerMIPS::ma_load(Register dest, Address address,
-                            LoadStoreSize size, LoadStoreExtension extension)
+MacroAssemblerMIPSShared::ma_load(Register dest, const BaseIndex& src,
+                                  LoadStoreSize size, LoadStoreExtension extension)
 {
-    int16_t encodedOffset;
-    Register base;
-    if (!Imm16::IsInSignedRange(address.offset)) {
-        ma_li(ScratchRegister, Imm32(address.offset));
-        as_addu(ScratchRegister, address.base, ScratchRegister);
-        base = ScratchRegister;
-        encodedOffset = Imm16(0).encode();
-    } else {
-        encodedOffset = Imm16(address.offset).encode();
-        base = address.base;
-    }
-
-    switch (size) {
-      case SizeByte:
-        if (ZeroExtend == extension)
-            as_lbu(dest, base, encodedOffset);
-        else
-            as_lb(dest, base, encodedOffset);
-        break;
-      case SizeHalfWord:
-        if (ZeroExtend == extension)
-            as_lhu(dest, base, encodedOffset);
-        else
-            as_lh(dest, base, encodedOffset);
-        break;
-      case SizeWord:
-        as_lw(dest, base, encodedOffset);
-        break;
-      default:
-        MOZ_CRASH("Invalid argument for ma_load");
-    }
+    asMasm().computeScaledAddress(src, SecondScratchReg);
+    asMasm().ma_load(dest, Address(SecondScratchReg, src.offset), size, extension);
 }
 
 void
-MacroAssemblerMIPS::ma_load(Register dest, const BaseIndex& src,
-                            LoadStoreSize size, LoadStoreExtension extension)
+MacroAssemblerMIPSShared::ma_store(Register data, const BaseIndex& dest,
+                                   LoadStoreSize size, LoadStoreExtension extension)
 {
-    asMasm().computeScaledAddress(src, SecondScratchReg);
-    ma_load(dest, Address(SecondScratchReg, src.offset), size, extension);
+    asMasm().computeScaledAddress(dest, SecondScratchReg);
+    asMasm().ma_store(data, Address(SecondScratchReg, dest.offset), size, extension);
 }
 
 void
-MacroAssemblerMIPS::ma_store(Register data, Address address, LoadStoreSize size,
-                             LoadStoreExtension extension)
-{
-    int16_t encodedOffset;
-    Register base;
-    if (!Imm16::IsInSignedRange(address.offset)) {
-        ma_li(ScratchRegister, Imm32(address.offset));
-        as_addu(ScratchRegister, address.base, ScratchRegister);
-        base = ScratchRegister;
-        encodedOffset = Imm16(0).encode();
-    } else {
-        encodedOffset = Imm16(address.offset).encode();
-        base = address.base;
-    }
-
-    switch (size) {
-      case SizeByte:
-        as_sb(data, base, encodedOffset);
-        break;
-      case SizeHalfWord:
-        as_sh(data, base, encodedOffset);
-        break;
-      case SizeWord:
-        as_sw(data, base, encodedOffset);
-        break;
-      default:
-        MOZ_CRASH("Invalid argument for ma_store");
-    }
-}
-
-void
-MacroAssemblerMIPS::ma_store(Register data, const BaseIndex& dest,
-                             LoadStoreSize size, LoadStoreExtension extension)
-{
-    asMasm().computeScaledAddress(dest, SecondScratchReg);
-    ma_store(data, Address(SecondScratchReg, dest.offset), size, extension);
-}
-
-void
-MacroAssemblerMIPS::ma_store(Imm32 imm, const BaseIndex& dest,
-                             LoadStoreSize size, LoadStoreExtension extension)
+MacroAssemblerMIPSShared::ma_store(Imm32 imm, const BaseIndex& dest,
+                                   LoadStoreSize size, LoadStoreExtension extension)
 {
     // Make sure that SecondScratchReg contains absolute address so that
     // offset is 0.
     asMasm().computeEffectiveAddress(dest, SecondScratchReg);
 
     // Scrach register is free now, use it for loading imm value
     ma_li(ScratchRegister, imm);
 
     // with offset=0 ScratchRegister will not be used in ma_store()
     // so we can use it as a parameter here
-    ma_store(ScratchRegister, Address(SecondScratchReg, 0), size, extension);
-}
-
-void
-MacroAssemblerMIPSCompat::computeScaledAddress(const BaseIndex& address, Register dest)
-{
-    int32_t shift = Imm32::ShiftOf(address.scale).value;
-    if (shift) {
-        ma_sll(ScratchRegister, address.index, Imm32(shift));
-        as_addu(dest, address.base, ScratchRegister);
-    } else {
-        as_addu(dest, address.base, address.index);
-    }
-}
-
-// Shortcut for when we know we're transferring 32 bits of data.
-void
-MacroAssemblerMIPS::ma_lw(Register data, Address address)
-{
-    ma_load(data, address, SizeWord);
-}
-
-void
-MacroAssemblerMIPS::ma_sw(Register data, Address address)
-{
-    ma_store(data, address, SizeWord);
-}
-
-void
-MacroAssemblerMIPS::ma_sw(Imm32 imm, Address address)
-{
-    MOZ_ASSERT(address.base != ScratchRegister);
-    ma_li(ScratchRegister, imm);
-
-    if (Imm16::IsInSignedRange(address.offset)) {
-        as_sw(ScratchRegister, address.base, address.offset);
-    } else {
-        MOZ_ASSERT(address.base != SecondScratchReg);
-
-        ma_li(SecondScratchReg, Imm32(address.offset));
-        as_addu(SecondScratchReg, address.base, SecondScratchReg);
-        as_sw(ScratchRegister, SecondScratchReg, 0);
-    }
-}
-
-void
-MacroAssemblerMIPS::ma_sw(Register data, BaseIndex& address)
-{
-    ma_store(data, address, SizeWord);
-}
-
-void
-MacroAssemblerMIPS::ma_pop(Register r)
-{
-    as_lw(r, StackPointer, 0);
-    as_addiu(StackPointer, StackPointer, sizeof(intptr_t));
-}
-
-void
-MacroAssemblerMIPS::ma_push(Register r)
-{
-    if (r == sp) {
-        // Pushing sp requires one more instruction.
-        ma_move(ScratchRegister, sp);
-        r = ScratchRegister;
-    }
-
-    as_addiu(StackPointer, StackPointer, -sizeof(intptr_t));
-    as_sw(r, StackPointer, 0);
+    asMasm().ma_store(ScratchRegister, Address(SecondScratchReg, 0), size, extension);
 }
 
 // Branches when done from within mips-specific code.
 void
-MacroAssemblerMIPS::ma_b(Register lhs, Register rhs, Label* label, Condition c, JumpKind jumpKind)
+MacroAssemblerMIPSShared::ma_b(Register lhs, Register rhs, Label* label, Condition c, JumpKind jumpKind)
 {
     switch (c) {
       case Equal :
       case NotEqual:
-        branchWithCode(getBranchCode(lhs, rhs, c), label, jumpKind);
+        asMasm().branchWithCode(getBranchCode(lhs, rhs, c), label, jumpKind);
         break;
       case Always:
         ma_b(label, jumpKind);
         break;
       case Zero:
       case NonZero:
       case Signed:
       case NotSigned:
         MOZ_ASSERT(lhs == rhs);
-        branchWithCode(getBranchCode(lhs, c), label, jumpKind);
+        asMasm().branchWithCode(getBranchCode(lhs, c), label, jumpKind);
         break;
       default:
         Condition cond = ma_cmp(ScratchRegister, lhs, rhs, c);
-        branchWithCode(getBranchCode(ScratchRegister, cond), label, jumpKind);
+        asMasm().branchWithCode(getBranchCode(ScratchRegister, cond), label, jumpKind);
         break;
     }
 }
 
 void
-MacroAssemblerMIPS::ma_b(Register lhs, Imm32 imm, Label* label, Condition c, JumpKind jumpKind)
+MacroAssemblerMIPSShared::ma_b(Register lhs, Imm32 imm, Label* label, Condition c, JumpKind jumpKind)
 {
     MOZ_ASSERT(c != Overflow);
     if (imm.value == 0) {
         if (c == Always || c == AboveOrEqual)
             ma_b(label, jumpKind);
         else if (c == Below)
             ; // This condition is always false. No branch required.
         else
-            branchWithCode(getBranchCode(lhs, c), label, jumpKind);
+            asMasm().branchWithCode(getBranchCode(lhs, c), label, jumpKind);
     } else {
         MOZ_ASSERT(lhs != ScratchRegister);
         ma_li(ScratchRegister, imm);
         ma_b(lhs, ScratchRegister, label, c, jumpKind);
     }
 }
 
 void
-MacroAssemblerMIPS::ma_b(Register lhs, Address addr, Label* label, Condition c, JumpKind jumpKind)
-{
-    MOZ_ASSERT(lhs != ScratchRegister);
-    ma_lw(ScratchRegister, addr);
-    ma_b(lhs, ScratchRegister, label, c, jumpKind);
-}
-
-void
-MacroAssemblerMIPS::ma_b(Address addr, Imm32 imm, Label* label, Condition c, JumpKind jumpKind)
-{
-    ma_lw(SecondScratchReg, addr);
-    ma_b(SecondScratchReg, imm, label, c, jumpKind);
-}
-
-void
-MacroAssemblerMIPS::ma_b(Address addr, ImmGCPtr imm, Label* label, Condition c, JumpKind jumpKind)
-{
-    ma_lw(SecondScratchReg, addr);
-    ma_b(SecondScratchReg, imm, label, c, jumpKind);
-}
-
-void
-MacroAssemblerMIPS::ma_b(Label* label, JumpKind jumpKind)
+MacroAssemblerMIPSShared::ma_b(Register lhs, ImmPtr imm, Label* l, Condition c, JumpKind jumpKind)
 {
-    branchWithCode(getBranchCode(BranchIsJump), label, jumpKind);
-}
-
-void
-MacroAssemblerMIPS::ma_bal(Label* label, DelaySlotFill delaySlotFill)
-{
-    if (label->bound()) {
-        // Generate the long jump for calls because return address has to be
-        // the address after the reserved block.
-        addLongJump(nextOffset());
-        ma_liPatchable(ScratchRegister, Imm32(label->offset()));
-        as_jalr(ScratchRegister);
-        if (delaySlotFill == FillDelaySlot)
-            as_nop();
-        return;
-    }
-
-    // Second word holds a pointer to the next branch in label's chain.
-    uint32_t nextInChain = label->used() ? label->offset() : LabelBase::INVALID_OFFSET;
-
-    // Make the whole branch continous in the buffer.
-    m_buffer.ensureSpace(4 * sizeof(uint32_t));
-
-    BufferOffset bo = writeInst(getBranchCode(BranchIsCall).encode());
-    writeInst(nextInChain);
-    label->use(bo.getOffset());
-    // Leave space for long jump.
-    as_nop();
-    if (delaySlotFill == FillDelaySlot)
-        as_nop();
+    asMasm().ma_b(lhs, ImmWord(uintptr_t(imm.value)), l, c, jumpKind);
 }
 
 void
-MacroAssemblerMIPS::branchWithCode(InstImm code, Label* label, JumpKind jumpKind)
+MacroAssemblerMIPSShared::ma_b(Label* label, JumpKind jumpKind)
 {
-    MOZ_ASSERT(code.encode() != InstImm(op_regimm, zero, rt_bgezal, BOffImm16(0)).encode());
-    InstImm inst_beq = InstImm(op_beq, zero, zero, BOffImm16(0));
-
-    if (label->bound()) {
-        int32_t offset = label->offset() - m_buffer.nextOffset().getOffset();
-
-        if (BOffImm16::IsInRange(offset))
-            jumpKind = ShortJump;
-
-        if (jumpKind == ShortJump) {
-            MOZ_ASSERT(BOffImm16::IsInRange(offset));
-            code.setBOffImm16(BOffImm16(offset));
-            writeInst(code.encode());
-            as_nop();
-            return;
-        }
-
-        if (code.encode() == inst_beq.encode()) {
-            // Handle long jump
-            addLongJump(nextOffset());
-            ma_liPatchable(ScratchRegister, Imm32(label->offset()));
-            as_jr(ScratchRegister);
-            as_nop();
-            return;
-        }
-
-        // Handle long conditional branch
-        writeInst(invertBranch(code, BOffImm16(5 * sizeof(uint32_t))).encode());
-        // No need for a "nop" here because we can clobber scratch.
-        addLongJump(nextOffset());
-        ma_liPatchable(ScratchRegister, Imm32(label->offset()));
-        as_jr(ScratchRegister);
-        as_nop();
-        return;
-    }
-
-    // Generate open jump and link it to a label.
-
-    // Second word holds a pointer to the next branch in label's chain.
-    uint32_t nextInChain = label->used() ? label->offset() : LabelBase::INVALID_OFFSET;
-
-    if (jumpKind == ShortJump) {
-        // Make the whole branch continous in the buffer.
-        m_buffer.ensureSpace(2 * sizeof(uint32_t));
-
-        // Indicate that this is short jump with offset 4.
-        code.setBOffImm16(BOffImm16(4));
-        BufferOffset bo = writeInst(code.encode());
-        writeInst(nextInChain);
-        label->use(bo.getOffset());
-        return;
-    }
-
-    bool conditional = code.encode() != inst_beq.encode();
-
-    // Make the whole branch continous in the buffer.
-    m_buffer.ensureSpace((conditional ? 5 : 4) * sizeof(uint32_t));
-
-    BufferOffset bo = writeInst(code.encode());
-    writeInst(nextInChain);
-    label->use(bo.getOffset());
-    // Leave space for potential long jump.
-    as_nop();
-    as_nop();
-    if (conditional)
-        as_nop();
+    asMasm().branchWithCode(getBranchCode(BranchIsJump), label, jumpKind);
 }
 
 Assembler::Condition
-MacroAssemblerMIPS::ma_cmp(Register scratch, Register lhs, Register rhs, Condition c)
+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
         as_sltu(scratch, rhs, lhs);
         return NotEqual;
@@ -1159,17 +507,17 @@ MacroAssemblerMIPS::ma_cmp(Register scra
         break;
       default:
         MOZ_CRASH("Invalid condition for branch.");
     }
     return Always;
 }
 
 void
-MacroAssemblerMIPS::ma_cmp_set(Register rd, Register rs, Register rt, Condition c)
+MacroAssemblerMIPSShared::ma_cmp_set(Register rd, Register rs, Register rt, Condition c)
 {
     switch (c) {
       case Equal :
         // seq d,s,t =>
         //   xor d,s,t
         //   sltiu d,d,1
         as_xor(rd, rs, rt);
         as_sltiu(rd, rd, 1);
@@ -1253,19 +601,19 @@ MacroAssemblerMIPS::ma_cmp_set(Register 
         as_xori(rd, rd, 1);
         break;
       default:
         MOZ_CRASH("Invalid condition for ma_cmp_set.");
     }
 }
 
 void
-MacroAssemblerMIPS::compareFloatingPoint(FloatFormat fmt, FloatRegister lhs, FloatRegister rhs,
-                                         DoubleCondition c, FloatTestKind* testKind,
-                                         FPConditionBit fcc)
+MacroAssemblerMIPSShared::compareFloatingPoint(FloatFormat fmt, FloatRegister lhs, FloatRegister rhs,
+                                               DoubleCondition c, FloatTestKind* testKind,
+                                               FPConditionBit fcc)
 {
     switch (c) {
       case DoubleOrdered:
         as_cun(fmt, lhs, rhs, fcc);
         *testKind = TestForFalse;
         break;
       case DoubleEqual:
         as_ceq(fmt, lhs, rhs, fcc);
@@ -1320,2252 +668,123 @@ MacroAssemblerMIPS::compareFloatingPoint
         *testKind = TestForTrue;
         break;
       default:
         MOZ_CRASH("Invalid DoubleCondition.");
     }
 }
 
 void
-MacroAssemblerMIPS::ma_cmp_set_double(Register dest, FloatRegister lhs, FloatRegister rhs,
-                                      DoubleCondition c)
+MacroAssemblerMIPSShared::ma_cmp_set_double(Register dest, FloatRegister lhs, FloatRegister rhs,
+                                            DoubleCondition c)
 {
     ma_li(dest, Imm32(0));
     ma_li(ScratchRegister, Imm32(1));
 
     FloatTestKind moveCondition;
     compareFloatingPoint(DoubleFloat, lhs, rhs, c, &moveCondition);
 
     if (moveCondition == TestForTrue)
         as_movt(dest, ScratchRegister);
     else
         as_movf(dest, ScratchRegister);
 }
 
 void
-MacroAssemblerMIPS::ma_cmp_set_float32(Register dest, FloatRegister lhs, FloatRegister rhs,
-                                       DoubleCondition c)
+MacroAssemblerMIPSShared::ma_cmp_set_float32(Register dest, FloatRegister lhs, FloatRegister rhs,
+                                             DoubleCondition c)
 {
     ma_li(dest, Imm32(0));
     ma_li(ScratchRegister, Imm32(1));
 
     FloatTestKind moveCondition;
     compareFloatingPoint(SingleFloat, lhs, rhs, c, &moveCondition);
 
     if (moveCondition == TestForTrue)
         as_movt(dest, ScratchRegister);
     else
         as_movf(dest, ScratchRegister);
 }
 
 void
-MacroAssemblerMIPS::ma_cmp_set(Register rd, Register rs, Imm32 imm, Condition c)
+MacroAssemblerMIPSShared::ma_cmp_set(Register rd, Register rs, Imm32 imm, Condition c)
 {
     ma_li(ScratchRegister, imm);
     ma_cmp_set(rd, rs, ScratchRegister, c);
 }
 
-void
-MacroAssemblerMIPS::ma_cmp_set(Register rd, Register rs, Address addr, Condition c)
-{
-    ma_lw(ScratchRegister, addr);
-    ma_cmp_set(rd, rs, ScratchRegister, c);
-}
-
-void
-MacroAssemblerMIPS::ma_cmp_set(Register dst, Address lhs, Register rhs, Condition c)
-{
-    ma_lw(ScratchRegister, lhs);
-    ma_cmp_set(dst, ScratchRegister, rhs, c);
-}
-
 // fp instructions
 void
-MacroAssemblerMIPS::ma_lis(FloatRegister dest, float value)
+MacroAssemblerMIPSShared::ma_lis(FloatRegister dest, float value)
 {
     Imm32 imm(mozilla::BitwiseCast<uint32_t>(value));
 
     ma_li(ScratchRegister, imm);
     moveToFloat32(ScratchRegister, dest);
 }
 
 void
-MacroAssemblerMIPS::ma_lid(FloatRegister dest, double value)
-{
-    struct DoubleStruct {
-        uint32_t lo;
-        uint32_t hi;
-    } ;
-    DoubleStruct intStruct = mozilla::BitwiseCast<DoubleStruct>(value);
-
-    // put hi part of 64 bit value into the odd register
-    if (intStruct.hi == 0) {
-        moveToDoubleHi(zero, dest);
-    } else {
-        ma_li(ScratchRegister, Imm32(intStruct.hi));
-        moveToDoubleHi(ScratchRegister, dest);
-    }
-
-    // put low part of 64 bit value into the even register
-    if (intStruct.lo == 0) {
-        moveToDoubleLo(zero, dest);
-    } else {
-        ma_li(ScratchRegister, Imm32(intStruct.lo));
-        moveToDoubleLo(ScratchRegister, dest);
-    }
-}
-
-void
-MacroAssemblerMIPS::ma_liNegZero(FloatRegister dest)
+MacroAssemblerMIPSShared::ma_liNegZero(FloatRegister dest)
 {
     moveToDoubleLo(zero, dest);
     ma_li(ScratchRegister, Imm32(INT_MIN));
-    moveToDoubleHi(ScratchRegister, dest);
-}
-
-void
-MacroAssemblerMIPS::ma_mv(FloatRegister src, ValueOperand dest)
-{
-    moveFromDoubleLo(src, dest.payloadReg());
-    moveFromDoubleHi(src, dest.typeReg());
-}
-
-void
-MacroAssemblerMIPS::ma_mv(ValueOperand src, FloatRegister dest)
-{
-    moveToDoubleLo(src.payloadReg(), dest);
-    moveToDoubleHi(src.typeReg(), dest);
-}
-
-void
-MacroAssemblerMIPS::ma_ls(FloatRegister ft, Address address)
-{
-    if (Imm16::IsInSignedRange(address.offset)) {
-        as_ls(ft, address.base, address.offset);
-    } else {
-        MOZ_ASSERT(address.base != ScratchRegister);
-        ma_li(ScratchRegister, Imm32(address.offset));
-        as_addu(ScratchRegister, address.base, ScratchRegister);
-        as_ls(ft, ScratchRegister, 0);
-    }
-}
-
-void
-MacroAssemblerMIPS::ma_ld(FloatRegister ft, Address address)
-{
-    // Use single precision load instructions so we don't have to worry about
-    // alignment.
-
-    int32_t off2 = address.offset + TAG_OFFSET;
-    if (Imm16::IsInSignedRange(address.offset) && Imm16::IsInSignedRange(off2)) {
-        as_ls(ft, address.base, address.offset);
-        as_ls(getOddPair(ft), address.base, off2);
-    } else {
-        ma_li(ScratchRegister, Imm32(address.offset));
-        as_addu(ScratchRegister, address.base, ScratchRegister);
-        as_ls(ft, ScratchRegister, PAYLOAD_OFFSET);
-        as_ls(getOddPair(ft), ScratchRegister, TAG_OFFSET);
-    }
-}
-
-void
-MacroAssemblerMIPS::ma_sd(FloatRegister ft, Address address)
-{
-    int32_t off2 = address.offset + TAG_OFFSET;
-    if (Imm16::IsInSignedRange(address.offset) && Imm16::IsInSignedRange(off2)) {
-        as_ss(ft, address.base, address.offset);
-        as_ss(getOddPair(ft), address.base, off2);
-    } else {
-        ma_li(ScratchRegister, Imm32(address.offset));
-        as_addu(ScratchRegister, address.base, ScratchRegister);
-        as_ss(ft, ScratchRegister, PAYLOAD_OFFSET);
-        as_ss(getOddPair(ft), ScratchRegister, TAG_OFFSET);
-    }
-}
-
-void
-MacroAssemblerMIPS::ma_sd(FloatRegister ft, BaseIndex address)
-{
-    asMasm().computeScaledAddress(address, SecondScratchReg);
-    ma_sd(ft, Address(SecondScratchReg, address.offset));
-}
-
-void
-MacroAssemblerMIPS::ma_ss(FloatRegister ft, Address address)
-{
-    if (Imm16::IsInSignedRange(address.offset)) {
-        as_ss(ft, address.base, address.offset);
-    } else {
-        ma_li(ScratchRegister, Imm32(address.offset));
-        as_addu(ScratchRegister, address.base, ScratchRegister);
-        as_ss(ft, ScratchRegister, 0);
-    }
-}
-
-void
-MacroAssemblerMIPS::ma_ss(FloatRegister ft, BaseIndex address)
-{
-    asMasm().computeScaledAddress(address, SecondScratchReg);
-    ma_ss(ft, Address(SecondScratchReg, address.offset));
-}
-
-void
-MacroAssemblerMIPS::ma_pop(FloatRegister fs)
-{
-    ma_ld(fs.doubleOverlay(0), Address(StackPointer, 0));
-    as_addiu(StackPointer, StackPointer, sizeof(double));
-}
-
-void
-MacroAssemblerMIPS::ma_push(FloatRegister fs)
-{
-    as_addiu(StackPointer, StackPointer, -sizeof(double));
-    ma_sd(fs.doubleOverlay(0), Address(StackPointer, 0));
-}
-
-void
-MacroAssemblerMIPS::ma_bc1s(FloatRegister lhs, FloatRegister rhs, Label* label,
-                            DoubleCondition c, JumpKind jumpKind, FPConditionBit fcc)
-{
-    FloatTestKind testKind;
-    compareFloatingPoint(SingleFloat, lhs, rhs, c, &testKind, fcc);
-    branchWithCode(getBranchCode(testKind, fcc), label, jumpKind);
-}
-
-void
-MacroAssemblerMIPS::ma_bc1d(FloatRegister lhs, FloatRegister rhs, Label* label,
-                            DoubleCondition c, JumpKind jumpKind, FPConditionBit fcc)
-{
-    FloatTestKind testKind;
-    compareFloatingPoint(DoubleFloat, lhs, rhs, c, &testKind, fcc);
-    branchWithCode(getBranchCode(testKind, fcc), label, jumpKind);
-}
-
-bool
-MacroAssemblerMIPSCompat::buildOOLFakeExitFrame(void* fakeReturnAddr)
-{
-    uint32_t descriptor = MakeFrameDescriptor(asMasm().framePushed(), JitFrame_IonJS);
-
-    asMasm().Push(Imm32(descriptor)); // descriptor_
-    asMasm().Push(ImmPtr(fakeReturnAddr));
-
-    return true;
-}
-
-void
-MacroAssemblerMIPSCompat::add32(Register src, Register dest)
-{
-    as_addu(dest, dest, src);
-}
-
-void
-MacroAssemblerMIPSCompat::add32(Imm32 imm, Register dest)
-{
-    ma_addu(dest, dest, imm);
-}
-
-void
-
-MacroAssemblerMIPSCompat::add32(Imm32 imm, const Address& dest)
-{
-    load32(dest, SecondScratchReg);
-    ma_addu(SecondScratchReg, imm);
-    store32(SecondScratchReg, dest);
-}
-
-void
-MacroAssemblerMIPSCompat::sub32(Imm32 imm, Register dest)
-{
-    ma_subu(dest, dest, imm);
-}
-
-void
-MacroAssemblerMIPSCompat::sub32(Register src, Register dest)
-{
-    as_subu(dest, dest, src);
-}
-
-void
-MacroAssemblerMIPSCompat::addPtr(Register src, Register dest)
-{
-    ma_addu(dest, src);
-}
-
-void
-MacroAssemblerMIPSCompat::addPtr(const Address& src, Register dest)
-{
-    loadPtr(src, ScratchRegister);
-    ma_addu(dest, ScratchRegister);
-}
-
-void
-MacroAssemblerMIPSCompat::subPtr(Register src, Register dest)
-{
-    as_subu(dest, dest, src);
-}
-
-void
-MacroAssemblerMIPSCompat::move32(Imm32 imm, Register dest)
-{
-    ma_li(dest, imm);
-}
-
-void
-MacroAssemblerMIPSCompat::move32(Register src, Register dest)
-{
-    ma_move(dest, src);
-}
-
-void
-MacroAssemblerMIPSCompat::movePtr(Register src, Register dest)
-{
-    ma_move(dest, src);
-}
-void
-MacroAssemblerMIPSCompat::movePtr(ImmWord imm, Register dest)
-{
-    ma_li(dest, imm);
-}
-
-void
-MacroAssemblerMIPSCompat::movePtr(ImmGCPtr imm, Register dest)
-{
-    ma_li(dest, imm);
-}
-
-void
-MacroAssemblerMIPSCompat::movePtr(ImmPtr imm, Register dest)
-{
-    movePtr(ImmWord(uintptr_t(imm.value)), dest);
-}
-void
-MacroAssemblerMIPSCompat::movePtr(AsmJSImmPtr imm, Register dest)
-{
-    append(AsmJSAbsoluteLink(CodeOffsetLabel(nextOffset().getOffset()), imm.kind()));
-    ma_liPatchable(dest, ImmWord(-1));
-}
-
-void
-MacroAssemblerMIPSCompat::load8ZeroExtend(const Address& address, Register dest)
-{
-    ma_load(dest, address, SizeByte, ZeroExtend);
-}
-
-void
-MacroAssemblerMIPSCompat::load8ZeroExtend(const BaseIndex& src, Register dest)
-{
-    ma_load(dest, src, SizeByte, ZeroExtend);
-}
-
-void
-MacroAssemblerMIPSCompat::load8SignExtend(const Address& address, Register dest)
-{
-    ma_load(dest, address, SizeByte, SignExtend);
-}
-
-void
-MacroAssemblerMIPSCompat::load8SignExtend(const BaseIndex& src, Register dest)
-{
-    ma_load(dest, src, SizeByte, SignExtend);
-}
-
-void
-MacroAssemblerMIPSCompat::load16ZeroExtend(const Address& address, Register dest)
-{
-    ma_load(dest, address, SizeHalfWord, ZeroExtend);
-}
-
-void
-MacroAssemblerMIPSCompat::load16ZeroExtend(const BaseIndex& src, Register dest)
-{
-    ma_load(dest, src, SizeHalfWord, ZeroExtend);
-}
-
-void
-MacroAssemblerMIPSCompat::load16SignExtend(const Address& address, Register dest)
-{
-    ma_load(dest, address, SizeHalfWord, SignExtend);
-}
-
-void
-MacroAssemblerMIPSCompat::load16SignExtend(const BaseIndex& src, Register dest)
-{
-    ma_load(dest, src, SizeHalfWord, SignExtend);
-}
-
-void
-MacroAssemblerMIPSCompat::load32(const Address& address, Register dest)
-{
-    ma_load(dest, address, SizeWord);
-}
-
-void
-MacroAssemblerMIPSCompat::load32(const BaseIndex& address, Register dest)
-{
-    ma_load(dest, address, SizeWord);
-}
-
-void
-MacroAssemblerMIPSCompat::load32(AbsoluteAddress address, Register dest)
-{
-    movePtr(ImmPtr(address.addr), ScratchRegister);
-    load32(Address(ScratchRegister, 0), dest);
-}
-
-void
-MacroAssemblerMIPSCompat::load32(AsmJSAbsoluteAddress address, Register dest)
-{
-    movePtr(AsmJSImmPtr(address.kind()), ScratchRegister);
-    load32(Address(ScratchRegister, 0), dest);
-}
-
-void
-MacroAssemblerMIPSCompat::loadPtr(const Address& address, Register dest)
-{
-    ma_load(dest, address, SizeWord);
-}
-
-void
-MacroAssemblerMIPSCompat::loadPtr(const BaseIndex& src, Register dest)
-{
-    ma_load(dest, src, SizeWord);
-}
-
-void
-MacroAssemblerMIPSCompat::loadPtr(AbsoluteAddress address, Register dest)
-{
-    movePtr(ImmPtr(address.addr), ScratchRegister);
-    loadPtr(Address(ScratchRegister, 0), dest);
-}
-
-void
-MacroAssemblerMIPSCompat::loadPtr(AsmJSAbsoluteAddress address, Register dest)
-{
-    movePtr(AsmJSImmPtr(address.kind()), ScratchRegister);
-    loadPtr(Address(ScratchRegister, 0), dest);
-}
-
-void
-MacroAssemblerMIPSCompat::loadPrivate(const Address& address, Register dest)
-{
-    ma_lw(dest, Address(address.base, address.offset + PAYLOAD_OFFSET));
-}
-
-void
-MacroAssemblerMIPSCompat::loadDouble(const Address& address, FloatRegister dest)
-{
-    ma_ld(dest, address);
-}
-
-void
-MacroAssemblerMIPSCompat::loadDouble(const BaseIndex& src, FloatRegister dest)
-{
-    computeScaledAddress(src, SecondScratchReg);
-    ma_ld(dest, Address(SecondScratchReg, src.offset));
-}
-
-void
-MacroAssemblerMIPSCompat::loadFloatAsDouble(const Address& address, FloatRegister dest)
-{
-    ma_ls(dest, address);
-    as_cvtds(dest, dest);
-}
-
-void
-MacroAssemblerMIPSCompat::loadFloatAsDouble(const BaseIndex& src, FloatRegister dest)
-{
-    loadFloat32(src, dest);
-    as_cvtds(dest, dest);
-}
-
-void
-MacroAssemblerMIPSCompat::loadFloat32(const Address& address, FloatRegister dest)
-{
-    ma_ls(dest, address);
+    asMasm().moveToDoubleHi(ScratchRegister, dest);
 }
 
 void
-MacroAssemblerMIPSCompat::loadFloat32(const BaseIndex& src, FloatRegister dest)
-{
-    computeScaledAddress(src, SecondScratchReg);
-    ma_ls(dest, Address(SecondScratchReg, src.offset));
-}
-
-void
-MacroAssemblerMIPSCompat::store8(Imm32 imm, const Address& address)
-{
-    ma_li(SecondScratchReg, imm);
-    ma_store(SecondScratchReg, address, SizeByte);
-}
-
-void
-MacroAssemblerMIPSCompat::store8(Register src, const Address& address)
-{
-    ma_store(src, address, SizeByte);
-}
-
-void
-MacroAssemblerMIPSCompat::store8(Imm32 imm, const BaseIndex& dest)
-{
-    ma_store(imm, dest, SizeByte);
-}
-
-void
-MacroAssemblerMIPSCompat::store8(Register src, const BaseIndex& dest)
-{
-    ma_store(src, dest, SizeByte);
-}
-
-void
-MacroAssemblerMIPSCompat::store16(Imm32 imm, const Address& address)
-{
-    ma_li(SecondScratchReg, imm);
-    ma_store(SecondScratchReg, address, SizeHalfWord);
-}
-
-void
-MacroAssemblerMIPSCompat::store16(Register src, const Address& address)
-{
-    ma_store(src, address, SizeHalfWord);
-}
-
-void
-MacroAssemblerMIPSCompat::store16(Imm32 imm, const BaseIndex& dest)
-{
-    ma_store(imm, dest, SizeHalfWord);
-}
-
-void
-MacroAssemblerMIPSCompat::store16(Register src, const BaseIndex& address)
-{
-    ma_store(src, address, SizeHalfWord);
-}
-
-void
-MacroAssemblerMIPSCompat::store32(Register src, AbsoluteAddress address)
-{
-    movePtr(ImmPtr(address.addr), ScratchRegister);
-    store32(src, Address(ScratchRegister, 0));
-}
-
-void
-MacroAssemblerMIPSCompat::store32(Register src, const Address& address)
+MacroAssemblerMIPSShared::ma_sd(FloatRegister ft, BaseIndex address)
 {
-    ma_store(src, address, SizeWord);
-}
-
-void
-MacroAssemblerMIPSCompat::store32(Imm32 src, const Address& address)
-{
-    move32(src, SecondScratchReg);
-    ma_store(SecondScratchReg, address, SizeWord);
-}
-
-void
-MacroAssemblerMIPSCompat::store32(Imm32 imm, const BaseIndex& dest)
-{
-    ma_store(imm, dest, SizeWord);
-}
-
-void
-MacroAssemblerMIPSCompat::store32(Register src, const BaseIndex& dest)
-{
-    ma_store(src, dest, SizeWord);
-}
-
-template <typename T>
-void
-MacroAssemblerMIPSCompat::storePtr(ImmWord imm, T address)
-{
-    ma_li(SecondScratchReg, imm);
-    ma_store(SecondScratchReg, address, SizeWord);
-}
-
-template void MacroAssemblerMIPSCompat::storePtr<Address>(ImmWord imm, Address address);
-template void MacroAssemblerMIPSCompat::storePtr<BaseIndex>(ImmWord imm, BaseIndex address);
-
-template <typename T>
-void
-MacroAssemblerMIPSCompat::storePtr(ImmPtr imm, T address)
-{
-    storePtr(ImmWord(uintptr_t(imm.value)), address);
-}
-
-template void MacroAssemblerMIPSCompat::storePtr<Address>(ImmPtr imm, Address address);
-template void MacroAssemblerMIPSCompat::storePtr<BaseIndex>(ImmPtr imm, BaseIndex address);
-
-template <typename T>
-void
-MacroAssemblerMIPSCompat::storePtr(ImmGCPtr imm, T address)
-{
-    storePtr(ImmWord(uintptr_t(imm.value)), address);
-}
-
-template void MacroAssemblerMIPSCompat::storePtr<Address>(ImmGCPtr imm, Address address);
-template void MacroAssemblerMIPSCompat::storePtr<BaseIndex>(ImmGCPtr imm, BaseIndex address);
-
-void
-MacroAssemblerMIPSCompat::storePtr(Register src, const Address& address)
-{
-    ma_store(src, address, SizeWord);
-}
-
-void
-MacroAssemblerMIPSCompat::storePtr(Register src, const BaseIndex& address)
-{
-    ma_store(src, address, SizeWord);
-}
-
-void
-MacroAssemblerMIPSCompat::storePtr(Register src, AbsoluteAddress dest)
-{
-    movePtr(ImmPtr(dest.addr), ScratchRegister);
-    storePtr(src, Address(ScratchRegister, 0));
+    asMasm().computeScaledAddress(address, SecondScratchReg);
+    asMasm().ma_sd(ft, Address(SecondScratchReg, address.offset));
 }
 
 void
-MacroAssemblerMIPSCompat::clampIntToUint8(Register reg)
-{
-    // look at (reg >> 8) if it is 0, then src shouldn't be clamped
-    // if it is <0, then we want to clamp to 0,
-    // otherwise, we wish to clamp to 255
-    Label done;
-    ma_move(ScratchRegister, reg);
-    asMasm().rshiftPtrArithmetic(Imm32(8), ScratchRegister);
-    ma_b(ScratchRegister, ScratchRegister, &done, Assembler::Zero, ShortJump);
-    {
-        Label negative;
-        ma_b(ScratchRegister, ScratchRegister, &negative, Assembler::Signed, ShortJump);
-        {
-            ma_li(reg, Imm32(255));
-            ma_b(&done, ShortJump);
-        }
-        bind(&negative);
-        {
-            ma_move(reg, zero);
-        }
-    }
-    bind(&done);
-}
-
-// Note: this function clobbers the input register.
-void
-MacroAssembler::clampDoubleToUint8(FloatRegister input, Register output)
-{
-    MOZ_ASSERT(input != ScratchDoubleReg);
-    Label positive, done;
-
-    // <= 0 or NaN --> 0
-    zeroDouble(ScratchDoubleReg);
-    branchDouble(DoubleGreaterThan, input, ScratchDoubleReg, &positive);
-    {
-        move32(Imm32(0), output);
-        jump(&done);
-    }
-
-    bind(&positive);
-
-    // Add 0.5 and truncate.
-    loadConstantDouble(0.5, ScratchDoubleReg);
-    addDouble(ScratchDoubleReg, input);
-
-    Label outOfRange;
-
-    branchTruncateDouble(input, output, &outOfRange);
-    branch32(Assembler::Above, output, Imm32(255), &outOfRange);
-    {
-        // Check if we had a tie.
-        convertInt32ToDouble(output, ScratchDoubleReg);
-        branchDouble(DoubleNotEqual, input, ScratchDoubleReg, &done);
-
-        // It was a tie. Mask out the ones bit to get an even value.
-        // See also js_TypedArray_uint8_clamp_double.
-        and32(Imm32(~1), output);
-        jump(&done);
-    }
-
-    // > 255 --> 255
-    bind(&outOfRange);
-    {
-        move32(Imm32(255), output);
-    }
-
-    bind(&done);
-}
-
-void
-MacroAssemblerMIPSCompat::subPtr(Imm32 imm, const Register dest)
-{
-    ma_subu(dest, dest, imm);
-}
-
-void
-MacroAssemblerMIPSCompat::subPtr(const Address& addr, const Register dest)
-{
-    loadPtr(addr, SecondScratchReg);
-    subPtr(SecondScratchReg, dest);
-}
-
-void
-MacroAssemblerMIPSCompat::subPtr(Register src, const Address& dest)
-{
-    loadPtr(dest, SecondScratchReg);
-    subPtr(src, SecondScratchReg);
-    storePtr(SecondScratchReg, dest);
-}
-
-void
-MacroAssemblerMIPSCompat::addPtr(Imm32 imm, const Register dest)
-{
-    ma_addu(dest, imm);
-}
-
-void
-MacroAssemblerMIPSCompat::addPtr(Imm32 imm, const Address& dest)
-{
-    loadPtr(dest, ScratchRegister);
-    addPtr(imm, ScratchRegister);
-    storePtr(ScratchRegister, dest);
-}
-
-void
-MacroAssemblerMIPSCompat::branchDouble(DoubleCondition cond, FloatRegister lhs,
-                                       FloatRegister rhs, Label* label)
-{
-    ma_bc1d(lhs, rhs, label, cond);
-}
-
-void
-MacroAssemblerMIPSCompat::branchFloat(DoubleCondition cond, FloatRegister lhs,
-                                      FloatRegister rhs, Label* label)
-{
-    ma_bc1s(lhs, rhs, label, cond);
-}
-
-// higher level tag testing code
-Operand
-MacroAssemblerMIPSCompat::ToPayload(Operand base)
-{
-    return Operand(Register::FromCode(base.base()), base.disp() + PAYLOAD_OFFSET);
-}
-
-Operand
-MacroAssemblerMIPSCompat::ToType(Operand base)
-{
-    return Operand(Register::FromCode(base.base()), base.disp() + TAG_OFFSET);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestGCThing(Condition cond, const Address& address, Label* label)
+MacroAssemblerMIPSShared::ma_ss(FloatRegister ft, BaseIndex address)
 {
-    MOZ_ASSERT(cond == Equal || cond == NotEqual);
-    extractTag(address, SecondScratchReg);
-    ma_b(SecondScratchReg, ImmTag(JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET), label,
-         (cond == Equal) ? AboveOrEqual : Below);
-}
-void
-MacroAssemblerMIPSCompat::branchTestGCThing(Condition cond, const BaseIndex& src, Label* label)
-{
-    MOZ_ASSERT(cond == Equal || cond == NotEqual);
-    extractTag(src, SecondScratchReg);
-    ma_b(SecondScratchReg, ImmTag(JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET), label,
-         (cond == Equal) ? AboveOrEqual : Below);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestPrimitive(Condition cond, const ValueOperand& value,
-                                              Label* label)
-{
-    branchTestPrimitive(cond, value.typeReg(), label);
-}
-void
-MacroAssemblerMIPSCompat::branchTestPrimitive(Condition cond, Register tag, Label* label)
-{
-    MOZ_ASSERT(cond == Equal || cond == NotEqual);
-    ma_b(tag, ImmTag(JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET), label,
-         (cond == Equal) ? Below : AboveOrEqual);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestInt32(Condition cond, const ValueOperand& value, Label* label)
-{
-    MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
-    ma_b(value.typeReg(), ImmType(JSVAL_TYPE_INT32), label, cond);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestInt32(Condition cond, Register tag, Label* label)
-{
-    MOZ_ASSERT(cond == Equal || cond == NotEqual);
-    ma_b(tag, ImmTag(JSVAL_TAG_INT32), label, cond);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestInt32(Condition cond, const Address& address, Label* label)
-{
-    MOZ_ASSERT(cond == Equal || cond == NotEqual);
-    extractTag(address, SecondScratchReg);
-    ma_b(SecondScratchReg, ImmTag(JSVAL_TAG_INT32), label, cond);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestInt32(Condition cond, const BaseIndex& src, Label* label)
-{
-    MOZ_ASSERT(cond == Equal || cond == NotEqual);
-    extractTag(src, SecondScratchReg);
-    ma_b(SecondScratchReg, ImmTag(JSVAL_TAG_INT32), label, cond);
-}
-
-void
-MacroAssemblerMIPSCompat:: branchTestBoolean(Condition cond, const ValueOperand& value,
-                                             Label* label)
-{
-    MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
-    ma_b(value.typeReg(), ImmType(JSVAL_TYPE_BOOLEAN), label, cond);
-}
-
-void
-MacroAssemblerMIPSCompat:: branchTestBoolean(Condition cond, Register tag, Label* label)
-{
-    MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
-    ma_b(tag, ImmType(JSVAL_TYPE_BOOLEAN), label, cond);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestBoolean(Condition cond, const BaseIndex& src, Label* label)
-{
-    MOZ_ASSERT(cond == Equal || cond == NotEqual);
-    extractTag(src, SecondScratchReg);
-    ma_b(SecondScratchReg, ImmType(JSVAL_TYPE_BOOLEAN), label, cond);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestDouble(Condition cond, const ValueOperand& value, Label* label)
-{
-    MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
-    Assembler::Condition actual = (cond == Equal) ? Below : AboveOrEqual;
-    ma_b(value.typeReg(), ImmTag(JSVAL_TAG_CLEAR), label, actual);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestDouble(Condition cond, Register tag, Label* label)
-{
-    MOZ_ASSERT(cond == Assembler::Equal || cond == NotEqual);
-    Condition actual = (cond == Equal) ? Below : AboveOrEqual;
-    ma_b(tag, ImmTag(JSVAL_TAG_CLEAR), label, actual);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestDouble(Condition cond, const Address& address, Label* label)
-{
-    MOZ_ASSERT(cond == Equal || cond == NotEqual);
-    extractTag(address, SecondScratchReg);
-    ma_b(SecondScratchReg, ImmTag(JSVAL_TAG_CLEAR), label, cond);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestDouble(Condition cond, const BaseIndex& src, Label* label)
-{
-    MOZ_ASSERT(cond == Equal || cond == NotEqual);
-    Condition actual = (cond == Equal) ? Below : AboveOrEqual;
-    extractTag(src, SecondScratchReg);
-    ma_b(SecondScratchReg, ImmTag(JSVAL_TAG_CLEAR), label, actual);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestNull(Condition cond, const ValueOperand& value, Label* label)
-{
-    MOZ_ASSERT(cond == Equal || cond == NotEqual);
-    ma_b(value.typeReg(), ImmType(JSVAL_TYPE_NULL), label, cond);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestNull(Condition cond, Register tag, Label* label)
-{
-    MOZ_ASSERT(cond == Equal || cond == NotEqual);
-    ma_b(tag, ImmTag(JSVAL_TAG_NULL), label, cond);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestNull(Condition cond, const BaseIndex& src, Label* label)
-{
-    MOZ_ASSERT(cond == Equal || cond == NotEqual);
-    extractTag(src, SecondScratchReg);
-    ma_b(SecondScratchReg, ImmTag(JSVAL_TAG_NULL), label, cond);
+    asMasm().computeScaledAddress(address, SecondScratchReg);
+    asMasm().ma_ss(ft, Address(SecondScratchReg, address.offset));
 }
 
 void
-MacroAssemblerMIPSCompat::branchTestNull(Condition cond, const Address& address, Label* label) {
-    MOZ_ASSERT(cond == Equal || cond == NotEqual);
-    extractTag(address, SecondScratchReg);
-    ma_b(SecondScratchReg, ImmTag(JSVAL_TAG_NULL), label, cond);
-}
-
-void
-MacroAssemblerMIPSCompat::testNullSet(Condition cond, const ValueOperand& value, Register dest)
-{
-    MOZ_ASSERT(cond == Equal || cond == NotEqual);
-    ma_cmp_set(dest, value.typeReg(), ImmType(JSVAL_TYPE_NULL), cond);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestObject(Condition cond, const ValueOperand& value, Label* label)
-{
-    branchTestObject(cond, value.typeReg(), label);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestObject(Condition cond, Register tag, Label* label)
-{
-    MOZ_ASSERT(cond == Equal || cond == NotEqual);
-    ma_b(tag, ImmTag(JSVAL_TAG_OBJECT), label, cond);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestObject(Condition cond, const BaseIndex& src, Label* label)
-{
-    MOZ_ASSERT(cond == Equal || cond == NotEqual);
-    extractTag(src, SecondScratchReg);
-    ma_b(SecondScratchReg, ImmTag(JSVAL_TAG_OBJECT), label, cond);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestObject(Condition cond, const Address& address, Label* label)
-{
-    MOZ_ASSERT(cond == Equal || cond == NotEqual);
-    extractTag(address, SecondScratchReg);
-    ma_b(SecondScratchReg, ImmTag(JSVAL_TAG_OBJECT), label, cond);
-}
-
-void
-MacroAssemblerMIPSCompat::testObjectSet(Condition cond, const ValueOperand& value, Register dest)
-{
-    MOZ_ASSERT(cond == Equal || cond == NotEqual);
-    ma_cmp_set(dest, value.typeReg(), ImmType(JSVAL_TYPE_OBJECT), cond);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestString(Condition cond, const ValueOperand& value, Label* label)
-{
-    branchTestString(cond, value.typeReg(), label);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestString(Condition cond, Register tag, Label* label)
-{
-    MOZ_ASSERT(cond == Equal || cond == NotEqual);
-    ma_b(tag, ImmTag(JSVAL_TAG_STRING), label, cond);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestString(Condition cond, const BaseIndex& src, Label* label)
-{
-    MOZ_ASSERT(cond == Equal || cond == NotEqual);
-    extractTag(src, SecondScratchReg);
-    ma_b(SecondScratchReg, ImmTag(JSVAL_TAG_STRING), label, cond);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestSymbol(Condition cond, const ValueOperand& value, Label* label)
-{
-    branchTestSymbol(cond, value.typeReg(), label);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestSymbol(Condition cond, const Register& tag, Label* label)
-{
-    MOZ_ASSERT(cond == Equal || cond == NotEqual);
-    ma_b(tag, ImmTag(JSVAL_TAG_SYMBOL), label, cond);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestSymbol(Condition cond, const BaseIndex& src, Label* label)
-{
-    MOZ_ASSERT(cond == Equal || cond == NotEqual);
-    extractTag(src, SecondScratchReg);
-    ma_b(SecondScratchReg, ImmTag(JSVAL_TAG_SYMBOL), label, cond);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestUndefined(Condition cond, const ValueOperand& value,
-                                              Label* label)
-{
-    MOZ_ASSERT(cond == Equal || cond == NotEqual);
-    ma_b(value.typeReg(), ImmType(JSVAL_TYPE_UNDEFINED), label, cond);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestUndefined(Condition cond, Register tag, Label* label)
-{
-    MOZ_ASSERT(cond == Equal || cond == NotEqual);
-    ma_b(tag, ImmTag(JSVAL_TAG_UNDEFINED), label, cond);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestUndefined(Condition cond, const BaseIndex& src, Label* label)
-{
-    MOZ_ASSERT(cond == Equal || cond == NotEqual);
-    extractTag(src, SecondScratchReg);
-    ma_b(SecondScratchReg, ImmTag(JSVAL_TAG_UNDEFINED), label, cond);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestUndefined(Condition cond, const Address& address, Label* label)
-{
-    MOZ_ASSERT(cond == Equal || cond == NotEqual);
-    extractTag(address, SecondScratchReg);
-    ma_b(SecondScratchReg, ImmTag(JSVAL_TAG_UNDEFINED), label, cond);
-}
-
-void
-MacroAssemblerMIPSCompat::testUndefinedSet(Condition cond, const ValueOperand& value, Register dest)
-{
-    MOZ_ASSERT(cond == Equal || cond == NotEqual);
-    ma_cmp_set(dest, value.typeReg(), ImmType(JSVAL_TYPE_UNDEFINED), cond);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestNumber(Condition cond, const ValueOperand& value, Label* label)
-{
-    branchTestNumber(cond, value.typeReg(), label);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestNumber(Condition cond, Register tag, Label* label)
-{
-    MOZ_ASSERT(cond == Equal || cond == NotEqual);
-    ma_b(tag, ImmTag(JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET), label,
-         cond == Equal ? BelowOrEqual : Above);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestMagic(Condition cond, const ValueOperand& value, Label* label)
-{
-    branchTestMagic(cond, value.typeReg(), label);
-}
-
-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)
-{
-    MOZ_ASSERT(cond == Equal || cond == NotEqual);
-    extractTag(address, SecondScratchReg);
-    ma_b(SecondScratchReg, ImmTag(JSVAL_TAG_MAGIC), label, cond);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestMagic(Condition cond, const BaseIndex& src, Label* label)
-{
-    MOZ_ASSERT(cond == Equal || cond == NotEqual);
-    extractTag(src, SecondScratchReg);
-    ma_b(SecondScratchReg, ImmTag(JSVAL_TAG_MAGIC), label, cond);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestValue(Condition cond, const ValueOperand& value,
-                                          const Value& v, Label* label)
+MacroAssemblerMIPSShared::ma_bc1s(FloatRegister lhs, FloatRegister rhs, Label* label,
+                                  DoubleCondition c, JumpKind jumpKind, FPConditionBit fcc)
 {
-    moveData(v, ScratchRegister);
-
-    if (cond == Equal) {
-        Label done;
-        ma_b(value.payloadReg(), ScratchRegister, &done, NotEqual, ShortJump);
-        {
-            ma_b(value.typeReg(), Imm32(getType(v)), label, Equal);
-        }
-        bind(&done);
-    } else {
-        MOZ_ASSERT(cond == NotEqual);
-        ma_b(value.payloadReg(), ScratchRegister, label, NotEqual);
-
-        ma_b(value.typeReg(), Imm32(getType(v)), label, NotEqual);
-    }
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestValue(Condition cond, const Address& valaddr,
-                                          const ValueOperand& value, Label* label)
-{
-    MOZ_ASSERT(cond == Equal || cond == NotEqual);
-
-    // Load tag.
-    ma_lw(ScratchRegister, Address(valaddr.base, valaddr.offset + TAG_OFFSET));
-    branchPtr(cond, ScratchRegister, value.typeReg(), label);
-
-    // Load payload
-    ma_lw(ScratchRegister, Address(valaddr.base, valaddr.offset + PAYLOAD_OFFSET));
-    branchPtr(cond, ScratchRegister, value.payloadReg(), label);
-}
-
-// unboxing code
-void
-MacroAssemblerMIPSCompat::unboxNonDouble(const ValueOperand& operand, Register dest)
-{
-    if (operand.payloadReg() != dest)
-        ma_move(dest, operand.payloadReg());
-}
-
-void
-MacroAssemblerMIPSCompat::unboxNonDouble(const Address& src, Register dest)
-{
-    ma_lw(dest, Address(src.base, src.offset + PAYLOAD_OFFSET));
-}
-
-void
-MacroAssemblerMIPSCompat::unboxNonDouble(const BaseIndex& src, Register dest)
-{
-    computeScaledAddress(src, SecondScratchReg);
-    ma_lw(dest, Address(SecondScratchReg, src.offset + PAYLOAD_OFFSET));
-}
-
-void
-MacroAssemblerMIPSCompat::unboxInt32(const ValueOperand& operand, Register dest)
-{
-    ma_move(dest, operand.payloadReg());
-}
-
-void
-MacroAssemblerMIPSCompat::unboxInt32(const Address& src, Register dest)
-{
-    ma_lw(dest, Address(src.base, src.offset + PAYLOAD_OFFSET));
-}
-
-void
-MacroAssemblerMIPSCompat::unboxBoolean(const ValueOperand& operand, Register dest)
-{
-    ma_move(dest, operand.payloadReg());
-}
-
-void
-MacroAssemblerMIPSCompat::unboxBoolean(const Address& src, Register dest)
-{
-    ma_lw(dest, Address(src.base, src.offset + PAYLOAD_OFFSET));
-}
-
-void
-MacroAssemblerMIPSCompat::unboxDouble(const ValueOperand& operand, FloatRegister dest)
-{
-    moveToDoubleLo(operand.payloadReg(), dest);
-    moveToDoubleHi(operand.typeReg(), dest);
-}
-
-void
-MacroAssemblerMIPSCompat::unboxDouble(const Address& src, FloatRegister dest)
-{
-    ma_lw(ScratchRegister, Address(src.base, src.offset + PAYLOAD_OFFSET));
-    moveToDoubleLo(ScratchRegister, dest);
-    ma_lw(ScratchRegister, Address(src.base, src.offset + TAG_OFFSET));
-    moveToDoubleHi(ScratchRegister, dest);
-}
-
-void
-MacroAssemblerMIPSCompat::unboxString(const ValueOperand& operand, Register dest)
-{
-    ma_move(dest, operand.payloadReg());
-}
-
-void
-MacroAssemblerMIPSCompat::unboxString(const Address& src, Register dest)
-{
-    ma_lw(dest, Address(src.base, src.offset + PAYLOAD_OFFSET));
-}
-
-void
-MacroAssemblerMIPSCompat::unboxObject(const ValueOperand& src, Register dest)
-{
-    ma_move(dest, src.payloadReg());
-}
-
-void
-MacroAssemblerMIPSCompat::unboxObject(const Address& src, Register dest)
-{
-    ma_lw(dest, Address(src.base, src.offset + PAYLOAD_OFFSET));
-}
-
-void
-MacroAssemblerMIPSCompat::unboxValue(const ValueOperand& src, AnyRegister dest)
-{
-    if (dest.isFloat()) {
-        Label notInt32, end;
-        branchTestInt32(Assembler::NotEqual, src, &notInt32);
-        convertInt32ToDouble(src.payloadReg(), dest.fpu());
-        ma_b(&end, ShortJump);
-        bind(&notInt32);
-        unboxDouble(src, dest.fpu());
-        bind(&end);
-    } else if (src.payloadReg() != dest.gpr()) {
-        ma_move(dest.gpr(), src.payloadReg());
-    }
-}
-
-void
-MacroAssemblerMIPSCompat::unboxPrivate(const ValueOperand& src, Register dest)
-{
-    ma_move(dest, src.payloadReg());
-}
-
-void
-MacroAssemblerMIPSCompat::boxDouble(FloatRegister src, const ValueOperand& dest)
-{
-    moveFromDoubleLo(src, dest.payloadReg());
-    moveFromDoubleHi(src, dest.typeReg());
-}
-
-void
-MacroAssemblerMIPSCompat::boxNonDouble(JSValueType type, Register src,
-                                       const ValueOperand& dest)
-{
-    if (src != dest.payloadReg())
-        ma_move(dest.payloadReg(), src);
-    ma_li(dest.typeReg(), ImmType(type));
-}
-
-void
-MacroAssemblerMIPSCompat::boolValueToDouble(const ValueOperand& operand, FloatRegister dest)
-{
-    convertBoolToInt32(operand.payloadReg(), ScratchRegister);
-    convertInt32ToDouble(ScratchRegister, dest);
-}
-
-void
-MacroAssemblerMIPSCompat::int32ValueToDouble(const ValueOperand& operand,
-                                             FloatRegister dest)
-{
-    convertInt32ToDouble(operand.payloadReg(), dest);
-}
-
-void
-MacroAssemblerMIPSCompat::boolValueToFloat32(const ValueOperand& operand,
-                                             FloatRegister dest)
-{
-
-    convertBoolToInt32(operand.payloadReg(), ScratchRegister);
-    convertInt32ToFloat32(ScratchRegister, dest);
-}
-
-void
-MacroAssemblerMIPSCompat::int32ValueToFloat32(const ValueOperand& operand,
-                                              FloatRegister dest)
-{
-    convertInt32ToFloat32(operand.payloadReg(), dest);
-}
-
-void
-MacroAssemblerMIPSCompat::loadConstantFloat32(float f, FloatRegister dest)
-{
-    ma_lis(dest, f);
-}
-
-void
-MacroAssemblerMIPSCompat::loadInt32OrDouble(const Address& src, FloatRegister dest)
-{
-    Label notInt32, end;
-    // If it's an int, convert it to double.
-    ma_lw(SecondScratchReg, Address(src.base, src.offset + TAG_OFFSET));
-    branchTestInt32(Assembler::NotEqual, SecondScratchReg, &notInt32);
-    ma_lw(SecondScratchReg, Address(src.base, src.offset + PAYLOAD_OFFSET));
-    convertInt32ToDouble(SecondScratchReg, dest);
-    ma_b(&end, ShortJump);
-
-    // Not an int, just load as double.
-    bind(&notInt32);
-    ma_ld(dest, src);
-    bind(&end);
+    FloatTestKind testKind;
+    compareFloatingPoint(SingleFloat, lhs, rhs, c, &testKind, fcc);
+    asMasm().branchWithCode(getBranchCode(testKind, fcc), label, jumpKind);
 }
 
 void
-MacroAssemblerMIPSCompat::loadInt32OrDouble(Register base, Register index,
-                                            FloatRegister dest, int32_t shift)
-{
-    Label notInt32, end;
-
-    // If it's an int, convert it to double.
-
-    computeScaledAddress(BaseIndex(base, index, ShiftToScale(shift)), SecondScratchReg);
-    // Since we only have one scratch, we need to stomp over it with the tag.
-    load32(Address(SecondScratchReg, TAG_OFFSET), SecondScratchReg);
-    branchTestInt32(Assembler::NotEqual, SecondScratchReg, &notInt32);
-
-    computeScaledAddress(BaseIndex(base, index, ShiftToScale(shift)), SecondScratchReg);
-    load32(Address(SecondScratchReg, PAYLOAD_OFFSET), SecondScratchReg);
-    convertInt32ToDouble(SecondScratchReg, dest);
-    ma_b(&end, ShortJump);
-
-    // Not an int, just load as double.
-    bind(&notInt32);
-    // First, recompute the offset that had been stored in the scratch register
-    // since the scratch register was overwritten loading in the type.
-    computeScaledAddress(BaseIndex(base, index, ShiftToScale(shift)), SecondScratchReg);
-    loadDouble(Address(SecondScratchReg, 0), dest);
-    bind(&end);
-}
-
-void
-MacroAssemblerMIPSCompat::loadConstantDouble(double dp, FloatRegister dest)
-{
-    ma_lid(dest, dp);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestInt32Truthy(bool b, const ValueOperand& value, Label* label)
-{
-    as_and(ScratchRegister, value.payloadReg(), value.payloadReg());
-    ma_b(ScratchRegister, ScratchRegister, label, b ? NonZero : Zero);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestStringTruthy(bool b, const ValueOperand& value, Label* label)
-{
-    Register string = value.payloadReg();
-    ma_lw(SecondScratchReg, Address(string, JSString::offsetOfLength()));
-    ma_b(SecondScratchReg, Imm32(0), label, b ? NotEqual : Equal);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestDoubleTruthy(bool b, FloatRegister value, Label* label)
-{
-    ma_lid(ScratchDoubleReg, 0.0);
-    DoubleCondition cond = b ? DoubleNotEqual : DoubleEqualOrUnordered;
-    ma_bc1d(value, ScratchDoubleReg, label, cond);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTestBooleanTruthy(bool b, const ValueOperand& operand,
-                                                  Label* label)
-{
-    ma_b(operand.payloadReg(), operand.payloadReg(), label, b ? NonZero : Zero);
-}
-
-void
-MacroAssemblerMIPSCompat::branchTest64(Condition cond, Register64 lhs, Register64 rhs,
-                                       Register temp, Label* label)
+MacroAssemblerMIPSShared::ma_bc1d(FloatRegister lhs, FloatRegister rhs, Label* label,
+                                  DoubleCondition c, JumpKind jumpKind, FPConditionBit fcc)
 {
-    if (cond == Assembler::Zero) {
-        MOZ_ASSERT(lhs.low == rhs.low);
-        MOZ_ASSERT(lhs.high == rhs.high);
-        as_or(ScratchRegister, lhs.low, lhs.high);
-        branchTestPtr(cond, ScratchRegister, ScratchRegister, label);
-    } else {
-        MOZ_CRASH("Unsupported condition");
-    }
-}
-
-Register
-MacroAssemblerMIPSCompat::extractObject(const Address& address, Register scratch)
-{
-    ma_lw(scratch, Address(address.base, address.offset + PAYLOAD_OFFSET));
-    return scratch;
-}
-
-Register
-MacroAssemblerMIPSCompat::extractTag(const Address& address, Register scratch)
-{
-    ma_lw(scratch, Address(address.base, address.offset + TAG_OFFSET));
-    return scratch;
-}
-
-Register
-MacroAssemblerMIPSCompat::extractTag(const BaseIndex& address, Register scratch)
-{
-    computeScaledAddress(address, scratch);
-    return extractTag(Address(scratch, address.offset), scratch);
-}
-
-
-uint32_t
-MacroAssemblerMIPSCompat::getType(const Value& val)
-{
-    jsval_layout jv = JSVAL_TO_IMPL(val);
-    return jv.s.tag;
-}
-
-template <typename T>
-void
-MacroAssemblerMIPSCompat::storeUnboxedValue(ConstantOrRegister value, MIRType valueType, const T& dest,
-                                            MIRType slotType)
-{
-    if (valueType == MIRType_Double) {
-        storeDouble(value.reg().typedReg().fpu(), dest);
-        return;
-    }
-
-    // Store the type tag if needed.
-    if (valueType != slotType)
-        storeTypeTag(ImmType(ValueTypeFromMIRType(valueType)), dest);
-
-    // Store the payload.
-    if (value.constant())
-        storePayload(value.value(), dest);
-    else
-        storePayload(value.reg().typedReg().gpr(), dest);
-}
-
-template void
-MacroAssemblerMIPSCompat::storeUnboxedValue(ConstantOrRegister value, MIRType valueType, const Address& dest,
-                                            MIRType slotType);
-
-template void
-MacroAssemblerMIPSCompat::storeUnboxedValue(ConstantOrRegister value, MIRType valueType, const BaseIndex& dest,
-                                            MIRType slotType);
-
-void
-MacroAssemblerMIPSCompat::moveData(const Value& val, Register data)
-{
-    jsval_layout jv = JSVAL_TO_IMPL(val);
-    if (val.isMarkable())
-        ma_li(data, ImmGCPtr(reinterpret_cast<gc::Cell*>(val.toGCThing())));
-    else
-        ma_li(data, Imm32(jv.s.payload.i32));
+    FloatTestKind testKind;
+    compareFloatingPoint(DoubleFloat, lhs, rhs, c, &testKind, fcc);
+    asMasm().branchWithCode(getBranchCode(testKind, fcc), label, jumpKind);
 }
 
 void
-MacroAssemblerMIPSCompat::moveValue(const Value& val, Register type, Register data)
-{
-    MOZ_ASSERT(type != data);
-    ma_li(type, Imm32(getType(val)));
-    moveData(val, data);
-}
-void
-MacroAssemblerMIPSCompat::moveValue(const Value& val, const ValueOperand& dest)
-{
-    moveValue(val, dest.typeReg(), dest.payloadReg());
-}
-
-/* There are 3 paths trough backedge jump. They are listed here in the order
- * in which instructions are executed.
- *  - The short jump is simple:
- *     b offset            # Jumps directly to target.
- *     lui at, addr1_hi    # In delay slot. Don't care about 'at' here.
- *
- *  - The long jump to loop header:
- *      b label1
- *      lui at, addr1_hi   # In delay slot. We use the value in 'at' later.
- *    label1:
- *      ori at, addr1_lo
- *      jr at
- *      lui at, addr2_hi   # In delay slot. Don't care about 'at' here.
- *
- *  - The long jump to interrupt loop:
- *      b label2
- *      lui at, addr1_hi   # In delay slot. Don't care about 'at' here.
- *    label2:
- *      lui at, addr2_hi
- *      ori at, addr2_lo
- *      jr at
- *      nop                # In delay slot.
- *
- * The backedge is done this way to avoid patching lui+ori pair while it is
- * being executed. Look also at jit::PatchBackedge().
- */
-CodeOffsetJump
-MacroAssemblerMIPSCompat::backedgeJump(RepatchLabel* label, Label* documentation)
-{
-    // Only one branch per label.
-    MOZ_ASSERT(!label->used());
-    uint32_t dest = label->bound() ? label->offset() : LabelBase::INVALID_OFFSET;
-    BufferOffset bo = nextOffset();
-    label->use(bo.getOffset());
-
-    // Backedges are short jumps when bound, but can become long when patched.
-    m_buffer.ensureSpace(8 * sizeof(uint32_t));
-    if (label->bound()) {
-        int32_t offset = label->offset() - bo.getOffset();
-        MOZ_ASSERT(BOffImm16::IsInRange(offset));
-        as_b(BOffImm16(offset));
-    } else {
-        // Jump to "label1" by default to jump to the loop header.
-        as_b(BOffImm16(2 * sizeof(uint32_t)));
-    }
-    // No need for nop here. We can safely put next instruction in delay slot.
-    ma_liPatchable(ScratchRegister, Imm32(dest));
-    MOZ_ASSERT(nextOffset().getOffset() - bo.getOffset() == 3 * sizeof(uint32_t));
-    as_jr(ScratchRegister);
-    // No need for nop here. We can safely put next instruction in delay slot.
-    ma_liPatchable(ScratchRegister, Imm32(dest));
-    as_jr(ScratchRegister);
-    as_nop();
-    MOZ_ASSERT(nextOffset().getOffset() - bo.getOffset() == 8 * sizeof(uint32_t));
-    return CodeOffsetJump(bo.getOffset());
-}
-
-CodeOffsetJump
-MacroAssemblerMIPSCompat::jumpWithPatch(RepatchLabel* label, Label* documentation)
-{
-    // Only one branch per label.
-    MOZ_ASSERT(!label->used());
-    uint32_t dest = label->bound() ? label->offset() : LabelBase::INVALID_OFFSET;
-
-    BufferOffset bo = nextOffset();
-    label->use(bo.getOffset());
-    addLongJump(bo);
-    ma_liPatchable(ScratchRegister, Imm32(dest));
-    as_jr(ScratchRegister);
-    as_nop();
-    return CodeOffsetJump(bo.getOffset());
-}
-
-/////////////////////////////////////////////////////////////////
-// X86/X64-common/ARM/MIPS interface.
-/////////////////////////////////////////////////////////////////
-void
-MacroAssemblerMIPSCompat::storeValue(ValueOperand val, Operand dst)
-{
-    storeValue(val, Address(Register::FromCode(dst.base()), dst.disp()));
-}
-
-void
-MacroAssemblerMIPSCompat::storeValue(ValueOperand val, const BaseIndex& dest)
-{
-    computeScaledAddress(dest, SecondScratchReg);
-    storeValue(val, Address(SecondScratchReg, dest.offset));
-}
-
-void
-MacroAssemblerMIPSCompat::storeValue(JSValueType type, Register reg, BaseIndex dest)
-{
-    computeScaledAddress(dest, ScratchRegister);
-
-    // Make sure that ma_sw doesn't clobber ScratchRegister
-    int32_t offset = dest.offset;
-    if (!Imm16::IsInSignedRange(offset)) {
-        ma_li(SecondScratchReg, Imm32(offset));
-        as_addu(ScratchRegister, ScratchRegister, SecondScratchReg);
-        offset = 0;
-    }
-
-    storeValue(type, reg, Address(ScratchRegister, offset));
-}
-
-void
-MacroAssemblerMIPSCompat::storeValue(ValueOperand val, const Address& dest)
-{
-    ma_sw(val.payloadReg(), Address(dest.base, dest.offset + PAYLOAD_OFFSET));
-    ma_sw(val.typeReg(), Address(dest.base, dest.offset + TAG_OFFSET));
-}
-
-void
-MacroAssemblerMIPSCompat::storeValue(JSValueType type, Register reg, Address dest)
-{
-    MOZ_ASSERT(dest.base != SecondScratchReg);
-
-    ma_sw(reg, Address(dest.base, dest.offset + PAYLOAD_OFFSET));
-    ma_li(SecondScratchReg, ImmTag(JSVAL_TYPE_TO_TAG(type)));
-    ma_sw(SecondScratchReg, Address(dest.base, dest.offset + TAG_OFFSET));
-}
-
-void
-MacroAssemblerMIPSCompat::storeValue(const Value& val, Address dest)
+MacroAssemblerMIPSShared::ma_call(ImmPtr dest)
 {
-    MOZ_ASSERT(dest.base != SecondScratchReg);
-
-    ma_li(SecondScratchReg, Imm32(getType(val)));
-    ma_sw(SecondScratchReg, Address(dest.base, dest.offset + TAG_OFFSET));
-    moveData(val, SecondScratchReg);
-    ma_sw(SecondScratchReg, Address(dest.base, dest.offset + PAYLOAD_OFFSET));
-}
-
-void
-MacroAssemblerMIPSCompat::storeValue(const Value& val, BaseIndex dest)
-{
-    computeScaledAddress(dest, ScratchRegister);
-
-    // Make sure that ma_sw doesn't clobber ScratchRegister
-    int32_t offset = dest.offset;
-    if (!Imm16::IsInSignedRange(offset)) {
-        ma_li(SecondScratchReg, Imm32(offset));
-        as_addu(ScratchRegister, ScratchRegister, SecondScratchReg);
-        offset = 0;
-    }
-    storeValue(val, Address(ScratchRegister, offset));
-}
-
-void
-MacroAssemblerMIPSCompat::loadValue(const BaseIndex& addr, ValueOperand val)
-{
-    computeScaledAddress(addr, SecondScratchReg);
-    loadValue(Address(SecondScratchReg, addr.offset), val);
-}
-
-void
-MacroAssemblerMIPSCompat::loadValue(Address src, ValueOperand val)
-{
-    // Ensure that loading the payload does not erase the pointer to the
-    // Value in memory.
-    if (src.base != val.payloadReg()) {
-        ma_lw(val.payloadReg(), Address(src.base, src.offset + PAYLOAD_OFFSET));
-        ma_lw(val.typeReg(), Address(src.base, src.offset + TAG_OFFSET));
-    } else {
-        ma_lw(val.typeReg(), Address(src.base, src.offset + TAG_OFFSET));
-        ma_lw(val.payloadReg(), Address(src.base, src.offset + PAYLOAD_OFFSET));
-    }
-}
-
-void
-MacroAssemblerMIPSCompat::tagValue(JSValueType type, Register payload, ValueOperand dest)
-{
-    MOZ_ASSERT(payload != dest.typeReg());
-    ma_li(dest.typeReg(), ImmType(type));
-    if (payload != dest.payloadReg())
-        ma_move(dest.payloadReg(), payload);
-}
-
-void
-MacroAssemblerMIPSCompat::pushValue(ValueOperand val)
-{
-    // Allocate stack slots for type and payload. One for each.
-    subPtr(Imm32(sizeof(Value)), StackPointer);
-    // Store type and payload.
-    storeValue(val, Address(StackPointer, 0));
-}
-
-void
-MacroAssemblerMIPSCompat::pushValue(const Address& addr)
-{
-    // Allocate stack slots for type and payload. One for each.
-    ma_subu(StackPointer, StackPointer, Imm32(sizeof(Value)));
-    // Store type and payload.
-    ma_lw(ScratchRegister, Address(addr.base, addr.offset + TAG_OFFSET));
-    ma_sw(ScratchRegister, Address(StackPointer, TAG_OFFSET));
-    ma_lw(ScratchRegister, Address(addr.base, addr.offset + PAYLOAD_OFFSET));
-    ma_sw(ScratchRegister, Address(StackPointer, PAYLOAD_OFFSET));
-}
-
-void
-MacroAssemblerMIPSCompat::popValue(ValueOperand val)
-{
-    // Load payload and type.
-    as_lw(val.payloadReg(), StackPointer, PAYLOAD_OFFSET);
-    as_lw(val.typeReg(), StackPointer, TAG_OFFSET);
-    // Free stack.
-    as_addiu(StackPointer, StackPointer, sizeof(Value));
-}
-
-void
-MacroAssemblerMIPSCompat::storePayload(const Value& val, Address dest)
-{
-    moveData(val, SecondScratchReg);
-    ma_sw(SecondScratchReg, Address(dest.base, dest.offset + PAYLOAD_OFFSET));
-}
-
-void
-MacroAssemblerMIPSCompat::storePayload(Register src, Address dest)
-{
-    ma_sw(src, Address(dest.base, dest.offset + PAYLOAD_OFFSET));
-    return;
-}
-
-void
-MacroAssemblerMIPSCompat::storePayload(const Value& val, const BaseIndex& dest)
-{
-    MOZ_ASSERT(dest.offset == 0);
-
-    computeScaledAddress(dest, SecondScratchReg);
-
-    moveData(val, ScratchRegister);
-
-    as_sw(ScratchRegister, SecondScratchReg, NUNBOX32_PAYLOAD_OFFSET);
-}
-
-void
-MacroAssemblerMIPSCompat::storePayload(Register src, const BaseIndex& dest)
-{
-    MOZ_ASSERT(dest.offset == 0);
-
-    computeScaledAddress(dest, SecondScratchReg);
-    as_sw(src, SecondScratchReg, NUNBOX32_PAYLOAD_OFFSET);
-}
-
-void
-MacroAssemblerMIPSCompat::storeTypeTag(ImmTag tag, Address dest)
-{
-    ma_li(SecondScratchReg, tag);
-    ma_sw(SecondScratchReg, Address(dest.base, dest.offset + TAG_OFFSET));
-}
-
-void
-MacroAssemblerMIPSCompat::storeTypeTag(ImmTag tag, const BaseIndex& dest)
-{
-    MOZ_ASSERT(dest.offset == 0);
-
-    computeScaledAddress(dest, SecondScratchReg);
-    ma_li(ScratchRegister, tag);
-    as_sw(ScratchRegister, SecondScratchReg, TAG_OFFSET);
-}
-
-void
-MacroAssemblerMIPS::ma_call(ImmPtr dest)
-{
-    ma_liPatchable(CallReg, dest);
+    asMasm().ma_liPatchable(CallReg, dest);
     as_jalr(CallReg);
     as_nop();
 }
 
 void
-MacroAssemblerMIPS::ma_jump(ImmPtr dest)
+MacroAssemblerMIPSShared::ma_jump(ImmPtr dest)
 {
-    ma_liPatchable(ScratchRegister, dest);
+    asMasm().ma_liPatchable(ScratchRegister, dest);
     as_jr(ScratchRegister);
     as_nop();
 }
 
-void
-MacroAssemblerMIPSCompat::breakpoint()
-{
-    as_break(0);
-}
-
-void
-MacroAssemblerMIPSCompat::ensureDouble(const ValueOperand& source, FloatRegister dest,
-                                       Label* failure)
-{
-    Label isDouble, done;
-    branchTestDouble(Assembler::Equal, source.typeReg(), &isDouble);
-    branchTestInt32(Assembler::NotEqual, source.typeReg(), failure);
-
-    convertInt32ToDouble(source.payloadReg(), dest);
-    jump(&done);
-
-    bind(&isDouble);
-    unboxDouble(source, dest);
-
-    bind(&done);
-}
-
-void
-MacroAssemblerMIPSCompat::checkStackAlignment()
-{
-#ifdef DEBUG
-    Label aligned;
-    as_andi(ScratchRegister, sp, ABIStackAlignment - 1);
-    ma_b(ScratchRegister, zero, &aligned, Equal, ShortJump);
-    as_break(BREAK_STACK_UNALIGNED);
-    bind(&aligned);
-#endif
-}
-
-void
-MacroAssemblerMIPSCompat::alignStackPointer()
-{
-    movePtr(StackPointer, SecondScratchReg);
-    subPtr(Imm32(sizeof(uintptr_t)), StackPointer);
-    asMasm().andPtr(Imm32(~(ABIStackAlignment - 1)), StackPointer);
-    storePtr(SecondScratchReg, Address(StackPointer, 0));
-}
-
-void
-MacroAssemblerMIPSCompat::restoreStackPointer()
-{
-    loadPtr(Address(StackPointer, 0), StackPointer);
-}
-
-void
-MacroAssembler::alignFrameForICArguments(AfterICSaveLive& aic)
-{
-    if (framePushed() % ABIStackAlignment != 0) {
-        aic.alignmentPadding = ABIStackAlignment - (framePushed() % ABIStackAlignment);
-        reserveStack(aic.alignmentPadding);
-    } else {
-        aic.alignmentPadding = 0;
-    }
-    MOZ_ASSERT(framePushed() % ABIStackAlignment == 0);
-    checkStackAlignment();
-}
-
-void
-MacroAssembler::restoreFrameAlignmentForICArguments(AfterICSaveLive& aic)
-{
-    if (aic.alignmentPadding != 0)
-        freeStack(aic.alignmentPadding);
-}
-
-void
-MacroAssemblerMIPSCompat::handleFailureWithHandlerTail(void* handler)
-{
-    // Reserve space for exception information.
-    int size = (sizeof(ResumeFromException) + ABIStackAlignment) & ~(ABIStackAlignment - 1);
-    subPtr(Imm32(size), StackPointer);
-    ma_move(a0, StackPointer); // Use a0 since it is a first function argument
-
-    // Call the handler.
-    asMasm().setupUnalignedABICall(a1);
-    asMasm().passABIArg(a0);
-    asMasm().callWithABI(handler);
-
-    Label entryFrame;
-    Label catch_;
-    Label finally;
-    Label return_;
-    Label bailout;
-
-    // Already clobbered a0, so use it...
-    load32(Address(StackPointer, offsetof(ResumeFromException, kind)), a0);
-    branch32(Assembler::Equal, a0, Imm32(ResumeFromException::RESUME_ENTRY_FRAME), &entryFrame);
-    branch32(Assembler::Equal, a0, Imm32(ResumeFromException::RESUME_CATCH), &catch_);
-    branch32(Assembler::Equal, a0, Imm32(ResumeFromException::RESUME_FINALLY), &finally);
-    branch32(Assembler::Equal, a0, Imm32(ResumeFromException::RESUME_FORCED_RETURN), &return_);
-    branch32(Assembler::Equal, a0, Imm32(ResumeFromException::RESUME_BAILOUT), &bailout);
-
-    breakpoint(); // Invalid kind.
-
-    // No exception handler. Load the error value, load the new stack pointer
-    // and return from the entry frame.
-    bind(&entryFrame);
-    moveValue(MagicValue(JS_ION_ERROR), JSReturnOperand);
-    loadPtr(Address(StackPointer, offsetof(ResumeFromException, stackPointer)), StackPointer);
-
-    // We're going to be returning by the ion calling convention
-    ma_pop(ra);
-    as_jr(ra);
-    as_nop();
-
-    // If we found a catch handler, this must be a baseline frame. Restore
-    // state and jump to the catch block.
-    bind(&catch_);
-    loadPtr(Address(StackPointer, offsetof(ResumeFromException, target)), a0);
-    loadPtr(Address(StackPointer, offsetof(ResumeFromException, framePointer)), BaselineFrameReg);
-    loadPtr(Address(StackPointer, offsetof(ResumeFromException, stackPointer)), StackPointer);
-    jump(a0);
-
-    // If we found a finally block, this must be a baseline frame. Push
-    // two values expected by JSOP_RETSUB: BooleanValue(true) and the
-    // exception.
-    bind(&finally);
-    ValueOperand exception = ValueOperand(a1, a2);
-    loadValue(Address(sp, offsetof(ResumeFromException, exception)), exception);
-
-    loadPtr(Address(sp, offsetof(ResumeFromException, target)), a0);
-    loadPtr(Address(sp, offsetof(ResumeFromException, framePointer)), BaselineFrameReg);
-    loadPtr(Address(sp, offsetof(ResumeFromException, stackPointer)), sp);
-
-    pushValue(BooleanValue(true));
-    pushValue(exception);
-    jump(a0);
-
-    // Only used in debug mode. Return BaselineFrame->returnValue() to the
-    // caller.
-    bind(&return_);
-    loadPtr(Address(StackPointer, offsetof(ResumeFromException, framePointer)), BaselineFrameReg);
-    loadPtr(Address(StackPointer, offsetof(ResumeFromException, stackPointer)), StackPointer);
-    loadValue(Address(BaselineFrameReg, BaselineFrame::reverseOffsetOfReturnValue()),
-              JSReturnOperand);
-    ma_move(StackPointer, BaselineFrameReg);
-    pop(BaselineFrameReg);
-
-    // If profiling is enabled, then update the lastProfilingFrame to refer to caller
-    // frame before returning.
-    {
-        Label skipProfilingInstrumentation;
-        // Test if profiler enabled.
-        AbsoluteAddress addressOfEnabled(GetJitContext()->runtime->spsProfiler().addressOfEnabled());
-        branch32(Assembler::Equal, addressOfEnabled, Imm32(0), &skipProfilingInstrumentation);
-        profilerExitFrame();
-        bind(&skipProfilingInstrumentation);
-    }
-
-    ret();
-
-    // If we are bailing out to baseline to handle an exception, jump to
-    // the bailout tail stub.
-    bind(&bailout);
-    loadPtr(Address(sp, offsetof(ResumeFromException, bailoutInfo)), a2);
-    ma_li(ReturnReg, Imm32(BAILOUT_RETURN_OK));
-    loadPtr(Address(sp, offsetof(ResumeFromException, target)), a1);
-    jump(a1);
-}
-
-CodeOffsetLabel
-MacroAssemblerMIPSCompat::toggledJump(Label* label)
-{
-    CodeOffsetLabel ret(nextOffset().getOffset());
-    ma_b(label);
-    return ret;
-}
-
-CodeOffsetLabel
-MacroAssemblerMIPSCompat::toggledCall(JitCode* target, bool enabled)
-{
-    BufferOffset bo = nextOffset();
-    CodeOffsetLabel offset(bo.getOffset());
-    addPendingJump(bo, ImmPtr(target->raw()), Relocation::JITCODE);
-    ma_liPatchable(ScratchRegister, ImmPtr(target->raw()));
-    if (enabled) {
-        as_jalr(ScratchRegister);
-        as_nop();
-    } else {
-        as_nop();
-        as_nop();
-    }
-    MOZ_ASSERT_IF(!oom(), nextOffset().getOffset() - offset.offset() == ToggledCallSize(nullptr));
-    return offset;
-}
-
-void
-MacroAssemblerMIPSCompat::branchPtrInNurseryRange(Condition cond, Register ptr, Register temp,
-                                                  Label* label)
-{
-    MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
-    MOZ_ASSERT(ptr != temp);
-    MOZ_ASSERT(ptr != SecondScratchReg);
-
-    const Nursery& nursery = GetJitContext()->runtime->gcNursery();
-    movePtr(ImmWord(-ptrdiff_t(nursery.start())), SecondScratchReg);
-    addPtr(ptr, SecondScratchReg);
-    branchPtr(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual,
-              SecondScratchReg, Imm32(nursery.nurserySize()), label);
-}
-
-void
-MacroAssemblerMIPSCompat::branchValueIsNurseryObject(Condition cond, ValueOperand value,
-                                                     Register temp, Label* label)
-{
-    MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
-
-    Label done;
-
-    branchTestObject(Assembler::NotEqual, value, cond == Assembler::Equal ? &done : label);
-    branchPtrInNurseryRange(cond, value.payloadReg(), temp, label);
-
-    bind(&done);
-}
-
-void
-MacroAssemblerMIPSCompat::profilerEnterFrame(Register framePtr, Register scratch)
-{
-    AbsoluteAddress activation(GetJitContext()->runtime->addressOfProfilingActivation());
-    loadPtr(activation, scratch);
-    storePtr(framePtr, Address(scratch, JitActivation::offsetOfLastProfilingFrame()));
-    storePtr(ImmPtr(nullptr), Address(scratch, JitActivation::offsetOfLastProfilingCallSite()));
-}
-
-void
-MacroAssemblerMIPSCompat::profilerExitFrame()
-{
-    branch(GetJitContext()->runtime->jitRuntime()->getProfilerExitFrameTail());
-}
-
 MacroAssembler&
-MacroAssemblerMIPS::asMasm()
+MacroAssemblerMIPSShared::asMasm()
 {
     return *static_cast<MacroAssembler*>(this);
 }
 
 const MacroAssembler&
-MacroAssemblerMIPS::asMasm() const
+MacroAssemblerMIPSShared::asMasm() const
 {
     return *static_cast<const MacroAssembler*>(this);
 }
-
-//{{{ check_macroassembler_style
-// ===============================================================
-// Stack manipulation functions.
-
-void
-MacroAssembler::PushRegsInMask(LiveRegisterSet set)
-{
-    int32_t diffF = set.fpus().getPushSizeInBytes();
-    int32_t diffG = set.gprs().size() * sizeof(intptr_t);
-
-    reserveStack(diffG);
-    for (GeneralRegisterBackwardIterator iter(set.gprs()); iter.more(); iter++) {
-        diffG -= sizeof(intptr_t);
-        storePtr(*iter, Address(StackPointer, diffG));
-    }
-    MOZ_ASSERT(diffG == 0);
-
-    // Double values have to be aligned. We reserve extra space so that we can
-    // start writing from the first aligned location.
-    // We reserve a whole extra double so that the buffer has even size.
-    ma_and(SecondScratchReg, sp, Imm32(~(ABIStackAlignment - 1)));
-    reserveStack(diffF + sizeof(double));
-
-    for (FloatRegisterForwardIterator iter(set.fpus().reduceSetForPush()); iter.more(); iter++) {
-        if ((*iter).code() % 2 == 0)
-            as_sd(*iter, SecondScratchReg, -diffF);
-        diffF -= sizeof(double);
-    }
-    MOZ_ASSERT(diffF == 0);
-}
-
-void
-MacroAssembler::PopRegsInMaskIgnore(LiveRegisterSet set, LiveRegisterSet ignore)
-{
-    int32_t diffG = set.gprs().size() * sizeof(intptr_t);
-    int32_t diffF = set.fpus().getPushSizeInBytes();
-    const int32_t reservedG = diffG;
-    const int32_t reservedF = diffF;
-
-    // Read the buffer form the first aligned location.
-    ma_addu(SecondScratchReg, sp, Imm32(reservedF + sizeof(double)));
-    ma_and(SecondScratchReg, SecondScratchReg, Imm32(~(ABIStackAlignment - 1)));
-
-    for (FloatRegisterForwardIterator iter(set.fpus().reduceSetForPush()); iter.more(); iter++) {
-        if (!ignore.has(*iter) && ((*iter).code() % 2 == 0))
-            // Use assembly l.d because we have alligned the stack.
-            as_ld(*iter, SecondScratchReg, -diffF);
-        diffF -= sizeof(double);
-    }
-    freeStack(reservedF + sizeof(double));
-    MOZ_ASSERT(diffF == 0);
-
-    for (GeneralRegisterBackwardIterator iter(set.gprs()); iter.more(); iter++) {
-        diffG -= sizeof(intptr_t);
-        if (!ignore.has(*iter))
-            loadPtr(Address(StackPointer, diffG), *iter);
-    }
-    freeStack(reservedG);
-    MOZ_ASSERT(diffG == 0);
-}
-
-void
-MacroAssembler::Push(Register reg)
-{
-    ma_push(reg);
-    adjustFrame(sizeof(intptr_t));
-}
-
-void
-MacroAssembler::Push(const Imm32 imm)
-{
-    ma_li(ScratchRegister, imm);
-    ma_push(ScratchRegister);
-    adjustFrame(sizeof(intptr_t));
-}
-
-void
-MacroAssembler::Push(const ImmWord imm)
-{
-    ma_li(ScratchRegister, imm);
-    ma_push(ScratchRegister);
-    adjustFrame(sizeof(intptr_t));
-}
-
-void
-MacroAssembler::Push(const ImmPtr imm)
-{
-    Push(ImmWord(uintptr_t(imm.value)));
-}
-
-void
-MacroAssembler::Push(const ImmGCPtr ptr)
-{
-    ma_li(ScratchRegister, ptr);
-    ma_push(ScratchRegister);
-    adjustFrame(sizeof(intptr_t));
-}
-
-void
-MacroAssembler::Push(FloatRegister f)
-{
-    ma_push(f);
-    adjustFrame(sizeof(double));
-}
-
-void
-MacroAssembler::Pop(Register reg)
-{
-    ma_pop(reg);
-    adjustFrame(-sizeof(intptr_t));
-}
-
-void
-MacroAssembler::Pop(const ValueOperand& val)
-{
-    popValue(val);
-    framePushed_ -= sizeof(Value);
-}
-
-void
-MacroAssembler::reserveStack(uint32_t amount)
-{
-    if (amount)
-        subPtr(Imm32(amount), StackPointer);
-    adjustFrame(amount);
-}
-
-// ===============================================================
-// Simple call functions.
-
-void
-MacroAssembler::call(Register reg)
-{
-    as_jalr(reg);
-    as_nop();
-}
-
-void
-MacroAssembler::call(Label* label)
-{
-    ma_bal(label);
-}
-
-void
-MacroAssembler::call(AsmJSImmPtr target)
-{
-    movePtr(target, CallReg);
-    call(CallReg);
-}
-
-void
-MacroAssembler::call(ImmWord target)
-{
-    call(ImmPtr((void*)target.value));
-}
-
-void
-MacroAssembler::call(ImmPtr target)
-{
-    BufferOffset bo = m_buffer.nextOffset();
-    addPendingJump(bo, target, Relocation::HARDCODED);
-    ma_call(target);
-}
-
-void
-MacroAssembler::call(JitCode* c)
-{
-    BufferOffset bo = m_buffer.nextOffset();
-    addPendingJump(bo, ImmPtr(c->raw()), Relocation::JITCODE);
-    ma_liPatchable(ScratchRegister, ImmPtr(c->raw()));
-    callJitNoProfiler(ScratchRegister);
-}
-
-void
-MacroAssembler::callAndPushReturnAddress(Register callee)
-{
-    // Push return address during jalr delay slot.
-    subPtr(Imm32(sizeof(intptr_t)), StackPointer);
-    as_jalr(callee);
-    storePtr(ra, Address(StackPointer, 0));
-}
-
-void
-MacroAssembler::callAndPushReturnAddress(Label* label)
-{
-    // Push return address during bal delay slot.
-    subPtr(Imm32(sizeof(intptr_t)), StackPointer);
-    ma_bal(label, DontFillDelaySlot);
-    storePtr(ra, Address(StackPointer, 0));
-}
-
-// ===============================================================
-// ABI function calls.
-
-void
-MacroAssembler::setupUnalignedABICall(Register scratch)
-{
-    setupABICall();
-    dynamicAlignment_ = true;
-
-    ma_move(scratch, StackPointer);
-
-    // Force sp to be aligned
-    subPtr(Imm32(sizeof(uintptr_t)), StackPointer);
-    ma_and(StackPointer, StackPointer, Imm32(~(ABIStackAlignment - 1)));
-    storePtr(scratch, Address(StackPointer, 0));
-}
-
-void
-MacroAssembler::callWithABIPre(uint32_t* stackAdjust, bool callFromAsmJS)
-{
-    MOZ_ASSERT(inCall_);
-    uint32_t stackForCall = abiArgs_.stackBytesConsumedSoFar();
-
-    // Reserve place for $ra.
-    stackForCall += sizeof(intptr_t);
-
-    if (dynamicAlignment_) {
-        stackForCall += ComputeByteAlignment(stackForCall, ABIStackAlignment);
-    } else {
-        uint32_t alignmentAtPrologue = callFromAsmJS ? sizeof(AsmJSFrame) : 0;
-        stackForCall += ComputeByteAlignment(stackForCall + framePushed() + alignmentAtPrologue,
-                                             ABIStackAlignment);
-    }
-
-    *stackAdjust = stackForCall;
-    reserveStack(stackForCall);
-
-    // Save $ra because call is going to clobber it. Restore it in
-    // callWithABIPost. NOTE: This is needed for calls from SharedIC.
-    // Maybe we can do this differently.
-    storePtr(ra, Address(StackPointer, stackForCall - sizeof(intptr_t)));
-
-    // Position all arguments.
-    {
-        enoughMemory_ = enoughMemory_ && moveResolver_.resolve();
-        if (!enoughMemory_)
-            return;
-
-        MoveEmitter emitter(*this);
-        emitter.emit(moveResolver_);
-        emitter.finish();
-    }
-
-    assertStackAlignment(ABIStackAlignment);
-}
-
-void
-MacroAssembler::callWithABIPost(uint32_t stackAdjust, MoveOp::Type result)
-{
-    // Restore ra value (as stored in callWithABIPre()).
-    loadPtr(Address(StackPointer, stackAdjust - sizeof(intptr_t)), ra);
-
-    if (dynamicAlignment_) {
-        // Restore sp value from stack (as stored in setupUnalignedABICall()).
-        loadPtr(Address(StackPointer, stackAdjust), StackPointer);
-        // Use adjustFrame instead of freeStack because we already restored sp.
-        adjustFrame(-stackAdjust);
-    } else {
-        freeStack(stackAdjust);
-    }
-
-#ifdef DEBUG
-    MOZ_ASSERT(inCall_);
-    inCall_ = false;
-#endif
-}
-
-void
-MacroAssembler::callWithABINoProfiler(Register fun, MoveOp::Type result)
-{
-    // Load the callee in t9, no instruction between the lw and call
-    // should clobber it. Note that we can't use fun.base because it may
-    // be one of the IntArg registers clobbered before the call.
-    ma_move(t9, fun);
-    uint32_t stackAdjust;
-    callWithABIPre(&stackAdjust);
-    call(t9);
-    callWithABIPost(stackAdjust, result);
-}
-
-void
-MacroAssembler::callWithABINoProfiler(const Address& fun, MoveOp::Type result)
-{
-    // Load the callee in t9, as above.
-    loadPtr(Address(fun.base, fun.offset), t9);
-    uint32_t stackAdjust;
-    callWithABIPre(&stackAdjust);
-    call(t9);
-    callWithABIPost(stackAdjust, result);
-}
-
-// ===============================================================
-// Jit Frames.
-
-uint32_t
-MacroAssembler::pushFakeReturnAddress(Register scratch)
-{
-    CodeLabel cl;
-
-    ma_li(scratch, cl.dest());
-    Push(scratch);
-    bind(cl.src());
-    uint32_t retAddr = currentOffset();
-
-    addCodeLabel(cl);
-    return retAddr;
-}
-
-//}}} check_macroassembler_style
copy from js/src/jit/mips32/MacroAssembler-mips32.h
copy to js/src/jit/mips-shared/MacroAssembler-mips-shared.h
--- a/js/src/jit/mips32/MacroAssembler-mips32.h
+++ b/js/src/jit/mips-shared/MacroAssembler-mips-shared.h
@@ -1,24 +1,20 @@
 /* -*- 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_MacroAssembler_mips32_h
-#define jit_mips32_MacroAssembler_mips32_h
-
-#include "jsopcode.h"
+#ifndef jit_mips_shared_MacroAssembler_mips_shared_h
+#define jit_mips_shared_MacroAssembler_mips_shared_h
 
-#include "jit/AtomicOp.h"
-#include "jit/IonCaches.h"
-#include "jit/JitFrames.h"
-#include "jit/mips32/Assembler-mips32.h"
-#include "jit/MoveResolver.h"
+#if defined(JS_CODEGEN_MIPS32)
+# include "jit/mips32/Assembler-mips32.h"
+#endif
 
 namespace js {
 namespace jit {
 
 enum LoadStoreSize
 {
     SizeByte = 8,
     SizeHalfWord = 16,
@@ -39,67 +35,37 @@ enum JumpKind
 };
 
 enum DelaySlotFill
 {
     DontFillDelaySlot = 0,
     FillDelaySlot = 1
 };
 
-struct ImmTag : public Imm32
-{
-    ImmTag(JSValueTag mask)
-      : Imm32(int32_t(mask))
-    { }
-};
+static Register CallReg = t9;
 
-struct ImmType : public ImmTag
-{
-    ImmType(JSValueType type)
-      : ImmTag(JSVAL_TYPE_TO_TAG(type))
-    { }
-};
-
-static const ValueOperand JSReturnOperand = ValueOperand(JSReturnReg_Type, JSReturnReg_Data);
-static const ValueOperand softfpReturnOperand = ValueOperand(v1, v0);
-
-static Register CallReg = t9;
-static const int defaultShift = 3;
-static_assert(1 << defaultShift == sizeof(JS::Value), "The defaultShift is wrong");
-
-static const uint32_t LOW_32_MASK = (1LL << 32) - 1;
-static const int32_t LOW_32_OFFSET = 0;
-static const int32_t HIGH_32_OFFSET = 4;
-
-class MacroAssemblerMIPS : public Assembler
+class MacroAssemblerMIPSShared : public Assembler
 {
   protected:
     // Perform a downcast. Should be removed by Bug 996602.
     MacroAssembler& asMasm();
     const MacroAssembler& asMasm() const;
 
-    void branchWithCode(InstImm code, Label* label, JumpKind jumpKind);
     Condition ma_cmp(Register rd, Register lhs, Register rhs, Condition c);
 
     void compareFloatingPoint(FloatFormat fmt, FloatRegister lhs, FloatRegister rhs,
                               DoubleCondition c, FloatTestKind* testKind,
                               FPConditionBit fcc = FCC0);
 
   public:
     void ma_move(Register rd, Register rs);
 
     void ma_li(Register dest, ImmGCPtr ptr);
 
-    void ma_li(Register dest, AbsoluteLabel* label);
-
     void ma_li(Register dest, Imm32 imm);
-    void ma_liPatchable(Register dest, Imm32 imm);
-    void ma_li(Register dest, ImmWord imm);
-    void ma_liPatchable(Register dest, ImmPtr imm);
-    void ma_liPatchable(Register dest, ImmWord imm);
 
     // Shift operations
     void ma_sll(Register rd, Register rt, Imm32 shift);
     void ma_srl(Register rd, Register rt, Imm32 shift);
     void ma_sra(Register rd, Register rt, Imm32 shift);
     void ma_ror(Register rd, Register rt, Imm32 shift);
     void ma_rol(Register rd, Register rt, Imm32 shift);
 
@@ -125,1281 +91,95 @@ class MacroAssemblerMIPS : public Assemb
     void ma_or(Register rd, Register rs, Imm32 imm);
 
     // xor
     void ma_xor(Register rd, Register rs);
     void ma_xor(Register rd, Imm32 imm);
     void ma_xor(Register rd, Register rs, Imm32 imm);
 
     // load
-    void ma_load(Register dest, Address address, LoadStoreSize size = SizeWord,
-                 LoadStoreExtension extension = SignExtend);
     void ma_load(Register dest, const BaseIndex& src, LoadStoreSize size = SizeWord,
                  LoadStoreExtension extension = SignExtend);
 
     // store
-    void ma_store(Register data, Address address, LoadStoreSize size = SizeWord,
-                  LoadStoreExtension extension = SignExtend);
     void ma_store(Register data, const BaseIndex& dest, LoadStoreSize size = SizeWord,
                   LoadStoreExtension extension = SignExtend);
     void ma_store(Imm32 imm, const BaseIndex& dest, LoadStoreSize size = SizeWord,
                   LoadStoreExtension extension = SignExtend);
 
     // arithmetic based ops
     // add
     void ma_addu(Register rd, Register rs, Imm32 imm);
     void ma_addu(Register rd, Register rs);
     void ma_addu(Register rd, Imm32 imm);
-    void ma_addTestOverflow(Register rd, Register rs, Register rt, Label* overflow);
-    void ma_addTestOverflow(Register rd, Register rs, Imm32 imm, Label* overflow);
 
     // subtract
     void ma_subu(Register rd, Register rs, Imm32 imm);
     void ma_subu(Register rd, Imm32 imm);
-    void ma_subTestOverflow(Register rd, Register rs, Register rt, Label* overflow);
     void ma_subTestOverflow(Register rd, Register rs, Imm32 imm, Label* overflow);
 
     // multiplies.  For now, there are only few that we care about.
     void ma_mult(Register rs, Imm32 imm);
     void ma_mul_branch_overflow(Register rd, Register rs, Register rt, Label* overflow);
     void ma_mul_branch_overflow(Register rd, Register rs, Imm32 imm, Label* overflow);
 
     // divisions
     void ma_div_branch_overflow(Register rd, Register rs, Register rt, Label* overflow);
     void ma_div_branch_overflow(Register rd, Register rs, Imm32 imm, Label* overflow);
 
     // fast mod, uses scratch registers, and thus needs to be in the assembler
     // implicitly assumes that we can overwrite dest at the beginning of the sequence
     void ma_mod_mask(Register src, Register dest, Register hold, Register remain,
                      int32_t shift, Label* negZero = nullptr);
 
-    // memory
-    // shortcut for when we know we're transferring 32 bits of data
-    void ma_lw(Register data, Address address);
-
-    void ma_sw(Register data, Address address);
-    void ma_sw(Imm32 imm, Address address);
-    void ma_sw(Register data, BaseIndex& address);
-
-    void ma_pop(Register r);
-    void ma_push(Register r);
-
     // branches when done from within mips-specific code
     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) {
-        ma_b(lhs, ImmWord(uintptr_t(imm.value)), l, c, jumpKind);
-    }
+    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);
     }
-    void ma_b(Register lhs, ImmWord imm, Label* l, Condition c, JumpKind jumpKind = LongJump)
-    {
-        ma_b(lhs, Imm32(uint32_t(imm.value)), l, c, jumpKind);
-    }
-    void ma_b(Address addr, ImmWord imm, Label* l, Condition c, JumpKind jumpKind = LongJump)
-    {
-        ma_b(addr, Imm32(uint32_t(imm.value)), l, c, jumpKind);
-    }
-
-    void ma_b(Register lhs, Address addr, Label* l, Condition c, JumpKind jumpKind = LongJump);
-    void ma_b(Address addr, Imm32 imm, Label* l, Condition c, JumpKind jumpKind = LongJump);
-    void ma_b(Address addr, ImmGCPtr imm, Label* l, Condition c, JumpKind jumpKind = LongJump);
-    void ma_b(Address addr, Register rhs, Label* l, Condition c, JumpKind jumpKind = LongJump) {
-        MOZ_ASSERT(rhs != ScratchRegister);
-        ma_load(ScratchRegister, addr, SizeWord);
-        ma_b(ScratchRegister, rhs, l, c, jumpKind);
-    }
 
     void ma_b(Label* l, JumpKind jumpKind = LongJump);
-    void ma_bal(Label* l, DelaySlotFill delaySlotFill = FillDelaySlot);
 
     // fp instructions
     void ma_lis(FloatRegister dest, float value);
-    void ma_lid(FloatRegister dest, double value);
     void ma_liNegZero(FloatRegister dest);
 
-    void ma_mv(FloatRegister src, ValueOperand dest);
-    void ma_mv(ValueOperand src, FloatRegister dest);
-
-    void ma_ls(FloatRegister fd, Address address);
-    void ma_ld(FloatRegister fd, Address address);
-    void ma_sd(FloatRegister fd, Address address);
     void ma_sd(FloatRegister fd, BaseIndex address);
-    void ma_ss(FloatRegister fd, Address address);
     void ma_ss(FloatRegister fd, BaseIndex address);
 
-    void ma_pop(FloatRegister fs);
-    void ma_push(FloatRegister fs);
-
     //FP branches
     void ma_bc1s(FloatRegister lhs, FloatRegister rhs, Label* label, DoubleCondition c,
                  JumpKind jumpKind = LongJump, FPConditionBit fcc = FCC0);
     void ma_bc1d(FloatRegister lhs, FloatRegister rhs, Label* label, DoubleCondition c,
                  JumpKind jumpKind = LongJump, FPConditionBit fcc = FCC0);
 
     void ma_call(ImmPtr dest);
 
     void ma_jump(ImmPtr dest);
 
     void ma_cmp_set(Register dst, Register lhs, Register rhs, Condition c);
     void ma_cmp_set(Register dst, Register lhs, Imm32 imm, Condition c);
-    void ma_cmp_set(Register dst, Register lhs, ImmPtr imm, Condition c) {
-        ma_cmp_set(dst, lhs, Imm32(uint32_t(imm.value)), c);
-    }
-    void ma_cmp_set(Register rd, Register rs, Address addr, Condition c);
-    void ma_cmp_set(Register dst, Address lhs, Register rhs, Condition c);
-    void ma_cmp_set(Register dst, Address lhs, ImmPtr imm, Condition c) {
-        ma_lw(ScratchRegister, lhs);
-        ma_li(SecondScratchReg, Imm32(uint32_t(imm.value)));
-        ma_cmp_set(dst, ScratchRegister, SecondScratchReg, c);
-    }
     void ma_cmp_set_double(Register dst, FloatRegister lhs, FloatRegister rhs, DoubleCondition c);
     void ma_cmp_set_float32(Register dst, FloatRegister lhs, FloatRegister rhs, DoubleCondition c);
 
-    // These fuctions abstract the access to high part of the double precision
-    // float register. It is intended to work on both 32 bit and 64 bit
-    // floating point coprocessor.
-    // :TODO: (Bug 985881) Modify this for N32 ABI to use mthc1 and mfhc1
-    void moveToDoubleHi(Register src, FloatRegister dest) {
-        as_mtc1(src, getOddPair(dest));
-    }
-    void moveFromDoubleHi(FloatRegister src, Register dest) {
-        as_mfc1(dest, getOddPair(src));
-    }
-
     void moveToDoubleLo(Register src, FloatRegister dest) {
         as_mtc1(src, dest);
     }
     void moveFromDoubleLo(FloatRegister src, Register dest) {
         as_mfc1(dest, src);
     }
 
     void moveToFloat32(Register src, FloatRegister dest) {
         as_mtc1(src, dest);
     }
     void moveFromFloat32(FloatRegister src, Register dest) {
         as_mfc1(dest, src);
     }
 };
 
-class MacroAssembler;
-
-class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS
-{
-  public:
-    using MacroAssemblerMIPS::call;
-
-    MacroAssemblerMIPSCompat()
-    { }
-
-    void convertBoolToInt32(Register source, Register dest);
-    void convertInt32ToDouble(Register src, FloatRegister dest);
-    void convertInt32ToDouble(const Address& src, FloatRegister dest);
-    void convertInt32ToDouble(const BaseIndex& src, FloatRegister dest);
-    void convertUInt32ToDouble(Register src, FloatRegister dest);
-    void convertUInt32ToFloat32(Register src, FloatRegister dest);
-    void convertDoubleToFloat32(FloatRegister src, FloatRegister dest);
-    void branchTruncateDouble(FloatRegister src, Register dest, Label* fail);
-    void convertDoubleToInt32(FloatRegister src, Register dest, Label* fail,
-                              bool negativeZeroCheck = true);
-    void convertFloat32ToInt32(FloatRegister src, Register dest, Label* fail,
-                               bool negativeZeroCheck = true);
-
-    void convertFloat32ToDouble(FloatRegister src, FloatRegister dest);
-    void branchTruncateFloat32(FloatRegister src, Register dest, Label* fail);
-    void convertInt32ToFloat32(Register src, FloatRegister dest);
-    void convertInt32ToFloat32(const Address& src, FloatRegister dest);
-
-    void addDouble(FloatRegister src, FloatRegister dest);
-    void subDouble(FloatRegister src, FloatRegister dest);
-    void mulDouble(FloatRegister src, FloatRegister dest);
-    void divDouble(FloatRegister src, FloatRegister dest);
-
-    void negateDouble(FloatRegister reg);
-    void inc64(AbsoluteAddress dest);
-
-    void computeScaledAddress(const BaseIndex& address, Register dest);
-
-    void computeEffectiveAddress(const Address& address, Register dest) {
-        ma_addu(dest, address.base, Imm32(address.offset));
-    }
-
-    void computeEffectiveAddress(const BaseIndex& address, Register dest) {
-        computeScaledAddress(address, dest);
-        if (address.offset) {
-            addPtr(Imm32(address.offset), dest);
-        }
-    }
-
-    void j(Label* dest) {
-        ma_b(dest);
-    }
-
-    void mov(Register src, Register dest) {
-        as_ori(dest, src, 0);
-    }
-    void mov(ImmWord imm, Register dest) {
-        ma_li(dest, imm);
-    }
-    void mov(ImmPtr imm, Register dest) {
-        mov(ImmWord(uintptr_t(imm.value)), dest);
-    }
-    void mov(Register src, Address dest) {
-        MOZ_CRASH("NYI-IC");
-    }
-    void mov(Address src, Register dest) {
-        MOZ_CRASH("NYI-IC");
-    }
-
-    void branch(JitCode* c) {
-        BufferOffset bo = m_buffer.nextOffset();
-        addPendingJump(bo, ImmPtr(c->raw()), Relocation::JITCODE);
-        ma_liPatchable(ScratchRegister, ImmPtr(c->raw()));
-        as_jr(ScratchRegister);
-        as_nop();
-    }
-    void branch(const Register reg) {
-        as_jr(reg);
-        as_nop();
-    }
-    void nop() {
-        as_nop();
-    }
-    void ret() {
-        ma_pop(ra);
-        as_jr(ra);
-        as_nop();
-    }
-    void retn(Imm32 n) {
-        // pc <- [sp]; sp += n
-        loadPtr(Address(StackPointer, 0), ra);
-        addPtr(n, StackPointer);
-        as_jr(ra);
-        as_nop();
-    }
-    void push(Imm32 imm) {
-        ma_li(ScratchRegister, imm);
-        ma_push(ScratchRegister);
-    }
-    void push(ImmWord imm) {
-        ma_li(ScratchRegister, imm);
-        ma_push(ScratchRegister);
-    }
-    void push(ImmGCPtr imm) {
-        ma_li(ScratchRegister, imm);
-        ma_push(ScratchRegister);
-    }
-    void push(const Address& address) {
-        loadPtr(address, ScratchRegister);
-        ma_push(ScratchRegister);
-    }
-    void push(Register reg) {
-        ma_push(reg);
-    }
-    void push(FloatRegister reg) {
-        ma_push(reg);
-    }
-    void pop(Register reg) {
-        ma_pop(reg);
-    }
-    void pop(FloatRegister reg) {
-        ma_pop(reg);
-    }
-
-    // Emit a branch that can be toggled to a non-operation. On MIPS we use
-    // "andi" instruction to toggle the branch.
-    // See ToggleToJmp(), ToggleToCmp().
-    CodeOffsetLabel toggledJump(Label* label);
-
-    // Emit a "jalr" or "nop" instruction. ToggleCall can be used to patch
-    // this instruction.
-    CodeOffsetLabel toggledCall(JitCode* target, bool enabled);
-
-    static size_t ToggledCallSize(uint8_t* code) {
-        // Four instructions used in: MacroAssemblerMIPSCompat::toggledCall
-        return 4 * sizeof(uint32_t);
-    }
-
-    CodeOffsetLabel pushWithPatch(ImmWord imm) {
-        CodeOffsetLabel label = movWithPatch(imm, ScratchRegister);
-        ma_push(ScratchRegister);
-        return label;
-    }
-
-    CodeOffsetLabel movWithPatch(ImmWord imm, Register dest) {
-        CodeOffsetLabel label = CodeOffsetLabel(currentOffset());
-        ma_liPatchable(dest, imm);
-        return label;
-    }
-    CodeOffsetLabel movWithPatch(ImmPtr imm, Register dest) {
-        return movWithPatch(ImmWord(uintptr_t(imm.value)), dest);
-    }
-
-    void jump(Label* label) {
-        ma_b(label);
-    }
-    void jump(Register reg) {
-        as_jr(reg);
-        as_nop();
-    }
-    void jump(const Address& address) {
-        loadPtr(address, ScratchRegister);
-        as_jr(ScratchRegister);
-        as_nop();
-    }
-
-    void jump(JitCode* code) {
-        branch(code);
-    }
-
-    void neg32(Register reg) {
-        ma_negu(reg, reg);
-    }
-    void negl(Register reg) {
-        ma_negu(reg, reg);
-    }
-
-    // Returns the register containing the type tag.
-    Register splitTagForTest(const ValueOperand& value) {
-        return value.typeReg();
-    }
-
-    void branchTestGCThing(Condition cond, const Address& address, Label* label);
-    void branchTestGCThing(Condition cond, const BaseIndex& src, Label* label);
-
-    void branchTestPrimitive(Condition cond, const ValueOperand& value, Label* label);
-    void branchTestPrimitive(Condition cond, Register tag, Label* label);
-
-    void branchTestValue(Condition cond, const ValueOperand& value, const Value& v, Label* label);
-    void branchTestValue(Condition cond, const Address& valaddr, const ValueOperand& value,
-                         Label* label);
-
-    // unboxing code
-    void unboxNonDouble(const ValueOperand& operand, Register dest);
-    void unboxNonDouble(const Address& src, Register dest);
-    void unboxNonDouble(const BaseIndex& src, Register dest);
-    void unboxInt32(const ValueOperand& operand, Register dest);
-    void unboxInt32(const Address& src, Register dest);
-    void unboxBoolean(const ValueOperand& operand, Register dest);
-    void unboxBoolean(const Address& src, Register dest);
-    void unboxDouble(const ValueOperand& operand, FloatRegister dest);
-    void unboxDouble(const Address& src, FloatRegister dest);
-    void unboxString(const ValueOperand& operand, Register dest);
-    void unboxString(const Address& src, Register dest);
-    void unboxObject(const ValueOperand& src, Register dest);
-    void unboxObject(const Address& src, Register dest);
-    void unboxObject(const BaseIndex& src, Register dest) { unboxNonDouble(src, dest); }
-    void unboxValue(const ValueOperand& src, AnyRegister dest);
-    void unboxPrivate(const ValueOperand& src, Register dest);
-
-    void notBoolean(const ValueOperand& val) {
-        as_xori(val.payloadReg(), val.payloadReg(), 1);
-    }
-
-    // boxing code
-    void boxDouble(FloatRegister src, const ValueOperand& dest);
-    void boxNonDouble(JSValueType type, Register src, const ValueOperand& dest);
-
-    // Extended unboxing API. If the payload is already in a register, returns
-    // that register. Otherwise, provides a move to the given scratch register,
-    // and returns that.
-    Register extractObject(const Address& address, Register scratch);
-    Register extractObject(const ValueOperand& value, Register scratch) {
-        return value.payloadReg();
-    }
-    Register extractInt32(const ValueOperand& value, Register scratch) {
-        return value.payloadReg();
-    }
-    Register extractBoolean(const ValueOperand& value, Register scratch) {
-        return value.payloadReg();
-    }
-    Register extractTag(const Address& address, Register scratch);
-    Register extractTag(const BaseIndex& address, Register scratch);
-    Register extractTag(const ValueOperand& value, Register scratch) {
-        return value.typeReg();
-    }
-
-    void boolValueToDouble(const ValueOperand& operand, FloatRegister dest);
-    void int32ValueToDouble(const ValueOperand& operand, FloatRegister dest);
-    void loadInt32OrDouble(const Address& address, FloatRegister dest);
-    void loadInt32OrDouble(Register base, Register index,
-                           FloatRegister dest, int32_t shift = defaultShift);
-    void loadConstantDouble(double dp, FloatRegister dest);
-
-    void boolValueToFloat32(const ValueOperand& operand, FloatRegister dest);
-    void int32ValueToFloat32(const ValueOperand& operand, FloatRegister dest);
-    void loadConstantFloat32(float f, FloatRegister dest);
-
-    void branchTestInt32(Condition cond, const ValueOperand& value, Label* label);
-    void branchTestInt32(Condition cond, Register tag, Label* label);
-    void branchTestInt32(Condition cond, const Address& address, Label* label);
-    void branchTestInt32(Condition cond, const BaseIndex& src, Label* label);
-
-    void branchTestBoolean(Condition cond, const ValueOperand& value, Label* label);
-    void branchTestBoolean(Condition cond, Register tag, Label* label);
-    void branchTestBoolean(Condition cond, const BaseIndex& src, Label* label);
-
-    void branch32(Condition cond, Register lhs, Register rhs, Label* label) {
-        ma_b(lhs, rhs, label, cond);
-    }
-    void branch32(Condition cond, Register lhs, Imm32 imm, Label* label) {
-        ma_b(lhs, imm, label, cond);
-    }
-    void branch32(Condition cond, const Operand& lhs, Register rhs, Label* label) {
-        if (lhs.getTag() == Operand::REG) {
-            ma_b(lhs.toReg(), rhs, label, cond);
-        } else {
-            branch32(cond, lhs.toAddress(), rhs, label);
-        }
-    }
-    void branch32(Condition cond, const Operand& lhs, Imm32 rhs, Label* label) {
-        if (lhs.getTag() == Operand::REG) {
-            ma_b(lhs.toReg(), rhs, label, cond);
-        } else {
-            branch32(cond, lhs.toAddress(), rhs, label);
-        }
-    }
-    void branch32(Condition cond, const Address& lhs, Register rhs, Label* label) {
-        load32(lhs, SecondScratchReg);
-        ma_b(SecondScratchReg, rhs, label, cond);
-    }
-    void branch32(Condition cond, const Address& lhs, Imm32 rhs, Label* label) {
-        load32(lhs, SecondScratchReg);
-        ma_b(SecondScratchReg, rhs, label, cond);
-    }
-    void branch32(Condition cond, const BaseIndex& lhs, Imm32 rhs, Label* label) {
-        load32(lhs, SecondScratchReg);
-        ma_b(SecondScratchReg, rhs, label, cond);
-    }
-    void branchPtr(Condition cond, const Address& lhs, Register rhs, Label* label) {
-        loadPtr(lhs, SecondScratchReg);
-        ma_b(SecondScratchReg, rhs, label, cond);
-    }
-
-    void branchPrivatePtr(Condition cond, const Address& lhs, ImmPtr ptr, Label* label) {
-        branchPtr(cond, lhs, ptr, label);
-    }
-
-    void branchPrivatePtr(Condition cond, const Address& lhs, Register ptr, Label* label) {
-        branchPtr(cond, lhs, ptr, label);
-    }
-
-    void branchPrivatePtr(Condition cond, Register lhs, ImmWord ptr, Label* label) {
-        branchPtr(cond, lhs, ptr, label);
-    }
-
-    void branchTestDouble(Condition cond, const ValueOperand& value, Label* label);
-    void branchTestDouble(Condition cond, Register tag, Label* label);
-    void branchTestDouble(Condition cond, const Address& address, Label* label);
-    void branchTestDouble(Condition cond, const BaseIndex& src, Label* label);
-
-    void branchTestNull(Condition cond, const ValueOperand& value, Label* label);
-    void branchTestNull(Condition cond, Register tag, Label* label);
-    void branchTestNull(Condition cond, const BaseIndex& src, Label* label);
-    void branchTestNull(Condition cond, const Address& address, Label* label);
-    void testNullSet(Condition cond, const ValueOperand& value, Register dest);
-
-    void branchTestObject(Condition cond, const ValueOperand& value, Label* label);
-    void branchTestObject(Condition cond, Register tag, Label* label);
-    void branchTestObject(Condition cond, const BaseIndex& src, Label* label);
-    void branchTestObject(Condition cond, const Address& src, Label* label);
-    void testObjectSet(Condition cond, const ValueOperand& value, Register dest);
-
-    void branchTestString(Condition cond, const ValueOperand& value, Label* label);
-    void branchTestString(Condition cond, Register tag, Label* label);
-    void branchTestString(Condition cond, const BaseIndex& src, Label* label);
-
-    void branchTestSymbol(Condition cond, const ValueOperand& value, Label* label);
-    void branchTestSymbol(Condition cond, const Register& tag, Label* label);
-    void branchTestSymbol(Condition cond, const BaseIndex& src, Label* label);
-
-    void branchTestUndefined(Condition cond, const ValueOperand& value, Label* label);
-    void branchTestUndefined(Condition cond, Register tag, Label* label);
-    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, 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);
-    }
-
-    void branchTestInt32Truthy(bool b, const ValueOperand& value, Label* label);
-
-    void branchTestStringTruthy(bool b, const ValueOperand& value, Label* label);
-
-    void branchTestDoubleTruthy(bool b, FloatRegister value, Label* label);
-
-    void branchTestBooleanTruthy(bool b, const ValueOperand& operand, Label* label);
-
-    void branchTest32(Condition cond, Register lhs, Register rhs, Label* label) {
-        MOZ_ASSERT(cond == Zero || cond == NonZero || cond == Signed || cond == NotSigned);
-        if (lhs == rhs) {
-            ma_b(lhs, rhs, label, cond);
-        } else {
-            as_and(ScratchRegister, lhs, rhs);
-            ma_b(ScratchRegister, ScratchRegister, label, cond);
-        }
-    }
-    void branchTest32(Condition cond, Register lhs, Imm32 imm, Label* label) {
-        ma_li(ScratchRegister, imm);
-        branchTest32(cond, lhs, ScratchRegister, label);
-    }
-    void branchTest32(Condition cond, const Address& address, Imm32 imm, Label* label) {
-        load32(address, SecondScratchReg);
-        branchTest32(cond, SecondScratchReg, imm, label);
-    }
-    void branchTest32(Condition cond, AbsoluteAddress address, Imm32 imm, Label* label) {
-        load32(address, ScratchRegister);
-        branchTest32(cond, ScratchRegister, imm, label);
-    }
-    void branchTestPtr(Condition cond, Register lhs, Register rhs, Label* label) {
-        MOZ_ASSERT(cond == Zero || cond == NonZero || cond == Signed || cond == NotSigned);
-        if (lhs == rhs) {
-            ma_b(lhs, rhs, label, cond);
-        } else {
-            as_and(ScratchRegister, lhs, rhs);
-            ma_b(ScratchRegister, ScratchRegister, label, cond);
-        }
-    }
-    void branchTestPtr(Condition cond, Register lhs, const Imm32 rhs, Label* label) {
-        ma_li(ScratchRegister, rhs);
-        branchTestPtr(cond, lhs, ScratchRegister, label);
-    }
-    void branchTestPtr(Condition cond, const Address& lhs, Imm32 imm, Label* label) {
-        loadPtr(lhs, SecondScratchReg);
-        branchTestPtr(cond, SecondScratchReg, imm, label);
-    }
-    void branchTest64(Condition cond, Register64 lhs, Register64 rhs, Register temp,
-                      Label* label);
-    void branchPtr(Condition cond, Register lhs, Register rhs, Label* label) {
-        ma_b(lhs, rhs, label, cond);
-    }
-    void branchPtr(Condition cond, Register lhs, ImmGCPtr ptr, Label* label) {
-        ma_b(lhs, ptr, label, cond);
-    }
-    void branchPtr(Condition cond, Register lhs, ImmWord imm, Label* label) {
-        ma_b(lhs, imm, label, cond);
-    }
-    void branchPtr(Condition cond, Register lhs, ImmPtr imm, Label* label) {
-        ma_b(lhs, imm, label, cond);
-    }
-    void branchPtr(Condition cond, Register lhs, AsmJSImmPtr imm, Label* label) {
-        movePtr(imm, SecondScratchReg);
-        ma_b(lhs, SecondScratchReg, label, cond);
-    }
-    void branchPtr(Condition cond, Register lhs, Imm32 imm, Label* label) {
-        ma_b(lhs, imm, label, cond);
-    }
-    void decBranchPtr(Condition cond, Register lhs, Imm32 imm, Label* label) {
-        subPtr(imm, lhs);
-        branchPtr(cond, lhs, Imm32(0), label);
-    }
-
-    // higher level tag testing code
-    Operand ToPayload(Operand base);
-    Address ToPayload(Address base) {
-        return ToPayload(Operand(base)).toAddress();
-    }
-
-  protected:
-    Operand ToType(Operand base);
-    Address ToType(Address base) {
-        return ToType(Operand(base)).toAddress();
-    }
-
-    uint32_t getType(const Value& val);
-    void moveData(const Value& val, Register data);
-  public:
-    void moveValue(const Value& val, Register type, Register data);
-
-    CodeOffsetJump backedgeJump(RepatchLabel* label, Label* documentation = nullptr);
-    CodeOffsetJump jumpWithPatch(RepatchLabel* label, Label* documentation = nullptr);
-
-    template <typename T>
-    CodeOffsetJump branchPtrWithPatch(Condition cond, Register reg, T ptr, RepatchLabel* label) {
-        movePtr(ptr, ScratchRegister);
-        Label skipJump;
-        ma_b(reg, ScratchRegister, &skipJump, InvertCondition(cond), ShortJump);
-        CodeOffsetJump off = jumpWithPatch(label);
-        bind(&skipJump);
-        return off;
-    }
-
-    template <typename T>
-    CodeOffsetJump branchPtrWithPatch(Condition cond, Address addr, T ptr, RepatchLabel* label) {
-        loadPtr(addr, SecondScratchReg);
-        movePtr(ptr, ScratchRegister);
-        Label skipJump;
-        ma_b(SecondScratchReg, ScratchRegister, &skipJump, InvertCondition(cond), ShortJump);
-        CodeOffsetJump off = jumpWithPatch(label);
-        bind(&skipJump);
-        return off;
-    }
-    void branchPtr(Condition cond, Address addr, ImmGCPtr ptr, Label* label) {
-        loadPtr(addr, SecondScratchReg);
-        ma_b(SecondScratchReg, ptr, label, cond);
-    }
-
-    void branchPtr(Condition cond, Address addr, ImmWord ptr, Label* label) {
-        loadPtr(addr, SecondScratchReg);
-        ma_b(SecondScratchReg, ptr, label, cond);
-    }
-    void branchPtr(Condition cond, Address addr, ImmPtr ptr, Label* label) {
-        loadPtr(addr, SecondScratchReg);
-        ma_b(SecondScratchReg, ptr, label, cond);
-    }
-    void branchPtr(Condition cond, AbsoluteAddress addr, Register ptr, Label* label) {
-        loadPtr(addr, SecondScratchReg);
-        ma_b(SecondScratchReg, ptr, label, cond);
-    }
-    void branchPtr(Condition cond, AbsoluteAddress addr, ImmWord ptr, Label* label) {
-        loadPtr(addr, SecondScratchReg);
-        ma_b(SecondScratchReg, ptr, label, cond);
-    }
-    void branchPtr(Condition cond, AsmJSAbsoluteAddress addr, Register ptr, Label* label) {
-        loadPtr(addr, SecondScratchReg);
-        ma_b(SecondScratchReg, ptr, label, cond);
-    }
-    void branch32(Condition cond, AbsoluteAddress lhs, Imm32 rhs, Label* label) {
-        load32(lhs, SecondScratchReg);
-        ma_b(SecondScratchReg, rhs, label, cond);
-    }
-    void branch32(Condition cond, AbsoluteAddress lhs, Register rhs, Label* label) {
-        load32(lhs, SecondScratchReg);
-        ma_b(SecondScratchReg, rhs, label, cond);
-    }
-    void branch32(Condition cond, AsmJSAbsoluteAddress addr, Imm32 imm, Label* label) {
-        load32(addr, SecondScratchReg);
-        ma_b(SecondScratchReg, imm, label, cond);
-    }
-
-    void loadUnboxedValue(Address address, MIRType type, AnyRegister dest) {
-        if (dest.isFloat())
-            loadInt32OrDouble(address, dest.fpu());
-        else
-            ma_lw(dest.gpr(), address);
-    }
-
-    void loadUnboxedValue(BaseIndex address, MIRType type, AnyRegister dest) {
-        if (dest.isFloat())
-            loadInt32OrDouble(address.base, address.index, dest.fpu(), address.scale);
-        else
-            load32(address, dest.gpr());
-    }
-
-    template <typename T>
-    void storeUnboxedValue(ConstantOrRegister value, MIRType valueType, const T& dest,
-                           MIRType slotType);
-
-    template <typename T>
-    void storeUnboxedPayload(ValueOperand value, T address, size_t nbytes) {
-        switch (nbytes) {
-          case 4:
-            store32(value.payloadReg(), address);
-            return;
-          case 1:
-            store8(value.payloadReg(), address);
-            return;
-          default: MOZ_CRASH("Bad payload width");
-        }
-    }
-
-    void moveValue(const Value& val, const ValueOperand& dest);
-
-    void moveValue(const ValueOperand& src, const ValueOperand& dest) {
-        Register s0 = src.typeReg(), d0 = dest.typeReg(),
-                 s1 = src.payloadReg(), d1 = dest.payloadReg();
-
-        // Either one or both of the source registers could be the same as a
-        // destination register.
-        if (s1 == d0) {
-            if (s0 == d1) {
-                // If both are, this is just a swap of two registers.
-                MOZ_ASSERT(d1 != ScratchRegister);
-                MOZ_ASSERT(d0 != ScratchRegister);
-                move32(d1, ScratchRegister);
-                move32(d0, d1);
-                move32(ScratchRegister, d0);
-                return;
-            }
-            // If only one is, copy that source first.
-            mozilla::Swap(s0, s1);
-            mozilla::Swap(d0, d1);
-        }
-
-        if (s0 != d0)
-            move32(s0, d0);
-        if (s1 != d1)
-            move32(s1, d1);
-    }
-
-    void storeValue(ValueOperand val, Operand dst);
-    void storeValue(ValueOperand val, const BaseIndex& dest);
-    void storeValue(JSValueType type, Register reg, BaseIndex dest);
-    void storeValue(ValueOperand val, const Address& dest);
-    void storeValue(JSValueType type, Register reg, Address dest);
-    void storeValue(const Value& val, Address dest);
-    void storeValue(const Value& val, BaseIndex dest);
-
-    void loadValue(Address src, ValueOperand val);
-    void loadValue(Operand dest, ValueOperand val) {
-        loadValue(dest.toAddress(), val);
-    }
-    void loadValue(const BaseIndex& addr, ValueOperand val);
-    void tagValue(JSValueType type, Register payload, ValueOperand dest);
-
-    void pushValue(ValueOperand val);
-    void popValue(ValueOperand val);
-    void pushValue(const Value& val) {
-        jsval_layout jv = JSVAL_TO_IMPL(val);
-        push(Imm32(jv.s.tag));
-        if (val.isMarkable())
-            push(ImmGCPtr(reinterpret_cast<gc::Cell*>(val.toGCThing())));
-        else
-            push(Imm32(jv.s.payload.i32));
-    }
-    void pushValue(JSValueType type, Register reg) {
-        push(ImmTag(JSVAL_TYPE_TO_TAG(type)));
-        ma_push(reg);
-    }
-    void pushValue(const Address& addr);
-
-    void storePayload(const Value& val, Address dest);
-    void storePayload(Register src, Address dest);
-    void storePayload(const Value& val, const BaseIndex& dest);
-    void storePayload(Register src, const BaseIndex& dest);
-    void storeTypeTag(ImmTag tag, Address dest);
-    void storeTypeTag(ImmTag tag, const BaseIndex& dest);
-
-    void handleFailureWithHandlerTail(void* handler);
-
-    /////////////////////////////////////////////////////////////////
-    // Common interface.
-    /////////////////////////////////////////////////////////////////
-  public:
-    // The following functions are exposed for use in platform-shared code.
-
-    template<typename T>
-    void compareExchange8SignExtend(const T& mem, Register oldval, Register newval, Register output)
-    {
-        MOZ_CRASH("NYI");
-    }
-    template<typename T>
-    void compareExchange8ZeroExtend(const T& mem, Register oldval, Register newval, Register output)
-    {
-        MOZ_CRASH("NYI");
-    }
-    template<typename T>
-    void compareExchange16SignExtend(const T& mem, Register oldval, Register newval, Register output)
-    {
-        MOZ_CRASH("NYI");
-    }
-    template<typename T>
-    void compareExchange16ZeroExtend(const T& mem, Register oldval, Register newval, Register output)
-    {
-        MOZ_CRASH("NYI");
-    }
-    template<typename T>
-    void compareExchange32(const T& mem, Register oldval, Register newval, Register output)
-    {
-        MOZ_CRASH("NYI");
-    }
-
-    template<typename T>
-    void atomicExchange8SignExtend(const T& mem, Register value, Register output)
-    {
-        MOZ_CRASH("NYI");
-    }
-    template<typename T>
-    void atomicExchange8ZeroExtend(const T& mem, Register value, Register output)
-    {
-        MOZ_CRASH("NYI");
-    }
-    template<typename T>
-    void atomicExchange16SignExtend(const T& mem, Register value, Register output)
-    {
-        MOZ_CRASH("NYI");
-    }
-    template<typename T>
-    void atomicExchange16ZeroExtend(const T& mem, Register value, Register output)
-    {
-        MOZ_CRASH("NYI");
-    }
-    template<typename T>
-    void atomicExchange32(const T& mem, Register value, Register output)
-    {
-        MOZ_CRASH("NYI");
-    }
-
-    template<typename T, typename S>
-    void atomicFetchAdd8SignExtend(const S& value, const T& mem, Register temp, Register output) {
-        MOZ_CRASH("NYI");
-    }
-    template<typename T, typename S>
-    void atomicFetchAdd8ZeroExtend(const S& value, const T& mem, Register temp, Register output) {
-        MOZ_CRASH("NYI");
-    }
-    template<typename T, typename S>
-    void atomicFetchAdd16SignExtend(const S& value, const T& mem, Register temp, Register output) {
-        MOZ_CRASH("NYI");
-    }
-    template<typename T, typename S>
-    void atomicFetchAdd16ZeroExtend(const S& value, const T& mem, Register temp, Register output) {
-        MOZ_CRASH("NYI");
-    }
-    template<typename T, typename S>
-    void atomicFetchAdd32(const S& value, const T& mem, Register temp, Register output) {
-        MOZ_CRASH("NYI");
-    }
-    template <typename T, typename S>
-    void atomicAdd8(const T& value, const S& mem) {
-        MOZ_CRASH("NYI");
-    }
-    template <typename T, typename S>
-    void atomicAdd16(const T& value, const S& mem) {
-        MOZ_CRASH("NYI");
-    }
-    template <typename T, typename S>
-    void atomicAdd32(const T& value, const S& mem) {
-        MOZ_CRASH("NYI");
-    }
-
-    template<typename T, typename S>
-    void atomicFetchSub8SignExtend(const S& value, const T& mem, Register temp, Register output) {
-        MOZ_CRASH("NYI");
-    }
-    template<typename T, typename S>
-    void atomicFetchSub8ZeroExtend(const S& value, const T& mem, Register temp, Register output) {
-        MOZ_CRASH("NYI");
-    }
-    template<typename T, typename S>
-    void atomicFetchSub16SignExtend(const S& value, const T& mem, Register temp, Register output) {
-        MOZ_CRASH("NYI");
-    }
-    template<typename T, typename S>
-    void atomicFetchSub16ZeroExtend(const S& value, const T& mem, Register temp, Register output) {
-        MOZ_CRASH("NYI");
-    }
-    template<typename T, typename S>
-    void atomicFetchSub32(const S& value, const T& mem, Register temp, Register output) {
-        MOZ_CRASH("NYI");
-    }
-    template <typename T, typename S> void atomicSub8(const T& value, const S& mem) {
-        MOZ_CRASH("NYI");
-    }
-    template <typename T, typename S> void atomicSub16(const T& value, const S& mem) {
-        MOZ_CRASH("NYI");
-    }
-    template <typename T, typename S> void atomicSub32(const T& value, const S& mem) {
-        MOZ_CRASH("NYI");
-    }
-
-    template<typename T, typename S>
-    void atomicFetchAnd8SignExtend(const S& value, const T& mem, Register temp, Register output) {
-        MOZ_CRASH("NYI");
-    }
-    template<typename T, typename S>
-    void atomicFetchAnd8ZeroExtend(const S& value, const T& mem, Register temp, Register output) {
-        MOZ_CRASH("NYI");
-    }
-    template<typename T, typename S>
-    void atomicFetchAnd16SignExtend(const S& value, const T& mem, Register temp, Register output) {
-        MOZ_CRASH("NYI");
-    }
-    template<typename T, typename S>
-    void atomicFetchAnd16ZeroExtend(const S& value, const T& mem, Register temp, Register output) {
-        MOZ_CRASH("NYI");
-    }
-    template<typename T, typename S>
-    void atomicFetchAnd32(const S& value, const T& mem, Register temp, Register output) {
-        MOZ_CRASH("NYI");
-    }
-    template <typename T, typename S>
-    void atomicAnd8(const T& value, const S& mem) {
-        MOZ_CRASH("NYI");
-    }
-    template <typename T, typename S>
-    void atomicAnd16(const T& value, const S& mem) {
-        MOZ_CRASH("NYI");
-    }
-    template <typename T, typename S>
-    void atomicAnd32(const T& value, const S& mem) {
-        MOZ_CRASH("NYI");
-    }
-
-    template<typename T, typename S>
-    void atomicFetchOr8SignExtend(const S& value, const T& mem, Register temp, Register output) {
-        MOZ_CRASH("NYI");
-    }
-    template<typename T, typename S>
-    void atomicFetchOr8ZeroExtend(const S& value, const T& mem, Register temp, Register output) {
-        MOZ_CRASH("NYI");
-    }
-    template<typename T, typename S>
-    void atomicFetchOr16SignExtend(const S& value, const T& mem, Register temp, Register output) {
-        MOZ_CRASH("NYI");
-    }
-    template<typename T, typename S>
-    void atomicFetchOr16ZeroExtend(const S& value, const T& mem, Register temp, Register output) {
-        MOZ_CRASH("NYI");
-    }
-    template<typename T, typename S>
-    void atomicFetchOr32(const S& value, const T& mem, Register temp, Register output) {
-        MOZ_CRASH("NYI");
-    }
-    template <typename T, typename S>
-    void atomicOr8(const T& value, const S& mem) {
-        MOZ_CRASH("NYI");
-    }
-    template <typename T, typename S>
-    void atomicOr16(const T& value, const S& mem) {
-        MOZ_CRASH("NYI");
-    }
-    template <typename T, typename S>
-    void atomicOr32(const T& value, const S& mem) {
-        MOZ_CRASH("NYI");
-    }
-
-    template<typename T, typename S>
-    void atomicFetchXor8SignExtend(const S& value, const T& mem, Register temp, Register output) {
-        MOZ_CRASH("NYI");
-    }
-    template<typename T, typename S>
-    void atomicFetchXor8ZeroExtend(const S& value, const T& mem, Register temp, Register output) {
-        MOZ_CRASH("NYI");
-    }
-    template<typename T, typename S>
-    void atomicFetchXor16SignExtend(const S& value, const T& mem, Register temp, Register output) {
-        MOZ_CRASH("NYI");
-    }
-    template<typename T, typename S>
-    void atomicFetchXor16ZeroExtend(const S& value, const T& mem, Register temp, Register output) {
-        MOZ_CRASH("NYI");
-    }
-    template<typename T, typename S>
-    void atomicFetchXor32(const S& value, const T& mem, Register temp, Register output) {
-        MOZ_CRASH("NYI");
-    }
-    template <typename T, typename S>
-    void atomicXor8(const T& value, const S& mem) {
-        MOZ_CRASH("NYI");
-    }
-    template <typename T, typename S>
-    void atomicXor16(const T& value, const S& mem) {
-        MOZ_CRASH("NYI");
-    }
-    template <typename T, typename S>
-    void atomicXor32(const T& value, const S& mem) {
-        MOZ_CRASH("NYI");
-    }
-
-    void add32(Register src, Register dest);
-    void add32(Imm32 imm, Register dest);
-    void add32(Imm32 imm, const Address& dest);
-    void add64(Imm32 imm, Register64 dest) {
-        as_addiu(dest.low, dest.low, imm.value);
-        as_sltiu(ScratchRegister, dest.low, imm.value);
-        as_addu(dest.high, dest.high, ScratchRegister);
-    }
-    void sub32(Imm32 imm, Register dest);
-    void sub32(Register src, Register dest);
-
-    void incrementInt32Value(const Address& addr) {
-        add32(Imm32(1), ToPayload(addr));
-    }
-
-    template <typename T>
-    void branchAdd32(Condition cond, T src, Register dest, Label* overflow) {
-        switch (cond) {
-          case Overflow:
-            ma_addTestOverflow(dest, dest, src, overflow);
-            break;
-          default:
-            MOZ_CRASH("NYI");
-        }
-    }
-    template <typename T>
-    void branchSub32(Condition cond, T src, Register dest, Label* overflow) {
-        switch (cond) {
-          case Overflow:
-            ma_subTestOverflow(dest, dest, src, overflow);
-            break;
-          case NonZero:
-          case Zero:
-            sub32(src, dest);
-            ma_b(dest, dest, overflow, cond);
-            break;
-          default:
-            MOZ_CRASH("NYI");
-        }
-    }
-
-    void addPtr(Register src, Register dest);
-    void subPtr(Register src, Register dest);
-    void addPtr(const Address& src, Register dest);
-
-    void move32(Imm32 imm, Register dest);
-    void move32(Register src, Register dest);
-    void move64(Register64 src, Register64 dest) {
-        move32(src.low, dest.low);
-        move32(src.high, dest.high);
-    }
-
-    void movePtr(Register src, Register dest);
-    void movePtr(ImmWord imm, Register dest);
-    void movePtr(ImmPtr imm, Register dest);
-    void movePtr(AsmJSImmPtr imm, Register dest);
-    void movePtr(ImmGCPtr imm, Register dest);
-
-    void load8SignExtend(const Address& address, Register dest);
-    void load8SignExtend(const BaseIndex& src, Register dest);
-
-    void load8ZeroExtend(const Address& address, Register dest);
-    void load8ZeroExtend(const BaseIndex& src, Register dest);
-
-    void load16SignExtend(const Address& address, Register dest);
-    void load16SignExtend(const BaseIndex& src, Register dest);
-
-    void load16ZeroExtend(const Address& address, Register dest);
-    void load16ZeroExtend(const BaseIndex& src, Register dest);
-
-    void load32(const Address& address, Register dest);
-    void load32(const BaseIndex& address, Register dest);
-    void load32(AbsoluteAddress address, Register dest);
-    void load32(AsmJSAbsoluteAddress address, Register dest);
-    void load64(const Address& address, Register64 dest) {
-        load32(Address(address.base, address.offset + LOW_32_OFFSET), dest.low);
-        load32(Address(address.base, address.offset + HIGH_32_OFFSET), dest.high);
-    }
-
-    void loadPtr(const Address& address, Register dest);
-    void loadPtr(const BaseIndex& src, Register dest);
-    void loadPtr(AbsoluteAddress address, Register dest);
-    void loadPtr(AsmJSAbsoluteAddress address, Register dest);
-
-    void loadPrivate(const Address& address, Register dest);
-
-    void loadInt32x1(const Address& addr, FloatRegister dest) { MOZ_CRASH("NYI"); }
-    void loadInt32x1(const BaseIndex& addr, FloatRegister dest) { MOZ_CRASH("NYI"); }
-    void loadInt32x2(const Address& addr, FloatRegister dest) { MOZ_CRASH("NYI"); }
-    void loadInt32x2(const BaseIndex& addr, FloatRegister dest) { MOZ_CRASH("NYI"); }
-    void loadInt32x3(const Address& src, FloatRegister dest) { MOZ_CRASH("NYI"); }
-    void loadInt32x3(const BaseIndex& src, FloatRegister dest) { MOZ_CRASH("NYI"); }
-    void storeInt32x1(FloatRegister src, const Address& dest) { MOZ_CRASH("NYI"); }
-    void storeInt32x1(FloatRegister src, const BaseIndex& dest) { MOZ_CRASH("NYI"); }
-    void storeInt32x2(FloatRegister src, const Address& dest) { MOZ_CRASH("NYI"); }
-    void storeInt32x2(FloatRegister src, const BaseIndex& dest) { MOZ_CRASH("NYI"); }
-    void storeInt32x3(FloatRegister src, const Address& dest) { MOZ_CRASH("NYI"); }
-    void storeInt32x3(FloatRegister src, const BaseIndex& dest) { MOZ_CRASH("NYI"); }
-    void loadAlignedInt32x4(const Address& addr, FloatRegister dest) { MOZ_CRASH("NYI"); }
-    void storeAlignedInt32x4(FloatRegister src, Address addr) { MOZ_CRASH("NYI"); }
-    void loadUnalignedInt32x4(const Address& addr, FloatRegister dest) { MOZ_CRASH("NYI"); }
-    void loadUnalignedInt32x4(const BaseIndex& addr, FloatRegister dest) { MOZ_CRASH("NYI"); }
-    void storeUnalignedInt32x4(FloatRegister src, Address addr) { MOZ_CRASH("NYI"); }
-    void storeUnalignedInt32x4(FloatRegister src, BaseIndex addr) { MOZ_CRASH("NYI"); }
-
-    void loadFloat32x3(const Address& src, FloatRegister dest) { MOZ_CRASH("NYI"); }
-    void loadFloat32x3(const BaseIndex& src, FloatRegister dest) { MOZ_CRASH("NYI"); }
-    void storeFloat32x3(FloatRegister src, const Address& dest) { MOZ_CRASH("NYI"); }
-    void storeFloat32x3(FloatRegister src, const BaseIndex& dest) { MOZ_CRASH("NYI"); }
-    void loadAlignedFloat32x4(const Address& addr, FloatRegister dest) { MOZ_CRASH("NYI"); }
-    void storeAlignedFloat32x4(FloatRegister src, Address addr) { MOZ_CRASH("NYI"); }
-    void loadUnalignedFloat32x4(const Address& addr, FloatRegister dest) { MOZ_CRASH("NYI"); }
-    void loadUnalignedFloat32x4(const BaseIndex& addr, FloatRegister dest) { MOZ_CRASH("NYI"); }
-    void storeUnalignedFloat32x4(FloatRegister src, Address addr) { MOZ_CRASH("NYI"); }
-    void storeUnalignedFloat32x4(FloatRegister src, BaseIndex addr) { MOZ_CRASH("NYI"); }
-
-    void loadDouble(const Address& addr, FloatRegister dest);
-    void loadDouble(const BaseIndex& src, FloatRegister dest);
-
-    // Load a float value into a register, then expand it to a double.
-    void loadFloatAsDouble(const Address& addr, FloatRegister dest);
-    void loadFloatAsDouble(const BaseIndex& src, FloatRegister dest);
-
-    void loadFloat32(const Address& addr, FloatRegister dest);
-    void loadFloat32(const BaseIndex& src, FloatRegister dest);
-
-    void store8(Register src, const Address& address);
-    void store8(Imm32 imm, const Address& address);
-    void store8(Register src, const BaseIndex& address);
-    void store8(Imm32 imm, const BaseIndex& address);
-
-    void store16(Register src, const Address& address);
-    void store16(Imm32 imm, const Address& address);
-    void store16(Register src, const BaseIndex& address);
-    void store16(Imm32 imm, const BaseIndex& address);
-
-    void store32(Register src, AbsoluteAddress address);
-    void store32(Register src, const Address& address);
-    void store32(Register src, const BaseIndex& address);
-    void store32(Imm32 src, const Address& address);
-    void store32(Imm32 src, const BaseIndex& address);
-
-    // NOTE: This will use second scratch on MIPS. Only ARM needs the
-    // implementation without second scratch.
-    void store32_NoSecondScratch(Imm32 src, const Address& address) {
-        store32(src, address);
-    }
-
-    void store64(Register64 src, Address address) {
-        store32(src.low, Address(address.base, address.offset + LOW_32_OFFSET));
-        store32(src.high, Address(address.base, address.offset + HIGH_32_OFFSET));
-    }
-
-    template <typename T> void storePtr(ImmWord imm, T address);
-    template <typename T> void storePtr(ImmPtr imm, T address);
-    template <typename T> void storePtr(ImmGCPtr imm, T address);
-    void storePtr(Register src, const Address& address);
-    void storePtr(Register src, const BaseIndex& address);
-    void storePtr(Register src, AbsoluteAddress dest);
-    void storeDouble(FloatRegister src, Address addr) {
-        ma_sd(src, addr);
-    }
-    void storeDouble(FloatRegister src, BaseIndex addr) {
-        MOZ_ASSERT(addr.offset == 0);
-        ma_sd(src, addr);
-    }
-    void moveDouble(FloatRegister src, FloatRegister dest) {
-        as_movd(dest, src);
-    }
-
-    void storeFloat32(FloatRegister src, Address addr) {
-        ma_ss(src, addr);
-    }
-    void storeFloat32(FloatRegister src, BaseIndex addr) {
-        MOZ_ASSERT(addr.offset == 0);
-        ma_ss(src, addr);
-    }
-
-    void zeroDouble(FloatRegister reg) {
-        moveToDoubleLo(zero, reg);
-        moveToDoubleHi(zero, reg);
-    }
-
-    void clampIntToUint8(Register reg);
-
-    void subPtr(Imm32 imm, const Register dest);
-    void subPtr(const Address& addr, const Register dest);
-    void subPtr(Register src, const Address& dest);
-    void addPtr(Imm32 imm, const Register dest);
-    void addPtr(Imm32 imm, const Address& dest);
-    void addPtr(ImmWord imm, const Register dest) {
-        addPtr(Imm32(imm.value), dest);
-    }
-    void addPtr(ImmPtr imm, const Register dest) {
-        addPtr(ImmWord(uintptr_t(imm.value)), dest);
-    }
-    void mulBy3(const Register& src, const Register& dest) {
-        as_addu(dest, src, src);
-        as_addu(dest, dest, src);
-    }
-
-    void mul64(Imm64 imm, const Register64& dest);
-
-    void convertUInt64ToDouble(Register64 src, Register temp, FloatRegister dest);
-    void mulDoublePtr(ImmPtr imm, Register temp, FloatRegister dest) {
-        movePtr(imm, ScratchRegister);
-        loadDouble(Address(ScratchRegister, 0), ScratchDoubleReg);
-        mulDouble(ScratchDoubleReg, dest);
-    }
-
-    void breakpoint();
-
-    void branchDouble(DoubleCondition cond, FloatRegister lhs, FloatRegister rhs,
-                      Label* label);
-
-    void branchFloat(DoubleCondition cond, FloatRegister lhs, FloatRegister rhs,
-                     Label* label);
-
-    void checkStackAlignment();
-
-    void alignStackPointer();
-    void restoreStackPointer();
-    static void calculateAlignedStackPointer(void** stackPointer);
-
-    // If source is a double, load it into dest. If source is int32,
-    // convert it to double. Else, branch to failure.
-    void ensureDouble(const ValueOperand& source, FloatRegister dest, Label* failure);
-
-    template <typename T1, typename T2>
-    void cmpPtrSet(Assembler::Condition cond, T1 lhs, T2 rhs, Register dest)
-    {
-        ma_cmp_set(dest, lhs, rhs, cond);
-    }
-
-    template <typename T1, typename T2>
-    void cmp32Set(Assembler::Condition cond, T1 lhs, T2 rhs, Register dest)
-    {
-        ma_cmp_set(dest, lhs, rhs, cond);
-    }
-
-  protected:
-    bool buildOOLFakeExitFrame(void* fakeReturnAddr);
-
-  public:
-    CodeOffsetLabel labelForPatch() {
-        return CodeOffsetLabel(nextOffset().getOffset());
-    }
-
-    void memIntToValue(Address Source, Address Dest) {
-        load32(Source, ScratchRegister);
-        storeValue(JSVAL_TYPE_INT32, ScratchRegister, Dest);
-    }
-
-    void lea(Operand addr, Register dest) {
-        ma_addu(dest, addr.baseReg(), Imm32(addr.disp()));
-    }
-
-    void abiret() {
-        as_jr(ra);
-        as_nop();
-    }
-
-    void ma_storeImm(Imm32 imm, const Address& addr) {
-        ma_sw(imm, addr);
-    }
-
-    BufferOffset ma_BoundsCheck(Register bounded) {
-        BufferOffset bo = m_buffer.nextOffset();
-        ma_liPatchable(bounded, ImmWord(0));
-        return bo;
-    }
-
-    void moveFloat32(FloatRegister src, FloatRegister dest) {
-        as_movs(dest, src);
-    }
-
-    void branchPtrInNurseryRange(Condition cond, Register ptr, Register temp, Label* label);
-    void branchValueIsNurseryObject(Condition cond, ValueOperand value, Register temp,
-                                    Label* label);
-
-    void loadAsmJSActivation(Register dest) {
-        loadPtr(Address(GlobalReg, AsmJSActivationGlobalDataOffset - AsmJSGlobalRegBias), dest);
-    }
-    void loadAsmJSHeapRegisterFromGlobalData() {
-        MOZ_ASSERT(Imm16::IsInSignedRange(AsmJSHeapGlobalDataOffset - AsmJSGlobalRegBias));
-        loadPtr(Address(GlobalReg, AsmJSHeapGlobalDataOffset - AsmJSGlobalRegBias), HeapReg);
-    }
-
-    // Instrumentation for entering and leaving the profiler.
-    void profilerEnterFrame(Register framePtr, Register scratch);
-    void profilerExitFrame();
-};
-
-typedef MacroAssemblerMIPSCompat MacroAssemblerSpecific;
-
 } // namespace jit
 } // namespace js
 
-#endif /* jit_mips32_MacroAssembler_mips32_h */
+#endif /* jit_mips_shared_MacroAssembler_mips_shared_h */
--- a/js/src/jit/mips32/MacroAssembler-mips32.cpp
+++ b/js/src/jit/mips32/MacroAssembler-mips32.cpp
@@ -307,55 +307,27 @@ MacroAssemblerMIPSCompat::inc64(Absolute
 
     as_addu(SecondScratchReg, ScratchRegister, SecondScratchReg);
 
     ma_li(ScratchRegister, Imm32((int32_t)dest.addr));
     as_sw(SecondScratchReg, ScratchRegister, 4);
 }
 
 void
-MacroAssemblerMIPS::ma_move(Register rd, Register rs)
-{
-    as_or(rd, rs, zero);
-}
-
-void
-MacroAssemblerMIPS::ma_li(Register dest, ImmGCPtr ptr)
-{
-    writeDataRelocation(ptr);
-    ma_liPatchable(dest, ImmPtr(ptr.value));
-}
-
-void
 MacroAssemblerMIPS::ma_li(Register dest, AbsoluteLabel* label)
 {
     MOZ_ASSERT(!label->bound());
     // Thread the patch list through the unpatched address word in the
     // instruction stream.
     BufferOffset bo = m_buffer.nextOffset();
     ma_liPatchable(dest, Imm32(label->prev()));
     label->setPrev(bo.getOffset());
 }
 
 void
-MacroAssemblerMIPS::ma_li(Register dest, Imm32 imm)
-{
-    if (Imm16::IsInSignedRange(imm.value)) {
-        as_addiu(dest, zero, imm.value);
-    } else if (Imm16::IsInUnsignedRange(imm.value)) {
-        as_ori(dest, zero, Imm16::Lower(imm).encode());
-    } else if (Imm16::Lower(imm).encode() == 0) {
-        as_lui(dest, Imm16::Upper(imm).encode());
-    } else {
-        as_lui(dest, Imm16::Upper(imm).encode());
-        as_ori(dest, dest, Imm16::Lower(imm).encode());
-    }
-}
-
-void
 MacroAssemblerMIPS::ma_li(Register dest, ImmWord imm)
 {
     ma_li(dest, Imm32(uint32_t(imm.value)));
 }
 
 // This method generates lui and ori instruction pair that can be modified by
 // UpdateLuiOriValue, either during compilation (eg. Assembler::bind), or
 // during execution (eg. jit::PatchJump).
@@ -374,188 +346,20 @@ MacroAssemblerMIPS::ma_liPatchable(Regis
 }
 
 void
 MacroAssemblerMIPS::ma_liPatchable(Register dest, ImmWord imm)
 {
     ma_liPatchable(dest, Imm32(int32_t(imm.value)));
 }
 
-// Shifts
-void
-MacroAssemblerMIPS::ma_sll(Register rd, Register rt, Imm32 shift)
-{
-    as_sll(rd, rt, shift.value % 32);
-}
-void
-MacroAssemblerMIPS::ma_srl(Register rd, Register rt, Imm32 shift)
-{
-    as_srl(rd, rt, shift.value % 32);
-}
-
-void
-MacroAssemblerMIPS::ma_sra(Register rd, Register rt, Imm32 shift)
-{
-    as_sra(rd, rt, shift.value % 32);
-}
-
-void
-MacroAssemblerMIPS::ma_ror(Register rd, Register rt, Imm32 shift)
-{
-    as_rotr(rd, rt, shift.value % 32);
-}
-
-void
-MacroAssemblerMIPS::ma_rol(Register rd, Register rt, Imm32 shift)
-{
-    as_rotr(rd, rt, 32 - (shift.value % 32));
-}
-
-void
-MacroAssemblerMIPS::ma_sll(Register rd, Register rt, Register shift)
-{
-    as_sllv(rd, rt, shift);
-}
-
-void
-MacroAssemblerMIPS::ma_srl(Register rd, Register rt, Register shift)
-{
-    as_srlv(rd, rt, shift);
-}
-
-void
-MacroAssemblerMIPS::ma_sra(Register rd, Register rt, Register shift)
-{
-    as_srav(rd, rt, shift);
-}
-
-void
-MacroAssemblerMIPS::ma_ror(Register rd, Register rt, Register shift)
-{
-    as_rotrv(rd, rt, shift);
-}
-
-void
-MacroAssemblerMIPS::ma_rol(Register rd, Register rt, Register shift)
-{
-    ma_negu(ScratchRegister, shift);
-    as_rotrv(rd, rt, ScratchRegister);
-}
-
-void
-MacroAssemblerMIPS::ma_negu(Register rd, Register rs)
-{
-    as_subu(rd, zero, rs);
-}
-
-void
-MacroAssemblerMIPS::ma_not(Register rd, Register rs)
-{
-    as_nor(rd, rs, zero);
-}
-
-// And.
-void
-MacroAssemblerMIPS::ma_and(Register rd, Register rs)
-{
-    as_and(rd, rd, rs);
-}
-
-void
-MacroAssemblerMIPS::ma_and(Register rd, Imm32 imm)
-{
-    ma_and(rd, rd, imm);
-}
-
-void
-MacroAssemblerMIPS::ma_and(Register rd, Register rs, Imm32 imm)
-{
-    if (Imm16::IsInUnsignedRange(imm.value)) {
-        as_andi(rd, rs, imm.value);
-    } else {
-        ma_li(ScratchRegister, imm);
-        as_and(rd, rs, ScratchRegister);
-    }
-}
-
-// Or.
-void
-MacroAssemblerMIPS::ma_or(Register rd, Register rs)
-{
-    as_or(rd, rd, rs);
-}
-
-void
-MacroAssemblerMIPS::ma_or(Register rd, Imm32 imm)
-{
-    ma_or(rd, rd, imm);
-}
-
-void
-MacroAssemblerMIPS::ma_or(Register rd, Register rs, Imm32 imm)
-{
-    if (Imm16::IsInUnsignedRange(imm.value)) {
-        as_ori(rd, rs, imm.value);
-    } else {
-        ma_li(ScratchRegister, imm);
-        as_or(rd, rs, ScratchRegister);
-    }
-}
-
-// xor
-void
-MacroAssemblerMIPS::ma_xor(Register rd, Register rs)
-{
-    as_xor(rd, rd, rs);
-}
-
-void
-MacroAssemblerMIPS::ma_xor(Register rd, Imm32 imm)
-{
-    ma_xor(rd, rd, imm);
-}
-
-void
-MacroAssemblerMIPS::ma_xor(Register rd, Register rs, Imm32 imm)
-{
-    if (Imm16::IsInUnsignedRange(imm.value)) {
-        as_xori(rd, rs, imm.value);
-    } else {
-        ma_li(ScratchRegister, imm);
-        as_xor(rd, rs, ScratchRegister);
-    }
-}
-
 // Arithmetic-based ops.
 
 // Add.
 void
-MacroAssemblerMIPS::ma_addu(Register rd, Register rs, Imm32 imm)
-{
-    if (Imm16::IsInSignedRange(imm.value)) {
-        as_addiu(rd, rs, imm.value);
-    } else {
-        ma_li(ScratchRegister, imm);
-        as_addu(rd, rs, ScratchRegister);
-    }
-}
-
-void
-MacroAssemblerMIPS::ma_addu(Register rd, Register rs)
-{
-    as_addu(rd, rd, rs);
-}
-
-void
-MacroAssemblerMIPS::ma_addu(Register rd, Imm32 imm)
-{
-    ma_addu(rd, rd, imm);
-}
-
-void
 MacroAssemblerMIPS::ma_addTestOverflow(Register rd, Register rs, Register rt, Label* overflow)
 {
     Label goodAddition;
     as_addu(rd, rs, rt);
 
     as_xor(ScratchRegister, rs, rt); // If different sign, no overflow
     ma_b(ScratchRegister, Imm32(0), &goodAddition, Assembler::LessThan, ShortJump);
 
@@ -587,33 +391,16 @@ MacroAssemblerMIPS::ma_addTestOverflow(R
     } else {
         ma_li(ScratchRegister, imm);
         ma_addTestOverflow(rd, rs, ScratchRegister, overflow);
     }
 }
 
 // Subtract.
 void
-MacroAssemblerMIPS::ma_subu(Register rd, Register rs, Imm32 imm)
-{
-    if (Imm16::IsInSignedRange(-imm.value)) {
-        as_addiu(rd, rs, -imm.value);
-    } else {
-        ma_li(ScratchRegister, imm);
-        as_subu(rd, rs, ScratchRegister);
-    }
-}
-
-void
-MacroAssemblerMIPS::ma_subu(Register rd, Imm32 imm)
-{
-    ma_subu(rd, rd, imm);
-}
-
-void
 MacroAssemblerMIPS::ma_subTestOverflow(Register rd, Register rs, Register rt, Label* overflow)
 {
     Label goodSubtraction;
     // Use second scratch. The instructions generated by ma_b don't use the
     // second scratch register.
     as_subu(rd, rs, rt);
 
     as_xor(ScratchRegister, rs, rt); // If same sign, no overflow
@@ -621,141 +408,16 @@ MacroAssemblerMIPS::ma_subTestOverflow(R
 
     // If different sign, then overflow
     as_xor(ScratchRegister, rs, rd);
     ma_b(ScratchRegister, Imm32(0), overflow, Assembler::LessThan);
 
     bind(&goodSubtraction);
 }
 
-void
-MacroAssemblerMIPS::ma_subTestOverflow(Register rd, Register rs, Imm32 imm, Label* overflow)
-{
-    if (imm.value != INT32_MIN) {
-        ma_addTestOverflow(rd, rs, Imm32(-imm.value), overflow);
-    } else {
-        ma_li(ScratchRegister, Imm32(imm.value));
-        ma_subTestOverflow(rd, rs, ScratchRegister, overflow);
-    }
-}
-
-void
-MacroAssemblerMIPS::ma_mult(Register rs, Imm32 imm)
-{
-    ma_li(ScratchRegister, imm);
-    as_mult(rs, ScratchRegister);
-}
-
-void
-MacroAssemblerMIPS::ma_mul_branch_overflow(Register rd, Register rs, Register rt, Label* overflow)
-{
-    as_mult(rs, rt);
-    as_mflo(rd);
-    as_sra(ScratchRegister, rd, 31);
-    as_mfhi(SecondScratchReg);
-    ma_b(ScratchRegister, SecondScratchReg, overflow, Assembler::NotEqual);
-}
-
-void
-MacroAssemblerMIPS::ma_mul_branch_overflow(Register rd, Register rs, Imm32 imm, Label* overflow)
-{
-    ma_li(ScratchRegister, imm);
-    ma_mul_branch_overflow(rd, rs, ScratchRegister, overflow);
-}
-
-void
-MacroAssemblerMIPS::ma_div_branch_overflow(Register rd, Register rs, Register rt, Label* overflow)
-{
-    as_div(rs, rt);
-    as_mflo(rd);
-    as_mfhi(ScratchRegister);
-    ma_b(ScratchRegister, ScratchRegister, overflow, Assembler::NonZero);
-}
-
-void
-MacroAssemblerMIPS::ma_div_branch_overflow(Register rd, Register rs, Imm32 imm, Label* overflow)
-{
-    ma_li(ScratchRegister, imm);
-    ma_div_branch_overflow(rd, rs, ScratchRegister, overflow);
-}
-
-void
-MacroAssemblerMIPS::ma_mod_mask(Register src, Register dest, Register hold, Register remain,
-                                int32_t shift, Label* negZero)
-{
-    // MATH:
-    // We wish to compute x % (1<<y) - 1 for a known constant, y.
-    // First, let b = (1<<y) and C = (1<<y)-1, then think of the 32 bit
-    // dividend as a number in base b, namely
-    // c_0*1 + c_1*b + c_2*b^2 ... c_n*b^n
-    // now, since both addition and multiplication commute with modulus,
-    // x % C == (c_0 + c_1*b + ... + c_n*b^n) % C ==
-    // (c_0 % C) + (c_1%C) * (b % C) + (c_2 % C) * (b^2 % C)...
-    // now, since b == C + 1, b % C == 1, and b^n % C == 1
-    // this means that the whole thing simplifies to:
-    // c_0 + c_1 + c_2 ... c_n % C
-    // each c_n can easily be computed by a shift/bitextract, and the modulus
-    // can be maintained by simply subtracting by C whenever the number gets
-    // over C.
-    int32_t mask = (1 << shift) - 1;
-    Label head, negative, sumSigned, done;
-
-    // hold holds -1 if the value was negative, 1 otherwise.
-    // remain holds the remaining bits that have not been processed
-    // SecondScratchReg serves as a temporary location to store extracted bits
-    // into as well as holding the trial subtraction as a temp value dest is
-    // the accumulator (and holds the final result)
-
-    // move the whole value into the remain.
-    ma_move(remain, src);
-    // Zero out the dest.
-    ma_li(dest, Imm32(0));
-    // Set the hold appropriately.
-    ma_b(remain, remain, &negative, Signed, ShortJump);
-    ma_li(hold, Imm32(1));
-    ma_b(&head, ShortJump);
-
-    bind(&negative);
-    ma_li(hold, Imm32(-1));
-    ma_negu(remain, remain);
-
-    // Begin the main loop.
-    bind(&head);
-
-    // Extract the bottom bits into SecondScratchReg.
-    ma_and(SecondScratchReg, remain, Imm32(mask));
-    // Add those bits to the accumulator.
-    as_addu(dest, dest, SecondScratchReg);
-    // Do a trial subtraction
-    ma_subu(SecondScratchReg, dest, Imm32(mask));
-    // If (sum - C) > 0, store sum - C back into sum, thus performing a
-    // modulus.
-    ma_b(SecondScratchReg, SecondScratchReg, &sumSigned, Signed, ShortJump);
-    ma_move(dest, SecondScratchReg);
-    bind(&sumSigned);
-    // Get rid of the bits that we extracted before.
-    as_srl(remain, remain, shift);
-    // If the shift produced zero, finish, otherwise, continue in the loop.
-    ma_b(remain, remain, &head, NonZero, ShortJump);
-    // Check the hold to see if we need to negate the result.
-    ma_b(hold, hold, &done, NotSigned, ShortJump);
-
-    // If the hold was non-zero, negate the result to be in line with
-    // what JS wants
-    if (negZero != nullptr) {
-        // Jump out in case of negative zero.
-        ma_b(hold, hold, negZero, Zero);
-        ma_negu(dest, dest);
-    } else {
-        ma_negu(dest, dest);
-    }
-
-    bind(&done);
-}
-
 // Memory.
 
 void
 MacroAssemblerMIPS::ma_load(Register dest, Address address,
                             LoadStoreSize size, LoadStoreExtension extension)
 {
     int16_t encodedOffset;
     Register base;
@@ -786,24 +448,16 @@ MacroAssemblerMIPS::ma_load(Register des
         as_lw(dest, base, encodedOffset);
         break;
       default:
         MOZ_CRASH("Invalid argument for ma_load");
     }
 }
 
 void
-MacroAssemblerMIPS::ma_load(Register dest, const BaseIndex& src,
-                            LoadStoreSize size, LoadStoreExtension extension)
-{
-    asMasm().computeScaledAddress(src, SecondScratchReg);
-    ma_load(dest, Address(SecondScratchReg, src.offset), size, extension);
-}
-
-void
 MacroAssemblerMIPS::ma_store(Register data, Address address, LoadStoreSize size,
                              LoadStoreExtension extension)
 {
     int16_t encodedOffset;
     Register base;
     if (!Imm16::IsInSignedRange(address.offset)) {
         ma_li(ScratchRegister, Imm32(address.offset));
         as_addu(ScratchRegister, address.base, ScratchRegister);
@@ -825,40 +479,16 @@ MacroAssemblerMIPS::ma_store(Register da
         as_sw(data, base, encodedOffset);
         break;
       default:
         MOZ_CRASH("Invalid argument for ma_store");
     }
 }
 
 void
-MacroAssemblerMIPS::ma_store(Register data, const BaseIndex& dest,
-                             LoadStoreSize size, LoadStoreExtension extension)
-{
-    asMasm().computeScaledAddress(dest, SecondScratchReg);
-    ma_store(data, Address(SecondScratchReg, dest.offset), size, extension);
-}
-
-void
-MacroAssemblerMIPS::ma_store(Imm32 imm, const BaseIndex& dest,
-                             LoadStoreSize size, LoadStoreExtension extension)
-{
-    // Make sure that SecondScratchReg contains absolute address so that
-    // offset is 0.
-    asMasm().computeEffectiveAddress(dest, SecondScratchReg);
-
-    // Scrach register is free now, use it for loading imm value
-    ma_li(ScratchRegister, imm);
-
-    // with offset=0 ScratchRegister will not be used in ma_store()
-    // so we can use it as a parameter here
-    ma_store(ScratchRegister, Address(SecondScratchReg, 0), size, extension);
-}
-
-void
 MacroAssemblerMIPSCompat::computeScaledAddress(const BaseIndex& address, Register dest)
 {
     int32_t shift = Imm32::ShiftOf(address.scale).value;
     if (shift) {
         ma_sll(ScratchRegister, address.index, Imm32(shift));
         as_addu(dest, address.base, ScratchRegister);
     } else {
         as_addu(dest, address.base, address.index);
@@ -918,59 +548,16 @@ MacroAssemblerMIPS::ma_push(Register r)
     }
 
     as_addiu(StackPointer, StackPointer, -sizeof(intptr_t));
     as_sw(r, StackPointer, 0);
 }
 
 // Branches when done from within mips-specific code.
 void
-MacroAssemblerMIPS::ma_b(Register lhs, Register rhs, Label* label, Condition c, JumpKind jumpKind)
-{
-    switch (c) {
-      case Equal :
-      case NotEqual:
-        branchWithCode(getBranchCode(lhs, rhs, c), label, jumpKind);
-        break;
-      case Always:
-        ma_b(label, jumpKind);
-        break;
-      case Zero:
-      case NonZero:
-      case Signed:
-      case NotSigned:
-        MOZ_ASSERT(lhs == rhs);
-        branchWithCode(getBranchCode(lhs, c), label, jumpKind);
-        break;
-      default:
-        Condition cond = ma_cmp(ScratchRegister, lhs, rhs, c);
-        branchWithCode(getBranchCode(ScratchRegister, cond), label, jumpKind);
-        break;
-    }
-}
-
-void
-MacroAssemblerMIPS::ma_b(Register lhs, Imm32 imm, Label* label, Condition c, JumpKind jumpKind)
-{
-    MOZ_ASSERT(c != Overflow);
-    if (imm.value == 0) {
-        if (c == Always || c == AboveOrEqual)
-            ma_b(label, jumpKind);
-        else if (c == Below)
-            ; // This condition is always false. No branch required.
-        else
-            branchWithCode(getBranchCode(lhs, c), label, jumpKind);
-    } else {
-        MOZ_ASSERT(lhs != ScratchRegister);
-        ma_li(ScratchRegister, imm);
-        ma_b(lhs, ScratchRegister, label, c, jumpKind);
-    }
-}
-
-void
 MacroAssemblerMIPS::ma_b(Register lhs, Address addr, Label* label, Condition c, JumpKind jumpKind)
 {
     MOZ_ASSERT(lhs != ScratchRegister);
     ma_lw(ScratchRegister, addr);
     ma_b(lhs, ScratchRegister, label, c, jumpKind);
 }
 
 void
@@ -983,22 +570,16 @@ MacroAssemblerMIPS::ma_b(Address addr, I
 void
 MacroAssemblerMIPS::ma_b(Address addr, ImmGCPtr imm, Label* label, Condition c, JumpKind jumpKind)
 {
     ma_lw(SecondScratchReg, addr);
     ma_b(SecondScratchReg, imm, label, c, jumpKind);
 }
 
 void
-MacroAssemblerMIPS::ma_b(Label* label, JumpKind jumpKind)
-{
-    branchWithCode(getBranchCode(BranchIsJump), label, jumpKind);
-}
-
-void
 MacroAssemblerMIPS::ma_bal(Label* label, DelaySlotFill delaySlotFill)
 {
     if (label->bound()) {
         // Generate the long jump for calls because return address has to be
         // the address after the reserved block.
         addLongJump(nextOffset());
         ma_liPatchable(ScratchRegister, Imm32(label->offset()));
         as_jalr(ScratchRegister);
@@ -1088,311 +669,32 @@ MacroAssemblerMIPS::branchWithCode(InstI
     label->use(bo.getOffset());
     // Leave space for potential long jump.
     as_nop();
     as_nop();
     if (conditional)
         as_nop();
 }
 
-Assembler::Condition
-MacroAssemblerMIPS::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
-        as_sltu(scratch, rhs, lhs);
-        return NotEqual;
-      case AboveOrEqual:
-        // bgeu s,t,label =>
-        //   sltu at,s,t
-        //   beq at,$zero,offs
-        as_sltu(scratch, lhs, rhs);
-        return Equal;
-      case Below:
-        // bltu s,t,label =>
-        //   sltu at,s,t
-        //   bne at,$zero,offs
-        as_sltu(scratch, lhs, rhs);
-        return NotEqual;
-      case BelowOrEqual:
-        // bleu s,t,label =>
-        //   sltu at,t,s
-        //   beq at,$zero,offs
-        as_sltu(scratch, rhs, lhs);
-        return Equal;
-      case GreaterThan:
-        // bgt s,t,label =>
-        //   slt at,t,s
-        //   bne at,$zero,offs
-        as_slt(scratch, rhs, lhs);
-        return NotEqual;
-      case GreaterThanOrEqual:
-        // bge s,t,label =>
-        //   slt at,s,t
-        //   beq at,$zero,offs
-        as_slt(scratch, lhs, rhs);
-        return Equal;
-      case LessThan:
-        // blt s,t,label =>
-        //   slt at,s,t
-        //   bne at,$zero,offs
-        as_slt(scratch, lhs, rhs);
-        return NotEqual;
-      case LessThanOrEqual:
-        // ble s,t,label =>
-        //   slt at,t,s
-        //   beq at,$zero,offs
-        as_slt(scratch, rhs, lhs);
-        return Equal;
-      case Equal :
-      case NotEqual:
-      case Zero:
-      case NonZero:
-      case Always:
-      case Signed:
-      case NotSigned:
-        MOZ_CRASH("There is a better way to compare for equality.");
-        break;
-      case Overflow:
-        MOZ_CRASH("Overflow condition not supported for MIPS.");
-        break;
-      default:
-        MOZ_CRASH("Invalid condition for branch.");
-    }
-    return Always;
-}
-
-void
-MacroAssemblerMIPS::ma_cmp_set(Register rd, Register rs, Register rt, Condition c)
-{
-    switch (c) {
-      case Equal :
-        // seq d,s,t =>
-        //   xor d,s,t
-        //   sltiu d,d,1
-        as_xor(rd, rs, rt);
-        as_sltiu(rd, rd, 1);
-        break;
-      case NotEqual:
-        // sne d,s,t =>
-        //   xor d,s,t
-        //   sltu d,$zero,d
-        as_xor(rd, rs, rt);
-        as_sltu(rd, zero, rd);
-        break;
-      case Above:
-        // sgtu d,s,t =>
-        //   sltu d,t,s
-        as_sltu(rd, rt, rs);
-        break;
-      case AboveOrEqual:
-        // sgeu d,s,t =>
-        //   sltu d,s,t
-        //   xori d,d,1
-        as_sltu(rd, rs, rt);
-        as_xori(rd, rd, 1);
-        break;
-      case Below:
-        // sltu d,s,t
-        as_sltu(rd, rs, rt);
-        break;
-      case BelowOrEqual:
-        // sleu d,s,t =>
-        //   sltu d,t,s
-        //   xori d,d,1
-        as_sltu(rd, rt, rs);
-        as_xori(rd, rd, 1);
-        break;
-      case GreaterThan:
-        // sgt d,s,t =>
-        //   slt d,t,s
-        as_slt(rd, rt, rs);
-        break;
-      case GreaterThanOrEqual:
-        // sge d,s,t =>
-        //   slt d,s,t
-        //   xori d,d,1
-        as_slt(rd, rs, rt);
-        as_xori(rd, rd, 1);
-        break;
-      case LessThan:
-        // slt d,s,t
-        as_slt(rd, rs, rt);
-        break;
-      case LessThanOrEqual:
-        // sle d,s,t =>
-        //   slt d,t,s
-        //   xori d,d,1
-        as_slt(rd, rt, rs);
-        as_xori(rd, rd, 1);
-        break;
-      case Zero:
-        MOZ_ASSERT(rs == rt);
-        // seq d,s,$zero =>
-        //   xor d,s,$zero
-        //   sltiu d,d,1
-        as_xor(rd, rs, zero);
-        as_sltiu(rd, rd, 1);
-        break;
-      case NonZero:
-        // sne d,s,$zero =>
-        //   xor d,s,$zero
-        //   sltu d,$zero,d
-        as_xor(rd, rs, zero);
-        as_sltu(rd, zero, rd);
-        break;
-      case Signed:
-        as_slt(rd, rs, zero);
-        break;
-      case NotSigned:
-        // sge d,s,$zero =>
-        //   slt d,s,$zero
-        //   xori d,d,1
-        as_slt(rd, rs, zero);
-        as_xori(rd, rd, 1);
-        break;
-      default:
-        MOZ_CRASH("Invalid condition for ma_cmp_set.");
-    }
-}
-
-void
-MacroAssemblerMIPS::compareFloatingPoint(FloatFormat fmt, FloatRegister lhs, FloatRegister rhs,
-                                         DoubleCondition c, FloatTestKind* testKind,
-                                         FPConditionBit fcc)
-{
-    switch (c) {
-      case DoubleOrdered:
-        as_cun(fmt, lhs, rhs, fcc);
-        *testKind = TestForFalse;
-        break;
-      case DoubleEqual:
-        as_ceq(fmt, lhs, rhs, fcc);
-        *testKind = TestForTrue;
-        break;
-      case DoubleNotEqual:
-        as_cueq(fmt, lhs, rhs, fcc);
-        *testKind = TestForFalse;
-        break;
-      case DoubleGreaterThan:
-        as_colt(fmt, rhs, lhs, fcc);
-        *testKind = TestForTrue;
-        break;
-      case DoubleGreaterThanOrEqual:
-        as_cole(fmt, rhs, lhs, fcc);
-        *testKind = TestForTrue;
-        break;
-      case DoubleLessThan:
-        as_colt(fmt, lhs, rhs, fcc);
-        *testKind = TestForTrue;
-        break;
-      case DoubleLessThanOrEqual:
-        as_cole(fmt, lhs, rhs, fcc);
-        *testKind = TestForTrue;
-        break;
-      case DoubleUnordered:
-        as_cun(fmt, lhs, rhs, fcc);
-        *testKind = TestForTrue;
-        break;
-      case DoubleEqualOrUnordered:
-        as_cueq(fmt, lhs, rhs, fcc);
-        *testKind = TestForTrue;
-        break;
-      case DoubleNotEqualOrUnordered:
-        as_ceq(fmt, lhs, rhs, fcc);
-        *testKind = TestForFalse;
-        break;
-      case DoubleGreaterThanOrUnordered:
-        as_cult(fmt, rhs, lhs, fcc);
-        *testKind = TestForTrue;
-        break;
-      case DoubleGreaterThanOrEqualOrUnordered:
-        as_cule(fmt, rhs, lhs, fcc);
-        *testKind = TestForTrue;
-        break;
-      case DoubleLessThanOrUnordered:
-        as_cult(fmt, lhs, rhs, fcc);
-        *testKind = TestForTrue;
-        break;
-      case DoubleLessThanOrEqualOrUnordered:
-        as_cule(fmt, lhs, rhs, fcc);
-        *testKind = TestForTrue;
-        break;
-      default:
-        MOZ_CRASH("Invalid DoubleCondition.");
-    }
-}
-
-void
-MacroAssemblerMIPS::ma_cmp_set_double(Register dest, FloatRegister lhs, FloatRegister rhs,
-                                      DoubleCondition c)
-{
-    ma_li(dest, Imm32(0));
-    ma_li(ScratchRegister, Imm32(1));
-
-    FloatTestKind moveCondition;
-    compareFloatingPoint(DoubleFloat, lhs, rhs, c, &moveCondition);
-
-    if (moveCondition == TestForTrue)
-        as_movt(dest, ScratchRegister);
-    else
-        as_movf(dest, ScratchRegister);
-}
-
-void
-MacroAssemblerMIPS::ma_cmp_set_float32(Register dest, FloatRegister lhs, FloatRegister rhs,
-                                       DoubleCondition c)
-{
-    ma_li(dest, Imm32(0));
-    ma_li(ScratchRegister, Imm32(1));
-
-    FloatTestKind moveCondition;
-    compareFloatingPoint(SingleFloat, lhs, rhs, c, &moveCondition);
-
-    if (moveCondition == TestForTrue)
-        as_movt(dest, ScratchRegister);
-    else
-        as_movf(dest, ScratchRegister);
-}
-
-void
-MacroAssemblerMIPS::ma_cmp_set(Register rd, Register rs, Imm32 imm, Condition c)
-{
-    ma_li(ScratchRegister, imm);
-    ma_cmp_set(rd, rs, ScratchRegister, c);
-}
-
 void
 MacroAssemblerMIPS::ma_cmp_set(Register rd, Register rs, Address addr, Condition c)
 {
     ma_lw(ScratchRegister, addr);
     ma_cmp_set(rd, rs, ScratchRegister, c);
 }
 
 void
 MacroAssemblerMIPS::ma_cmp_set(Register dst, Address lhs, Register rhs, Condition c)
 {
     ma_lw(ScratchRegister, lhs);
     ma_cmp_set(dst, ScratchRegister, rhs, c);
 }
 
 // fp instructions
 void
-MacroAssemblerMIPS::ma_lis(FloatRegister dest, float value)
-{
-    Imm32 imm(mozilla::BitwiseCast<uint32_t>(value));
-
-    ma_li(ScratchRegister, imm);
-    moveToFloat32(ScratchRegister, dest);
-}
-
-void
 MacroAssemblerMIPS::ma_lid(FloatRegister dest, double value)
 {
     struct DoubleStruct {
         uint32_t lo;
         uint32_t hi;
     } ;
     DoubleStruct intStruct = mozilla::BitwiseCast<DoubleStruct>(value);
 
@@ -1409,24 +711,16 @@ MacroAssemblerMIPS::ma_lid(FloatRegister
         moveToDoubleLo(zero, dest);
     } else {
         ma_li(ScratchRegister, Imm32(intStruct.lo));
         moveToDoubleLo(ScratchRegister, dest);
     }
 }
 
 void
-MacroAssemblerMIPS::ma_liNegZero(FloatRegister dest)
-{
-    moveToDoubleLo(zero, dest);
-    ma_li(ScratchRegister, Imm32(INT_MIN));
-    moveToDoubleHi(ScratchRegister, dest);
-}
-
-void
 MacroAssemblerMIPS::ma_mv(FloatRegister src, ValueOperand dest)
 {
     moveFromDoubleLo(src, dest.payloadReg());
     moveFromDoubleHi(src, dest.typeReg());
 }
 
 void
 MacroAssemblerMIPS::ma_mv(ValueOperand src, FloatRegister dest)
@@ -1477,73 +771,41 @@ MacroAssemblerMIPS::ma_sd(FloatRegister 
         ma_li(ScratchRegister, Imm32(address.offset));
         as_addu(ScratchRegister, address.base, ScratchRegister);
         as_ss(ft, ScratchRegister, PAYLOAD_OFFSET);
         as_ss(getOddPair(ft), ScratchRegister, TAG_OFFSET);
     }
 }
 
 void
-MacroAssemblerMIPS::ma_sd(FloatRegister ft, BaseIndex address)
-{
-    asMasm().computeScaledAddress(address, SecondScratchReg);
-    ma_sd(ft, Address(SecondScratchReg, address.offset));
-}
-
-void
 MacroAssemblerMIPS::ma_ss(FloatRegister ft, Address address)
 {
     if (Imm16::IsInSignedRange(address.offset)) {
         as_ss(ft, address.base, address.offset);
     } else {
         ma_li(ScratchRegister, Imm32(address.offset));
         as_addu(ScratchRegister, address.base, ScratchRegister);
         as_ss(ft, ScratchRegister, 0);
     }
 }
 
 void
-MacroAssemblerMIPS::ma_ss(FloatRegister ft, BaseIndex address)
-{
-    asMasm().computeScaledAddress(address, SecondScratchReg);
-    ma_ss(ft, Address(SecondScratchReg, address.offset));
-}
-
-void
 MacroAssemblerMIPS::ma_pop(FloatRegister fs)
 {
     ma_ld(fs.doubleOverlay(0), Address(StackPointer, 0));
     as_addiu(StackPointer, StackPointer, sizeof(double));
 }
 
 void
 MacroAssemblerMIPS::ma_push(FloatRegister fs)
 {
     as_addiu(StackPointer, StackPointer, -sizeof(double));
     ma_sd(fs.doubleOverlay(0), Address(StackPointer, 0));
 }
 
-void
-MacroAssemblerMIPS::ma_bc1s(FloatRegister lhs, FloatRegister rhs, Label* label,
-                            DoubleCondition c, JumpKind jumpKind, FPConditionBit fcc)
-{
-    FloatTestKind testKind;
-    compareFloatingPoint(SingleFloat, lhs, rhs, c, &testKind, fcc);
-    branchWithCode(getBranchCode(testKind, fcc), label, jumpKind);
-}
-
-void
-MacroAssemblerMIPS::ma_bc1d(FloatRegister lhs, FloatRegister rhs, Label* label,
-                            DoubleCondition c, JumpKind jumpKind, FPConditionBit fcc)
-{
-    FloatTestKind testKind;
-    compareFloatingPoint(DoubleFloat, lhs, rhs, c, &testKind, fcc);
-    branchWithCode(getBranchCode(testKind, fcc), label, jumpKind);
-}
-
 bool
 MacroAssemblerMIPSCompat::buildOOLFakeExitFrame(void* fakeReturnAddr)
 {
     uint32_t descriptor = MakeFrameDescriptor(asMasm().framePushed(), JitFrame_IonJS);
 
     asMasm().Push(Imm32(descriptor)); // descriptor_
     asMasm().Push(ImmPtr(fakeReturnAddr));
 
@@ -2992,32 +2254,16 @@ MacroAssemblerMIPSCompat::storeTypeTag(I
     MOZ_ASSERT(dest.offset == 0);
 
     computeScaledAddress(dest, SecondScratchReg);
     ma_li(ScratchRegister, tag);
     as_sw(ScratchRegister, SecondScratchReg, TAG_OFFSET);
 }
 
 void
-MacroAssemblerMIPS::ma_call(ImmPtr dest)
-{
-    ma_liPatchable(CallReg, dest);
-    as_jalr(CallReg);
-    as_nop();
-}
-
-void
-MacroAssemblerMIPS::ma_jump(ImmPtr dest)
-{
-    ma_liPatchable(ScratchRegister, dest);
-    as_jr(ScratchRegister);
-    as_nop();
-}
-
-void
 MacroAssemblerMIPSCompat::breakpoint()
 {
     as_break(0);
 }
 
 void
 MacroAssemblerMIPSCompat::ensureDouble(const ValueOperand& source, FloatRegister dest,
                                        Label* failure)
@@ -3242,28 +2488,16 @@ MacroAssemblerMIPSCompat::profilerEnterF
 }
 
 void
 MacroAssemblerMIPSCompat::profilerExitFrame()
 {
     branch(GetJitContext()->runtime->jitRuntime()->getProfilerExitFrameTail());
 }
 
-MacroAssembler&
-MacroAssemblerMIPS::asMasm()
-{
-    return *static_cast<MacroAssembler*>(this);
-}
-
-const MacroAssembler&
-MacroAssemblerMIPS::asMasm() const
-{
-    return *static_cast<const MacroAssembler*>(this);
-}
-
 //{{{ check_macroassembler_style
 // ===============================================================
 // Stack manipulation functions.
 
 void
 MacroAssembler::PushRegsInMask(LiveRegisterSet set)
 {
     int32_t diffF = set.fpus().getPushSizeInBytes();
--- a/js/src/jit/mips32/MacroAssembler-mips32.h
+++ b/js/src/jit/mips32/MacroAssembler-mips32.h
@@ -7,48 +7,22 @@
 #ifndef jit_mips32_MacroAssembler_mips32_h
 #define jit_mips32_MacroAssembler_mips32_h
 
 #include "jsopcode.h"
 
 #include "jit/AtomicOp.h"
 #include "jit/IonCaches.h"
 #include "jit/JitFrames.h"
-#include "jit/mips32/Assembler-mips32.h"
+#include "jit/mips-shared/MacroAssembler-mips-shared.h"
 #include "jit/MoveResolver.h"
 
 namespace js {
 namespace jit {
 
-enum LoadStoreSize
-{
-    SizeByte = 8,
-    SizeHalfWord = 16,
-    SizeWord = 32,
-    SizeDouble = 64
-};
-
-enum LoadStoreExtension
-{
-    ZeroExtend = 0,
-    SignExtend = 1
-};
-
-enum JumpKind
-{
-    LongJump = 0,
-    ShortJump = 1
-};
-
-enum DelaySlotFill
-{
-    DontFillDelaySlot = 0,
-    FillDelaySlot = 1
-};
-
 struct ImmTag : public Imm32
 {
     ImmTag(JSValueTag mask)
       : Imm32(int32_t(mask))
     { }
 };
 
 struct ImmType : public ImmTag
@@ -56,148 +30,71 @@ struct ImmType : public ImmTag
     ImmType(JSValueType type)
       : ImmTag(JSVAL_TYPE_TO_TAG(type))
     { }
 };
 
 static const ValueOperand JSReturnOperand = ValueOperand(JSReturnReg_Type, JSReturnReg_Data);
 static const ValueOperand softfpReturnOperand = ValueOperand(v1, v0);
 
-static Register CallReg = t9;
 static const int defaultShift = 3;
 static_assert(1 << defaultShift == sizeof(JS::Value), "The defaultShift is wrong");
 
 static const uint32_t LOW_32_MASK = (1LL << 32) - 1;
 static const int32_t LOW_32_OFFSET = 0;
 static const int32_t HIGH_32_OFFSET = 4;
 
-class MacroAssemblerMIPS : public Assembler
+class MacroAssemblerMIPS : public MacroAssemblerMIPSShared
 {
-  protected:
-    // Perform a downcast. Should be removed by Bug 996602.
-    MacroAssembler& asMasm();
-    const MacroAssembler& asMasm() const;
-
-    void branchWithCode(InstImm code, Label* label, JumpKind jumpKind);
-    Condition ma_cmp(Register rd, Register lhs, Register rhs, Condition c);
-
-    void compareFloatingPoint(FloatFormat fmt, FloatRegister lhs, FloatRegister rhs,
-                              DoubleCondition c, FloatTestKind* testKind,
-                              FPConditionBit fcc = FCC0);
-
   public:
-    void ma_move(Register rd, Register rs);
-
-    void ma_li(Register dest, ImmGCPtr ptr);
+    using MacroAssemblerMIPSShared::ma_b;
+    using MacroAssemblerMIPSShared::ma_li;
+    using MacroAssemblerMIPSShared::ma_ss;
+    using MacroAssemblerMIPSShared::ma_sd;
+    using MacroAssemblerMIPSShared::ma_load;
+    using MacroAssemblerMIPSShared::ma_store;
+    using MacroAssemblerMIPSShared::ma_cmp_set;
+    using MacroAssemblerMIPSShared::ma_subTestOverflow;
 
     void ma_li(Register dest, AbsoluteLabel* label);
 
-    void ma_li(Register dest, Imm32 imm);
     void ma_liPatchable(Register dest, Imm32 imm);
     void ma_li(Register dest, ImmWord imm);
     void ma_liPatchable(Register dest, ImmPtr imm);
     void ma_liPatchable(Register dest, ImmWord imm);
 
-    // Shift operations
-    void ma_sll(Register rd, Register rt, Imm32 shift);
-    void ma_srl(Register rd, Register rt, Imm32 shift);
-    void ma_sra(Register rd, Register rt, Imm32 shift);
-    void ma_ror(Register rd, Register rt, Imm32 shift);
-    void ma_rol(Register rd, Register rt, Imm32 shift);
-
-    void ma_sll(Register rd, Register rt, Register shift);
-    void ma_srl(Register rd, Register rt, Register shift);
-    void ma_sra(Register rd, Register rt, Register shift);
-    void ma_ror(Register rd, Register rt, Register shift);
-    void ma_rol(Register rd, Register rt, Register shift);
-
-    // Negate
-    void ma_negu(Register rd, Register rs);
-
-    void ma_not(Register rd, Register rs);
-
-    // and
-    void ma_and(Register rd, Register rs);
-    void ma_and(Register rd, Imm32 imm);
-    void ma_and(Register rd, Register rs, Imm32 imm);
-
-    // or
-    void ma_or(Register rd, Register rs);
-    void ma_or(Register rd, Imm32 imm);
-    void ma_or(Register rd, Register rs, Imm32 imm);
-
-    // xor
-    void ma_xor(Register rd, Register rs);
-    void ma_xor(Register rd, Imm32 imm);
-    void ma_xor(Register rd, Register rs, Imm32 imm);
-
     // load
     void ma_load(Register dest, Address address, LoadStoreSize size = SizeWord,
                  LoadStoreExtension extension = SignExtend);
-    void ma_load(Register dest, const BaseIndex& src, LoadStoreSize size = SizeWord,
-                 LoadStoreExtension extension = SignExtend);
 
     // store
     void ma_store(Register data, Address address, LoadStoreSize size = SizeWord,
                   LoadStoreExtension extension = SignExtend);
-    void ma_store(Register data, const BaseIndex& dest, LoadStoreSize size = SizeWord,
-                  LoadStoreExtension extension = SignExtend);
-    void ma_store(Imm32 imm, const BaseIndex& dest, LoadStoreSize size = SizeWord,
-                  LoadStoreExtension extension = SignExtend);
 
     // arithmetic based ops
     // add
-    void ma_addu(Register rd, Register rs, Imm32 imm);
-    void ma_addu(Register rd, Register rs);
-    void ma_addu(Register rd, Imm32 imm);
     void ma_addTestOverflow(Register rd, Register rs, Register rt, Label* overflow);
     void ma_addTestOverflow(Register rd, Register rs, Imm32 imm, Label* overflow);
 
     // subtract
-    void ma_subu(Register rd, Register rs, Imm32 imm);
-    void ma_subu(Register rd, Imm32 imm);
     void ma_subTestOverflow(Register rd, Register rs, Register rt, Label* overflow);
-    void ma_subTestOverflow(Register rd, Register rs, Imm32 imm, Label* overflow);
-
-    // multiplies.  For now, there are only few that we care about.
-    void ma_mult(Register rs, Imm32 imm);
-    void ma_mul_branch_overflow(Register rd, Register rs, Register rt, Label* overflow);
-    void ma_mul_branch_overflow(Register rd, Register rs, Imm32 imm, Label* overflow);
-
-    // divisions
-    void ma_div_branch_overflow(Register rd, Register rs, Register rt, Label* overflow);
-    void ma_div_branch_overflow(Register rd, Register rs, Imm32 imm, Label* overflow);
-
-    // fast mod, uses scratch registers, and thus needs to be in the assembler
-    // implicitly assumes that we can overwrite dest at the beginning of the sequence
-    void ma_mod_mask(Register src, Register dest, Register hold, Register remain,
-                     int32_t shift, Label* negZero = nullptr);
 
     // memory
     // shortcut for when we know we're transferring 32 bits of data
     void ma_lw(Register data, Address address);
 
     void ma_sw(Register data, Address address);
     void ma_sw(Imm32 imm, Address address);
     void ma_sw(Register data, BaseIndex& address);
 
     void ma_pop(Register r);
     void ma_push(Register r);
 
+    void branchWithCode(InstImm code, Label* label, JumpKind jumpKind);
     // branches when done from within mips-specific code
-    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) {
-        ma_b(lhs, ImmWord(uintptr_t(imm.value)), l, c, jumpKind);
-    }
-    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);
-    }
     void ma_b(Register lhs, ImmWord imm, Label* l, Condition c, JumpKind jumpKind = LongJump)
     {
         ma_b(lhs, Imm32(uint32_t(imm.value)), l, c, jumpKind);
     }
     void ma_b(Address addr, ImmWord imm, Label* l, Condition c, JumpKind jumpKind = LongJump)
     {
         ma_b(addr, Imm32(uint32_t(imm.value)), l, c, jumpKind);
     }
@@ -206,86 +103,53 @@ class MacroAssemblerMIPS : public Assemb
     void ma_b(Address addr, Imm32 imm, Label* l, Condition c, JumpKind jumpKind = LongJump);
     void ma_b(Address addr, ImmGCPtr imm, Label* l, Condition c, JumpKind jumpKind = LongJump);
     void ma_b(Address addr, Register rhs, Label* l, Condition c, JumpKind jumpKind = LongJump) {
         MOZ_ASSERT(rhs != ScratchRegister);
         ma_load(ScratchRegister, addr, SizeWord);
         ma_b(ScratchRegister, rhs, l, c, jumpKind);
     }
 
-    void ma_b(Label* l, JumpKind jumpKind = LongJump);
     void ma_bal(Label* l, DelaySlotFill delaySlotFill = FillDelaySlot);
 
     // fp instructions
-    void ma_lis(FloatRegister dest, float value);
     void ma_lid(FloatRegister dest, double value);
-    void ma_liNegZero(FloatRegister dest);
 
     void ma_mv(FloatRegister src, ValueOperand dest);
     void ma_mv(ValueOperand src, FloatRegister dest);
 
     void ma_ls(FloatRegister fd, Address address);
     void ma_ld(FloatRegister fd, Address address);
     void ma_sd(FloatRegister fd, Address address);
-    void ma_sd(FloatRegister fd, BaseIndex address);
     void ma_ss(FloatRegister fd, Address address);
-    void ma_ss(FloatRegister fd, BaseIndex address);
 
     void ma_pop(FloatRegister fs);
     void ma_push(FloatRegister fs);
 
-    //FP branches
-    void ma_bc1s(FloatRegister lhs, FloatRegister rhs, Label* label, DoubleCondition c,
-                 JumpKind jumpKind = LongJump, FPConditionBit fcc = FCC0);
-    void ma_bc1d(FloatRegister lhs, FloatRegister rhs, Label* label, DoubleCondition c,
-                 JumpKind jumpKind = LongJump, FPConditionBit fcc = FCC0);
-
-    void ma_call(ImmPtr dest);
-
-    void ma_jump(ImmPtr dest);
-
-    void ma_cmp_set(Register dst, Register lhs, Register rhs, Condition c);
-    void ma_cmp_set(Register dst, Register lhs, Imm32 imm, Condition c);
     void ma_cmp_set(Register dst, Register lhs, ImmPtr imm, Condition c) {
         ma_cmp_set(dst, lhs, Imm32(uint32_t(imm.value)), c);
     }
     void ma_cmp_set(Register rd, Register rs, Address addr, Condition c);
     void ma_cmp_set(Register dst, Address lhs, Register rhs, Condition c);
     void ma_cmp_set(Register dst, Address lhs, ImmPtr imm, Condition c) {
         ma_lw(ScratchRegister, lhs);
         ma_li(SecondScratchReg, Imm32(uint32_t(imm.value)));
         ma_cmp_set(dst, ScratchRegister, SecondScratchReg, c);
     }
-    void ma_cmp_set_double(Register dst, FloatRegister lhs, FloatRegister rhs, DoubleCondition c);
-    void ma_cmp_set_float32(Register dst, FloatRegister lhs, FloatRegister rhs, DoubleCondition c);
 
     // These fuctions abstract the access to high part of the double precision
     // float register. It is intended to work on both 32 bit and 64 bit
     // floating point coprocessor.
     // :TODO: (Bug 985881) Modify this for N32 ABI to use mthc1 and mfhc1
     void moveToDoubleHi(Register src, FloatRegister dest) {
         as_mtc1(src, getOddPair(dest));
     }
     void moveFromDoubleHi(FloatRegister src, Register dest) {
         as_mfc1(dest, getOddPair(src));
     }
-
-    void moveToDoubleLo(Register src, FloatRegister dest) {
-        as_mtc1(src, dest);
-    }
-    void moveFromDoubleLo(FloatRegister src, Register dest) {
-        as_mfc1(dest, src);
-    }
-
-    void moveToFloat32(Register src, FloatRegister dest) {
-        as_mtc1(src, dest);
-    }
-    void moveFromFloat32(FloatRegister src, Register dest) {
-        as_mfc1(dest, src);
-    }
 };
 
 class MacroAssembler;
 
 class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS
 {
   public:
     using MacroAssemblerMIPS::call;
--- a/js/src/moz.build
+++ b/js/src/moz.build
@@ -482,16 +482,17 @@ elif CONFIG['JS_CODEGEN_MIPS32'] or CONF
     UNIFIED_SOURCES += [
         'jit/mips-shared/Architecture-mips-shared.cpp',
         'jit/mips-shared/Assembler-mips-shared.cpp',
         'jit/mips-shared/Bailouts-mips-shared.cpp',
         'jit/mips-shared/BaselineCompiler-mips-shared.cpp',
         'jit/mips-shared/BaselineIC-mips-shared.cpp',
         'jit/mips-shared/CodeGenerator-mips-shared.cpp',
         'jit/mips-shared/Lowering-mips-shared.cpp',
+        'jit/mips-shared/MacroAssembler-mips-shared.cpp',
         'jit/mips-shared/MoveEmitter-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',