Bug 1393347 - MIPS: Output some more infomation when debug jit code. r=luke
authorYu Yin <yuyin-hf@loongson.cn>
Thu, 24 Aug 2017 00:02:00 -0400
changeset 377393 2c395a5be25de6a0be1fd93a38784118127a7208
parent 377392 78b06492f28e1b7249df0719cbcb923d5e0ff723
child 377394 1de6b40aa43e96b3cf0cb7f1d098d7cf3e046b7d
push id94272
push userryanvm@gmail.com
push dateTue, 29 Aug 2017 11:55:53 +0000
treeherdermozilla-inbound@1de6b40aa43e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs1393347
milestone57.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1393347 - MIPS: Output some more infomation when debug jit code. r=luke
js/src/jit/mips-shared/Assembler-mips-shared.cpp
js/src/jit/mips-shared/Assembler-mips-shared.h
js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp
js/src/jit/mips32/MacroAssembler-mips32.cpp
js/src/jit/mips64/MacroAssembler-mips64.cpp
--- a/js/src/jit/mips-shared/Assembler-mips-shared.cpp
+++ b/js/src/jit/mips-shared/Assembler-mips-shared.cpp
@@ -310,83 +310,94 @@ AssemblerMIPSShared::nopAlign(int alignm
         }
     }
     return ret;
 }
 
 BufferOffset
 AssemblerMIPSShared::as_nop()
 {
+    spew("nop");
     return writeInst(op_special | ff_sll);
 }
 
 // Logical operations.
 BufferOffset
 AssemblerMIPSShared::as_and(Register rd, Register rs, Register rt)
 {
+    spew("and    %3s,%3s,%3s", rd.name(), rs.name(), rt.name());
     return writeInst(InstReg(op_special, rs, rt, rd, ff_and).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_or(Register rd, Register rs, Register rt)
 {
+    spew("or     %3s,%3s,%3s", rd.name(), rs.name(), rt.name());
     return writeInst(InstReg(op_special, rs, rt, rd, ff_or).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_xor(Register rd, Register rs, Register rt)
 {
+    spew("xor    %3s,%3s,%3s", rd.name(), rs.name(), rt.name());
     return writeInst(InstReg(op_special, rs, rt, rd, ff_xor).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_nor(Register rd, Register rs, Register rt)
 {
+    spew("nor    %3s,%3s,%3s", rd.name(), rs.name(), rt.name());
     return writeInst(InstReg(op_special, rs, rt, rd, ff_nor).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_andi(Register rd, Register rs, int32_t j)
 {
     MOZ_ASSERT(Imm16::IsInUnsignedRange(j));
+    spew("andi   %3s,%3s,0x%x", rd.name(), rs.name(), j);
     return writeInst(InstImm(op_andi, rs, rd, Imm16(j)).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_ori(Register rd, Register rs, int32_t j)
 {
     MOZ_ASSERT(Imm16::IsInUnsignedRange(j));
+    spew("ori    %3s,%3s,0x%x", rd.name(), rs.name(), j);
     return writeInst(InstImm(op_ori, rs, rd, Imm16(j)).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_xori(Register rd, Register rs, int32_t j)
 {
     MOZ_ASSERT(Imm16::IsInUnsignedRange(j));
+    spew("xori   %3s,%3s,0x%x", rd.name(), rs.name(), j);
     return writeInst(InstImm(op_xori, rs, rd, Imm16(j)).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_lui(Register rd, int32_t j)
 {
     MOZ_ASSERT(Imm16::IsInUnsignedRange(j));
+    spew("lui    %3s,0x%x", rd.name(), j);
     return writeInst(InstImm(op_lui, zero, rd, Imm16(j)).encode());
 }
 
 // Branch and jump instructions
 BufferOffset
 AssemblerMIPSShared::as_bal(BOffImm16 off)
 {
+    spew("bal    %d", off.decode());
     BufferOffset bo = writeInst(InstImm(op_regimm, zero, rt_bgezal, off).encode());
     return bo;
 }
 
 BufferOffset
 AssemblerMIPSShared::as_b(BOffImm16 off)
 {
+    spew("b      %d", off.decode());
     BufferOffset bo = writeInst(InstImm(op_beq, zero, zero, off).encode());
     return bo;
 }
 
 InstImm
 AssemblerMIPSShared::getBranchCode(JumpOrCall jumpOrCall)
 {
     if (jumpOrCall == BranchIsCall)
@@ -436,1102 +447,1315 @@ AssemblerMIPSShared::getBranchCode(Float
     uint32_t rtField = ((testKind == TestForTrue ? 1 : 0) | (fcc << FccShift)) << RTShift;
 
     return InstImm(op_cop1, rs_bc1, rtField, BOffImm16(0));
 }
 
 BufferOffset
 AssemblerMIPSShared::as_j(JOffImm26 off)
 {
+    spew("j      0x%x", off.decode());
     BufferOffset bo = writeInst(InstJump(op_j, off).encode());
     return bo;
 }
 BufferOffset
 AssemblerMIPSShared::as_jal(JOffImm26 off)
 {
+    spew("jal    0x%x", off.decode());
     BufferOffset bo = writeInst(InstJump(op_jal, off).encode());
     return bo;
 }
 
 BufferOffset
 AssemblerMIPSShared::as_jr(Register rs)
 {
+    spew("jr     %3s", rs.name());
     BufferOffset bo = writeInst(InstReg(op_special, rs, zero, zero, ff_jr).encode());
     return bo;
 }
 BufferOffset
 AssemblerMIPSShared::as_jalr(Register rs)
 {
+    spew("jalr   %3s", rs.name());
     BufferOffset bo = writeInst(InstReg(op_special, rs, zero, ra, ff_jalr).encode());
     return bo;
 }
 
 
 // Arithmetic instructions
 BufferOffset
 AssemblerMIPSShared::as_addu(Register rd, Register rs, Register rt)
 {
+    spew("addu   %3s,%3s,%3s", rd.name(), rs.name(), rt.name());
     return writeInst(InstReg(op_special, rs, rt, rd, ff_addu).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_addiu(Register rd, Register rs, int32_t j)
 {
     MOZ_ASSERT(Imm16::IsInSignedRange(j));
+    spew("addiu  %3s,%3s,0x%x", rd.name(), rs.name(), j);
     return writeInst(InstImm(op_addiu, rs, rd, Imm16(j)).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_daddu(Register rd, Register rs, Register rt)
 {
+    spew("daddu  %3s,%3s,%3s", rd.name(), rs.name(), rt.name());
     return writeInst(InstReg(op_special, rs, rt, rd, ff_daddu).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_daddiu(Register rd, Register rs, int32_t j)
 {
     MOZ_ASSERT(Imm16::IsInSignedRange(j));
+    spew("daddiu %3s,%3s,0x%x", rd.name(), rs.name(), j);
     return writeInst(InstImm(op_daddiu, rs, rd, Imm16(j)).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_subu(Register rd, Register rs, Register rt)
 {
+    spew("subu   %3s,%3s,%3s", rd.name(), rs.name(), rt.name());
     return writeInst(InstReg(op_special, rs, rt, rd, ff_subu).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_dsubu(Register rd, Register rs, Register rt)
 {
+    spew("dsubu  %3s,%3s,%3s", rd.name(), rs.name(), rt.name());
     return writeInst(InstReg(op_special, rs, rt, rd, ff_dsubu).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_mult(Register rs, Register rt)
 {
+    spew("mult   %3s,%3s", rs.name(), rt.name());
     return writeInst(InstReg(op_special, rs, rt, ff_mult).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_multu(Register rs, Register rt)
 {
+    spew("multu  %3s,%3s", rs.name(), rt.name());
     return writeInst(InstReg(op_special, rs, rt, ff_multu).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_dmult(Register rs, Register rt)
 {
+    spew("dmult  %3s,%3s", rs.name(), rt.name());
     return writeInst(InstReg(op_special, rs, rt, ff_dmult).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_dmultu(Register rs, Register rt)
 {
+    spew("dmultu %3s,%3s", rs.name(), rt.name());
     return writeInst(InstReg(op_special, rs, rt, ff_dmultu).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_div(Register rs, Register rt)
 {
+    spew("div    %3s,%3s", rs.name(), rt.name());
     return writeInst(InstReg(op_special, rs, rt, ff_div).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_divu(Register rs, Register rt)
 {
+    spew("divu   %3s,%3s", rs.name(), rt.name());
     return writeInst(InstReg(op_special, rs, rt, ff_divu).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_ddiv(Register rs, Register rt)
 {
+    spew("ddiv   %3s,%3s", rs.name(), rt.name());
     return writeInst(InstReg(op_special, rs, rt, ff_ddiv).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_ddivu(Register rs, Register rt)
 {
+    spew("ddivu  %3s,%3s", rs.name(), rt.name());
     return writeInst(InstReg(op_special, rs, rt, ff_ddivu).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_mul(Register rd, Register rs, Register rt)
 {
+    spew("mul    %3s,%3s,%3s", rd.name(), rs.name(), rt.name());
     return writeInst(InstReg(op_special2, rs, rt, rd, ff_mul).encode());
 }
 
 // Shift instructions
 BufferOffset
 AssemblerMIPSShared::as_sll(Register rd, Register rt, uint16_t sa)
 {
     MOZ_ASSERT(sa < 32);
+    spew("sll    %3s,%3s, 0x%x", rd.name(), rt.name(), sa);
     return writeInst(InstReg(op_special, rs_zero, rt, rd, sa, ff_sll).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_dsll(Register rd, Register rt, uint16_t sa)
 {
     MOZ_ASSERT(sa < 32);
+    spew("dsll   %3s,%3s, 0x%x", rd.name(), rt.name(), sa);
     return writeInst(InstReg(op_special, rs_zero, rt, rd, sa, ff_dsll).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_dsll32(Register rd, Register rt, uint16_t sa)
 {
     MOZ_ASSERT(31 < sa && sa < 64);
+    spew("dsll32 %3s,%3s, 0x%x", rd.name(), rt.name(), sa - 32);
     return writeInst(InstReg(op_special, rs_zero, rt, rd, sa - 32, ff_dsll32).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_sllv(Register rd, Register rt, Register rs)
 {
+    spew("sllv   %3s,%3s,%3s", rd.name(), rt.name(), rs.name());
     return writeInst(InstReg(op_special, rs, rt, rd, ff_sllv).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_dsllv(Register rd, Register rt, Register rs)
 {
+    spew("dsllv  %3s,%3s,%3s", rd.name(), rt.name(), rs.name());
     return writeInst(InstReg(op_special, rs, rt, rd, ff_dsllv).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_srl(Register rd, Register rt, uint16_t sa)
 {
     MOZ_ASSERT(sa < 32);
+    spew("srl    %3s,%3s, 0x%x", rd.name(), rt.name(), sa);
     return writeInst(InstReg(op_special, rs_zero, rt, rd, sa, ff_srl).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_dsrl(Register rd, Register rt, uint16_t sa)
 {
     MOZ_ASSERT(sa < 32);
+    spew("dsrl   %3s,%3s, 0x%x", rd.name(), rt.name(), sa);
     return writeInst(InstReg(op_special, rs_zero, rt, rd, sa, ff_dsrl).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_dsrl32(Register rd, Register rt, uint16_t sa)
 {
     MOZ_ASSERT(31 < sa && sa < 64);
+    spew("dsrl32 %3s,%3s, 0x%x", rd.name(), rt.name(), sa - 32);
     return writeInst(InstReg(op_special, rs_zero, rt, rd, sa - 32, ff_dsrl32).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_srlv(Register rd, Register rt, Register rs)
 {
+    spew("srlv   %3s,%3s,%3s", rd.name(), rt.name(), rs.name());
     return writeInst(InstReg(op_special, rs, rt, rd, ff_srlv).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_dsrlv(Register rd, Register rt, Register rs)
 {
+    spew("dsrlv  %3s,%3s,%3s", rd.name(), rt.name(), rs.name());
     return writeInst(InstReg(op_special, rs, rt, rd, ff_dsrlv).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_sra(Register rd, Register rt, uint16_t sa)
 {
     MOZ_ASSERT(sa < 32);
+    spew("sra    %3s,%3s, 0x%x", rd.name(), rt.name(), sa);
     return writeInst(InstReg(op_special, rs_zero, rt, rd, sa, ff_sra).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_dsra(Register rd, Register rt, uint16_t sa)
 {
     MOZ_ASSERT(sa < 32);
+    spew("dsra   %3s,%3s, 0x%x", rd.name(), rt.name(), sa);
     return writeInst(InstReg(op_special, rs_zero, rt, rd, sa, ff_dsra).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_dsra32(Register rd, Register rt, uint16_t sa)
 {
     MOZ_ASSERT(31 < sa && sa < 64);
+    spew("dsra32 %3s,%3s, 0x%x", rd.name(), rt.name(), sa - 32);
     return writeInst(InstReg(op_special, rs_zero, rt, rd, sa - 32, ff_dsra32).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_srav(Register rd, Register rt, Register rs)
 {
+    spew("srav   %3s,%3s,%3s", rd.name(), rt.name(), rs.name());
     return writeInst(InstReg(op_special, rs, rt, rd, ff_srav).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_dsrav(Register rd, Register rt, Register rs)
 {
+    spew("dsrav  %3s,%3s,%3s", rd.name(), rt.name(), rs.name());
     return writeInst(InstReg(op_special, rs, rt, rd, ff_dsrav).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_rotr(Register rd, Register rt, uint16_t sa)
 {
     MOZ_ASSERT(sa < 32);
+    spew("rotr   %3s,%3s, 0x%x", rd.name(), rt.name(), sa);
     return writeInst(InstReg(op_special, rs_one, rt, rd, sa, ff_srl).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_drotr(Register rd, Register rt, uint16_t sa)
 {
     MOZ_ASSERT(sa < 32);
+    spew("drotr  %3s,%3s, 0x%x", rd.name(), rt.name(), sa);
     return writeInst(InstReg(op_special, rs_one, rt, rd, sa, ff_dsrl).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_drotr32(Register rd, Register rt, uint16_t sa)
 {
     MOZ_ASSERT(31 < sa && sa < 64);
+    spew("drotr32%3s,%3s, 0x%x", rd.name(), rt.name(), sa - 32);
     return writeInst(InstReg(op_special, rs_one, rt, rd, sa - 32, ff_dsrl32).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_rotrv(Register rd, Register rt, Register rs)
 {
+    spew("rotrv  %3s,%3s,%3s", rd.name(), rt.name(), rs.name());
     return writeInst(InstReg(op_special, rs, rt, rd, 1, ff_srlv).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_drotrv(Register rd, Register rt, Register rs)
 {
+    spew("drotrv %3s,%3s,%3s", rd.name(), rt.name(), rs.name());
     return writeInst(InstReg(op_special, rs, rt, rd, 1, ff_dsrlv).encode());
 }
 
 // Load and store instructions
 BufferOffset
 AssemblerMIPSShared::as_lb(Register rd, Register rs, int16_t off)
 {
+    spew("lb     %3s, (0x%x)%2s", rd.name(), off, rs.name());
     return writeInst(InstImm(op_lb, rs, rd, Imm16(off)).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_lbu(Register rd, Register rs, int16_t off)
 {
+    spew("lbu    %3s, (0x%x)%2s", rd.name(), off, rs.name());
     return writeInst(InstImm(op_lbu, rs, rd, Imm16(off)).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_lh(Register rd, Register rs, int16_t off)
 {
+    spew("lh     %3s, (0x%x)%2s", rd.name(), off, rs.name());
     return writeInst(InstImm(op_lh, rs, rd, Imm16(off)).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_lhu(Register rd, Register rs, int16_t off)
 {
+    spew("lhu    %3s, (0x%x)%2s", rd.name(), off, rs.name());
     return writeInst(InstImm(op_lhu, rs, rd, Imm16(off)).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_lw(Register rd, Register rs, int16_t off)
 {
+    spew("lw     %3s, (0x%x)%2s", rd.name(), off, rs.name());
     return writeInst(InstImm(op_lw, rs, rd, Imm16(off)).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_lwu(Register rd, Register rs, int16_t off)
 {
+    spew("lwu    %3s, (0x%x)%2s", rd.name(), off, rs.name());
     return writeInst(InstImm(op_lwu, rs, rd, Imm16(off)).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_lwl(Register rd, Register rs, int16_t off)
 {
+    spew("lwl    %3s, (0x%x)%2s", rd.name(), off, rs.name());
     return writeInst(InstImm(op_lwl, rs, rd, Imm16(off)).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_lwr(Register rd, Register rs, int16_t off)
 {
+    spew("lwr    %3s, (0x%x)%2s", rd.name(), off, rs.name());
     return writeInst(InstImm(op_lwr, rs, rd, Imm16(off)).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_ll(Register rd, Register rs, int16_t off)
 {
+    spew("ll     %3s, (0x%x)%2s", rd.name(), off, rs.name());
     return writeInst(InstImm(op_ll, rs, rd, Imm16(off)).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_ld(Register rd, Register rs, int16_t off)
 {
+    spew("ld     %3s, (0x%x)%2s", rd.name(), off, rs.name());
     return writeInst(InstImm(op_ld, rs, rd, Imm16(off)).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_ldl(Register rd, Register rs, int16_t off)
 {
+    spew("ldl    %3s, (0x%x)%2s", rd.name(), off, rs.name());
     return writeInst(InstImm(op_ldl, rs, rd, Imm16(off)).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_ldr(Register rd, Register rs, int16_t off)
 {
+    spew("ldr    %3s, (0x%x)%2s", rd.name(), off, rs.name());
     return writeInst(InstImm(op_ldr, rs, rd, Imm16(off)).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_sb(Register rd, Register rs, int16_t off)
 {
+    spew("sb     %3s, (0x%x)%2s", rd.name(), off, rs.name());
     return writeInst(InstImm(op_sb, rs, rd, Imm16(off)).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_sh(Register rd, Register rs, int16_t off)
 {
+    spew("sh     %3s, (0x%x)%2s", rd.name(), off, rs.name());
     return writeInst(InstImm(op_sh, rs, rd, Imm16(off)).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_sw(Register rd, Register rs, int16_t off)
 {
+    spew("sw     %3s, (0x%x)%2s", rd.name(), off, rs.name());
     return writeInst(InstImm(op_sw, rs, rd, Imm16(off)).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_swl(Register rd, Register rs, int16_t off)
 {
+    spew("swl    %3s, (0x%x)%2s", rd.name(), off, rs.name());
     return writeInst(InstImm(op_swl, rs, rd, Imm16(off)).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_swr(Register rd, Register rs, int16_t off)
 {
+    spew("swr    %3s, (0x%x)%2s", rd.name(), off, rs.name());
     return writeInst(InstImm(op_swr, rs, rd, Imm16(off)).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_sc(Register rd, Register rs, int16_t off)
 {
+    spew("sc     %3s, (0x%x)%2s", rd.name(), off, rs.name());
     return writeInst(InstImm(op_sc, rs, rd, Imm16(off)).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_sd(Register rd, Register rs, int16_t off)
 {
+    spew("sd     %3s, (0x%x)%2s", rd.name(), off, rs.name());
     return writeInst(InstImm(op_sd, rs, rd, Imm16(off)).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_sdl(Register rd, Register rs, int16_t off)
 {
+    spew("sdl    %3s, (0x%x)%2s", rd.name(), off, rs.name());
     return writeInst(InstImm(op_sdl, rs, rd, Imm16(off)).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_sdr(Register rd, Register rs, int16_t off)
 {
+    spew("sdr    %3s, (0x%x)%2s", rd.name(), off, rs.name());
     return writeInst(InstImm(op_sdr, rs, rd, Imm16(off)).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_gslbx(Register rd, Register rs, Register ri, int16_t off)
 {
     MOZ_ASSERT(Imm8::IsInSignedRange(off));
+    spew("gslbx  %3s,%3s, (0x%x)%2s", rd.name(), rs.name(), off, ri.name());
     return writeInst(InstGS(op_ldc2, rs, rd, ri, Imm8(off), ff_gsxbx).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_gssbx(Register rd, Register rs, Register ri, int16_t off)
 {
     MOZ_ASSERT(Imm8::IsInSignedRange(off));
+    spew("gssbx  %3s,%3s, (0x%x)%2s", rd.name(), rs.name(), off, ri.name());
     return writeInst(InstGS(op_sdc2, rs, rd, ri, Imm8(off), ff_gsxbx).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_gslhx(Register rd, Register rs, Register ri, int16_t off)
 {
     MOZ_ASSERT(Imm8::IsInSignedRange(off));
+    spew("gslhx  %3s,%3s, (0x%x)%2s", rd.name(), rs.name(), off, ri.name());
     return writeInst(InstGS(op_ldc2, rs, rd, ri, Imm8(off), ff_gsxhx).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_gsshx(Register rd, Register rs, Register ri, int16_t off)
 {
     MOZ_ASSERT(Imm8::IsInSignedRange(off));
+    spew("gsshx  %3s,%3s, (0x%x)%2s", rd.name(), rs.name(), off, ri.name());
     return writeInst(InstGS(op_sdc2, rs, rd, ri, Imm8(off), ff_gsxhx).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_gslwx(Register rd, Register rs, Register ri, int16_t off)
 {
     MOZ_ASSERT(Imm8::IsInSignedRange(off));
+    spew("gslwx  %3s,%3s, (0x%x)%2s", rd.name(), rs.name(), off, ri.name());
     return writeInst(InstGS(op_ldc2, rs, rd, ri, Imm8(off), ff_gsxwx).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_gsswx(Register rd, Register rs, Register ri, int16_t off)
 {
     MOZ_ASSERT(Imm8::IsInSignedRange(off));
+    spew("gsswx  %3s,%3s, (0x%x)%2s", rd.name(), rs.name(), off, ri.name());
     return writeInst(InstGS(op_sdc2, rs, rd, ri, Imm8(off), ff_gsxwx).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_gsldx(Register rd, Register rs, Register ri, int16_t off)
 {
     MOZ_ASSERT(Imm8::IsInSignedRange(off));
+    spew("gsldx  %3s,%3s, (0x%x)%2s", rd.name(), rs.name(), off, ri.name());
     return writeInst(InstGS(op_ldc2, rs, rd, ri, Imm8(off), ff_gsxdx).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_gssdx(Register rd, Register rs, Register ri, int16_t off)
 {
     MOZ_ASSERT(Imm8::IsInSignedRange(off));
+    spew("gssdx  %3s,%3s, (0x%x)%2s", rd.name(), rs.name(), off, ri.name());
     return writeInst(InstGS(op_sdc2, rs, rd, ri, Imm8(off), ff_gsxdx).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_gslq(Register rh, Register rl, Register rs, int16_t off)
 {
     MOZ_ASSERT(GSImm13::IsInRange(off));
+    spew("gslq   %3s,%3s, (0x%x)%2s", rh.name(), rl.name(), off, rs.name());
     return writeInst(InstGS(op_lwc2, rs, rl, rh, GSImm13(off), ff_gsxq).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_gssq(Register rh, Register rl, Register rs, int16_t off)
 {
     MOZ_ASSERT(GSImm13::IsInRange(off));
+    spew("gssq   %3s,%3s, (0x%x)%2s", rh.name(), rl.name(), off, rs.name());
     return writeInst(InstGS(op_swc2, rs, rl, rh, GSImm13(off), ff_gsxq).encode());
 }
 
 // Move from HI/LO register.
 BufferOffset
 AssemblerMIPSShared::as_mfhi(Register rd)
 {
+    spew("mfhi   %3s", rd.name());
     return writeInst(InstReg(op_special, rd, ff_mfhi).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_mflo(Register rd)
 {
+    spew("mflo   %3s", rd.name());
     return writeInst(InstReg(op_special, rd, ff_mflo).encode());
 }
 
 // Set on less than.
 BufferOffset
 AssemblerMIPSShared::as_slt(Register rd, Register rs, Register rt)
 {
+    spew("slt    %3s,%3s,%3s", rd.name(), rs.name(), rt.name());
     return writeInst(InstReg(op_special, rs, rt, rd, ff_slt).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_sltu(Register rd, Register rs, Register rt)
 {
+    spew("sltu   %3s,%3s,%3s", rd.name(), rs.name(), rt.name());
     return writeInst(InstReg(op_special, rs, rt, rd, ff_sltu).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_slti(Register rd, Register rs, int32_t j)
 {
     MOZ_ASSERT(Imm16::IsInSignedRange(j));
+    spew("slti   %3s,%3s, 0x%x", rd.name(), rs.name(), j);
     return writeInst(InstImm(op_slti, rs, rd, Imm16(j)).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_sltiu(Register rd, Register rs, uint32_t j)
 {
     MOZ_ASSERT(Imm16::IsInUnsignedRange(j));
+    spew("sltiu  %3s,%3s, 0x%x", rd.name(), rs.name(), j);
     return writeInst(InstImm(op_sltiu, rs, rd, Imm16(j)).encode());
 }
 
 // Conditional move.
 BufferOffset
 AssemblerMIPSShared::as_movz(Register rd, Register rs, Register rt)
 {
+    spew("movz   %3s,%3s,%3s", rd.name(), rs.name(), rt.name());
     return writeInst(InstReg(op_special, rs, rt, rd, ff_movz).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_movn(Register rd, Register rs, Register rt)
 {
+    spew("movn   %3s,%3s,%3s", rd.name(), rs.name(), rt.name());
     return writeInst(InstReg(op_special, rs, rt, rd, ff_movn).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_movt(Register rd, Register rs, uint16_t cc)
 {
     Register rt;
     rt = Register::FromCode((cc & 0x7) << 2 | 1);
+    spew("movt   %3s,%3s, FCC%d", rd.name(), rs.name(), cc);
     return writeInst(InstReg(op_special, rs, rt, rd, ff_movci).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_movf(Register rd, Register rs, uint16_t cc)
 {
     Register rt;
     rt = Register::FromCode((cc & 0x7) << 2 | 0);
+    spew("movf   %3s,%3s, FCC%d", rd.name(), rs.name(), cc);
     return writeInst(InstReg(op_special, rs, rt, rd, ff_movci).encode());
 }
 
 // Bit twiddling.
 BufferOffset
 AssemblerMIPSShared::as_clz(Register rd, Register rs)
 {
+    spew("clz    %3s,%3s", rd.name(), rs.name());
     return writeInst(InstReg(op_special2, rs, rd, rd, ff_clz).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_dclz(Register rd, Register rs)
 {
+    spew("dclz   %3s,%3s", rd.name(), rs.name());
     return writeInst(InstReg(op_special2, rs, rd, rd, ff_dclz).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_ins(Register rt, Register rs, uint16_t pos, uint16_t size)
 {
     MOZ_ASSERT(pos < 32 && size != 0 && size <= 32 && pos + size != 0 && pos + size <= 32);
     Register rd;
     rd = Register::FromCode(pos + size - 1);
+    spew("ins    %3s,%3s, %d, %d", rt.name(), rs.name(), pos, size);
     return writeInst(InstReg(op_special3, rs, rt, rd, pos, ff_ins).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_dins(Register rt, Register rs, uint16_t pos, uint16_t size)
 {
     MOZ_ASSERT(pos < 32 && size != 0 && size <= 32 && pos + size != 0 && pos + size <= 32);
     Register rd;
     rd = Register::FromCode(pos + size - 1);
+    spew("dins   %3s,%3s, %d, %d", rt.name(), rs.name(), pos, size);
     return writeInst(InstReg(op_special3, rs, rt, rd, pos, ff_dins).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_dinsm(Register rt, Register rs, uint16_t pos, uint16_t size)
 {
     MOZ_ASSERT(pos < 32 && size >= 2 && size <= 64 && pos + size > 32 && pos + size <= 64);
     Register rd;
     rd = Register::FromCode(pos + size - 1 - 32);
+    spew("dinsm  %3s,%3s, %d, %d", rt.name(), rs.name(), pos, size);
     return writeInst(InstReg(op_special3, rs, rt, rd, pos, ff_dinsm).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_dinsu(Register rt, Register rs, uint16_t pos, uint16_t size)
 {
     MOZ_ASSERT(pos >= 32 && pos < 64 && size >= 1 && size <= 32 && pos + size > 32 && pos + size <= 64);
     Register rd;
     rd = Register::FromCode(pos + size - 1 - 32);
+    spew("dinsu  %3s,%3s, %d, %d", rt.name(), rs.name(), pos, size);
     return writeInst(InstReg(op_special3, rs, rt, rd, pos - 32, ff_dinsu).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_ext(Register rt, Register rs, uint16_t pos, uint16_t size)
 {
     MOZ_ASSERT(pos < 32 && size != 0 && size <= 32 && pos + size != 0 && pos + size <= 32);
     Register rd;
     rd = Register::FromCode(size - 1);
+    spew("ext    %3s,%3s, %d, %d", rt.name(), rs.name(), pos, size);
     return writeInst(InstReg(op_special3, rs, rt, rd, pos, ff_ext).encode());
 }
 
 // Sign extend
 BufferOffset
 AssemblerMIPSShared::as_seb(Register rd, Register rt)
 {
+    spew("seb    %3s,%3s", rd.name(), rt.name());
     return writeInst(InstReg(op_special3, zero, rt, rd, 16, ff_bshfl).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_seh(Register rd, Register rt)
 {
+    spew("seh    %3s,%3s", rd.name(), rt.name());
     return writeInst(InstReg(op_special3, zero, rt, rd, 24, ff_bshfl).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_dext(Register rt, Register rs, uint16_t pos, uint16_t size)
 {
     MOZ_ASSERT(pos < 32 && size != 0 && size <= 32 && pos + size != 0 && pos + size <= 63);
     Register rd;
     rd = Register::FromCode(size - 1);
+    spew("dext   %3s,%3s, %d, %d", rt.name(), rs.name(), pos, size);
     return writeInst(InstReg(op_special3, rs, rt, rd, pos, ff_dext).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_dextm(Register rt, Register rs, uint16_t pos, uint16_t size)
 {
     MOZ_ASSERT(pos < 32 && size > 32 && size <= 64 && pos + size > 32 && pos + size <= 64);
     Register rd;
     rd = Register::FromCode(size - 1 - 32);
+    spew("dextm  %3s,%3s, %d, %d", rt.name(), rs.name(), pos, size);
    return writeInst(InstReg(op_special3, rs, rt, rd, pos, ff_dextm).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_dextu(Register rt, Register rs, uint16_t pos, uint16_t size)
 {
     MOZ_ASSERT(pos >= 32 && pos < 64 && size != 0 && size <= 32 && pos + size > 32 && pos + size <= 64);
     Register rd;
     rd = Register::FromCode(size - 1);
+    spew("dextu  %3s,%3s, %d, %d", rt.name(), rs.name(), pos, size);
     return writeInst(InstReg(op_special3, rs, rt, rd, pos - 32, ff_dextu).encode());
 }
 
 // FP instructions
 BufferOffset
 AssemblerMIPSShared::as_ld(FloatRegister fd, Register base, int32_t off)
 {
     MOZ_ASSERT(Imm16::IsInSignedRange(off));
+    spew("ldc1   %3s, (0x%x)%2s", fd.name(), off, base.name());
     return writeInst(InstImm(op_ldc1, base, fd, Imm16(off)).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_sd(FloatRegister fd, Register base, int32_t off)
 {
     MOZ_ASSERT(Imm16::IsInSignedRange(off));
+    spew("sdc1   %3s, (0x%x)%2s", fd.name(), off, base.name());
     return writeInst(InstImm(op_sdc1, base, fd, Imm16(off)).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_ls(FloatRegister fd, Register base, int32_t off)
 {
     MOZ_ASSERT(Imm16::IsInSignedRange(off));
+    spew("lwc1   %3s, (0x%x)%2s", fd.name(), off, base.name());
     return writeInst(InstImm(op_lwc1, base, fd, Imm16(off)).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_ss(FloatRegister fd, Register base, int32_t off)
 {
     MOZ_ASSERT(Imm16::IsInSignedRange(off));
+    spew("swc1   %3s, (0x%x)%2s", fd.name(), off, base.name());
     return writeInst(InstImm(op_swc1, base, fd, Imm16(off)).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_gsldl(FloatRegister fd, Register base, int32_t off)
 {
     MOZ_ASSERT(Imm8::IsInSignedRange(off));
+    spew("gsldl  %3s, (0x%x)%2s", fd.name(), off, base.name());
     return writeInst(InstGS(op_lwc2, base, fd, Imm8(off), ff_gsxdlc1).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_gsldr(FloatRegister fd, Register base, int32_t off)
 {
     MOZ_ASSERT(Imm8::IsInSignedRange(off));
+    spew("gsldr  %3s, (0x%x)%2s", fd.name(), off, base.name());
     return writeInst(InstGS(op_lwc2, base, fd, Imm8(off), ff_gsxdrc1).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_gssdl(FloatRegister fd, Register base, int32_t off)
 {
     MOZ_ASSERT(Imm8::IsInSignedRange(off));
+    spew("gssdl  %3s, (0x%x)%2s", fd.name(), off, base.name());
     return writeInst(InstGS(op_swc2, base, fd, Imm8(off), ff_gsxdlc1).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_gssdr(FloatRegister fd, Register base, int32_t off)
 {
     MOZ_ASSERT(Imm8::IsInSignedRange(off));
+    spew("gssdr  %3s, (0x%x)%2s", fd.name(), off, base.name());
     return writeInst(InstGS(op_swc2, base, fd, Imm8(off), ff_gsxdrc1).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_gslsl(FloatRegister fd, Register base, int32_t off)
 {
     MOZ_ASSERT(Imm8::IsInSignedRange(off));
+    spew("gslsl  %3s, (0x%x)%2s", fd.name(), off, base.name());
     return writeInst(InstGS(op_lwc2, base, fd, Imm8(off), ff_gsxwlc1).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_gslsr(FloatRegister fd, Register base, int32_t off)
 {
     MOZ_ASSERT(Imm8::IsInSignedRange(off));
+    spew("gslsr  %3s, (0x%x)%2s", fd.name(), off, base.name());
     return writeInst(InstGS(op_lwc2, base, fd, Imm8(off), ff_gsxwrc1).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_gsssl(FloatRegister fd, Register base, int32_t off)
 {
     MOZ_ASSERT(Imm8::IsInSignedRange(off));
+    spew("gsssl  %3s, (0x%x)%2s", fd.name(), off, base.name());
     return writeInst(InstGS(op_swc2, base, fd, Imm8(off), ff_gsxwlc1).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_gsssr(FloatRegister fd, Register base, int32_t off)
 {
     MOZ_ASSERT(Imm8::IsInSignedRange(off));
+    spew("gsssr  %3s, (0x%x)%2s", fd.name(), off, base.name());
     return writeInst(InstGS(op_swc2, base, fd, Imm8(off), ff_gsxwrc1).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_gslsx(FloatRegister fd, Register rs, Register ri, int16_t off)
 {
     MOZ_ASSERT(Imm8::IsInSignedRange(off));
+    spew("gslsx  %3s, (%3s,%3s, 0x%x)", fd.name(), rs.name(), ri.name(), off);
     return writeInst(InstGS(op_ldc2, rs, fd, ri, Imm8(off), ff_gsxwxc1).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_gsssx(FloatRegister fd, Register rs, Register ri, int16_t off)
 {
     MOZ_ASSERT(Imm8::IsInSignedRange(off));
+    spew("gsssx  %3s, (%3s,%3s, 0x%x)", fd.name(), rs.name(), ri.name(), off);
     return writeInst(InstGS(op_sdc2, rs, fd, ri, Imm8(off), ff_gsxwxc1).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_gsldx(FloatRegister fd, Register rs, Register ri, int16_t off)
 {
     MOZ_ASSERT(Imm8::IsInSignedRange(off));
+    spew("gsldx  %3s, (%3s,%3s, 0x%x)", fd.name(), rs.name(), ri.name(), off);
     return writeInst(InstGS(op_ldc2, rs, fd, ri, Imm8(off), ff_gsxdxc1).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_gssdx(FloatRegister fd, Register rs, Register ri, int16_t off)
 {
     MOZ_ASSERT(Imm8::IsInSignedRange(off));
+    spew("gssdx  %3s, (%3s,%3s, 0x%x)", fd.name(), rs.name(), ri.name(), off);
     return writeInst(InstGS(op_sdc2, rs, fd, ri, Imm8(off), ff_gsxdxc1).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_gslq(FloatRegister rh, FloatRegister rl, Register rs, int16_t off)
 {
     MOZ_ASSERT(GSImm13::IsInRange(off));
+    spew("gslq   %3s,%3s, (0x%x)%2s", rh.name(), rl.name(), off, rs.name());
     return writeInst(InstGS(op_lwc2, rs, rl, rh, GSImm13(off), ff_gsxqc1).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_gssq(FloatRegister rh, FloatRegister rl, Register rs, int16_t off)
 {
     MOZ_ASSERT(GSImm13::IsInRange(off));
+    spew("gssq   %3s,%3s, (0x%x)%2s", rh.name(), rl.name(), off, rs.name());
     return writeInst(InstGS(op_swc2, rs, rl, rh, GSImm13(off), ff_gsxqc1).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_movs(FloatRegister fd, FloatRegister fs)
 {
+    spew("mov.s  %3s,%3s", fd.name(), fs.name());
     return writeInst(InstReg(op_cop1, rs_s, zero, fs, fd, ff_mov_fmt).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_movd(FloatRegister fd, FloatRegister fs)
 {
+    spew("mov.d  %3s,%3s", fd.name(), fs.name());
     return writeInst(InstReg(op_cop1, rs_d, zero, fs, fd, ff_mov_fmt).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_ctc1(Register rt, FPControl fc)
 {
+    spew("ctc1   %3s,%3s", rt.name(), FloatRegister(fc).name());
     return writeInst(InstReg(op_cop1, rs_ctc1, rt, FloatRegister(fc)).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_cfc1(Register rt, FPControl fc)
 {
+    spew("cfc1   %3s,%3s", rt.name(), FloatRegister(fc).name());
     return writeInst(InstReg(op_cop1, rs_cfc1, rt, FloatRegister(fc)).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_mtc1(Register rt, FloatRegister fs)
 {
+    spew("mtc1   %3s,%3s", rt.name(), fs.name());
     return writeInst(InstReg(op_cop1, rs_mtc1, rt, fs).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_mfc1(Register rt, FloatRegister fs)
 {
+    spew("mfc1   %3s,%3s", rt.name(), fs.name());
     return writeInst(InstReg(op_cop1, rs_mfc1, rt, fs).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_mthc1(Register rt, FloatRegister fs)
 {
+    spew("mthc1  %3s,%3s", rt.name(), fs.name());
     return writeInst(InstReg(op_cop1, rs_mthc1, rt, fs).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_mfhc1(Register rt, FloatRegister fs)
 {
+    spew("mfhc1  %3s,%3s", rt.name(), fs.name());
     return writeInst(InstReg(op_cop1, rs_mfhc1, rt, fs).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_dmtc1(Register rt, FloatRegister fs)
 {
+    spew("dmtc1  %3s,%3s", rt.name(), fs.name());
     return writeInst(InstReg(op_cop1, rs_dmtc1, rt, fs).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_dmfc1(Register rt, FloatRegister fs)
 {
+    spew("dmfc1  %3s,%3s", rt.name(), fs.name());
     return writeInst(InstReg(op_cop1, rs_dmfc1, rt, fs).encode());
 }
 
 // FP convert instructions
 BufferOffset
 AssemblerMIPSShared::as_ceilws(FloatRegister fd, FloatRegister fs)
 {
+    spew("ceil.w.s%3s,%3s", fd.name(), fs.name());
     return writeInst(InstReg(op_cop1, rs_s, zero, fs, fd, ff_ceil_w_fmt).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_floorws(FloatRegister fd, FloatRegister fs)
 {
+    spew("floor.w.s%3s,%3s", fd.name(), fs.name());
     return writeInst(InstReg(op_cop1, rs_s, zero, fs, fd, ff_floor_w_fmt).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_roundws(FloatRegister fd, FloatRegister fs)
 {
+    spew("round.w.s%3s,%3s", fd.name(), fs.name());
     return writeInst(InstReg(op_cop1, rs_s, zero, fs, fd, ff_round_w_fmt).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_truncws(FloatRegister fd, FloatRegister fs)
 {
+    spew("trunc.w.s%3s,%3s", fd.name(), fs.name());
     return writeInst(InstReg(op_cop1, rs_s, zero, fs, fd, ff_trunc_w_fmt).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_truncls(FloatRegister fd, FloatRegister fs)
 {
+    spew("trunc.l.s%3s,%3s", fd.name(), fs.name());
     return writeInst(InstReg(op_cop1, rs_s, zero, fs, fd, ff_trunc_l_fmt).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_ceilwd(FloatRegister fd, FloatRegister fs)
 {
+    spew("ceil.w.d%3s,%3s", fd.name(), fs.name());
     return writeInst(InstReg(op_cop1, rs_d, zero, fs, fd, ff_ceil_w_fmt).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_floorwd(FloatRegister fd, FloatRegister fs)
 {
+    spew("floor.w.d%3s,%3s", fd.name(), fs.name());
     return writeInst(InstReg(op_cop1, rs_d, zero, fs, fd, ff_floor_w_fmt).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_roundwd(FloatRegister fd, FloatRegister fs)
 {
+    spew("round.w.d%3s,%3s", fd.name(), fs.name());
     return writeInst(InstReg(op_cop1, rs_d, zero, fs, fd, ff_round_w_fmt).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_truncwd(FloatRegister fd, FloatRegister fs)
 {
+    spew("trunc.w.d%3s,%3s", fd.name(), fs.name());
     return writeInst(InstReg(op_cop1, rs_d, zero, fs, fd, ff_trunc_w_fmt).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_truncld(FloatRegister fd, FloatRegister fs)
 {
+    spew("trunc.l.d%3s,%3s", fd.name(), fs.name());
     return writeInst(InstReg(op_cop1, rs_d, zero, fs, fd, ff_trunc_l_fmt).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_cvtdl(FloatRegister fd, FloatRegister fs)
 {
+    spew("cvt.d.l%3s,%3s", fd.name(), fs.name());
     return writeInst(InstReg(op_cop1, rs_l, zero, fs, fd, ff_cvt_d_fmt).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_cvtds(FloatRegister fd, FloatRegister fs)
 {
+    spew("cvt.d.s%3s,%3s", fd.name(), fs.name());
     return writeInst(InstReg(op_cop1, rs_s, zero, fs, fd, ff_cvt_d_fmt).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_cvtdw(FloatRegister fd, FloatRegister fs)
 {
+    spew("cvt.d.w%3s,%3s", fd.name(), fs.name());
     return writeInst(InstReg(op_cop1, rs_w, zero, fs, fd, ff_cvt_d_fmt).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_cvtsd(FloatRegister fd, FloatRegister fs)
 {
+    spew("cvt.s.d%3s,%3s", fd.name(), fs.name());
     return writeInst(InstReg(op_cop1, rs_d, zero, fs, fd, ff_cvt_s_fmt).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_cvtsl(FloatRegister fd, FloatRegister fs)
 {
+    spew("cvt.s.l%3s,%3s", fd.name(), fs.name());
     return writeInst(InstReg(op_cop1, rs_l, zero, fs, fd, ff_cvt_s_fmt).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_cvtsw(FloatRegister fd, FloatRegister fs)
 {
+    spew("cvt.s.w%3s,%3s", fd.name(), fs.name());
     return writeInst(InstReg(op_cop1, rs_w, zero, fs, fd, ff_cvt_s_fmt).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_cvtwd(FloatRegister fd, FloatRegister fs)
 {
+    spew("cvt.w.d%3s,%3s", fd.name(), fs.name());
     return writeInst(InstReg(op_cop1, rs_d, zero, fs, fd, ff_cvt_w_fmt).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_cvtws(FloatRegister fd, FloatRegister fs)
 {
+    spew("cvt.w.s%3s,%3s", fd.name(), fs.name());
     return writeInst(InstReg(op_cop1, rs_s, zero, fs, fd, ff_cvt_w_fmt).encode());
 }
 
 // FP arithmetic instructions
 BufferOffset
 AssemblerMIPSShared::as_adds(FloatRegister fd, FloatRegister fs, FloatRegister ft)
 {
+    spew("add.s  %3s,%3s,%3s", fd.name(), fs.name(), ft.name());
     return writeInst(InstReg(op_cop1, rs_s, ft, fs, fd, ff_add_fmt).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_addd(FloatRegister fd, FloatRegister fs, FloatRegister ft)
 {
+    spew("add.d  %3s,%3s,%3s", fd.name(), fs.name(), ft.name());
     return writeInst(InstReg(op_cop1, rs_d, ft, fs, fd, ff_add_fmt).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_subs(FloatRegister fd, FloatRegister fs, FloatRegister ft)
 {
+    spew("sub.s  %3s,%3s,%3s", fd.name(), fs.name(), ft.name());
     return writeInst(InstReg(op_cop1, rs_s, ft, fs, fd, ff_sub_fmt).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_subd(FloatRegister fd, FloatRegister fs, FloatRegister ft)
 {
+    spew("sub.d  %3s,%3s,%3s", fd.name(), fs.name(), ft.name());
     return writeInst(InstReg(op_cop1, rs_d, ft, fs, fd, ff_sub_fmt).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_abss(FloatRegister fd, FloatRegister fs)
 {
+    spew("abs.s  %3s,%3s", fd.name(), fs.name());
     return writeInst(InstReg(op_cop1, rs_s, zero, fs, fd, ff_abs_fmt).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_absd(FloatRegister fd, FloatRegister fs)
 {
+    spew("abs.d  %3s,%3s", fd.name(), fs.name());
     return writeInst(InstReg(op_cop1, rs_d, zero, fs, fd, ff_abs_fmt).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_negs(FloatRegister fd, FloatRegister fs)
 {
+    spew("neg.s  %3s,%3s", fd.name(), fs.name());
     return writeInst(InstReg(op_cop1, rs_s, zero, fs, fd, ff_neg_fmt).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_negd(FloatRegister fd, FloatRegister fs)
 {
+    spew("neg.d  %3s,%3s", fd.name(), fs.name());
     return writeInst(InstReg(op_cop1, rs_d, zero, fs, fd, ff_neg_fmt).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_muls(FloatRegister fd, FloatRegister fs, FloatRegister ft)
 {
+    spew("mul.s  %3s,%3s,%3s", fd.name(), fs.name(), ft.name());
     return writeInst(InstReg(op_cop1, rs_s, ft, fs, fd, ff_mul_fmt).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_muld(FloatRegister fd, FloatRegister fs, FloatRegister ft)
 {
+    spew("mul.d  %3s,%3s,%3s", fd.name(), fs.name(), ft.name());
     return writeInst(InstReg(op_cop1, rs_d, ft, fs, fd, ff_mul_fmt).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_divs(FloatRegister fd, FloatRegister fs, FloatRegister ft)
 {
+    spew("div.s  %3s,%3s,%3s", fd.name(), fs.name(), ft.name());
     return writeInst(InstReg(op_cop1, rs_s, ft, fs, fd, ff_div_fmt).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_divd(FloatRegister fd, FloatRegister fs, FloatRegister ft)
 {
+    spew("divd.d  %3s,%3s,%3s", fd.name(), fs.name(), ft.name());
     return writeInst(InstReg(op_cop1, rs_d, ft, fs, fd, ff_div_fmt).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_sqrts(FloatRegister fd, FloatRegister fs)
 {
+    spew("sqrts  %3s,%3s", fd.name(), fs.name());
     return writeInst(InstReg(op_cop1, rs_s, zero, fs, fd, ff_sqrt_fmt).encode());
 }
 
 BufferOffset
 AssemblerMIPSShared::as_sqrtd(FloatRegister fd, FloatRegister fs)
 {
+    spew("sqrtd  %3s,%3s", fd.name(), fs.name());
     return writeInst(InstReg(op_cop1, rs_d, zero, fs, fd, ff_sqrt_fmt).encode());
 }
 
 // FP compare instructions
 BufferOffset
 AssemblerMIPSShared::as_cf(FloatFormat fmt, FloatRegister fs, FloatRegister ft, FPConditionBit fcc)
 {
-    RSField rs = fmt == DoubleFloat ? rs_d : rs_s;
-    return writeInst(InstReg(op_cop1, rs, ft, fs, fcc << FccShift, ff_c_f_fmt).encode());
+    if (fmt == DoubleFloat) {
+        spew("c.f.d  FCC%d,%3s,%3s", fcc, fs.name(), ft.name());
+        return writeInst(InstReg(op_cop1, rs_d, ft, fs, fcc << FccShift, ff_c_f_fmt).encode());
+    } else {
+        spew("c.f.s  FCC%d,%3s,%3s", fcc, fs.name(), ft.name());
+        return writeInst(InstReg(op_cop1, rs_s, ft, fs, fcc << FccShift, ff_c_f_fmt).encode());
+    }
 }
 
 BufferOffset
 AssemblerMIPSShared::as_cun(FloatFormat fmt, FloatRegister fs, FloatRegister ft, FPConditionBit fcc)
 {
-    RSField rs = fmt == DoubleFloat ? rs_d : rs_s;
-    return writeInst(InstReg(op_cop1, rs, ft, fs, fcc << FccShift, ff_c_un_fmt).encode());
+    if (fmt == DoubleFloat) {
+        spew("c.un.d FCC%d,%3s,%3s", fcc, fs.name(), ft.name());
+        return writeInst(InstReg(op_cop1, rs_d, ft, fs, fcc << FccShift, ff_c_un_fmt).encode());
+    } else {
+        spew("c.un.s FCC%d,%3s,%3s", fcc, fs.name(), ft.name());
+        return writeInst(InstReg(op_cop1, rs_s, ft, fs, fcc << FccShift, ff_c_un_fmt).encode());
+    }
 }
 
 BufferOffset
 AssemblerMIPSShared::as_ceq(FloatFormat fmt, FloatRegister fs, FloatRegister ft, FPConditionBit fcc)
 {
-    RSField rs = fmt == DoubleFloat ? rs_d : rs_s;
-    return writeInst(InstReg(op_cop1, rs, ft, fs, fcc << FccShift, ff_c_eq_fmt).encode());
+    if (fmt == DoubleFloat) {
+        spew("c.eq.d FCC%d,%3s,%3s", fcc, fs.name(), ft.name());
+        return writeInst(InstReg(op_cop1, rs_d, ft, fs, fcc << FccShift, ff_c_eq_fmt).encode());
+    } else {
+        spew("c.eq.s FCC%d,%3s,%3s", fcc, fs.name(), ft.name());
+        return writeInst(InstReg(op_cop1, rs_s, ft, fs, fcc << FccShift, ff_c_eq_fmt).encode());
+    }
 }
 
 BufferOffset
 AssemblerMIPSShared::as_cueq(FloatFormat fmt, FloatRegister fs, FloatRegister ft, FPConditionBit fcc)
 {
-    RSField rs = fmt == DoubleFloat ? rs_d : rs_s;
-    return writeInst(InstReg(op_cop1, rs, ft, fs, fcc << FccShift, ff_c_ueq_fmt).encode());
+    if (fmt == DoubleFloat) {
+        spew("c.ueq.d FCC%d,%3s,%3s", fcc, fs.name(), ft.name());
+        return writeInst(InstReg(op_cop1, rs_d, ft, fs, fcc << FccShift, ff_c_ueq_fmt).encode());
+    } else {
+        spew("c.ueq.s FCC%d,%3s,%3s", fcc, fs.name(), ft.name());
+        return writeInst(InstReg(op_cop1, rs_s, ft, fs, fcc << FccShift, ff_c_ueq_fmt).encode());
+    }
 }
 
 BufferOffset
 AssemblerMIPSShared::as_colt(FloatFormat fmt, FloatRegister fs, FloatRegister ft, FPConditionBit fcc)
 {
-    RSField rs = fmt == DoubleFloat ? rs_d : rs_s;
-    return writeInst(InstReg(op_cop1, rs, ft, fs, fcc << FccShift, ff_c_olt_fmt).encode());
+    if (fmt == DoubleFloat) {
+        spew("c.olt.d FCC%d,%3s,%3s", fcc, fs.name(), ft.name());
+        return writeInst(InstReg(op_cop1, rs_d, ft, fs, fcc << FccShift, ff_c_olt_fmt).encode());
+    } else {
+        spew("c.olt.s FCC%d,%3s,%3s", fcc, fs.name(), ft.name());
+        return writeInst(InstReg(op_cop1, rs_s, ft, fs, fcc << FccShift, ff_c_olt_fmt).encode());
+    }
 }
 
 BufferOffset
 AssemblerMIPSShared::as_cult(FloatFormat fmt, FloatRegister fs, FloatRegister ft, FPConditionBit fcc)
 {
-    RSField rs = fmt == DoubleFloat ? rs_d : rs_s;
-    return writeInst(InstReg(op_cop1, rs, ft, fs, fcc << FccShift, ff_c_ult_fmt).encode());
+    if (fmt == DoubleFloat) {
+        spew("c.ult.d FCC%d,%3s,%3s", fcc, fs.name(), ft.name());
+        return writeInst(InstReg(op_cop1, rs_d, ft, fs, fcc << FccShift, ff_c_ult_fmt).encode());
+    } else {
+        spew("c.ult.s FCC%d,%3s,%3s", fcc, fs.name(), ft.name());
+        return writeInst(InstReg(op_cop1, rs_s, ft, fs, fcc << FccShift, ff_c_ult_fmt).encode());
+    }
 }
 
 BufferOffset
 AssemblerMIPSShared::as_cole(FloatFormat fmt, FloatRegister fs, FloatRegister ft, FPConditionBit fcc)
 {
-    RSField rs = fmt == DoubleFloat ? rs_d : rs_s;
-    return writeInst(InstReg(op_cop1, rs, ft, fs, fcc << FccShift, ff_c_ole_fmt).encode());
+    if (fmt == DoubleFloat) {
+        spew("c.ole.d FCC%d,%3s,%3s", fcc, fs.name(), ft.name());
+        return writeInst(InstReg(op_cop1, rs_d, ft, fs, fcc << FccShift, ff_c_ole_fmt).encode());
+    } else {
+        spew("c.ole.s FCC%d,%3s,%3s", fcc, fs.name(), ft.name());
+        return writeInst(InstReg(op_cop1, rs_s, ft, fs, fcc << FccShift, ff_c_ole_fmt).encode());
+    }
 }
 
 BufferOffset
 AssemblerMIPSShared::as_cule(FloatFormat fmt, FloatRegister fs, FloatRegister ft, FPConditionBit fcc)
 {
-    RSField rs = fmt == DoubleFloat ? rs_d : rs_s;
-    return writeInst(InstReg(op_cop1, rs, ft, fs, fcc << FccShift, ff_c_ule_fmt).encode());
+    if (fmt == DoubleFloat) {
+        spew("c.ule.d FCC%d,%3s,%3s", fcc, fs.name(), ft.name());
+        return writeInst(InstReg(op_cop1, rs_d, ft, fs, fcc << FccShift, ff_c_ule_fmt).encode());
+    } else {
+        spew("c.ule.s FCC%d,%3s,%3s", fcc, fs.name(), ft.name());
+        return writeInst(InstReg(op_cop1, rs_s, ft, fs, fcc << FccShift, ff_c_ule_fmt).encode());
+    }
 }
 
 // FP conditional move.
 BufferOffset
 AssemblerMIPSShared::as_movt(FloatFormat fmt, FloatRegister fd, FloatRegister fs, FPConditionBit fcc)
 {
-    RSField rs = fmt == DoubleFloat ? rs_d : rs_s;
     Register rt = Register::FromCode(fcc << 2 | 1);
-    return writeInst(InstReg(op_cop1, rs, rt, fs, fd, ff_movf_fmt).encode());
+    if (fmt == DoubleFloat) {
+        spew("movt.d FCC%d,%3s,%3s", fcc, fd.name(), fs.name());
+        return writeInst(InstReg(op_cop1, rs_d, rt, fs, fd, ff_movf_fmt).encode());
+    } else {
+        spew("movt.s FCC%d,%3s,%3s", fcc, fd.name(), fs.name());
+        return writeInst(InstReg(op_cop1, rs_s, rt, fs, fd, ff_movf_fmt).encode());
+    }
 }
 
 BufferOffset
 AssemblerMIPSShared::as_movf(FloatFormat fmt, FloatRegister fd, FloatRegister fs, FPConditionBit fcc)
 {
-    RSField rs = fmt == DoubleFloat ? rs_d : rs_s;
     Register rt = Register::FromCode(fcc << 2 | 0);
-    return writeInst(InstReg(op_cop1, rs, rt, fs, fd, ff_movf_fmt).encode());
+    if (fmt == DoubleFloat) {
+        spew("movf.d FCC%d,%3s,%3s", fcc, fd.name(), fs.name());
+        return writeInst(InstReg(op_cop1, rs_d, rt, fs, fd, ff_movf_fmt).encode());
+    } else {
+        spew("movf.s FCC%d,%3s,%3s", fcc, fd.name(), fs.name());
+        return writeInst(InstReg(op_cop1, rs_s, rt, fs, fd, ff_movf_fmt).encode());
+    }
 }
 
 BufferOffset
 AssemblerMIPSShared::as_movz(FloatFormat fmt, FloatRegister fd, FloatRegister fs, Register rt)
 {
-    RSField rs = fmt == DoubleFloat ? rs_d : rs_s;
-    return writeInst(InstReg(op_cop1, rs, rt, fs, fd, ff_movz_fmt).encode());
+    if (fmt == DoubleFloat) {
+        spew("movz.d %3s,%3s,%3s", fd.name(), fs.name(), rt.name());
+        return writeInst(InstReg(op_cop1, rs_d, rt, fs, fd, ff_movz_fmt).encode());
+    } else {
+        spew("movz.s %3s,%3s,%3s", fd.name(), fs.name(), rt.name());
+        return writeInst(InstReg(op_cop1, rs_s, rt, fs, fd, ff_movz_fmt).encode());
+    }
 }
 
 BufferOffset
 AssemblerMIPSShared::as_movn(FloatFormat fmt, FloatRegister fd, FloatRegister fs, Register rt)
 {
-    RSField rs = fmt == DoubleFloat ? rs_d : rs_s;
-    return writeInst(InstReg(op_cop1, rs, rt, fs, fd, ff_movn_fmt).encode());
+    if (fmt == DoubleFloat) {
+        spew("movn.d %3s,%3s,%3s", fd.name(), fs.name(), rt.name());
+        return writeInst(InstReg(op_cop1, rs_d, rt, fs, fd, ff_movn_fmt).encode());
+    } else {
+        spew("movn.s %3s,%3s,%3s", fd.name(), fs.name(), rt.name());
+        return writeInst(InstReg(op_cop1, rs_s, rt, fs, fd, ff_movn_fmt).encode());
+    }
 }
 
 void
 AssemblerMIPSShared::bind(Label* label, BufferOffset boff)
 {
+    spew(".set Llabel %p", label);
     // If our caller didn't give us an explicit target to bind to
     // then we want to bind to the location of the next instruction
     BufferOffset dest = boff.assigned() ? boff : nextOffset();
     if (label->used()) {
         int32_t next;
 
         // A used label holds a link to branch that uses it.
         BufferOffset b(label);
@@ -1570,16 +1794,17 @@ AssemblerMIPSShared::bindLater(Label* la
         } while (next != LabelBase::INVALID_OFFSET);
     }
     label->reset();
 }
 
 void
 AssemblerMIPSShared::retarget(Label* label, Label* target)
 {
+    spew("retarget %p -> %p", label, target);
     if (label->used() && !oom()) {
         if (target->bound()) {
             bind(label, BufferOffset(target));
         } else if (target->used()) {
             // The target is not bound but used. Prepend label's branch list
             // onto target's.
             int32_t next;
             BufferOffset labelBranchOffset(label);
@@ -1608,25 +1833,27 @@ AssemblerMIPSShared::retarget(Label* lab
     label->reset();
 }
 
 void dbg_break() {}
 void
 AssemblerMIPSShared::as_break(uint32_t code)
 {
     MOZ_ASSERT(code <= MAX_BREAK_CODE);
+    spew("break %d", code);
     writeInst(op_special | code << FunctionBits | ff_break);
 }
 
 void
 AssemblerMIPSShared::as_sync(uint32_t stype)
 {
     MOZ_ASSERT(stype <= 31);
     if (isLoongson())
         stype = 0;
+    spew("sync %d", stype);
     writeInst(InstReg(op_special, zero, zero, zero, stype, ff_sync).encode());
 }
 
 // This just stomps over memory with 32 bits of raw data. Its purpose is to
 // overwrite the call of JITed code with 32 bits worth of an offset. This will
 // is only meant to function on code that has been invalidated, so it should
 // be totally safe. Since that instruction will never be executed again, a
 // ICache flush should not be necessary
@@ -1735,8 +1962,65 @@ void
 AssemblerMIPSShared::UpdateLuiOriValue(Instruction* inst0, Instruction* inst1, uint32_t value)
 {
     MOZ_ASSERT(inst0->extractOpcode() == ((uint32_t)op_lui >> OpcodeShift));
     MOZ_ASSERT(inst1->extractOpcode() == ((uint32_t)op_ori >> OpcodeShift));
 
     ((InstImm*) inst0)->setImm16(Imm16::Upper(Imm32(value)));
     ((InstImm*) inst1)->setImm16(Imm16::Lower(Imm32(value)));
 }
+
+
+#ifdef JS_JITSPEW
+void
+AssemblerMIPSShared::decodeBranchInstAndSpew(InstImm branch) {
+    Opcode op = (Opcode) (branch.extractOpcode() << OpcodeShift);
+    uint32_t rt_id;
+    uint32_t rs_id;
+    uint32_t immi = branch.extractImm16Value();
+    uint32_t fcc;
+    switch(op) {
+        case op_beq:
+          rt_id = branch.extractRT();
+          rs_id = branch.extractRS();
+          spew("beq    %3s,%3s,0x%x", Registers::GetName(rs_id), Registers::GetName(rt_id), (int32_t(immi << 18) >> 16) + 4);
+          break;
+        case op_bne:
+          rt_id = branch.extractRT();
+          rs_id = branch.extractRS();
+          spew("bne    %3s,%3s,0x%x", Registers::GetName(rs_id), Registers::GetName(rt_id), (int32_t(immi << 18) >> 16) + 4);
+          break;
+        case op_bgtz:
+          rs_id = branch.extractRS();
+          spew("bgt    %3s,  0,0x%x", Registers::GetName(rs_id), (int32_t(immi << 18) >> 16) + 4);
+          break;
+        case op_blez:
+          rs_id = branch.extractRS();
+          spew("ble    %3s,  0,0x%x", Registers::GetName(rs_id), (int32_t(immi << 18) >> 16) + 4);
+          break;
+        case op_regimm:
+          rt_id = branch.extractRT();
+          if (rt_id == (rt_bltz >> RTShift)) {
+              rs_id = branch.extractRS();
+              spew("blt   %3s,  0,0x%x", Registers::GetName(rs_id), (int32_t(immi << 18) >> 16) + 4);
+          } else if (rt_id == (rt_bgez >> RTShift)) {
+              rs_id = branch.extractRS();
+              spew("bge   %3s,  0,0x%x", Registers::GetName(rs_id), (int32_t(immi << 18) >> 16) + 4);
+          } else {
+              MOZ_CRASH("Error disassemble branch.");
+          }
+          break;
+        case op_cop1:
+          MOZ_ASSERT(branch.extractRS() == rs_bc1 >> RSShift);
+          rt_id = branch.extractRT();
+          fcc = branch.extractBitField(FCccShift + FCccBits - 1, FCccShift);
+          if (rt_id & 0x1) {
+              spew("bc1t  FCC%d, 0x%x", fcc, (int32_t(immi << 18) >> 16) + 4);
+          }
+          else {
+              spew("bc1f  FCC%d, 0x%x", fcc, (int32_t(immi << 18) >> 16) + 4);
+          }
+          break;
+        default:
+          MOZ_CRASH("Error disassemble branch.");
+    }
+}
+#endif
--- a/js/src/jit/mips-shared/Assembler-mips-shared.h
+++ b/js/src/jit/mips-shared/Assembler-mips-shared.h
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef jit_mips_shared_Assembler_mips_shared_h
 #define jit_mips_shared_Assembler_mips_shared_h
 
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/MathAlgorithms.h"
+#include "mozilla/Sprintf.h"
 
 #include "jit/CompactBuffer.h"
 #include "jit/IonCode.h"
 #include "jit/JitCompartment.h"
 #include "jit/JitSpewer.h"
 #include "jit/mips-shared/Architecture-mips-shared.h"
 #include "jit/shared/Assembler-shared.h"
 #include "jit/shared/IonAssemblerBuffer.h"
@@ -757,16 +758,19 @@ class MIPSBufferWithExecutableCopy : pub
                 return false;
         }
         return true;
     }
 };
 
 class AssemblerMIPSShared : public AssemblerShared
 {
+#ifdef JS_JITSPEW
+   Sprinter* printer;
+#endif
   public:
 
     enum Condition {
         Equal,
         NotEqual,
         Above,
         AboveOrEqual,
         Below,
@@ -878,17 +882,20 @@ class AssemblerMIPSShared : public Assem
     CompactBufferWriter jumpRelocations_;
     CompactBufferWriter dataRelocations_;
 
     MIPSBufferWithExecutableCopy m_buffer;
 
   public:
     AssemblerMIPSShared()
       : m_buffer(),
-        isFinished(false)
+#ifdef JS_JITSPEW
+       printer(nullptr),
+#endif
+       isFinished(false)
     { }
 
     static Condition InvertCondition(Condition cond);
     static DoubleCondition InvertCondition(DoubleCondition cond);
 
     void writeRelocation(BufferOffset src) {
         jumpRelocations_.writeUnsigned(src.getOffset());
     }
@@ -902,18 +909,52 @@ class AssemblerMIPSShared : public Assem
             dataRelocations_.writeUnsigned(nextOffset().getOffset());
         }
     }
 
   public:
     bool oom() const;
 
     void setPrinter(Sprinter* sp) {
+#ifdef JS_JITSPEW
+            printer = sp;
+#endif
     }
 
+#ifdef JS_JITSPEW
+    inline void spew(const char* fmt, ...) MOZ_FORMAT_PRINTF(2, 3) {
+        if (MOZ_UNLIKELY(printer || JitSpewEnabled(JitSpew_Codegen))) {
+            va_list va;
+            va_start(va, fmt);
+            spew(fmt, va);
+            va_end(va);
+        }
+    }
+
+    void decodeBranchInstAndSpew(InstImm branch);
+#else
+    MOZ_ALWAYS_INLINE void spew(const char* fmt, ...) MOZ_FORMAT_PRINTF(2, 3) {
+    }
+#endif
+
+#ifdef JS_JITSPEW
+    MOZ_COLD void spew(const char* fmt, va_list va) MOZ_FORMAT_PRINTF(2, 0) {
+        // Buffer to hold the formatted string. Note that this may contain
+        // '%' characters, so do not pass it directly to printf functions.
+        char buf[200];
+
+        int i = VsprintfLiteral(buf, fmt, va);
+        if (i > -1) {
+            if (printer)
+                printer->printf("%s\n", buf);
+            js::jit::JitSpew(js::jit::JitSpew_Codegen, "%s", buf);
+        }
+    }
+#endif
+
     static const Register getStackPointer() {
         return StackPointer;
     }
 
   protected:
     bool isFinished;
   public:
     void finish();
@@ -1252,18 +1293,17 @@ class AssemblerMIPSShared : public Assem
     uint32_t longJump(size_t i) {
         return longJumps_[i];
     }
 
     void flushBuffer() {
     }
 
     void comment(const char* msg) {
-        // This is not implemented because setPrinter() is not implemented.
-        // TODO spew("; %s", msg);
+        spew("; %s", msg);
     }
 
     static uint32_t NopSize() { return 4; }
 
     static void PatchWrite_Imm32(CodeLocationLabel label, Imm32 imm);
 
     static uint32_t AlignDoubleArg(uint32_t offset) {
         return (offset + 1U) &~ 1U;
--- a/js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp
+++ b/js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp
@@ -1574,16 +1574,17 @@ MacroAssembler::call(Label* label)
 }
 
 CodeOffset
 MacroAssembler::callWithPatch()
 {
     as_bal(BOffImm16(3 * sizeof(uint32_t)));
     addPtr(Imm32(5 * sizeof(uint32_t)), ra);
     // Allocate space which will be patched by patchCall().
+    spew(".space 32bit initValue 0xffff ffff");
     writeInst(UINT32_MAX);
     as_lw(ScratchRegister, ra, -(int32_t)(5 * sizeof(uint32_t)));
     addPtr(ra, ScratchRegister);
     as_jr(ScratchRegister);
     as_nop();
     return CodeOffset(currentOffset());
 }
 
@@ -1606,16 +1607,17 @@ MacroAssembler::patchCall(uint32_t calle
 CodeOffset
 MacroAssembler::farJumpWithPatch()
 {
     ma_move(SecondScratchReg, ra);
     as_bal(BOffImm16(3 * sizeof(uint32_t)));
     as_lw(ScratchRegister, ra, 0);
     // Allocate space which will be patched by patchFarJump().
     CodeOffset farJump(currentOffset());
+    spew(".space 32bit initValue 0xffff ffff");
     writeInst(UINT32_MAX);
     addPtr(ra, ScratchRegister);
     as_jr(ScratchRegister);
     ma_move(ra, SecondScratchReg);
     return farJump;
 }
 
 void
--- a/js/src/jit/mips32/MacroAssembler-mips32.cpp
+++ b/js/src/jit/mips32/MacroAssembler-mips32.cpp
@@ -501,16 +501,17 @@ MacroAssemblerMIPS::ma_b(Address addr, I
 {
     ma_lw(SecondScratchReg, addr);
     ma_b(SecondScratchReg, imm, label, c, jumpKind);
 }
 
 void
 MacroAssemblerMIPS::ma_bal(Label* label, DelaySlotFill delaySlotFill)
 {
+    spew("branch .Llabel %p\n", label);
     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();
@@ -518,57 +519,68 @@ MacroAssemblerMIPS::ma_bal(Label* label,
     }
 
     // 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));
 
+    spew("bal .Llabel %p\n", label);
     BufferOffset bo = writeInst(getBranchCode(BranchIsCall).encode());
     writeInst(nextInChain);
     if (!oom())
         label->use(bo.getOffset());
     // Leave space for long jump.
     as_nop();
     if (delaySlotFill == FillDelaySlot)
         as_nop();
 }
 
 void
 MacroAssemblerMIPS::branchWithCode(InstImm code, Label* label, JumpKind jumpKind)
 {
+    spew("branch .Llabel %p", label);
     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));
+#ifdef JS_JITSPEW
+            decodeBranchInstAndSpew(code);
+#endif
             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());
+        spew("invert branch .Llabel %p", label);
+        InstImm code_r = invertBranch(code, BOffImm16(5 * sizeof(uint32_t)));
+#ifdef JS_JITSPEW
+        decodeBranchInstAndSpew(code_r);
+#endif
+        writeInst(code_r.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;
     }
 
@@ -578,28 +590,34 @@ MacroAssemblerMIPS::branchWithCode(InstI
     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));
+#ifdef JS_JITSPEW
+        decodeBranchInstAndSpew(code);
+#endif
         BufferOffset bo = writeInst(code.encode());
         writeInst(nextInChain);
         if (!oom())
             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));
 
+#ifdef JS_JITSPEW
+    decodeBranchInstAndSpew(code);
+#endif
     BufferOffset bo = writeInst(code.encode());
     writeInst(nextInChain);
     if (!oom())
         label->use(bo.getOffset());
     // Leave space for potential long jump.
     as_nop();
     as_nop();
     if (conditional)
--- a/js/src/jit/mips64/MacroAssembler-mips64.cpp
+++ b/js/src/jit/mips64/MacroAssembler-mips64.cpp
@@ -754,16 +754,17 @@ MacroAssemblerMIPS64::ma_b(Address addr,
 {
     ma_load(SecondScratchReg, addr, SizeDouble);
     ma_b(SecondScratchReg, imm, label, c, jumpKind);
 }
 
 void
 MacroAssemblerMIPS64::ma_bal(Label* label, DelaySlotFill delaySlotFill)
 {
+    spew("branch .Llabel %p\n", label);
     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, ImmWord(label->offset()));
         as_jalr(ScratchRegister);
         if (delaySlotFill == FillDelaySlot)
             as_nop();
@@ -772,60 +773,72 @@ MacroAssemblerMIPS64::ma_bal(Label* labe
 
     // 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. The '6'
     // instructions are writing at below (contain delay slot).
     m_buffer.ensureSpace(6 * sizeof(uint32_t));
 
+    spew("bal .Llabel %p\n", label);
     BufferOffset bo = writeInst(getBranchCode(BranchIsCall).encode());
     writeInst(nextInChain);
     if (!oom())
         label->use(bo.getOffset());
     // Leave space for long jump.
     as_nop();
     as_nop();
     as_nop();
     if (delaySlotFill == FillDelaySlot)
         as_nop();
 }
 
 void
 MacroAssemblerMIPS64::branchWithCode(InstImm code, Label* label, JumpKind jumpKind)
 {
+    // simply output the pointer of one label as its id,
+    // notice that after one label destructor, the pointer will be reused.
+    spew("branch .Llabel %p", label);
     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));
+#ifdef JS_JITSPEW
+            decodeBranchInstAndSpew(code);
+#endif
             writeInst(code.encode());
             as_nop();
             return;
         }
 
         if (code.encode() == inst_beq.encode()) {
             // Handle long jump
             addLongJump(nextOffset());
             ma_liPatchable(ScratchRegister, ImmWord(label->offset()));
             as_jr(ScratchRegister);
             as_nop();
             return;
         }
 
         // Handle long conditional branch, the target offset is based on self,
         // point to next instruction of nop at below.
-        writeInst(invertBranch(code, BOffImm16(7 * sizeof(uint32_t))).encode());
+        spew("invert branch .Llabel %p", label);
+        InstImm code_r = invertBranch(code, BOffImm16(7 * sizeof(uint32_t)));
+#ifdef JS_JITSPEW
+        decodeBranchInstAndSpew(code_r);
+#endif
+        writeInst(code_r.encode());
         // No need for a "nop" here because we can clobber scratch.
         addLongJump(nextOffset());
         ma_liPatchable(ScratchRegister, ImmWord(label->offset()));
         as_jr(ScratchRegister);
         as_nop();
         return;
     }
 
@@ -835,29 +848,35 @@ MacroAssemblerMIPS64::branchWithCode(Ins
     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));
+#ifdef JS_JITSPEW
+        decodeBranchInstAndSpew(code);
+#endif
         BufferOffset bo = writeInst(code.encode());
         writeInst(nextInChain);
         if (!oom())
             label->use(bo.getOffset());
         return;
     }
 
     bool conditional = code.encode() != inst_beq.encode();
 
     // Make the whole branch continous in the buffer. The '7'
     // instructions are writing at below (contain conditional nop).
     m_buffer.ensureSpace(7 * sizeof(uint32_t));
 
+#ifdef JS_JITSPEW
+    decodeBranchInstAndSpew(code);
+#endif
     BufferOffset bo = writeInst(code.encode());
     writeInst(nextInChain);
     if (!oom())
         label->use(bo.getOffset());
     // Leave space for potential long jump.
     as_nop();
     as_nop();
     as_nop();