From cb79bfa1dc75764b8f83b355526eb7597f34bf6e Mon Sep 17 00:00:00 2001 From: sunho Date: Wed, 5 May 2021 19:09:41 +0900 Subject: [PATCH] thumb32: Support setflags in shift reg instructions --- src/frontend/A32/decoder/thumb32.inc | 8 +++---- .../impl/thumb32_data_processing_register.cpp | 24 ++++++++++++------- src/frontend/A32/translate/impl/translate.h | 8 +++---- 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src/frontend/A32/decoder/thumb32.inc b/src/frontend/A32/decoder/thumb32.inc index d5d49e4c..d35771f3 100644 --- a/src/frontend/A32/decoder/thumb32.inc +++ b/src/frontend/A32/decoder/thumb32.inc @@ -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") diff --git a/src/frontend/A32/translate/impl/thumb32_data_processing_register.cpp b/src/frontend/A32/translate/impl/thumb32_data_processing_register.cpp index 3f11f0c6..63141b81 100644 --- a/src/frontend/A32/translate/impl/thumb32_data_processing_register.cpp +++ b/src/frontend/A32/translate/impl/thumb32_data_processing_register.cpp @@ -14,7 +14,7 @@ IR::U32 Rotate(A32::IREmitter& ir, Reg m, SignExtendRotation rotate) { using ShiftFunction = IR::ResultAndCarry (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) { diff --git a/src/frontend/A32/translate/impl/translate.h b/src/frontend/A32/translate/impl/translate.h index a819a971..6cdeac02 100644 --- a/src/frontend/A32/translate/impl/translate.h +++ b/src/frontend/A32/translate/impl/translate.h @@ -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);