зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
f437f61b75
Коммит
30f2572606
|
@ -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);
|
||||
|
||||
// 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.
|
||||
InstImm* inst = (InstImm*)editSrc(b);
|
||||
InstImm inst_beq = InstImm(op_beq, zero, zero, BOffImm16(0));
|
||||
uint32_t offset = dest.getOffset() - label->offset();
|
||||
MOZ_ASSERT(BOffImm16::IsInRange(offset));
|
||||
inst1->setBOffImm16(BOffImm16(offset));
|
||||
} else {
|
||||
Assembler::UpdateLuiOriValue(inst1, inst1->next(), dest.getOffset());
|
||||
}
|
||||
|
||||
// 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));
|
||||
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 {
|
||||
// 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);
|
||||
|
||||
// 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.
|
||||
InstImm* inst = (InstImm*)editSrc(b);
|
||||
InstImm inst_beq = InstImm(op_beq, zero, zero, BOffImm16(0));
|
||||
uint64_t offset = dest.getOffset() - label->offset();
|
||||
MOZ_ASSERT(BOffImm16::IsInRange(offset));
|
||||
inst1->setBOffImm16(BOffImm16(offset));
|
||||
} else {
|
||||
Assembler::UpdateLoad64Value(inst1, dest.getOffset());
|
||||
}
|
||||
|
||||
// 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));
|
||||
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 {
|
||||
// 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());
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче