Commit ea147c93 authored by swift_gan's avatar swift_gan Committed by swift_gan

almost done

parent 5e75202d
......@@ -143,8 +143,28 @@ void AssemblerA64::Str(RegisterA64 &rt, const MemOperand& memOperand) {
}
}
void AssemblerA64::Pop(RegisterA64 &rd) {
void AssemblerA64::Ldr(RegisterA64 &rt, const MemOperand &memOperand) {
if (memOperand.addr_mode == Offset) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(LDR_UIMM)(rt, memOperand)));
} else {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(LDR_IMM)(rt, memOperand)));
}
}
void AssemblerA64::Ldrsw(XRegister &rt, const MemOperand& memOperand) {
if (memOperand.addr_mode == Offset) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(LDRSW_UIMM)(rt, memOperand)));
} else {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(LDRSW_IMM)(rt, memOperand)));
}
}
void AssemblerA64::Pop(RegisterA64 &rd) {
if (rd.isX()) {
Ldr(rd, MemOperand(&SP, -1 * rd.getWideInBytes(), PreIndex));
} else {
Ldr(rd, MemOperand(&WSP, -1 * rd.getWideInBytes(), PreIndex));
}
}
void AssemblerA64::Push(RegisterA64 &rt) {
......
......@@ -59,7 +59,9 @@ namespace SandHook {
void Cbnz(RegisterA64 &rt, Label* label);
void Str(RegisterA64& rt, const MemOperand& memOperand);
void Ldr(RegisterA64& rt, const MemOperand& memOperand);
void Ldrsw(XRegister& rt, const MemOperand& memOperand);
void Pop(RegisterA64& rt);
void Push(RegisterA64& rt);
......
......@@ -580,7 +580,7 @@ A64_LDR_IMM::A64_LDR_IMM(STRUCT_A64(LDR_IMM) &inst) : A64LoadAndStoreImm(&inst)
decode(&inst);
}
A64_LDR_IMM::A64_LDR_IMM(RegisterA64 *rt, const MemOperand &operand) : A64LoadAndStoreImm(rt,
A64_LDR_IMM::A64_LDR_IMM(RegisterA64 &rt, const MemOperand &operand) : A64LoadAndStoreImm(&rt,
operand) {}
void A64_LDR_IMM::decode(STRUCT_A64(LDR_IMM) *inst) {
......@@ -657,7 +657,7 @@ A64_LDR_UIMM::A64_LDR_UIMM(STRUCT_A64(LDR_UIMM) &inst) : A64LoadAndStoreImm(&ins
decode(&inst);
}
A64_LDR_UIMM::A64_LDR_UIMM(RegisterA64 *rt, const MemOperand &operand) : A64LoadAndStoreImm(rt,
A64_LDR_UIMM::A64_LDR_UIMM(RegisterA64 &rt, const MemOperand &operand) : A64LoadAndStoreImm(&rt,
operand) {}
void A64_LDR_UIMM::decode(STRUCT_A64(LDR_UIMM) *inst) {
......@@ -696,3 +696,85 @@ void A64_LDR_UIMM::assembler() {
get()->imm12 = operand.offset >> get()->size;
}
A64_LDRSW_IMM::A64_LDRSW_IMM() {}
A64_LDRSW_IMM::A64_LDRSW_IMM(INST_A64(LDRSW_IMM) &inst) : A64_LDR_IMM(inst) {}
A64_LDRSW_IMM::A64_LDRSW_IMM(XRegister &rt, const MemOperand &operand) : A64_LDR_IMM(rt,
operand) {}
void A64_LDRSW_IMM::decode(STRUCT_A64(LDR_IMM) *inst) {
rt = XReg(static_cast<U8>(inst->rt));
addrMode = AdMod(inst->addrmode);
switch (addrMode) {
case PostIndex:
wback = true;
postindex = true;
operand.addr_mode = AddrMode::PostIndex;
break;
case PreIndex:
wback = true;
postindex = false;
operand.addr_mode = AddrMode::PreIndex;
break;
default:
valid = false;
return;
}
scale = static_cast<U8>(inst->size);
offset = signExtend64(9, inst->imm9);
operand.offset = offset;
rt = XReg(static_cast<U8>(inst->rt));
operand.base = XReg(static_cast<U8>(inst->rn));
}
void A64_LDRSW_IMM::assembler() {
SET_OPCODE(LDRSW_IMM);
get()->size = Size32;
get()->rt = rt->getCode();
get()->rn = operand.base->getCode();
get()->imm9 = TruncateToUint9(operand.offset);
switch (operand.addr_mode) {
case AddrMode::PostIndex:
wback = true;
postindex = true;
get()->addrmode = PostIndex;
break;
case AddrMode::PreIndex:
wback = true;
postindex = false;
get()->addrmode = PreIndex;
break;
default:
valid = false;
return;
}
}
A64_LDRSW_UIMM::A64_LDRSW_UIMM() {}
A64_LDRSW_UIMM::A64_LDRSW_UIMM(STRUCT_A64(LDR_UIMM) &inst) : A64_LDR_UIMM(inst) {}
A64_LDRSW_UIMM::A64_LDRSW_UIMM(XRegister &rt, const MemOperand &operand) : A64_LDR_UIMM(rt,
operand) {}
void A64_LDRSW_UIMM::decode(STRUCT_A64(LDR_UIMM) *inst) {
rt = XReg(static_cast<U8>(inst->rt));
operand.base = XReg(static_cast<U8>(inst->rn));
operand.addr_mode = AddrMode::Offset;
scale = static_cast<U8>(inst->size);
offset = inst->imm12 << Size32;
operand.offset = offset;
}
void A64_LDRSW_UIMM::assembler() {
SET_OPCODE(LDRSW_UIMM);
get()->size = Size32;
get()->rt = rt->getCode();
get()->rn = operand.base->getCode();
get()->imm12 = operand.offset >> Size32;
}
......@@ -611,7 +611,7 @@ namespace SandHook {
};
class INST_A64(SUB_EXT_REG) : InstructionA64<STRUCT_A64(SUB_EXT_REG)> {
class INST_A64(SUB_EXT_REG) : public InstructionA64<STRUCT_A64(SUB_EXT_REG)> {
public:
enum S {
......@@ -664,7 +664,7 @@ namespace SandHook {
DEFINE_INST_CODE(EXCEPTION_GEN)
void decode(A64_STRUCT_EXCEPTION_GEN *inst) override;
void decode(STRUCT_A64(EXCEPTION_GEN) *inst) override;
void assembler() override;
......@@ -689,30 +689,72 @@ namespace SandHook {
};
class INST_A64(LDR_IMM) : A64LoadAndStoreImm<STRUCT_A64(LDR_IMM)> {
class INST_A64(LDR_IMM) : public A64LoadAndStoreImm<STRUCT_A64(LDR_IMM)> {
public:
A64_LDR_IMM();
A64_LDR_IMM(STRUCT_A64(LDR_IMM) &inst);
A64_LDR_IMM(RegisterA64 *rt, const MemOperand &operand);
A64_LDR_IMM(RegisterA64 &rt, const MemOperand &operand);
DEFINE_IS(LDR_IMM)
DEFINE_INST_CODE(LDR_IMM)
private:
void decode(STRUCT_A64(LDR_IMM) *inst) override;
void assembler() override;
};
class INST_A64(LDR_UIMM) : A64LoadAndStoreImm<STRUCT_A64(LDR_UIMM)> {
class INST_A64(LDR_UIMM) : public A64LoadAndStoreImm<STRUCT_A64(LDR_UIMM)> {
public:
A64_LDR_UIMM();
A64_LDR_UIMM(STRUCT_A64(LDR_UIMM) &inst);
A64_LDR_UIMM(RegisterA64 *rt, const MemOperand &operand);
A64_LDR_UIMM(RegisterA64 &rt, const MemOperand &operand);
DEFINE_IS(LDR_UIMM)
DEFINE_INST_CODE(LDR_UIMM)
void decode(STRUCT_A64(LDR_UIMM) *inst) override;
void assembler() override;
};
class INST_A64(LDRSW_IMM) : public INST_A64(LDR_IMM) {
public:
A64_LDRSW_IMM();
A64_LDRSW_IMM(INST_A64(LDRSW_IMM) &inst);
A64_LDRSW_IMM(XRegister &rt, const MemOperand &operand);
DEFINE_IS_EXT(LDRSW_IMM, TEST_INST_FIELD(opcode, OPCODE_A64(LDRSW_IMM)) && TEST_INST_FIELD(size, Size32))
DEFINE_INST_CODE(LDRSW_IMM)
void decode(STRUCT_A64(LDR_IMM) *inst) override;
void assembler() override;
};
class INST_A64(LDRSW_UIMM) : public INST_A64(LDR_UIMM) {
public:
A64_LDRSW_UIMM();
A64_LDRSW_UIMM(STRUCT_A64(LDR_UIMM) &inst);
A64_LDRSW_UIMM(XRegister &rt, const MemOperand &operand);
DEFINE_IS_EXT(LDRSW_UIMM, TEST_INST_FIELD(opcode, OPCODE_A64(LDRSW_UIMM)) && TEST_INST_FIELD(size, Size32))
DEFINE_INST_CODE(LDRSW_UIMM)
private:
void decode(STRUCT_A64(LDR_UIMM) *inst) override;
void assembler() override;
......
......@@ -15,6 +15,8 @@ enum InstCodeA64 {
LDR_LIT,
LDR_UIMM,
LDR_IMM,
LDRSW_UIMM,
LDRSW_IMM,
STR_IMM,
STR_UIMM,
B_BL,
......
......@@ -169,6 +169,14 @@ DEFINE_STRUCT_A64(LDR_IMM) {
InstA64 size:2;
};
DEFINE_OPCODE(LDRSW_UIMM, 0b11100110)
struct STRUCT_A64(LDRSW_UIMM) : public STRUCT_A64(LDR_UIMM) {
};
DEFINE_OPCODE(LDRSW_IMM, 0b111000100)
struct STRUCT_A64(LDRSW_IMM) : public STRUCT_A64(LDR_IMM) {
};
DEFINE_OPCODE(BR_BLR_RET_1, 0b110101100)
DEFINE_OPCODE(BR_BLR_RET_2, 0b11111000000)
DEFINE_OPCODE(BR_BLR_RET_3, 0b00000)
......
......@@ -107,7 +107,27 @@ IMPL_RELOCATE(CBZ_CBNZ) {
}
IMPL_RELOCATE(LDR_LIT) {
Addr targetAddr = inst->getImmPCOffsetTarget();
XRegister* rtX = XReg(inst->rt->getCode());
WRegister* rtW = WReg(inst->rt->getCode());
switch (inst->op) {
case INST_A64(LDR_LIT)::LDR_X:
__ Mov(*rtX, targetAddr);
__ Ldr(*rtW, MemOperand(rtX, 0, Offset));
break;
case INST_A64(LDR_LIT)::LDR_W:
__ Mov(*rtX, targetAddr);
__ Ldr(*rtX, MemOperand(rtX, 0, Offset));
break;
case INST_A64(LDR_LIT)::LDR_SW:
break;
case INST_A64(LDR_LIT)::LDR_PRFM:
__ Push(X0);
__ Mov(X0, targetAddr);
__ Ldrsw(X0, MemOperand(rtX, 0, Offset));
__ Pop(X0);
break;
}
}
IMPL_RELOCATE(ADR_ADRP) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment