diff --git a/src/frontend/A32/translate/impl/translate_thumb.h b/src/frontend/A32/translate/impl/translate_thumb.h index 230a8121..c29086bc 100644 --- a/src/frontend/A32/translate/impl/translate_thumb.h +++ b/src/frontend/A32/translate/impl/translate_thumb.h @@ -24,6 +24,38 @@ struct ThumbTranslatorVisitor final { ASSERT_MSG(descriptor.TFlag(), "The processor must be in Thumb mode"); } + struct ImmAndCarry { + u32 imm32; + IR::U1 carry; + }; + + ImmAndCarry ThumbExpandImm_C(Imm<1> i, Imm<3> imm3, Imm<8> imm8, IR::U1 carry_in) { + const Imm<12> imm12 = concatenate(i, imm3, imm8); + if (imm12.Bits<10, 11>() == 0) { + const u32 imm32 = [&]{ + const u32 imm8 = imm12.Bits<0, 7>(); + switch (imm12.Bits<8, 9>()) { + case 0b00: + return imm8; + case 0b01: + return Common::Replicate(imm8, 16); + case 0b10: + return Common::Replicate(imm8 << 8, 16); + case 0b11: + return Common::Replicate(imm8, 8); + } + UNREACHABLE(); + }(); + return {imm32, carry_in}; + } + const u32 imm32 = Common::RotateRight((1 << 7) | imm12.Bits<0, 6>(), imm12.Bits<7, 11>()); + return {imm32, ir.Imm1(Common::Bit<31>(imm32))}; + } + + u32 ThumbExpandImm(Imm<1> i, Imm<3> imm3, Imm<8> imm8) { + return ThumbExpandImm_C(i, imm3, imm8, ir.Imm1(0)).imm32; + } + A32::IREmitter ir; ConditionalState cond_state = ConditionalState::None; TranslationOptions options;