mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-05 07:18:39 +09:00
Bug 1271968 - IonMonkey: MIPS: Handle conditional branch in out of line code of mixed jump.
Tag: #1542
This commit is contained in:
parent
14ed1d3e3c
commit
90edf5c5e4
3 changed files with 39 additions and 41 deletions
|
|
@ -1621,7 +1621,12 @@ AssemblerMIPSShared::bind(InstImm* inst, uintptr_t branch, uintptr_t target)
|
|||
return;
|
||||
}
|
||||
|
||||
addMixedJump(BufferOffset(branch), ImmPtr((void*)target));
|
||||
MixedJumpPatch::Kind kind = MixedJumpPatch::NONE;
|
||||
InstImm inst_beq = InstImm(op_beq, zero, zero, BOffImm16(0));
|
||||
if (inst[0].encode() != inst_beq.encode())
|
||||
kind = MixedJumpPatch::CONDITIONAL;
|
||||
|
||||
addMixedJump(BufferOffset(branch), ImmPtr((const void*)target), kind);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -1763,6 +1768,8 @@ AssemblerMIPSShared::GetInstructionImmediateFromJump(Instruction* jump)
|
|||
uint32_t index = j->extractImm26Value() << 2;
|
||||
|
||||
jump = (Instruction*)(base | index);
|
||||
if (jump->extractOpcode() != ((uint32_t)op_lui >> OpcodeShift))
|
||||
jump = jump->next();
|
||||
}
|
||||
|
||||
return jump;
|
||||
|
|
@ -1776,8 +1783,16 @@ AssemblerMIPSShared::PatchMixedJump(uint8_t* src, uint8_t* mid, uint8_t* target)
|
|||
int offset;
|
||||
|
||||
if (mid) {
|
||||
int o = 0;
|
||||
InstImm* insn = (InstImm*)mid;
|
||||
|
||||
offset = intptr_t(mid);
|
||||
Assembler::PatchInstructionImmediate(mid, PatchedImmPtr(target));
|
||||
if (insn->extractOpcode() != ((uint32_t)op_lui >> OpcodeShift)) {
|
||||
o = 1 * sizeof(uint32_t);
|
||||
Assembler::PatchInstructionImmediate(mid + Assembler::PatchWrite_NearCallSize(),
|
||||
PatchedImmPtr(&b[2]));
|
||||
}
|
||||
Assembler::PatchInstructionImmediate(mid + o, PatchedImmPtr(target));
|
||||
} else {
|
||||
offset = intptr_t(target);
|
||||
}
|
||||
|
|
@ -1789,10 +1804,7 @@ AssemblerMIPSShared::PatchMixedJump(uint8_t* src, uint8_t* mid, uint8_t* target)
|
|||
|
||||
j->setJOffImm26(JOffImm26(offset));
|
||||
} else {
|
||||
InstImm inst_beq = InstImm(op_beq, zero, zero, BOffImm16(0));
|
||||
int i = (b[0].encode() == inst_beq.encode()) ? 0 : 2;
|
||||
|
||||
b[i] = InstJump(op_j, JOffImm26(offset)).encode();
|
||||
b[0] = InstJump(op_j, JOffImm26(offset)).encode();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1802,35 +1814,20 @@ AssemblerMIPSShared::PatchMixedJumps(uint8_t* buffer)
|
|||
// Patch all mixed jumps.
|
||||
for (size_t i = 0; i < numMixedJumps(); i++) {
|
||||
MixedJumpPatch& mjp = mixedJump(i);
|
||||
InstImm* b = (InstImm*)(buffer + mjp.src.getOffset());
|
||||
uint32_t opcode = b->extractOpcode();
|
||||
int offset;
|
||||
uint8_t* src = buffer + mjp.src.getOffset();
|
||||
uint8_t* mid = nullptr;
|
||||
uint8_t* target = buffer + uintptr_t(mjp.target);
|
||||
InstImm* b = (InstImm*)src;
|
||||
|
||||
if (mjp.mid.assigned()) {
|
||||
offset = intptr_t(buffer) + mjp.mid.getOffset();
|
||||
Assembler::PatchInstructionImmediate(buffer + mjp.mid.getOffset(),
|
||||
PatchedImmPtr(buffer + uintptr_t(mjp.target)));
|
||||
} else {
|
||||
offset = intptr_t(buffer) + intptr_t(mjp.target);
|
||||
}
|
||||
|
||||
if (((uint32_t)op_j >> OpcodeShift) == opcode ||
|
||||
((uint32_t)op_jal >> OpcodeShift) == opcode)
|
||||
{
|
||||
InstJump* j = (InstJump*)b;
|
||||
|
||||
j->setJOffImm26(JOffImm26(offset));
|
||||
} else {
|
||||
InstImm inst_beq = InstImm(op_beq, zero, zero, BOffImm16(0));
|
||||
|
||||
if (b[0].encode() == inst_beq.encode()) {
|
||||
b[0] = InstJump(op_j, JOffImm26(offset)).encode();
|
||||
} else {
|
||||
b[0] = invertBranch(b[0], BOffImm16(4 * sizeof(uint32_t)));
|
||||
b[2] = InstJump(op_j, JOffImm26(offset)).encode();
|
||||
mid = buffer + mjp.mid.getOffset();
|
||||
if (MixedJumpPatch::CONDITIONAL & mjp.kind) {
|
||||
InstImm* bc = (InstImm*)(buffer + mjp.mid.getOffset());
|
||||
bc[0] = invertBranch(b[0], BOffImm16(Assembler::PatchWrite_NearCallSize()));
|
||||
}
|
||||
}
|
||||
|
||||
PatchMixedJump(src, mid, target);
|
||||
b[1].makeNop();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -836,7 +836,8 @@ class AssemblerMIPSShared : public AssemblerShared
|
|||
{
|
||||
enum Kind {
|
||||
NONE,
|
||||
PATCHABLE
|
||||
PATCHABLE,
|
||||
CONDITIONAL,
|
||||
};
|
||||
|
||||
BufferOffset src;
|
||||
|
|
|
|||
|
|
@ -647,7 +647,6 @@ void
|
|||
MacroAssemblerMIPSShared::branchWithCode(InstImm code, 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();
|
||||
|
|
@ -663,6 +662,7 @@ MacroAssemblerMIPSShared::branchWithCode(InstImm code, Label* label, JumpKind ju
|
|||
return;
|
||||
}
|
||||
|
||||
InstImm inst_beq = InstImm(op_beq, zero, zero, BOffImm16(0));
|
||||
if (code.encode() == inst_beq.encode()) {
|
||||
// Handle mixed jump
|
||||
addMixedJump(nextOffset(), ImmPtr((void*)label->offset()));
|
||||
|
|
@ -672,10 +672,8 @@ MacroAssemblerMIPSShared::branchWithCode(InstImm code, Label* label, JumpKind ju
|
|||
}
|
||||
|
||||
// Handle long conditional branch
|
||||
writeInst(invertBranch(code, BOffImm16(4 * sizeof(uint32_t))).encode());
|
||||
as_nop();
|
||||
addMixedJump(nextOffset(), ImmPtr((void*)label->offset()));
|
||||
as_j(JOffImm26(0));
|
||||
addMixedJump(nextOffset(), ImmPtr((void*)label->offset()), MixedJumpPatch::CONDITIONAL);
|
||||
writeInst(code.encode());
|
||||
as_nop();
|
||||
return;
|
||||
}
|
||||
|
|
@ -686,7 +684,7 @@ MacroAssemblerMIPSShared::branchWithCode(InstImm code, Label* label, JumpKind ju
|
|||
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));
|
||||
m_buffer.ensureSpace(2 * sizeof(uint32_t));
|
||||
|
||||
if (jumpKind == ShortJump) {
|
||||
// Indicate that this is short jump with offset 4.
|
||||
|
|
@ -696,10 +694,6 @@ MacroAssemblerMIPSShared::branchWithCode(InstImm code, Label* label, JumpKind ju
|
|||
writeInst(nextInChain);
|
||||
if (!oom())
|
||||
label->use(bo.getOffset());
|
||||
if (jumpKind != ShortJump && code.encode() != inst_beq.encode()) {
|
||||
as_nop();
|
||||
as_nop();
|
||||
}
|
||||
}
|
||||
|
||||
// Branches when done from within mips-specific code.
|
||||
|
|
@ -1050,6 +1044,12 @@ MacroAssemblerMIPSShared::GenerateMixedJumps()
|
|||
if (MixedJumpPatch::NONE == mjp.kind && uintptr_t(mjp.target) <= size())
|
||||
continue;
|
||||
BufferOffset bo = m_buffer.nextOffset();
|
||||
if (MixedJumpPatch::CONDITIONAL & mjp.kind) {
|
||||
// Leave space for conditional branch.
|
||||
as_nop();
|
||||
asMasm().ma_liPatchable(ScratchRegister, ImmWord(0));
|
||||
as_jr(ScratchRegister);
|
||||
}
|
||||
asMasm().ma_liPatchable(ScratchRegister, ImmWord(0));
|
||||
as_jr(ScratchRegister);
|
||||
as_nop();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue