From f9755870bbbfef9203d4bb9cd090a0b8b22f13e1 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Mon, 18 Jul 2016 18:01:15 +0100 Subject: [PATCH] Implement Thumb Instructions: LDR (reg), LDRH (reg), LDRSH (reg), LDRB (reg), LDRSB (reg) --- src/frontend/decoder/thumb16.h | 14 +++--- .../disassembler/disassembler_thumb.cpp | 20 +++++++++ src/frontend/translate/translate_thumb.cpp | 45 +++++++++++++++++++ 3 files changed, 72 insertions(+), 7 deletions(-) diff --git a/src/frontend/decoder/thumb16.h b/src/frontend/decoder/thumb16.h index 9bc9d065..18d2d369 100644 --- a/src/frontend/decoder/thumb16.h +++ b/src/frontend/decoder/thumb16.h @@ -102,14 +102,14 @@ boost::optional&> DecodeThumb16(u16 instruction) { INST(&V::thumb16_STR_reg, "STR (reg)", "0101000mmmnnnttt"), INST(&V::thumb16_STRH_reg, "STRH (reg)", "0101001mmmnnnttt"), INST(&V::thumb16_STRB_reg, "STRB (reg)", "0101010mmmnnnttt"), - //INST(&V::thumb16_LDRSB_rrr, "LDRSB (rrr)", "0101011mmmnnnddd"), - //INST(&V::thumb16_LDR_rrr, "LDR (rrr)", "0101100mmmnnnddd"), - //INST(&V::thumb16_LDRH_rrr, "LDRH (rrr)", "0101101mmmnnnddd"), - //INST(&V::thumb16_LDRB_rrr, "LDRB (rrr)", "0101110mmmnnnddd"), - //INST(&V::thumb16_LDRSH_rrr, "LDRSH (rrr)", "0101111mmmnnnddd"), + INST(&V::thumb16_LDRSB_reg, "LDRSB (reg)", "0101011mmmnnnttt"), + INST(&V::thumb16_LDR_reg, "LDR (reg)", "0101100mmmnnnttt"), + INST(&V::thumb16_LDRH_reg, "LDRH (reg)", "0101101mmmnnnttt"), + INST(&V::thumb16_LDRB_reg, "LDRB (reg)", "0101110mmmnnnttt"), + INST(&V::thumb16_LDRSH_reg, "LDRSH (reg)", "0101111mmmnnnttt"), INST(&V::thumb16_LDR_imm_t1, "LDR (imm, T1)", "01101vvvvvnnnttt"), - //INST(&V::thumb16_STRH_rri, "STRH (rri)", "10000vvvvvnnnddd"), - //INST(&V::thumb16_LDRH_rri, "LDRH (rri)", "10001vvvvvnnnddd"), + //INST(&V::thumb16_STRH_imm, "STRH (imm)", "10000vvvvvnnnttt"), + //INST(&V::thumb16_LDRH_imm, "LDRH (imm)", "10001vvvvvnnnttt"), //INST(&V::thumb16_STR_sp, "STR (SP)", "10010dddvvvvvvvv"), //INST(&V::thumb16_LDR_sp, "LDR (SP)", "10011dddvvvvvvvv"), diff --git a/src/frontend/disassembler/disassembler_thumb.cpp b/src/frontend/disassembler/disassembler_thumb.cpp index 235ce780..6881704e 100644 --- a/src/frontend/disassembler/disassembler_thumb.cpp +++ b/src/frontend/disassembler/disassembler_thumb.cpp @@ -239,6 +239,26 @@ public: return Common::StringFromFormat("strb %s, [%s, %s]", RegStr(t), RegStr(n), RegStr(m)); } + std::string thumb16_LDRSB_reg(Reg m, Reg n, Reg t) { + return Common::StringFromFormat("ldrsb %s, [%s, %s]", RegStr(t), RegStr(n), RegStr(m)); + } + + std::string thumb16_LDR_reg(Reg m, Reg n, Reg t) { + return Common::StringFromFormat("ldr %s, [%s, %s]", RegStr(t), RegStr(n), RegStr(m)); + } + + std::string thumb16_LDRH_reg(Reg m, Reg n, Reg t) { + return Common::StringFromFormat("ldrh %s, [%s, %s]", RegStr(t), RegStr(n), RegStr(m)); + } + + std::string thumb16_LDRB_reg(Reg m, Reg n, Reg t) { + return Common::StringFromFormat("ldrb %s, [%s, %s]", RegStr(t), RegStr(n), RegStr(m)); + } + + std::string thumb16_LDRSH_reg(Reg m, Reg n, Reg t) { + return Common::StringFromFormat("ldrsh %s, [%s, %s]", RegStr(t), RegStr(n), RegStr(m)); + } + std::string thumb16_LDR_imm_t1(Imm5 imm5, Reg n, Reg t) { u32 imm32 = imm5 << 2; return Common::StringFromFormat("ldr %s, [%s, #%u]", RegStr(t), RegStr(n), imm32); diff --git a/src/frontend/translate/translate_thumb.cpp b/src/frontend/translate/translate_thumb.cpp index 98bb5fd4..cac60d15 100644 --- a/src/frontend/translate/translate_thumb.cpp +++ b/src/frontend/translate/translate_thumb.cpp @@ -431,6 +431,51 @@ struct ThumbTranslatorVisitor final { return true; } + bool thumb16_LDRSB_reg(Reg m, Reg n, Reg t) { + // LDRSB , [, ] + // Rt cannot encode R15. + auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m)); + auto data = ir.SignExtendByteToWord(ir.ReadMemory8(address)); + ir.SetRegister(t, data); + return true; + } + + bool thumb16_LDR_reg(Reg m, Reg n, Reg t) { + // LDR , [, ] + // Rt cannot encode R15. + auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m)); + auto data = ir.ReadMemory32(address); + ir.SetRegister(t, data); + return true; + } + + bool thumb16_LDRH_reg(Reg m, Reg n, Reg t) { + // LDRH , [, ] + // Rt cannot encode R15. + auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m)); + auto data = ir.ZeroExtendHalfToWord(ir.ReadMemory16(address)); + ir.SetRegister(t, data); + return true; + } + + bool thumb16_LDRB_reg(Reg m, Reg n, Reg t) { + // LDRB , [, ] + // Rt cannot encode R15. + auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m)); + auto data = ir.ZeroExtendByteToWord(ir.ReadMemory8(address)); + ir.SetRegister(t, data); + return true; + } + + bool thumb16_LDRSH_reg(Reg m, Reg n, Reg t) { + // LDRH , [, ] + // Rt cannot encode R15. + auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m)); + auto data = ir.SignExtendHalfToWord(ir.ReadMemory16(address)); + ir.SetRegister(t, data); + return true; + } + bool thumb16_LDR_imm_t1(Imm5 imm5, Reg n, Reg t) { u32 imm32 = imm5 << 2; // LDR , [, #}