Bug 1280843 - IonMonkey: MIPS: Fix ma_b(Register, T, JumpTarget) for Wasm. r=nbp

---
 js/src/jit/mips32/Assembler-mips32.cpp | 56 +++++++++++++++++++++++++------
 js/src/jit/mips64/Assembler-mips64.cpp | 60 ++++++++++++++++++++++++++++------
 2 files changed, 96 insertions(+), 20 deletions(-)
This commit is contained in:
Heiher 2016-07-04 22:11:31 +08:00
Родитель f437f61b75
Коммит 30f2572606
2 изменённых файлов: 94 добавлений и 18 удалений

Просмотреть файл

@ -315,19 +315,55 @@ Assembler::bind(RepatchLabel* label)
// If the label has a use, then change this use to refer to
// the bound label;
BufferOffset b(label->offset());
InstImm* inst1 = (InstImm*)editSrc(b);
InstImm* inst = (InstImm*)editSrc(b);
InstImm inst_beq = InstImm(op_beq, zero, zero, BOffImm16(0));
uint32_t offset = dest.getOffset() - label->offset();
// If first instruction is branch, then this is a loop backedge.
if (inst1->extractOpcode() == ((uint32_t)op_beq >> OpcodeShift)) {
// Backedges are short jumps when bound, but can become long
// when patched.
uint32_t offset = dest.getOffset() - label->offset();
// If first instruction is lui, then this is a long jump.
// If second instruction is lui, then this is a loop backedge.
if (inst[0].extractOpcode() == (uint32_t(op_lui) >> OpcodeShift)) {
// For unconditional long branches generated by ma_liPatchable,
// such as under:
// jumpWithpatch
Assembler::UpdateLuiOriValue(inst, inst->next(), dest.getOffset());
} else if (inst[1].extractOpcode() == (uint32_t(op_lui) >> OpcodeShift) ||
BOffImm16::IsInRange(offset))
{
// Handle code produced by:
// backedgeJump
// branchWithCode
MOZ_ASSERT(BOffImm16::IsInRange(offset));
inst1->setBOffImm16(BOffImm16(offset));
MOZ_ASSERT(inst[0].extractOpcode() == (uint32_t(op_beq) >> OpcodeShift) ||
inst[0].extractOpcode() == (uint32_t(op_bne) >> OpcodeShift) ||
inst[0].extractOpcode() == (uint32_t(op_blez) >> OpcodeShift) ||
inst[0].extractOpcode() == (uint32_t(op_bgtz) >> OpcodeShift));
inst[0].setBOffImm16(BOffImm16(offset));
} else if (inst[0].encode() == inst_beq.encode()) {
// Handle open long unconditional jumps created by
// MacroAssemblerMIPSShared::ma_b(..., wasm::JumpTarget, ...).
// We need to add it to long jumps array here.
// See MacroAssemblerMIPS::branchWithCode().
MOZ_ASSERT(inst[1].encode() == NopInst);
MOZ_ASSERT(inst[2].encode() == NopInst);
MOZ_ASSERT(inst[3].encode() == NopInst);
addLongJump(BufferOffset(label->offset()));
Assembler::WriteLuiOriInstructions(inst, &inst[1], ScratchRegister, dest.getOffset());
inst[2] = InstReg(op_special, ScratchRegister, zero, zero, ff_jr).encode();
} else {
Assembler::UpdateLuiOriValue(inst1, inst1->next(), dest.getOffset());
// Handle open long conditional jumps created by
// MacroAssemblerMIPSShared::ma_b(..., wasm::JumpTarget, ...).
inst[0] = invertBranch(inst[0], BOffImm16(5 * sizeof(void*)));
// No need for a "nop" here because we can clobber scratch.
// We need to add it to long jumps array here.
// See MacroAssemblerMIPS::branchWithCode().
MOZ_ASSERT(inst[1].encode() == NopInst);
MOZ_ASSERT(inst[2].encode() == NopInst);
MOZ_ASSERT(inst[3].encode() == NopInst);
MOZ_ASSERT(inst[4].encode() == NopInst);
addLongJump(BufferOffset(label->offset() + sizeof(void*)));
Assembler::WriteLuiOriInstructions(&inst[1], &inst[2], ScratchRegister, dest.getOffset());
inst[3] = InstReg(op_special, ScratchRegister, zero, zero, ff_jr).encode();
}
}
label->bind(dest.getOffset());
}

