From ec3a98cf95557dc6b0b76876ac4ea7d3a0209d28 Mon Sep 17 00:00:00 2001 From: bunnei Date: Thu, 4 Aug 2016 23:12:45 -0400 Subject: [PATCH] arm: Implement LDRH reg/imm instructions. --- src/frontend/decoder/arm.h | 4 +-- .../translate/translate_arm/load_store.cpp | 28 +++++++++++++++++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/frontend/decoder/arm.h b/src/frontend/decoder/arm.h index 2b8972d2..10017d87 100644 --- a/src/frontend/decoder/arm.h +++ b/src/frontend/decoder/arm.h @@ -185,8 +185,8 @@ boost::optional&> DecodeArm(u32 instruction) { //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_LDRH_imm, "LDRH (imm)", "cccc000pu1w1nnnnddddvvvv1011vvvv"), - //INST(&V::arm_LDRH_reg, "LDRH (reg)", "cccc000pu0w1nnnndddd00001011mmmm"), + 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----"), //INST(&V::arm_LDRHT, "LDRHT (A2)", "----0000-011--------00001011----"), //INST(&V::arm_LDRSB_imm, "LDRSB (imm)", "cccc000pu1w1nnnnddddvvvv1101vvvv"), diff --git a/src/frontend/translate/translate_arm/load_store.cpp b/src/frontend/translate/translate_arm/load_store.cpp index 616e12c8..47245efd 100644 --- a/src/frontend/translate/translate_arm/load_store.cpp +++ b/src/frontend/translate/translate_arm/load_store.cpp @@ -117,11 +117,35 @@ bool ArmTranslatorVisitor::arm_LDRD_reg(Cond cond, bool P, bool U, bool W, Reg n } bool ArmTranslatorVisitor::arm_LDRH_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg d, Imm4 imm8a, Imm4 imm8b) { - return InterpretThisInstruction(); + if (ConditionPassed(cond)) { + const auto data = ir.ReadMemory16(GetAddressingMode(ir, P, U, W, n, ir.Imm32(imm8a << 4 | imm8b))); + + if (d == Reg::PC) { + ir.ALUWritePC(ir.Add(data, ir.Imm32(4))); + ir.SetTerm(IR::Term::ReturnToDispatch{}); + return false; + } + + ir.SetRegister(d, data); + } + + return true; } bool ArmTranslatorVisitor::arm_LDRH_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg d, Reg m) { - return InterpretThisInstruction(); + if (ConditionPassed(cond)) { + const auto data = ir.ReadMemory16(GetAddressingMode(ir, P, U, W, n, ir.GetRegister(m))); + + if (d == Reg::PC) { + ir.ALUWritePC(ir.Add(data, ir.Imm32(4))); + ir.SetTerm(IR::Term::ReturnToDispatch{}); + return false; + } + + ir.SetRegister(d, data); + } + + return true; } bool ArmTranslatorVisitor::arm_LDRHT() {