thumb32: Support setflags in shift reg instructions

This commit is contained in:
sunho 2021-05-05 19:09:41 +09:00 committed by MerryMage
parent 075fdeaee0
commit cb79bfa1dc
3 changed files with 23 additions and 17 deletions

View file

@ -181,10 +181,10 @@ INST(thumb32_LDR_imm8, "LDR (imm8)", "111110000101nnnntttt1P
INST(thumb32_LDR_imm12, "LDR (imm12)", "111110001101nnnnttttiiiiiiiiiiii")
// Data Processing (register)
INST(thumb32_LSL_reg, "LSL (reg)", "111110100000mmmm1111dddd0000ssss")
INST(thumb32_LSR_reg, "LSR (reg)", "111110100010mmmm1111dddd0000ssss")
INST(thumb32_ASR_reg, "ASR (reg)", "111110100100mmmm1111dddd0000ssss")
INST(thumb32_ROR_reg, "ROR (reg)", "111110100110mmmm1111dddd0000ssss")
INST(thumb32_LSL_reg, "LSL (reg)", "11111010000Smmmm1111dddd0000ssss")
INST(thumb32_LSR_reg, "LSR (reg)", "11111010001Smmmm1111dddd0000ssss")
INST(thumb32_ASR_reg, "ASR (reg)", "11111010010Smmmm1111dddd0000ssss")
INST(thumb32_ROR_reg, "ROR (reg)", "11111010011Smmmm1111dddd0000ssss")
INST(thumb32_SXTH, "SXTH", "11111010000011111111dddd10rrmmmm")
INST(thumb32_SXTAH, "SXTAH", "111110100000nnnn1111dddd10rrmmmm")
INST(thumb32_UXTH, "UXTH", "11111010000111111111dddd10rrmmmm")

View file

@ -14,7 +14,7 @@ IR::U32 Rotate(A32::IREmitter& ir, Reg m, SignExtendRotation rotate) {
using ShiftFunction = IR::ResultAndCarry<IR::U32> (IREmitter::*)(const IR::U32&, const IR::U8&, const IR::U1&);
bool ShiftInstruction(TranslatorVisitor& v, Reg m, Reg d, Reg s, ShiftFunction shift_fn) {
bool ShiftInstruction(TranslatorVisitor& v, Reg m, Reg d, Reg s, bool S, ShiftFunction shift_fn) {
if (d == Reg::PC || m == Reg::PC || s == Reg::PC) {
return v.UnpredictableInstruction();
}
@ -23,25 +23,31 @@ bool ShiftInstruction(TranslatorVisitor& v, Reg m, Reg d, Reg s, ShiftFunction s
const auto apsr_c = v.ir.GetCFlag();
const auto result_carry = (v.ir.*shift_fn)(v.ir.GetRegister(m), shift_s, apsr_c);
if (S) {
v.ir.SetNFlag(v.ir.MostSignificantBit(result_carry.result));
v.ir.SetZFlag(v.ir.IsZero(result_carry.result));
v.ir.SetCFlag(result_carry.carry);
}
v.ir.SetRegister(d, result_carry.result);
return true;
}
} // Anonymous namespace
bool TranslatorVisitor::thumb32_ASR_reg(Reg m, Reg d, Reg s) {
return ShiftInstruction(*this, m, d, s, &IREmitter::ArithmeticShiftRight);
bool TranslatorVisitor::thumb32_ASR_reg(bool S, Reg m, Reg d, Reg s) {
return ShiftInstruction(*this, m, d, s, S, &IREmitter::ArithmeticShiftRight);
}
bool TranslatorVisitor::thumb32_LSL_reg(Reg m, Reg d, Reg s) {
return ShiftInstruction(*this, m, d, s, &IREmitter::LogicalShiftLeft);
bool TranslatorVisitor::thumb32_LSL_reg(bool S, Reg m, Reg d, Reg s) {
return ShiftInstruction(*this, m, d, s, S, &IREmitter::LogicalShiftLeft);
}
bool TranslatorVisitor::thumb32_LSR_reg(Reg m, Reg d, Reg s) {
return ShiftInstruction(*this, m, d, s, &IREmitter::LogicalShiftRight);
bool TranslatorVisitor::thumb32_LSR_reg(bool S, Reg m, Reg d, Reg s) {
return ShiftInstruction(*this, m, d, s, S, &IREmitter::LogicalShiftRight);
}
bool TranslatorVisitor::thumb32_ROR_reg(Reg m, Reg d, Reg s) {
return ShiftInstruction(*this, m, d, s, &IREmitter::RotateRight);
bool TranslatorVisitor::thumb32_ROR_reg(bool S, Reg m, Reg d, Reg s) {
return ShiftInstruction(*this, m, d, s, S, &IREmitter::RotateRight);
}
bool TranslatorVisitor::thumb32_SXTB(Reg d, SignExtendRotation rotate, Reg m) {

View file

@ -641,10 +641,10 @@ struct TranslatorVisitor final {
bool thumb32_LDRT(Reg n, Reg t, Imm<8> imm8);
// thumb32 data processing (register) instructions
bool thumb32_ASR_reg(Reg m, Reg d, Reg s);
bool thumb32_LSL_reg(Reg m, Reg d, Reg s);
bool thumb32_LSR_reg(Reg m, Reg d, Reg s);
bool thumb32_ROR_reg(Reg m, Reg d, Reg s);
bool thumb32_ASR_reg(bool S, Reg m, Reg d, Reg s);
bool thumb32_LSL_reg(bool S, Reg m, Reg d, Reg s);
bool thumb32_LSR_reg(bool S, Reg m, Reg d, Reg s);
bool thumb32_ROR_reg(bool S, Reg m, Reg d, Reg s);
bool thumb32_SXTB(Reg d, SignExtendRotation rotate, Reg m);
bool thumb32_SXTB16(Reg d, SignExtendRotation rotate, Reg m);
bool thumb32_SXTAB(Reg n, Reg d, SignExtendRotation rotate, Reg m);