mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 831754 part 1 - Add patchable call instruction, ARM part. r=mjrosenb a=nonlibxul
This commit is contained in:
parent
d936b0c724
commit
97406e74ca
@ -181,6 +181,20 @@ InstLDR::asTHIS(Instruction &i)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
InstNOP *
|
||||
InstNOP::asTHIS(Instruction &i)
|
||||
{
|
||||
if (isTHIS(i))
|
||||
return (InstNOP*) (&i);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool
|
||||
InstNOP::isTHIS(const Instruction &i)
|
||||
{
|
||||
return (i.encode() & 0x0fffffff) == NopInst;
|
||||
}
|
||||
|
||||
bool
|
||||
InstBranchReg::isTHIS(const Instruction &i)
|
||||
{
|
||||
@ -2471,6 +2485,31 @@ Assembler::ToggleToCmp(CodeLocationLabel inst_)
|
||||
AutoFlushCache::updateTop((uintptr_t)ptr, 4);
|
||||
}
|
||||
|
||||
void
|
||||
Assembler::ToggleCall(CodeLocationLabel inst_, bool enabled)
|
||||
{
|
||||
Instruction *inst = (Instruction *)inst_.raw();
|
||||
JS_ASSERT(inst->is<InstMovW>());
|
||||
|
||||
inst = inst->next();
|
||||
JS_ASSERT(inst->is<InstMovT>());
|
||||
|
||||
inst = inst->next();
|
||||
JS_ASSERT(inst->is<InstNOP>() || inst->is<InstBLXReg>());
|
||||
|
||||
if (enabled == inst->is<InstBLXReg>()) {
|
||||
// Nothing to do.
|
||||
return;
|
||||
}
|
||||
|
||||
if (enabled)
|
||||
*inst = InstBLXReg(ScratchRegister, Always);
|
||||
else
|
||||
*inst = InstNOP();
|
||||
|
||||
AutoFlushCache::updateTop(uintptr_t(inst), 4);
|
||||
}
|
||||
|
||||
void
|
||||
AutoFlushCache::update(uintptr_t newStart, size_t len)
|
||||
{
|
||||
|
@ -1698,6 +1698,7 @@ class Assembler
|
||||
static void ToggleToJmp(CodeLocationLabel inst_);
|
||||
static void ToggleToCmp(CodeLocationLabel inst_);
|
||||
|
||||
static void ToggleCall(CodeLocationLabel inst_, bool enabled);
|
||||
}; // Assembler
|
||||
|
||||
// An Instruction is a structure for both encoding and decoding any and all ARM instructions.
|
||||
@ -1787,6 +1788,20 @@ class InstLDR : public InstDTR
|
||||
|
||||
};
|
||||
JS_STATIC_ASSERT(sizeof(InstDTR) == sizeof(InstLDR));
|
||||
|
||||
class InstNOP : public Instruction
|
||||
{
|
||||
static const uint32_t NopInst = 0x0320f000;
|
||||
|
||||
public:
|
||||
InstNOP()
|
||||
: Instruction(NopInst, Assembler::Always)
|
||||
{ }
|
||||
|
||||
static bool isTHIS(const Instruction &i);
|
||||
static InstNOP *asTHIS(Instruction &i);
|
||||
};
|
||||
|
||||
// Branching to a register, or calling a register
|
||||
class InstBranchReg : public Instruction
|
||||
{
|
||||
@ -1798,7 +1813,7 @@ class InstBranchReg : public Instruction
|
||||
};
|
||||
static const uint32_t IsBRegMask = 0x0ffffff0;
|
||||
InstBranchReg(BranchTag tag, Register rm, Assembler::Condition c)
|
||||
: Instruction(tag | RM(rm), c)
|
||||
: Instruction(tag | rm.code(), c)
|
||||
{ }
|
||||
public:
|
||||
static bool isTHIS (const Instruction &i);
|
||||
@ -1841,6 +1856,10 @@ class InstBXReg : public InstBranchReg
|
||||
class InstBLXReg : public InstBranchReg
|
||||
{
|
||||
public:
|
||||
InstBLXReg(Register reg, Assembler::Condition c)
|
||||
: InstBranchReg(IsBLX, reg, c)
|
||||
{ }
|
||||
|
||||
static bool isTHIS (const Instruction &i);
|
||||
static InstBLXReg *asTHIS (const Instruction &i);
|
||||
};
|
||||
|
@ -1136,6 +1136,12 @@ MacroAssemblerARM::ma_bl(Label *dest, Assembler::Condition c)
|
||||
as_bl(dest, c);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerARM::ma_blx(Register reg, Assembler::Condition c)
|
||||
{
|
||||
as_blx(reg, c);
|
||||
}
|
||||
|
||||
// VFP/ALU
|
||||
void
|
||||
MacroAssemblerARM::ma_vadd(FloatRegister src1, FloatRegister src2, FloatRegister dst)
|
||||
@ -3019,6 +3025,20 @@ MacroAssemblerARMCompat::toggledJump(Label *label)
|
||||
return ret;
|
||||
}
|
||||
|
||||
CodeOffsetLabel
|
||||
MacroAssemblerARMCompat::toggledCall(IonCode *target, bool enabled)
|
||||
{
|
||||
CodeOffsetLabel offset(size());
|
||||
BufferOffset bo = m_buffer.nextOffset();
|
||||
addPendingJump(bo, target->raw(), Relocation::IONCODE);
|
||||
ma_movPatchable(Imm32(uint32_t(target->raw())), ScratchRegister, Always, L_MOVWT);
|
||||
if (enabled)
|
||||
ma_blx(ScratchRegister);
|
||||
else
|
||||
ma_nop();
|
||||
return offset;
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerARMCompat::round(FloatRegister input, Register output, Label *bail, FloatRegister tmp)
|
||||
{
|
||||
|
@ -277,6 +277,8 @@ class MacroAssemblerARM : public Assembler
|
||||
// except, possibly in the crazy bailout-table case.
|
||||
void ma_bl(Label *dest, Condition c = Always);
|
||||
|
||||
void ma_blx(Register dest, Condition c = Always);
|
||||
|
||||
//VFP/ALU
|
||||
void ma_vadd(FloatRegister src1, FloatRegister src2, FloatRegister dst);
|
||||
void ma_vsub(FloatRegister src1, FloatRegister src2, FloatRegister dst);
|
||||
@ -500,6 +502,10 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
|
||||
|
||||
CodeOffsetLabel toggledJump(Label *label);
|
||||
|
||||
// Emit a BLX or NOP instruction. ToggleCall can be used to patch
|
||||
// this instruction.
|
||||
CodeOffsetLabel toggledCall(IonCode *target, bool enabled);
|
||||
|
||||
CodeOffsetLabel pushWithPatch(ImmWord imm) {
|
||||
CodeOffsetLabel label = currentOffset();
|
||||
ma_movPatchable(Imm32(imm.value), ScratchRegister, Always, L_MOVWT);
|
||||
|
Loading…
Reference in New Issue
Block a user