Просмотреть файл

@ -310,19 +310,59 @@ Assembler::bind(RepatchLabel* label)
// If the label has a use, then change this use to refer to
// the bound label;
BufferOffset b(label->offset());
InstImm* inst1 = (InstImm*)editSrc(b);
InstImm* inst = (InstImm*)editSrc(b);
InstImm inst_beq = InstImm(op_beq, zero, zero, BOffImm16(0));
uint64_t offset = dest.getOffset() - label->offset();
// If first instruction is branch, then this is a loop backedge.
if (inst1->extractOpcode() == ((uint32_t)op_beq >> OpcodeShift)) {
// Backedges are short jumps when bound, but can become long
// when patched.
uint64_t offset = dest.getOffset() - label->offset();
// If first instruction is lui, then this is a long jump.
// If second instruction is lui, then this is a loop backedge.
if (inst[0].extractOpcode() == (uint32_t(op_lui) >> OpcodeShift)) {
// For unconditional long branches generated by ma_liPatchable,
// such as under:
// jumpWithpatch
Assembler::UpdateLoad64Value(inst, dest.getOffset());
} else if (inst[1].extractOpcode() == (uint32_t(op_lui) >> OpcodeShift) ||
BOffImm16::IsInRange(offset))
{
// Handle code produced by:
// backedgeJump
// branchWithCode
MOZ_ASSERT(BOffImm16::IsInRange(offset));
inst1->setBOffImm16(BOffImm16(offset));
MOZ_ASSERT(inst[0].extractOpcode() == (uint32_t(op_beq) >> OpcodeShift) ||
inst[0].extractOpcode() == (uint32_t(op_bne) >> OpcodeShift) ||
inst[0].extractOpcode() == (uint32_t(op_blez) >> OpcodeShift) ||
inst[0].extractOpcode() == (uint32_t(op_bgtz) >> OpcodeShift));
inst[0].setBOffImm16(BOffImm16(offset));
} else if (inst[0].encode() == inst_beq.encode()) {
// Handle open long unconditional jumps created by
// MacroAssemblerMIPSShared::ma_b(..., wasm::JumpTarget, ...).
// We need to add it to long jumps array here.
// See MacroAssemblerMIPS64::branchWithCode().
MOZ_ASSERT(inst[1].encode() == NopInst);
MOZ_ASSERT(inst[2].encode() == NopInst);
MOZ_ASSERT(inst[3].encode() == NopInst);
MOZ_ASSERT(inst[4].encode() == NopInst);
MOZ_ASSERT(inst[5].encode() == NopInst);
addLongJump(BufferOffset(label->offset()));
Assembler::WriteLoad64Instructions(inst, ScratchRegister, dest.getOffset());
inst[4] = InstReg(op_special, ScratchRegister, zero, zero, ff_jr).encode();
} else {
Assembler::UpdateLoad64Value(inst1, dest.getOffset());
// Handle open long conditional jumps created by
// MacroAssemblerMIPSShared::ma_b(..., wasm::JumpTarget, ...).
inst[0] = invertBranch(inst[0], BOffImm16(7 * sizeof(uint32_t)));
// No need for a "nop" here because we can clobber scratch.
// We need to add it to long jumps array here.
// See MacroAssemblerMIPS64::branchWithCode().
MOZ_ASSERT(inst[1].encode() == NopInst);
MOZ_ASSERT(inst[2].encode() == NopInst);
MOZ_ASSERT(inst[3].encode() == NopInst);
MOZ_ASSERT(inst[4].encode() == NopInst);
MOZ_ASSERT(inst[5].encode() == NopInst);
MOZ_ASSERT(inst[6].encode() == NopInst);
addLongJump(BufferOffset(label->offset() + sizeof(uint32_t)));
Assembler::WriteLoad64Instructions(&inst[1], ScratchRegister, dest.getOffset());
inst[5] = InstReg(op_special, ScratchRegister, zero, zero, ff_jr).encode();
}
}
label->bind(dest.getOffset());
}