From 531bb42ab5192821fdff28cad2946c95db7a8499 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Sat, 6 Mar 2021 17:28:19 +0000 Subject: [PATCH] thumb32: Implement B (T3) --- src/frontend/A32/decoder/thumb32.inc | 3 ++- .../A32/translate/impl/thumb32_branch.cpp | 17 +++++++++++++++++ .../A32/translate/impl/translate_thumb.h | 1 + 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/frontend/A32/decoder/thumb32.inc b/src/frontend/A32/decoder/thumb32.inc index cbfcbc7e..19019865 100644 --- a/src/frontend/A32/decoder/thumb32.inc +++ b/src/frontend/A32/decoder/thumb32.inc @@ -125,7 +125,8 @@ INST(thumb32_UDF, "UDF", "111101111111----1010-- INST(thumb32_BL_imm, "BL (imm)", "11110Svvvvvvvvvv11j1jvvvvvvvvvvv") // v4T INST(thumb32_BLX_imm, "BLX (imm)", "11110Svvvvvvvvvv11j0jvvvvvvvvvvv") // v5T INST(thumb32_B, "B", "11110Svvvvvvvvvv10j1jvvvvvvvvvvv") -//INST(thumb32_B_cond, "B (cond)", "11110-----------10-0------------") +INST(thumb32_UDF, "Invalid decoding", "11110-111-------10-0------------") +INST(thumb32_B_cond, "B (cond)", "11110Sccccvvvvvv10i0ivvvvvvvvvvv") // Store Single Data Item //INST(thumb32_STRB_imm_1, "STRB (imm)", "111110000000--------1--1--------") diff --git a/src/frontend/A32/translate/impl/thumb32_branch.cpp b/src/frontend/A32/translate/impl/thumb32_branch.cpp index 9bf8edff..e9f23741 100644 --- a/src/frontend/A32/translate/impl/thumb32_branch.cpp +++ b/src/frontend/A32/translate/impl/thumb32_branch.cpp @@ -68,4 +68,21 @@ bool ThumbTranslatorVisitor::thumb32_B(Imm<1> S, Imm<10> hi, Imm<1> j1, Imm<1> j return false; } +bool ThumbTranslatorVisitor::thumb32_B_cond(Imm<1> S, Cond cond, Imm<6> hi, Imm<1> i1, Imm<1> i2, Imm<11> lo) { + if (ir.current_location.IT().IsInITBlock()) { + return UnpredictableInstruction(); + } + + // Note: i1 and i2 were not inverted from encoding and are opposite compared to the other B instructions. + const s32 imm32 = static_cast((concatenate(S, i2, i1, hi, lo).SignExtend() << 1) + 4); + const auto then_location = ir.current_location + .AdvancePC(imm32) + .AdvanceIT(); + const auto else_location = ir.current_location + .AdvancePC(4) + .AdvanceIT(); + ir.SetTerm(IR::Term::If{cond, IR::Term::LinkBlock{then_location}, IR::Term::LinkBlock{else_location}}); + return false; +} + } // namespace Dynarmic::A32 diff --git a/src/frontend/A32/translate/impl/translate_thumb.h b/src/frontend/A32/translate/impl/translate_thumb.h index 63407a8d..e1120cf8 100644 --- a/src/frontend/A32/translate/impl/translate_thumb.h +++ b/src/frontend/A32/translate/impl/translate_thumb.h @@ -200,6 +200,7 @@ struct ThumbTranslatorVisitor final { 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); bool thumb32_B(Imm<1> S, Imm<10> hi, Imm<1> j1, Imm<1> j2, Imm<11> lo); + bool thumb32_B_cond(Imm<1> S, Cond cond, Imm<6> hi, Imm<1> j1, Imm<1> j2, Imm<11> lo); // thumb32 store single data item instructions bool thumb32_STRB(Reg n, Reg t, Imm<2> imm2, Reg m);