mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-04 14:58:37 +09:00
Bug 1271968 - IonMonkey: MIPS: Refactor PatchWrite_NearCall.
Tag: #1542
This commit is contained in:
parent
90edf5c5e4
commit
7d346d2f61
6 changed files with 31 additions and 86 deletions
|
|
@ -1748,6 +1748,25 @@ AssemblerMIPSShared::PatchWrite_Imm32(CodeLocationLabel label, Imm32 imm)
|
|||
*(raw - 1) = imm.value;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
AssemblerMIPSShared::PatchWrite_NearCallSize()
|
||||
{
|
||||
return 2 * sizeof(uint32_t);
|
||||
}
|
||||
|
||||
void
|
||||
AssemblerMIPSShared::PatchWrite_NearCall(CodeLocationLabel start, CodeLocationLabel toCall)
|
||||
{
|
||||
Instruction* inst = (Instruction*) start.raw();
|
||||
|
||||
// Overwrite whatever instruction used to be here with a call.
|
||||
inst[0] = InstJump(op_jal, JOffImm26(uintptr_t(toCall.raw())));
|
||||
inst[1] = InstNOP();
|
||||
|
||||
// Ensure everyone sees the code that was just written into memory.
|
||||
AutoFlushICache::flush(uintptr_t(inst), PatchWrite_NearCallSize());
|
||||
}
|
||||
|
||||
uint8_t*
|
||||
AssemblerMIPSShared::NextInstruction(uint8_t* inst_, uint32_t* count)
|
||||
{
|
||||
|
|
@ -1789,8 +1808,8 @@ AssemblerMIPSShared::PatchMixedJump(uint8_t* src, uint8_t* mid, uint8_t* target)
|
|||
offset = intptr_t(mid);
|
||||
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 + Assembler::InstructionImmediateSize() +
|
||||
2 * sizeof(uint32_t), PatchedImmPtr(&b[2]));
|
||||
}
|
||||
Assembler::PatchInstructionImmediate(mid + o, PatchedImmPtr(target));
|
||||
} else {
|
||||
|
|
@ -1823,7 +1842,8 @@ AssemblerMIPSShared::PatchMixedJumps(uint8_t* buffer)
|
|||
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()));
|
||||
BOffImm16 offset(Assembler::InstructionImmediateSize() + 2 * sizeof(uint32_t));
|
||||
bc[0] = invertBranch(b[0], offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1282,8 +1282,10 @@ class AssemblerMIPSShared : public AssemblerShared
|
|||
}
|
||||
|
||||
static uint32_t NopSize() { return 4; }
|
||||
static uint32_t PatchWrite_NearCallSize();
|
||||
|
||||
static void PatchWrite_Imm32(CodeLocationLabel label, Imm32 imm);
|
||||
static void PatchWrite_NearCall(CodeLocationLabel start, CodeLocationLabel toCall);
|
||||
|
||||
static uint32_t AlignDoubleArg(uint32_t offset) {
|
||||
return (offset + 1U) &~ 1U;
|
||||
|
|
|
|||
|
|
@ -296,31 +296,6 @@ Assembler::Bind(uint8_t* rawCode, CodeOffset* label, const void* address)
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Assembler::PatchWrite_NearCallSize()
|
||||
{
|
||||
return 4 * sizeof(uint32_t);
|
||||
}
|
||||
|
||||
void
|
||||
Assembler::PatchWrite_NearCall(CodeLocationLabel start, CodeLocationLabel toCall)
|
||||
{
|
||||
Instruction* inst = (Instruction*) start.raw();
|
||||
uint8_t* dest = toCall.raw();
|
||||
|
||||
// Overwrite whatever instruction used to be here with a call.
|
||||
// Always use long jump for two reasons:
|
||||
// - Jump has to be the same size because of PatchWrite_NearCallSize.
|
||||
// - Return address has to be at the end of replaced block.
|
||||
// Short jump wouldn't be more efficient.
|
||||
Assembler::WriteLuiOriInstructions(inst, &inst[1], ScratchRegister, (uint32_t)dest);
|
||||
inst[2] = InstReg(op_special, ScratchRegister, zero, ra, ff_jalr);
|
||||
inst[3] = InstNOP();
|
||||
|
||||
// Ensure everyone sees the code that was just written into memory.
|
||||
AutoFlushICache::flush(uintptr_t(inst), PatchWrite_NearCallSize());
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Assembler::ExtractLuiOriValue(Instruction* inst0, Instruction* inst1)
|
||||
{
|
||||
|
|
@ -334,14 +309,6 @@ Assembler::ExtractLuiOriValue(Instruction* inst0, Instruction* inst1)
|
|||
return value;
|
||||
}
|
||||
|
||||
void
|
||||
Assembler::WriteLuiOriInstructions(Instruction* inst0, Instruction* inst1,
|
||||
Register reg, uint32_t value)
|
||||
{
|
||||
*inst0 = InstImm(op_lui, zero, reg, Imm16::Upper(Imm32(value)));
|
||||
*inst1 = InstImm(op_ori, reg, reg, Imm16::Lower(Imm32(value)));
|
||||
}
|
||||
|
||||
void
|
||||
Assembler::PatchDataWithValueCheck(CodeLocationLabel label, ImmPtr newValue,
|
||||
ImmPtr expectedValue)
|
||||
|
|
|
|||
|
|
@ -149,13 +149,10 @@ class Assembler : public AssemblerMIPSShared
|
|||
static void TraceJumpRelocations(JSTracer* trc, JitCode* code, CompactBufferReader& reader);
|
||||
static void TraceDataRelocations(JSTracer* trc, JitCode* code, CompactBufferReader& reader);
|
||||
|
||||
static uint32_t PatchWrite_NearCallSize();
|
||||
|
||||
static uint32_t InstructionImmediateSize() {
|
||||
return 2 * sizeof(uint32_t);
|
||||
}
|
||||
static uint32_t ExtractLuiOriValue(Instruction* inst0, Instruction* inst1);
|
||||
static void WriteLuiOriInstructions(Instruction* inst, Instruction* inst1,
|
||||
Register reg, uint32_t value);
|
||||
|
||||
static void PatchWrite_NearCall(CodeLocationLabel start, CodeLocationLabel toCall);
|
||||
static void PatchDataWithValueCheck(CodeLocationLabel label, ImmPtr newValue,
|
||||
ImmPtr expectedValue);
|
||||
static void PatchDataWithValueCheck(CodeLocationLabel label, PatchedImmPtr newValue,
|
||||
|
|
|
|||
|
|
@ -228,32 +228,6 @@ Assembler::Bind(uint8_t* rawCode, CodeOffset* label, const void* address)
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Assembler::PatchWrite_NearCallSize()
|
||||
{
|
||||
// Load an address needs 4 instructions, and a jump with a delay slot.
|
||||
return (4 + 2) * sizeof(uint32_t);
|
||||
}
|
||||
|
||||
void
|
||||
Assembler::PatchWrite_NearCall(CodeLocationLabel start, CodeLocationLabel toCall)
|
||||
{
|
||||
Instruction* inst = (Instruction*) start.raw();
|
||||
uint8_t* dest = toCall.raw();
|
||||
|
||||
// Overwrite whatever instruction used to be here with a call.
|
||||
// Always use long jump for two reasons:
|
||||
// - Jump has to be the same size because of PatchWrite_NearCallSize.
|
||||
// - Return address has to be at the end of replaced block.
|
||||
// Short jump wouldn't be more efficient.
|
||||
Assembler::WriteLoad64Instructions(inst, ScratchRegister, (uint64_t)dest);
|
||||
inst[4] = InstReg(op_special, ScratchRegister, zero, ra, ff_jalr);
|
||||
inst[5] = InstNOP();
|
||||
|
||||
// Ensure everyone sees the code that was just written into memory.
|
||||
AutoFlushICache::flush(uintptr_t(inst), PatchWrite_NearCallSize());
|
||||
}
|
||||
|
||||
uint64_t
|
||||
Assembler::ExtractLoad64Value(Instruction* inst0)
|
||||
{
|
||||
|
|
@ -314,19 +288,6 @@ Assembler::UpdateLoad64Value(Instruction* inst0, uint64_t value)
|
|||
i5->setImm16(Imm16::Lower(Imm32(value)));
|
||||
}
|
||||
|
||||
void
|
||||
Assembler::WriteLoad64Instructions(Instruction* inst0, Register reg, uint64_t value)
|
||||
{
|
||||
Instruction* inst1 = inst0->next();
|
||||
Instruction* inst2 = inst1->next();
|
||||
Instruction* inst3 = inst2->next();
|
||||
|
||||
*inst0 = InstImm(op_lui, zero, reg, Imm16::Lower(Imm32(value >> 32)));
|
||||
*inst1 = InstImm(op_ori, reg, reg, Imm16::Upper(Imm32(value)));
|
||||
*inst2 = InstReg(op_special, rs_one, reg, reg, 48 - 32, ff_dsrl32);
|
||||
*inst3 = InstImm(op_ori, reg, reg, Imm16::Lower(Imm32(value)));
|
||||
}
|
||||
|
||||
void
|
||||
Assembler::PatchDataWithValueCheck(CodeLocationLabel label, ImmPtr newValue,
|
||||
ImmPtr expectedValue)
|
||||
|
|
|
|||
|
|
@ -148,14 +148,12 @@ class Assembler : public AssemblerMIPSShared
|
|||
static void TraceJumpRelocations(JSTracer* trc, JitCode* code, CompactBufferReader& reader);
|
||||
static void TraceDataRelocations(JSTracer* trc, JitCode* code, CompactBufferReader& reader);
|
||||
|
||||
static uint32_t PatchWrite_NearCallSize();
|
||||
|
||||
static uint32_t InstructionImmediateSize() {
|
||||
return 4 * sizeof(uint32_t);
|
||||
}
|
||||
static uint64_t ExtractLoad64Value(Instruction* inst0);
|
||||
static void UpdateLoad64Value(Instruction* inst0, uint64_t value);
|
||||
static void WriteLoad64Instructions(Instruction* inst0, Register reg, uint64_t value);
|
||||
|
||||
|
||||
static void PatchWrite_NearCall(CodeLocationLabel start, CodeLocationLabel toCall);
|
||||
static void PatchDataWithValueCheck(CodeLocationLabel label, ImmPtr newValue,
|
||||
ImmPtr expectedValue);
|
||||
static void PatchDataWithValueCheck(CodeLocationLabel label, PatchedImmPtr newValue,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue