thumb32: Implement LDMDB/LDMEA

This commit is contained in:
Lioncash 2021-03-12 19:35:28 -05:00
parent ae83713f4f
commit 39edee70ff
3 changed files with 27 additions and 1 deletions

View file

@ -6,7 +6,7 @@ INST(thumb32_STMIA, "STMIA/STMEA", "1110100010W0nnnn0iiiii
INST(thumb32_LDMIA, "LDMIA/LDMFD", "1110100010W1nnnniiiiiiiiiiiiiiii") INST(thumb32_LDMIA, "LDMIA/LDMFD", "1110100010W1nnnniiiiiiiiiiiiiiii")
//INST(thumb32_PUSH, "PUSH", "1110100100101101----------------") //INST(thumb32_PUSH, "PUSH", "1110100100101101----------------")
INST(thumb32_STMDB, "STMDB/STMFD", "1110100100W0nnnn0iiiiiiiiiiiiiii") 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_SRS_1, "SRS", "1110100110-0--------------------")
//INST(thumb32_RFE_2, "RFE", "1110100110-1--------------------") //INST(thumb32_RFE_2, "RFE", "1110100110-1--------------------")

View file

@ -51,6 +51,31 @@ static bool STMHelper(A32::IREmitter& ir, bool W, Reg n, u32 list,
return true; 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<u32>(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<size_t>(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) { bool ThumbTranslatorVisitor::thumb32_LDMIA(bool W, Reg n, Imm<16> reg_list) {
const auto regs_imm = reg_list.ZeroExtend(); const auto regs_imm = reg_list.ZeroExtend();
const auto num_regs = static_cast<u32>(Common::BitCount(regs_imm)); const auto num_regs = static_cast<u32>(Common::BitCount(regs_imm));

View file

@ -172,6 +172,7 @@ struct ThumbTranslatorVisitor final {
bool thumb16_B_t2(Imm<11> imm11); bool thumb16_B_t2(Imm<11> imm11);
// thumb32 load/store multiple instructions // 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_LDMIA(bool W, Reg n, Imm<16> reg_list);
bool thumb32_STMIA(bool W, Reg n, 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); bool thumb32_STMDB(bool W, Reg n, Imm<15> reg_list);