diff --git a/src/frontend/A32/decoder/thumb32.inc b/src/frontend/A32/decoder/thumb32.inc index aee79da8..cbfcbc7e 100644 --- a/src/frontend/A32/decoder/thumb32.inc +++ b/src/frontend/A32/decoder/thumb32.inc @@ -124,7 +124,7 @@ INST(thumb32_UDF, "UDF", "111101111111----1010-- // 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, "B", "11110Svvvvvvvvvv10j1jvvvvvvvvvvv") //INST(thumb32_B_cond, "B (cond)", "11110-----------10-0------------") // Store Single Data Item diff --git a/src/frontend/A32/translate/impl/thumb32_branch.cpp b/src/frontend/A32/translate/impl/thumb32_branch.cpp index 1a8e87e8..9bf8edff 100644 --- a/src/frontend/A32/translate/impl/thumb32_branch.cpp +++ b/src/frontend/A32/translate/impl/thumb32_branch.cpp @@ -52,4 +52,20 @@ bool ThumbTranslatorVisitor::thumb32_BLX_imm(Imm<1> S, Imm<10> hi, Imm<1> j1, Im return false; } +bool ThumbTranslatorVisitor::thumb32_B(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(); + } + + const s32 imm32 = static_cast((concatenate(S, i1, i2, hi, lo).SignExtend() << 1) + 4); + const auto new_location = ir.current_location + .AdvancePC(imm32) + .AdvanceIT(); + ir.SetTerm(IR::Term::LinkBlock{new_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 ddaa7a3e..63407a8d 100644 --- a/src/frontend/A32/translate/impl/translate_thumb.h +++ b/src/frontend/A32/translate/impl/translate_thumb.h @@ -199,6 +199,7 @@ struct ThumbTranslatorVisitor final { // 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); + bool thumb32_B(Imm<1> S, Imm<10> 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);