A32: Fix thumb32 BL and BLX

More fields required
This commit is contained in:
sunho 2020-08-14 06:45:47 +09:00 committed by MerryMage
parent df027a7998
commit 43a1a523f6
3 changed files with 22 additions and 21 deletions

View file

@ -120,10 +120,11 @@
//INST(thumb32_MRS_reg_2, "MRS (reg)", "111100111110----10-0------0-----") //INST(thumb32_MRS_reg_2, "MRS (reg)", "111100111110----10-0------0-----")
//INST(thumb32_HVC, "HVC", "111101111110----1000------------") //INST(thumb32_HVC, "HVC", "111101111110----1000------------")
//INST(thumb32_SMC, "SMC", "111101111111----1000000000000000") //INST(thumb32_SMC, "SMC", "111101111111----1000000000000000")
//INST(thumb32_UDF, "UDF", "111101111111----1010------------") INST(thumb32_UDF, "UDF", "111101111111----1010------------") // v6T2
//INST(thumb32_BL, "BL", "11110-----------11-1------------") // Branch instructions
//INST(thumb32_BLX, "BLX", "11110-----------11-0------------") INST(thumb32_BL_imm, "BL (imm)", "11110Svvvvvvvvvv11j1jvvvvvvvvvvv") // v4T
INST(thumb32_BLX_imm, "BLX (imm)", "11110Svvvvvvvvvv11j0jvvvvvvvvvvv") // v5T
//INST(thumb32_B, "B", "11110-----------10-1------------") //INST(thumb32_B, "B", "11110-----------10-1------------")
//INST(thumb32_B_cond, "B (cond)", "11110-----------10-0------------") //INST(thumb32_B_cond, "B (cond)", "11110-----------10-0------------")
@ -187,9 +188,6 @@
//INST(thumb32_LDR_imm8, "LDR (imm8)", "111110000101--------1-----------") //INST(thumb32_LDR_imm8, "LDR (imm8)", "111110000101--------1-----------")
//INST(thumb32_LDR_imm12, "LDR (imm12)", "111110001101--------------------") //INST(thumb32_LDR_imm12, "LDR (imm12)", "111110001101--------------------")
// Undefined
//INST(thumb32_UDF, "UDF", "1111100--111--------------------")
// Data Processing (register) // Data Processing (register)
//INST(thumb32_LSL_reg, "LSL (reg)", "11111010000-----1111----0000----") //INST(thumb32_LSL_reg, "LSL (reg)", "11111010000-----1111----0000----")
//INST(thumb32_LSR_reg, "LSR (reg)", "11111010001-----1111----0000----") //INST(thumb32_LSR_reg, "LSR (reg)", "11111010001-----1111----0000----")
@ -307,10 +305,3 @@ INST(thumb32_UMAAL, "UMAAL", "111110111110nnnnllllhh
//INST(thumb32_MCR, "MCR", "11101110---0---------------1----") //INST(thumb32_MCR, "MCR", "11101110---0---------------1----")
//INST(thumb32_MRC2, "MRC2", "11111110---1---------------1----") //INST(thumb32_MRC2, "MRC2", "11111110---1---------------1----")
//INST(thumb32_MRC, "MRC", "11101110---1---------------1----") //INST(thumb32_MRC, "MRC", "11101110---1---------------1----")
// Branch instructions
INST(thumb32_BL_imm, "BL (imm)", "11110vvvvvvvvvvv11111vvvvvvvvvvv") // v4T
INST(thumb32_BLX_imm, "BLX (imm)", "11110vvvvvvvvvvv11101vvvvvvvvvvv") // v5T
// Misc instructions
INST(thumb32_UDF, "UDF", "111101111111----1010------------") // v6T2

View file

@ -8,7 +8,10 @@
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
// BL <label> // BL <label>
bool ThumbTranslatorVisitor::thumb32_BL_imm(Imm<11> hi, Imm<11> lo) { bool ThumbTranslatorVisitor::thumb32_BL_imm(Imm<1> S, Imm<10> hi, Imm<1> j1, Imm<1> j2, Imm<11> lo) {
const Imm<1> i1{j1 == S};
const Imm<1> i2{j2 == S};
if (ir.current_location.IT().IsInITBlock() && !ir.current_location.IT().IsLastInITBlock()) { if (ir.current_location.IT().IsInITBlock() && !ir.current_location.IT().IsLastInITBlock()) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -16,14 +19,19 @@ bool ThumbTranslatorVisitor::thumb32_BL_imm(Imm<11> hi, Imm<11> lo) {
ir.PushRSB(ir.current_location.AdvancePC(4)); ir.PushRSB(ir.current_location.AdvancePC(4));
ir.SetRegister(Reg::LR, ir.Imm32((ir.current_location.PC() + 4) | 1)); ir.SetRegister(Reg::LR, ir.Imm32((ir.current_location.PC() + 4) | 1));
const s32 imm32 = static_cast<s32>((concatenate(hi, lo).SignExtend<u32>() << 1) + 4); const s32 imm32 = static_cast<s32>((concatenate(S, i1, i2, hi, lo).SignExtend<u32>() << 1) + 4);
const auto new_location = ir.current_location.AdvancePC(imm32).AdvanceIT(); const auto new_location = ir.current_location
.AdvancePC(imm32)
.AdvanceIT();
ir.SetTerm(IR::Term::LinkBlock{new_location}); ir.SetTerm(IR::Term::LinkBlock{new_location});
return false; return false;
} }
// BLX <label> // BLX <label>
bool ThumbTranslatorVisitor::thumb32_BLX_imm(Imm<11> hi, Imm<11> lo) { bool ThumbTranslatorVisitor::thumb32_BLX_imm(Imm<1> S, Imm<10> hi, Imm<1> j1, Imm<1> j2, Imm<11> lo) {
const Imm<1> i1{j1 == S};
const Imm<1> i2{j2 == S};
if (ir.current_location.IT().IsInITBlock() && !ir.current_location.IT().IsLastInITBlock()) { if (ir.current_location.IT().IsInITBlock() && !ir.current_location.IT().IsLastInITBlock()) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -35,7 +43,7 @@ bool ThumbTranslatorVisitor::thumb32_BLX_imm(Imm<11> hi, Imm<11> lo) {
ir.PushRSB(ir.current_location.AdvancePC(4)); ir.PushRSB(ir.current_location.AdvancePC(4));
ir.SetRegister(Reg::LR, ir.Imm32((ir.current_location.PC() + 4) | 1)); ir.SetRegister(Reg::LR, ir.Imm32((ir.current_location.PC() + 4) | 1));
const s32 imm32 = static_cast<s32>(concatenate(hi, lo).SignExtend<u32>() << 1); const s32 imm32 = static_cast<s32>(concatenate(S, i1, i2, hi, lo).SignExtend<u32>() << 1);
const auto new_location = ir.current_location const auto new_location = ir.current_location
.SetPC(ir.AlignPC(4) + imm32) .SetPC(ir.AlignPC(4) + imm32)
.SetTFlag(false) .SetTFlag(false)

View file

@ -116,11 +116,13 @@ struct ThumbTranslatorVisitor final {
bool thumb16_B_t1(Cond cond, Imm<8> imm8); bool thumb16_B_t1(Cond cond, Imm<8> imm8);
bool thumb16_B_t2(Imm<11> imm11); bool thumb16_B_t2(Imm<11> imm11);
// thumb32 // thumb32 miscellaneous control instructions
bool thumb32_BL_imm(Imm<11> hi, Imm<11> lo);
bool thumb32_BLX_imm(Imm<11> hi, Imm<11> lo);
bool thumb32_UDF(); bool thumb32_UDF();
// thumb32 branch instructions
bool thumb32_BL_imm(Imm<1> S, Imm<10> hi, Imm<1> j1, Imm<1> j2, Imm<11> lo);
bool thumb32_BLX_imm(Imm<1> S, Imm<10> hi, Imm<1> j1, Imm<1> j2, Imm<11> lo);
// thumb32 data processing (register) instructions // thumb32 data processing (register) instructions
bool thumb32_SXTB(Reg d, SignExtendRotation rotate, Reg m); bool thumb32_SXTB(Reg d, SignExtendRotation rotate, Reg m);
bool thumb32_SXTB16(Reg d, SignExtendRotation rotate, Reg m); bool thumb32_SXTB16(Reg d, SignExtendRotation rotate, Reg m);