From 43a1a523f64403c75c9ab5a9400e32903b1f7b33 Mon Sep 17 00:00:00 2001 From: sunho <ksunhokim123@naver.com> Date: Fri, 14 Aug 2020 06:45:47 +0900 Subject: [PATCH] A32: Fix thumb32 BL and BLX More fields required --- src/frontend/A32/decoder/thumb32.inc | 17 ++++------------- .../A32/translate/impl/thumb32_branch.cpp | 18 +++++++++++++----- .../A32/translate/impl/translate_thumb.h | 8 +++++--- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/frontend/A32/decoder/thumb32.inc b/src/frontend/A32/decoder/thumb32.inc index e03e2712..32ce0960 100644 --- a/src/frontend/A32/decoder/thumb32.inc +++ b/src/frontend/A32/decoder/thumb32.inc @@ -120,10 +120,11 @@ //INST(thumb32_MRS_reg_2, "MRS (reg)", "111100111110----10-0------0-----") //INST(thumb32_HVC, "HVC", "111101111110----1000------------") //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------------") -//INST(thumb32_BLX, "BLX", "11110-----------11-0------------") +// Branch instructions +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_cond, "B (cond)", "11110-----------10-0------------") @@ -187,9 +188,6 @@ //INST(thumb32_LDR_imm8, "LDR (imm8)", "111110000101--------1-----------") //INST(thumb32_LDR_imm12, "LDR (imm12)", "111110001101--------------------") -// Undefined -//INST(thumb32_UDF, "UDF", "1111100--111--------------------") - // Data Processing (register) //INST(thumb32_LSL_reg, "LSL (reg)", "11111010000-----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_MRC2, "MRC2", "11111110---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 diff --git a/src/frontend/A32/translate/impl/thumb32_branch.cpp b/src/frontend/A32/translate/impl/thumb32_branch.cpp index ebd82401..1a8e87e8 100644 --- a/src/frontend/A32/translate/impl/thumb32_branch.cpp +++ b/src/frontend/A32/translate/impl/thumb32_branch.cpp @@ -8,7 +8,10 @@ namespace Dynarmic::A32 { // 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()) { 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.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 auto new_location = ir.current_location.AdvancePC(imm32).AdvanceIT(); + 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(); ir.SetTerm(IR::Term::LinkBlock{new_location}); return false; } // 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()) { 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.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 .SetPC(ir.AlignPC(4) + imm32) .SetTFlag(false) diff --git a/src/frontend/A32/translate/impl/translate_thumb.h b/src/frontend/A32/translate/impl/translate_thumb.h index ceb54407..230a8121 100644 --- a/src/frontend/A32/translate/impl/translate_thumb.h +++ b/src/frontend/A32/translate/impl/translate_thumb.h @@ -116,11 +116,13 @@ struct ThumbTranslatorVisitor final { bool thumb16_B_t1(Cond cond, Imm<8> imm8); bool thumb16_B_t2(Imm<11> imm11); - // thumb32 - bool thumb32_BL_imm(Imm<11> hi, Imm<11> lo); - bool thumb32_BLX_imm(Imm<11> hi, Imm<11> lo); + // thumb32 miscellaneous control instructions 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 bool thumb32_SXTB(Reg d, SignExtendRotation rotate, Reg m); bool thumb32_SXTB16(Reg d, SignExtendRotation rotate, Reg m);