From 91c4d59da908c9fcdee61483743d8109672b3d48 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 12 Mar 2021 18:29:55 -0500 Subject: [PATCH 1/7] thumb32: Implement STMIA/STMEA --- src/CMakeLists.txt | 1 + src/frontend/A32/decoder/thumb32.inc | 2 +- .../impl/thumb32_load_store_multiple.cpp | 40 +++++++++++++++++++ .../A32/translate/impl/translate_thumb.h | 3 ++ 4 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 src/frontend/A32/translate/impl/thumb32_load_store_multiple.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 83cece7b..949e50ac 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -163,6 +163,7 @@ if ("A32" IN_LIST DYNARMIC_FRONTENDS) frontend/A32/translate/impl/thumb32_data_processing_shifted_register.cpp frontend/A32/translate/impl/thumb32_load_byte.cpp frontend/A32/translate/impl/thumb32_load_halfword.cpp + frontend/A32/translate/impl/thumb32_load_store_multiple.cpp frontend/A32/translate/impl/thumb32_load_word.cpp frontend/A32/translate/impl/thumb32_long_multiply.cpp frontend/A32/translate/impl/thumb32_misc.cpp diff --git a/src/frontend/A32/decoder/thumb32.inc b/src/frontend/A32/decoder/thumb32.inc index a2737352..8095927c 100644 --- a/src/frontend/A32/decoder/thumb32.inc +++ b/src/frontend/A32/decoder/thumb32.inc @@ -1,7 +1,7 @@ // Load/Store Multiple //INST(thumb32_SRS_1, "SRS", "1110100000-0--------------------") //INST(thumb32_RFE_2, "RFE", "1110100000-1--------------------") -//INST(thumb32_STMIA, "STMIA/STMEA", "1110100010-0--------------------") +INST(thumb32_STMIA, "STMIA/STMEA", "1110100010W0nnnn0iiiiiiiiiiiiiii") //INST(thumb32_POP, "POP", "1110100010111101----------------") //INST(thumb32_LDMIA, "LDMIA/LDMFD", "1110100010-1--------------------") //INST(thumb32_PUSH, "PUSH", "1110100100101101----------------") diff --git a/src/frontend/A32/translate/impl/thumb32_load_store_multiple.cpp b/src/frontend/A32/translate/impl/thumb32_load_store_multiple.cpp new file mode 100644 index 00000000..a821d0aa --- /dev/null +++ b/src/frontend/A32/translate/impl/thumb32_load_store_multiple.cpp @@ -0,0 +1,40 @@ +/* This file is part of the dynarmic project. + * Copyright (c) 2021 MerryMage + * SPDX-License-Identifier: 0BSD + */ + +#include "common/bit_util.h" +#include "frontend/A32/translate/impl/translate_thumb.h" + +namespace Dynarmic::A32 { + +bool ThumbTranslatorVisitor::thumb32_STMIA(bool W, Reg n, Imm<15> reg_list) { + const auto regs_imm = reg_list.ZeroExtend(); + const auto num_regs = static_cast(Common::BitCount(regs_imm)); + + if (n == Reg::PC || num_regs < 2) { + return UnpredictableInstruction(); + } + if (W && Common::Bit(static_cast(n), regs_imm)) { + return UnpredictableInstruction(); + } + if (reg_list.Bit<13>()) { + return UnpredictableInstruction(); + } + + IR::U32 address = ir.GetRegister(n); + for (size_t i = 0; i < 15; i++) { + if (Common::Bit(i, regs_imm)) { + ir.WriteMemory32(address, ir.GetRegister(static_cast(i))); + } + + address = ir.Add(address, ir.Imm32(4)); + } + + if (W) { + ir.SetRegister(n, address); + } + return true; +} + +} // namespace Dynarmic::A32 diff --git a/src/frontend/A32/translate/impl/translate_thumb.h b/src/frontend/A32/translate/impl/translate_thumb.h index 0999f59a..044bd9dd 100644 --- a/src/frontend/A32/translate/impl/translate_thumb.h +++ b/src/frontend/A32/translate/impl/translate_thumb.h @@ -171,6 +171,9 @@ struct ThumbTranslatorVisitor final { bool thumb16_B_t1(Cond cond, Imm<8> imm8); bool thumb16_B_t2(Imm<11> imm11); + // thumb32 load/store multiple instructions + bool thumb32_STMIA(bool W, Reg n, Imm<15> reg_list); + // thumb32 data processing (shifted register) instructions bool thumb32_TST_reg(Reg n, Imm<3> imm3, Imm<2> imm2, ShiftType type, Reg m); bool thumb32_AND_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m); From 714ccf13ddac1ea70f598d6fd518ae2404fac799 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 12 Mar 2021 18:53:25 -0500 Subject: [PATCH 2/7] thumb32: Implement STMDB/STMFD --- src/frontend/A32/decoder/thumb32.inc | 2 +- .../impl/thumb32_load_store_multiple.cpp | 33 +++++++++++++++++-- .../A32/translate/impl/translate_thumb.h | 1 + 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/frontend/A32/decoder/thumb32.inc b/src/frontend/A32/decoder/thumb32.inc index 8095927c..8aabfc88 100644 --- a/src/frontend/A32/decoder/thumb32.inc +++ b/src/frontend/A32/decoder/thumb32.inc @@ -5,7 +5,7 @@ INST(thumb32_STMIA, "STMIA/STMEA", "1110100010W0nnnn0iiiii //INST(thumb32_POP, "POP", "1110100010111101----------------") //INST(thumb32_LDMIA, "LDMIA/LDMFD", "1110100010-1--------------------") //INST(thumb32_PUSH, "PUSH", "1110100100101101----------------") -//INST(thumb32_STMDB, "STMDB/STMFD", "1110100100-0--------------------") +INST(thumb32_STMDB, "STMDB/STMFD", "1110100100W0nnnn0iiiiiiiiiiiiiii") //INST(thumb32_LDMDB, "LDMDB/LDMEA", "1110100100-1--------------------") //INST(thumb32_SRS_1, "SRS", "1110100110-0--------------------") //INST(thumb32_RFE_2, "RFE", "1110100110-1--------------------") diff --git a/src/frontend/A32/translate/impl/thumb32_load_store_multiple.cpp b/src/frontend/A32/translate/impl/thumb32_load_store_multiple.cpp index a821d0aa..f6fb751d 100644 --- a/src/frontend/A32/translate/impl/thumb32_load_store_multiple.cpp +++ b/src/frontend/A32/translate/impl/thumb32_load_store_multiple.cpp @@ -26,9 +26,8 @@ bool ThumbTranslatorVisitor::thumb32_STMIA(bool W, Reg n, Imm<15> reg_list) { for (size_t i = 0; i < 15; i++) { if (Common::Bit(i, regs_imm)) { ir.WriteMemory32(address, ir.GetRegister(static_cast(i))); + address = ir.Add(address, ir.Imm32(4)); } - - address = ir.Add(address, ir.Imm32(4)); } if (W) { @@ -37,4 +36,34 @@ bool ThumbTranslatorVisitor::thumb32_STMIA(bool W, Reg n, Imm<15> reg_list) { return true; } +bool ThumbTranslatorVisitor::thumb32_STMDB(bool W, Reg n, Imm<15> reg_list) { + const auto regs_imm = reg_list.ZeroExtend(); + const auto num_regs = static_cast(Common::BitCount(regs_imm)); + + if (n == Reg::PC || num_regs < 2) { + return UnpredictableInstruction(); + } + if (W && Common::Bit(static_cast(n), regs_imm)) { + return UnpredictableInstruction(); + } + if (reg_list.Bit<13>()) { + return UnpredictableInstruction(); + } + + const IR::U32 start_address = ir.Sub(ir.GetRegister(n), ir.Imm32(4 * num_regs)); + IR::U32 address = start_address; + + for (size_t i = 0; i < 15; i++) { + if (Common::Bit(i, regs_imm)) { + ir.WriteMemory32(address, ir.GetRegister(static_cast(i))); + address = ir.Add(address, ir.Imm32(4)); + } + } + + if (W) { + ir.SetRegister(n, start_address); + } + return true; +} + } // namespace Dynarmic::A32 diff --git a/src/frontend/A32/translate/impl/translate_thumb.h b/src/frontend/A32/translate/impl/translate_thumb.h index 044bd9dd..33fa6147 100644 --- a/src/frontend/A32/translate/impl/translate_thumb.h +++ b/src/frontend/A32/translate/impl/translate_thumb.h @@ -173,6 +173,7 @@ struct ThumbTranslatorVisitor final { // thumb32 load/store multiple instructions bool thumb32_STMIA(bool W, Reg n, Imm<15> reg_list); + bool thumb32_STMDB(bool W, Reg n, Imm<15> reg_list); // thumb32 data processing (shifted register) instructions bool thumb32_TST_reg(Reg n, Imm<3> imm3, Imm<2> imm2, ShiftType type, Reg m); From 0d887d9ecdbe864d2c69ab62fad3864148fb7a13 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 12 Mar 2021 19:26:03 -0500 Subject: [PATCH 3/7] thumb32: Implement LDMIA/LDMFD --- src/frontend/A32/decoder/thumb32.inc | 2 +- .../impl/thumb32_load_store_multiple.cpp | 53 +++++++++++++++++++ .../A32/translate/impl/translate_thumb.h | 1 + 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/src/frontend/A32/decoder/thumb32.inc b/src/frontend/A32/decoder/thumb32.inc index 8aabfc88..20fed89a 100644 --- a/src/frontend/A32/decoder/thumb32.inc +++ b/src/frontend/A32/decoder/thumb32.inc @@ -3,7 +3,7 @@ //INST(thumb32_RFE_2, "RFE", "1110100000-1--------------------") INST(thumb32_STMIA, "STMIA/STMEA", "1110100010W0nnnn0iiiiiiiiiiiiiii") //INST(thumb32_POP, "POP", "1110100010111101----------------") -//INST(thumb32_LDMIA, "LDMIA/LDMFD", "1110100010-1--------------------") +INST(thumb32_LDMIA, "LDMIA/LDMFD", "1110100010W1nnnniiiiiiiiiiiiiiii") //INST(thumb32_PUSH, "PUSH", "1110100100101101----------------") INST(thumb32_STMDB, "STMDB/STMFD", "1110100100W0nnnn0iiiiiiiiiiiiiii") //INST(thumb32_LDMDB, "LDMDB/LDMEA", "1110100100-1--------------------") diff --git a/src/frontend/A32/translate/impl/thumb32_load_store_multiple.cpp b/src/frontend/A32/translate/impl/thumb32_load_store_multiple.cpp index f6fb751d..528bec7f 100644 --- a/src/frontend/A32/translate/impl/thumb32_load_store_multiple.cpp +++ b/src/frontend/A32/translate/impl/thumb32_load_store_multiple.cpp @@ -7,6 +7,59 @@ #include "frontend/A32/translate/impl/translate_thumb.h" namespace Dynarmic::A32 { +static bool ITBlockCheck(const A32::IREmitter& ir) { + return ir.current_location.IT().IsInITBlock() && !ir.current_location.IT().IsLastInITBlock(); +} + +static bool LDMHelper(A32::IREmitter& ir, bool W, Reg n, u32 list, + const IR::U32& start_address, const IR::U32& writeback_address) { + auto address = start_address; + for (size_t i = 0; i <= 14; i++) { + if (Common::Bit(i, list)) { + ir.SetRegister(static_cast(i), ir.ReadMemory32(address)); + address = ir.Add(address, ir.Imm32(4)); + } + } + if (W && !Common::Bit(RegNumber(n), list)) { + ir.SetRegister(n, writeback_address); + } + if (Common::Bit<15>(list)) { + ir.UpdateUpperLocationDescriptor(); + ir.LoadWritePC(ir.ReadMemory32(address)); + if (n == Reg::R13) { + ir.SetTerm(IR::Term::PopRSBHint{}); + } else { + ir.SetTerm(IR::Term::FastDispatchHint{}); + } + return false; + } + return true; +} + +bool ThumbTranslatorVisitor::thumb32_LDMIA(bool W, Reg n, Imm<16> reg_list) { + const auto regs_imm = reg_list.ZeroExtend(); + const auto num_regs = static_cast(Common::BitCount(regs_imm)); + + if (n == Reg::PC || num_regs < 2) { + return UnpredictableInstruction(); + } + if (reg_list.Bit<15>() && reg_list.Bit<14>()) { + return UnpredictableInstruction(); + } + if (W && Common::Bit(static_cast(n), regs_imm)) { + return UnpredictableInstruction(); + } + if (reg_list.Bit<13>()) { + return UnpredictableInstruction(); + } + if (reg_list.Bit<15>() && ITBlockCheck(ir)) { + return UnpredictableInstruction(); + } + + const auto start_address = ir.GetRegister(n); + const auto writeback_address = ir.Add(start_address, ir.Imm32(num_regs * 4)); + return LDMHelper(ir, W, n, regs_imm, start_address, writeback_address); +} bool ThumbTranslatorVisitor::thumb32_STMIA(bool W, Reg n, Imm<15> reg_list) { const auto regs_imm = reg_list.ZeroExtend(); diff --git a/src/frontend/A32/translate/impl/translate_thumb.h b/src/frontend/A32/translate/impl/translate_thumb.h index 33fa6147..a4728a16 100644 --- a/src/frontend/A32/translate/impl/translate_thumb.h +++ b/src/frontend/A32/translate/impl/translate_thumb.h @@ -172,6 +172,7 @@ struct ThumbTranslatorVisitor final { bool thumb16_B_t2(Imm<11> imm11); // thumb32 load/store multiple instructions + bool thumb32_LDMIA(bool W, Reg n, Imm<16> reg_list); bool thumb32_STMIA(bool W, Reg n, Imm<15> reg_list); bool thumb32_STMDB(bool W, Reg n, Imm<15> reg_list); From ae83713f4f8bf793d90d8019acb98c63388e324a Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 12 Mar 2021 19:30:28 -0500 Subject: [PATCH 4/7] thumb32: Simplify existing store functions into helper function We can also make a STM helper. --- .../impl/thumb32_load_store_multiple.cpp | 45 +++++++++---------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/src/frontend/A32/translate/impl/thumb32_load_store_multiple.cpp b/src/frontend/A32/translate/impl/thumb32_load_store_multiple.cpp index 528bec7f..6b76d6d5 100644 --- a/src/frontend/A32/translate/impl/thumb32_load_store_multiple.cpp +++ b/src/frontend/A32/translate/impl/thumb32_load_store_multiple.cpp @@ -36,6 +36,21 @@ static bool LDMHelper(A32::IREmitter& ir, bool W, Reg n, u32 list, return true; } +static bool STMHelper(A32::IREmitter& ir, bool W, Reg n, u32 list, + const IR::U32& start_address, const IR::U32& writeback_address) { + auto address = start_address; + for (size_t i = 0; i <= 14; i++) { + if (Common::Bit(i, list)) { + ir.WriteMemory32(address, ir.GetRegister(static_cast(i))); + address = ir.Add(address, ir.Imm32(4)); + } + } + if (W) { + ir.SetRegister(n, writeback_address); + } + return true; +} + bool ThumbTranslatorVisitor::thumb32_LDMIA(bool W, Reg n, Imm<16> reg_list) { const auto regs_imm = reg_list.ZeroExtend(); const auto num_regs = static_cast(Common::BitCount(regs_imm)); @@ -75,18 +90,9 @@ bool ThumbTranslatorVisitor::thumb32_STMIA(bool W, Reg n, Imm<15> reg_list) { return UnpredictableInstruction(); } - IR::U32 address = ir.GetRegister(n); - for (size_t i = 0; i < 15; i++) { - if (Common::Bit(i, regs_imm)) { - ir.WriteMemory32(address, ir.GetRegister(static_cast(i))); - address = ir.Add(address, ir.Imm32(4)); - } - } - - if (W) { - ir.SetRegister(n, address); - } - return true; + const auto start_address = ir.GetRegister(n); + const auto writeback_address = ir.Add(start_address, ir.Imm32(num_regs * 4)); + return STMHelper(ir, W, n, regs_imm, start_address, writeback_address); } bool ThumbTranslatorVisitor::thumb32_STMDB(bool W, Reg n, Imm<15> reg_list) { @@ -103,20 +109,9 @@ bool ThumbTranslatorVisitor::thumb32_STMDB(bool W, Reg n, Imm<15> reg_list) { return UnpredictableInstruction(); } + // Start address is the same as the writeback address. const IR::U32 start_address = ir.Sub(ir.GetRegister(n), ir.Imm32(4 * num_regs)); - IR::U32 address = start_address; - - for (size_t i = 0; i < 15; i++) { - if (Common::Bit(i, regs_imm)) { - ir.WriteMemory32(address, ir.GetRegister(static_cast(i))); - address = ir.Add(address, ir.Imm32(4)); - } - } - - if (W) { - ir.SetRegister(n, start_address); - } - return true; + return STMHelper(ir, W, n, regs_imm, start_address, start_address); } } // namespace Dynarmic::A32 From 39edee70ff537d26b0116901f418e3ff435cb301 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 12 Mar 2021 19:35:28 -0500 Subject: [PATCH 5/7] thumb32: Implement LDMDB/LDMEA --- src/frontend/A32/decoder/thumb32.inc | 2 +- .../impl/thumb32_load_store_multiple.cpp | 25 +++++++++++++++++++ .../A32/translate/impl/translate_thumb.h | 1 + 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/frontend/A32/decoder/thumb32.inc b/src/frontend/A32/decoder/thumb32.inc index 20fed89a..63292053 100644 --- a/src/frontend/A32/decoder/thumb32.inc +++ b/src/frontend/A32/decoder/thumb32.inc @@ -6,7 +6,7 @@ INST(thumb32_STMIA, "STMIA/STMEA", "1110100010W0nnnn0iiiii INST(thumb32_LDMIA, "LDMIA/LDMFD", "1110100010W1nnnniiiiiiiiiiiiiiii") //INST(thumb32_PUSH, "PUSH", "1110100100101101----------------") INST(thumb32_STMDB, "STMDB/STMFD", "1110100100W0nnnn0iiiiiiiiiiiiiii") -//INST(thumb32_LDMDB, "LDMDB/LDMEA", "1110100100-1--------------------") +INST(thumb32_LDMDB, "LDMDB/LDMEA", "1110100100W1nnnniiiiiiiiiiiiiiii") //INST(thumb32_SRS_1, "SRS", "1110100110-0--------------------") //INST(thumb32_RFE_2, "RFE", "1110100110-1--------------------") diff --git a/src/frontend/A32/translate/impl/thumb32_load_store_multiple.cpp b/src/frontend/A32/translate/impl/thumb32_load_store_multiple.cpp index 6b76d6d5..b538bfef 100644 --- a/src/frontend/A32/translate/impl/thumb32_load_store_multiple.cpp +++ b/src/frontend/A32/translate/impl/thumb32_load_store_multiple.cpp @@ -51,6 +51,31 @@ static bool STMHelper(A32::IREmitter& ir, bool W, Reg n, u32 list, return true; } +bool ThumbTranslatorVisitor::thumb32_LDMDB(bool W, Reg n, Imm<16> reg_list) { + const auto regs_imm = reg_list.ZeroExtend(); + const auto num_regs = static_cast(Common::BitCount(regs_imm)); + + if (n == Reg::PC || num_regs < 2) { + return UnpredictableInstruction(); + } + if (reg_list.Bit<15>() && reg_list.Bit<14>()) { + return UnpredictableInstruction(); + } + if (W && Common::Bit(static_cast(n), regs_imm)) { + return UnpredictableInstruction(); + } + if (reg_list.Bit<13>()) { + return UnpredictableInstruction(); + } + if (reg_list.Bit<15>() && ITBlockCheck(ir)) { + return UnpredictableInstruction(); + } + + // Start address is the same as the writeback address. + const IR::U32 start_address = ir.Sub(ir.GetRegister(n), ir.Imm32(4 * num_regs)); + return LDMHelper(ir, W, n, regs_imm, start_address, start_address); +} + bool ThumbTranslatorVisitor::thumb32_LDMIA(bool W, Reg n, Imm<16> reg_list) { const auto regs_imm = reg_list.ZeroExtend(); const auto num_regs = static_cast(Common::BitCount(regs_imm)); diff --git a/src/frontend/A32/translate/impl/translate_thumb.h b/src/frontend/A32/translate/impl/translate_thumb.h index a4728a16..5a066cdd 100644 --- a/src/frontend/A32/translate/impl/translate_thumb.h +++ b/src/frontend/A32/translate/impl/translate_thumb.h @@ -172,6 +172,7 @@ struct ThumbTranslatorVisitor final { bool thumb16_B_t2(Imm<11> imm11); // thumb32 load/store multiple instructions + bool thumb32_LDMDB(bool W, Reg n, Imm<16> reg_list); bool thumb32_LDMIA(bool W, Reg n, Imm<16> reg_list); bool thumb32_STMIA(bool W, Reg n, Imm<15> reg_list); bool thumb32_STMDB(bool W, Reg n, Imm<15> reg_list); From 9cb4790428f8f1f54ec54016df33a04beed711cb Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 12 Mar 2021 19:43:44 -0500 Subject: [PATCH 6/7] thumb32: Implement POP This can just be treated as an alias to LDMIA --- src/frontend/A32/decoder/thumb32.inc | 2 +- .../A32/translate/impl/thumb32_load_store_multiple.cpp | 4 ++++ src/frontend/A32/translate/impl/translate_thumb.h | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/frontend/A32/decoder/thumb32.inc b/src/frontend/A32/decoder/thumb32.inc index 63292053..e104fd43 100644 --- a/src/frontend/A32/decoder/thumb32.inc +++ b/src/frontend/A32/decoder/thumb32.inc @@ -2,7 +2,7 @@ //INST(thumb32_SRS_1, "SRS", "1110100000-0--------------------") //INST(thumb32_RFE_2, "RFE", "1110100000-1--------------------") INST(thumb32_STMIA, "STMIA/STMEA", "1110100010W0nnnn0iiiiiiiiiiiiiii") -//INST(thumb32_POP, "POP", "1110100010111101----------------") +INST(thumb32_POP, "POP", "1110100010111101iiiiiiiiiiiiiiii") INST(thumb32_LDMIA, "LDMIA/LDMFD", "1110100010W1nnnniiiiiiiiiiiiiiii") //INST(thumb32_PUSH, "PUSH", "1110100100101101----------------") INST(thumb32_STMDB, "STMDB/STMFD", "1110100100W0nnnn0iiiiiiiiiiiiiii") diff --git a/src/frontend/A32/translate/impl/thumb32_load_store_multiple.cpp b/src/frontend/A32/translate/impl/thumb32_load_store_multiple.cpp index b538bfef..bac48eb3 100644 --- a/src/frontend/A32/translate/impl/thumb32_load_store_multiple.cpp +++ b/src/frontend/A32/translate/impl/thumb32_load_store_multiple.cpp @@ -101,6 +101,10 @@ bool ThumbTranslatorVisitor::thumb32_LDMIA(bool W, Reg n, Imm<16> reg_list) { return LDMHelper(ir, W, n, regs_imm, start_address, writeback_address); } +bool ThumbTranslatorVisitor::thumb32_POP(Imm<16> reg_list) { + return thumb32_LDMIA(true, Reg::SP, reg_list); +} + bool ThumbTranslatorVisitor::thumb32_STMIA(bool W, Reg n, Imm<15> reg_list) { const auto regs_imm = reg_list.ZeroExtend(); const auto num_regs = static_cast(Common::BitCount(regs_imm)); diff --git a/src/frontend/A32/translate/impl/translate_thumb.h b/src/frontend/A32/translate/impl/translate_thumb.h index 5a066cdd..495a7d9d 100644 --- a/src/frontend/A32/translate/impl/translate_thumb.h +++ b/src/frontend/A32/translate/impl/translate_thumb.h @@ -174,6 +174,7 @@ struct ThumbTranslatorVisitor final { // thumb32 load/store multiple instructions bool thumb32_LDMDB(bool W, Reg n, Imm<16> reg_list); bool thumb32_LDMIA(bool W, Reg n, Imm<16> reg_list); + bool thumb32_POP(Imm<16> reg_list); bool thumb32_STMIA(bool W, Reg n, Imm<15> reg_list); bool thumb32_STMDB(bool W, Reg n, Imm<15> reg_list); From 1d0b705996709291dd38a7fabf172225a312cdc8 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 12 Mar 2021 19:54:31 -0500 Subject: [PATCH 7/7] thumb32: Implement PUSH This can be handled as an alias for STMDB. --- src/frontend/A32/decoder/thumb32.inc | 2 +- .../A32/translate/impl/thumb32_load_store_multiple.cpp | 4 ++++ src/frontend/A32/translate/impl/translate_thumb.h | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/frontend/A32/decoder/thumb32.inc b/src/frontend/A32/decoder/thumb32.inc index e104fd43..e5def4ca 100644 --- a/src/frontend/A32/decoder/thumb32.inc +++ b/src/frontend/A32/decoder/thumb32.inc @@ -4,7 +4,7 @@ INST(thumb32_STMIA, "STMIA/STMEA", "1110100010W0nnnn0iiiiiiiiiiiiiii") INST(thumb32_POP, "POP", "1110100010111101iiiiiiiiiiiiiiii") INST(thumb32_LDMIA, "LDMIA/LDMFD", "1110100010W1nnnniiiiiiiiiiiiiiii") -//INST(thumb32_PUSH, "PUSH", "1110100100101101----------------") +INST(thumb32_PUSH, "PUSH", "11101001001011010iiiiiiiiiiiiiii") INST(thumb32_STMDB, "STMDB/STMFD", "1110100100W0nnnn0iiiiiiiiiiiiiii") INST(thumb32_LDMDB, "LDMDB/LDMEA", "1110100100W1nnnniiiiiiiiiiiiiiii") //INST(thumb32_SRS_1, "SRS", "1110100110-0--------------------") diff --git a/src/frontend/A32/translate/impl/thumb32_load_store_multiple.cpp b/src/frontend/A32/translate/impl/thumb32_load_store_multiple.cpp index bac48eb3..49af9d76 100644 --- a/src/frontend/A32/translate/impl/thumb32_load_store_multiple.cpp +++ b/src/frontend/A32/translate/impl/thumb32_load_store_multiple.cpp @@ -105,6 +105,10 @@ bool ThumbTranslatorVisitor::thumb32_POP(Imm<16> reg_list) { return thumb32_LDMIA(true, Reg::SP, reg_list); } +bool ThumbTranslatorVisitor::thumb32_PUSH(Imm<15> reg_list) { + return thumb32_STMDB(true, Reg::SP, reg_list); +} + bool ThumbTranslatorVisitor::thumb32_STMIA(bool W, Reg n, Imm<15> reg_list) { const auto regs_imm = reg_list.ZeroExtend(); const auto num_regs = static_cast(Common::BitCount(regs_imm)); diff --git a/src/frontend/A32/translate/impl/translate_thumb.h b/src/frontend/A32/translate/impl/translate_thumb.h index 495a7d9d..174f601c 100644 --- a/src/frontend/A32/translate/impl/translate_thumb.h +++ b/src/frontend/A32/translate/impl/translate_thumb.h @@ -175,6 +175,7 @@ struct ThumbTranslatorVisitor final { bool thumb32_LDMDB(bool W, Reg n, Imm<16> reg_list); bool thumb32_LDMIA(bool W, Reg n, Imm<16> reg_list); bool thumb32_POP(Imm<16> reg_list); + bool thumb32_PUSH(Imm<15> reg_list); bool thumb32_STMIA(bool W, Reg n, Imm<15> reg_list); bool thumb32_STMDB(bool W, Reg n, Imm<15> reg_list);