A32: Add ThumbExpandImm and ThumbExpandImm_C

These are used by many thumb2 instructions
This commit is contained in:
Sunho Kim 2020-08-06 04:55:57 +09:00 committed by MerryMage
parent 43a1a523f6
commit 069beb5228

View file

@ -24,6 +24,38 @@ struct ThumbTranslatorVisitor final {
ASSERT_MSG(descriptor.TFlag(), "The processor must be in Thumb mode"); 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<u32>((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; A32::IREmitter ir;
ConditionalState cond_state = ConditionalState::None; ConditionalState cond_state = ConditionalState::None;
TranslationOptions options; TranslationOptions options;