From 14dcb18bbeb3ce5fc4317ff0f7aa6a3fe3eaff7d Mon Sep 17 00:00:00 2001 From: MerryMage Date: Mon, 18 Jul 2016 18:48:08 +0100 Subject: [PATCH] Implemented Thumb Instructions: STR (imm, T1), STRB (imm), LDRB (imm), STR (imm, T2), LDR (imm, T2) --- src/frontend/decoder/thumb16.h | 7 ++- .../disassembler/disassembler_thumb.cpp | 25 +++++++++ src/frontend/translate/translate_thumb.cpp | 54 ++++++++++++++++++- 3 files changed, 83 insertions(+), 3 deletions(-) diff --git a/src/frontend/decoder/thumb16.h b/src/frontend/decoder/thumb16.h index c38f452e..3292d270 100644 --- a/src/frontend/decoder/thumb16.h +++ b/src/frontend/decoder/thumb16.h @@ -107,11 +107,14 @@ boost::optional&> DecodeThumb16(u16 instruction) { 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_STR_imm_t1, "STR (imm, T1)", "01100vvvvvnnnttt"), INST(&V::thumb16_LDR_imm_t1, "LDR (imm, T1)", "01101vvvvvnnnttt"), + INST(&V::thumb16_STRB_imm, "STRB (imm)", "01110vvvvvnnnttt"), + INST(&V::thumb16_LDRB_imm, "LDRB (imm)", "01111vvvvvnnnttt"), 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"), + INST(&V::thumb16_STR_imm_t2, "STR (imm, T2)", "10010tttvvvvvvvv"), + INST(&V::thumb16_LDR_imm_t2, "LDR (imm, T2)", "10011tttvvvvvvvv"), // Generate relative address instructions INST(&V::thumb16_ADR, "ADR", "10100dddvvvvvvvv"), diff --git a/src/frontend/disassembler/disassembler_thumb.cpp b/src/frontend/disassembler/disassembler_thumb.cpp index d71f27ad..780b7f56 100644 --- a/src/frontend/disassembler/disassembler_thumb.cpp +++ b/src/frontend/disassembler/disassembler_thumb.cpp @@ -259,11 +259,26 @@ public: return Common::StringFromFormat("ldrsh %s, [%s, %s]", RegStr(t), RegStr(n), RegStr(m)); } + std::string thumb16_STR_imm_t1(Imm5 imm5, Reg n, Reg t) { + u32 imm32 = imm5 << 2; + return Common::StringFromFormat("str %s, [%s, #%u]", RegStr(t), RegStr(n), imm32); + } + 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); } + std::string thumb16_STRB_imm(Imm5 imm5, Reg n, Reg t) { + u32 imm32 = imm5; + return Common::StringFromFormat("strb %s, [%s, #%u]", RegStr(t), RegStr(n), imm32); + } + + std::string thumb16_LDRB_imm(Imm5 imm5, Reg n, Reg t) { + u32 imm32 = imm5; + return Common::StringFromFormat("ldrb %s, [%s, #%u]", RegStr(t), RegStr(n), imm32); + } + std::string thumb16_STRH_imm(Imm5 imm5, Reg n, Reg t) { u32 imm32 = imm5 << 1; return Common::StringFromFormat("strh %s, [%s, #%u]", RegStr(t), RegStr(n), imm32); @@ -274,6 +289,16 @@ public: return Common::StringFromFormat("ldrh %s, [%s, #%u]", RegStr(t), RegStr(n), imm32); } + std::string thumb16_STR_imm_t2(Reg t, Imm5 imm5) { + u32 imm32 = imm5 << 2; + return Common::StringFromFormat("str %s, [sp, #%u]", RegStr(t), imm32); + } + + std::string thumb16_LDR_imm_t2(Reg t, Imm5 imm5) { + u32 imm32 = imm5 << 2; + return Common::StringFromFormat("ldr %s, [sp, #%u]", RegStr(t), imm32); + } + std::string thumb16_ADR(Reg d, Imm8 imm8) { u32 imm32 = imm8 << 2; return Common::StringFromFormat("adr %s, +#%u", RegStr(d), imm32); diff --git a/src/frontend/translate/translate_thumb.cpp b/src/frontend/translate/translate_thumb.cpp index e053027c..64d2f799 100644 --- a/src/frontend/translate/translate_thumb.cpp +++ b/src/frontend/translate/translate_thumb.cpp @@ -476,9 +476,19 @@ struct ThumbTranslatorVisitor final { return true; } + bool thumb16_STR_imm_t1(Imm5 imm5, Reg n, Reg t) { + u32 imm32 = imm5 << 2; + // STR , [, #] + // Rt cannot encode R15. + auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32)); + auto data = ir.GetRegister(t); + ir.WriteMemory32(address, data); + return true; + } + bool thumb16_LDR_imm_t1(Imm5 imm5, Reg n, Reg t) { u32 imm32 = imm5 << 2; - // LDR , [, #} + // LDR , [, #] // Rt cannot encode R15. auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32)); auto data = ir.ReadMemory32(address); @@ -486,6 +496,26 @@ struct ThumbTranslatorVisitor final { return true; } + bool thumb16_STRB_imm(Imm5 imm5, Reg n, Reg t) { + u32 imm32 = imm5; + // STRB , [, #] + // Rt cannot encode R15. + auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32)); + auto data = ir.LeastSignificantByte(ir.GetRegister(t)); + ir.WriteMemory8(address, data); + return true; + } + + bool thumb16_LDRB_imm(Imm5 imm5, Reg n, Reg t) { + u32 imm32 = imm5; + // LDRB , [, #] + // Rt cannot encode R15. + auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32)); + auto data = ir.ZeroExtendByteToWord(ir.ReadMemory8(address)); + ir.SetRegister(t, data); + return true; + } + bool thumb16_STRH_imm(Imm5 imm5, Reg n, Reg t) { u32 imm32 = imm5 << 1; // STRH , [, #] @@ -504,6 +534,28 @@ struct ThumbTranslatorVisitor final { return true; } + bool thumb16_STR_imm_t2(Reg t, Imm5 imm5) { + u32 imm32 = imm5 << 2; + Reg n = Reg::SP; + // STR , [, #] + // Rt cannot encode R15. + auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32)); + auto data = ir.GetRegister(t); + ir.WriteMemory32(address, data); + return true; + } + + bool thumb16_LDR_imm_t2(Reg t, Imm5 imm5) { + u32 imm32 = imm5 << 2; + Reg n = Reg::SP; + // LDR , [, #] + // Rt cannot encode R15. + auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32)); + auto data = ir.ReadMemory32(address); + ir.SetRegister(t, data); + return true; + } + bool thumb16_ADR(Reg d, Imm8 imm8) { u32 imm32 = imm8 << 2; // ADR ,