arm: Implement LDRD reg/imm instructions.
This commit is contained in:
parent
72608b7af6
commit
8c2300d477
2 changed files with 72 additions and 4 deletions
|
@ -183,8 +183,8 @@ boost::optional<const ArmMatcher<V>&> DecodeArm(u32 instruction) {
|
|||
INST(&V::arm_LDRB_reg, "LDRB (reg)", "cccc011pu1w1nnnnddddvvvvvrr0mmmm"),
|
||||
//INST(&V::arm_LDRBT, "LDRBT (A1)", "cccc0100u111nnnnttttvvvvvvvvvvvv"),
|
||||
//INST(&V::arm_LDRBT, "LDRBT (A2)", "cccc0110u111nnnnttttvvvvvrr0mmmm"),
|
||||
//INST(&V::arm_LDRD_imm, "LDRD (imm)", "cccc000pu1w0nnnnddddvvvv1101vvvv"), // v5E
|
||||
//INST(&V::arm_LDRD_reg, "LDRD (reg)", "cccc000pu0w0nnnndddd00001101mmmm"), // v5E
|
||||
INST(&V::arm_LDRD_imm, "LDRD (imm)", "cccc000pu1w0nnnnddddvvvv1101vvvv"), // v5E
|
||||
INST(&V::arm_LDRD_reg, "LDRD (reg)", "cccc000pu0w0nnnndddd00001101mmmm"), // v5E
|
||||
INST(&V::arm_LDRH_imm, "LDRH (imm)", "cccc000pu1w1nnnnddddvvvv1011vvvv"),
|
||||
INST(&V::arm_LDRH_reg, "LDRH (reg)", "cccc000pu0w1nnnndddd00001011mmmm"),
|
||||
//INST(&V::arm_LDRHT, "LDRHT (A1)", "----0000-111------------1011----"),
|
||||
|
|
|
@ -109,11 +109,79 @@ bool ArmTranslatorVisitor::arm_LDRBT() {
|
|||
}
|
||||
|
||||
bool ArmTranslatorVisitor::arm_LDRD_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg d, Imm4 imm8a, Imm4 imm8b) {
|
||||
return InterpretThisInstruction();
|
||||
if (ConditionPassed(cond)) {
|
||||
const auto address_a = GetAddressingMode(ir, P, U, W, n, ir.Imm32(imm8a << 4 | imm8b));
|
||||
const auto address_b = ir.Add(address_a, ir.Imm32(4));
|
||||
auto data_a = ir.ReadMemory32(address_a);
|
||||
auto data_b = ir.ReadMemory32(address_b);
|
||||
|
||||
switch(d) {
|
||||
case Reg::PC:
|
||||
data_a = ir.Add(data_a, ir.Imm32(4));
|
||||
break;
|
||||
case Reg::LR:
|
||||
data_b = ir.Add(data_b, ir.Imm32(4));
|
||||
break;
|
||||
}
|
||||
|
||||
if (d == Reg::PC) {
|
||||
ir.ALUWritePC(data_a);
|
||||
} else {
|
||||
ir.SetRegister(d, data_a);
|
||||
}
|
||||
|
||||
const Reg reg_b = static_cast<Reg>(std::min(d + 1, Reg::R15));
|
||||
if (reg_b == Reg::PC) {
|
||||
ir.ALUWritePC(data_b);
|
||||
} else {
|
||||
ir.SetRegister(reg_b, data_b);
|
||||
}
|
||||
|
||||
if (d == Reg::PC || reg_b == Reg::PC) {
|
||||
ir.SetTerm(IR::Term::ReturnToDispatch{});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ArmTranslatorVisitor::arm_LDRD_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg d, Reg m) {
|
||||
return InterpretThisInstruction();
|
||||
if (ConditionPassed(cond)) {
|
||||
const auto address_a = GetAddressingMode(ir, P, U, W, n, ir.GetRegister(m));
|
||||
const auto address_b = ir.Add(address_a, ir.Imm32(4));
|
||||
auto data_a = ir.ReadMemory32(address_a);
|
||||
auto data_b = ir.ReadMemory32(address_b);
|
||||
|
||||
switch(d) {
|
||||
case Reg::PC:
|
||||
data_a = ir.Add(data_a, ir.Imm32(4));
|
||||
break;
|
||||
case Reg::LR:
|
||||
data_b = ir.Add(data_b, ir.Imm32(4));
|
||||
break;
|
||||
}
|
||||
|
||||
if (d == Reg::PC) {
|
||||
ir.ALUWritePC(data_a);
|
||||
} else {
|
||||
ir.SetRegister(d, data_a);
|
||||
}
|
||||
|
||||
const Reg reg_b = static_cast<Reg>(std::min(d + 1, Reg::R15));
|
||||
if (reg_b == Reg::PC) {
|
||||
ir.ALUWritePC(data_b);
|
||||
} else {
|
||||
ir.SetRegister(reg_b, data_b);
|
||||
}
|
||||
|
||||
if (d == Reg::PC || reg_b == Reg::PC) {
|
||||
ir.SetTerm(IR::Term::ReturnToDispatch{});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ArmTranslatorVisitor::arm_LDRH_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg d, Imm4 imm8a, Imm4 imm8b) {
|
||||
|
|
Loading…
Reference in a new issue