From fdd379a36ce116c510c1853dda6558ed4005f435 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 23 Feb 2021 04:37:31 -0500 Subject: [PATCH 1/5] thumb32: Implement LSL (register) --- src/frontend/A32/decoder/thumb32.inc | 2 +- .../impl/thumb32_data_processing_register.cpp | 13 +++++++++++++ src/frontend/A32/translate/impl/translate_thumb.h | 1 + 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/frontend/A32/decoder/thumb32.inc b/src/frontend/A32/decoder/thumb32.inc index 71e3e4ef..07354644 100644 --- a/src/frontend/A32/decoder/thumb32.inc +++ b/src/frontend/A32/decoder/thumb32.inc @@ -189,7 +189,7 @@ INST(thumb32_BLX_imm, "BLX (imm)", "11110Svvvvvvvvvv11j0jv //INST(thumb32_LDR_imm12, "LDR (imm12)", "111110001101--------------------") // Data Processing (register) -//INST(thumb32_LSL_reg, "LSL (reg)", "11111010000-----1111----0000----") +INST(thumb32_LSL_reg, "LSL (reg)", "111110100000mmmm1111dddd0000ssss") //INST(thumb32_LSR_reg, "LSR (reg)", "11111010001-----1111----0000----") //INST(thumb32_ASR_reg, "ASR (reg)", "11111010010-----1111----0000----") //INST(thumb32_ROR_reg, "ROR (reg)", "11111010011-----1111----0000----") 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 cf6bbf7b..ecd71197 100644 --- a/src/frontend/A32/translate/impl/thumb32_data_processing_register.cpp +++ b/src/frontend/A32/translate/impl/thumb32_data_processing_register.cpp @@ -11,6 +11,19 @@ static IR::U32 Rotate(A32::IREmitter& ir, Reg m, SignExtendRotation rotate) { return ir.RotateRight(ir.GetRegister(m), ir.Imm8(rotate_by), ir.Imm1(0)).result; } +bool ThumbTranslatorVisitor::thumb32_LSL_reg(Reg m, Reg d, Reg s) { + if (d == Reg::PC || m == Reg::PC || s == Reg::PC) { + return UnpredictableInstruction(); + } + + const auto shift_s = ir.LeastSignificantByte(ir.GetRegister(s)); + const auto apsr_c = ir.GetCFlag(); + const auto result_carry = ir.LogicalShiftLeft(ir.GetRegister(m), shift_s, apsr_c); + + ir.SetRegister(d, result_carry.result); + return true; +} + bool ThumbTranslatorVisitor::thumb32_SXTB(Reg d, SignExtendRotation rotate, Reg m) { if (d == Reg::PC || m == Reg::PC) { return UnpredictableInstruction(); diff --git a/src/frontend/A32/translate/impl/translate_thumb.h b/src/frontend/A32/translate/impl/translate_thumb.h index 5ffecd9d..388abca8 100644 --- a/src/frontend/A32/translate/impl/translate_thumb.h +++ b/src/frontend/A32/translate/impl/translate_thumb.h @@ -182,6 +182,7 @@ struct ThumbTranslatorVisitor final { bool thumb32_BLX_imm(Imm<1> S, Imm<10> hi, Imm<1> j1, Imm<1> j2, Imm<11> lo); // thumb32 data processing (register) instructions + bool thumb32_LSL_reg(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); From e06d4bcbb25666a02c76baafc3a9fdde3986bd85 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 23 Feb 2021 04:40:23 -0500 Subject: [PATCH 2/5] thumb32: Implement LSR (register) --- src/frontend/A32/decoder/thumb32.inc | 2 +- .../impl/thumb32_data_processing_register.cpp | 13 +++++++++++++ src/frontend/A32/translate/impl/translate_thumb.h | 1 + 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/frontend/A32/decoder/thumb32.inc b/src/frontend/A32/decoder/thumb32.inc index 07354644..def176dc 100644 --- a/src/frontend/A32/decoder/thumb32.inc +++ b/src/frontend/A32/decoder/thumb32.inc @@ -190,7 +190,7 @@ INST(thumb32_BLX_imm, "BLX (imm)", "11110Svvvvvvvvvv11j0jv // Data Processing (register) INST(thumb32_LSL_reg, "LSL (reg)", "111110100000mmmm1111dddd0000ssss") -//INST(thumb32_LSR_reg, "LSR (reg)", "11111010001-----1111----0000----") +INST(thumb32_LSR_reg, "LSR (reg)", "111110100010mmmm1111dddd0000ssss") //INST(thumb32_ASR_reg, "ASR (reg)", "11111010010-----1111----0000----") //INST(thumb32_ROR_reg, "ROR (reg)", "11111010011-----1111----0000----") INST(thumb32_SXTH, "SXTH", "11111010000011111111dddd10rrmmmm") 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 ecd71197..c30addcb 100644 --- a/src/frontend/A32/translate/impl/thumb32_data_processing_register.cpp +++ b/src/frontend/A32/translate/impl/thumb32_data_processing_register.cpp @@ -24,6 +24,19 @@ bool ThumbTranslatorVisitor::thumb32_LSL_reg(Reg m, Reg d, Reg s) { return true; } +bool ThumbTranslatorVisitor::thumb32_LSR_reg(Reg m, Reg d, Reg s) { + if (d == Reg::PC || m == Reg::PC || s == Reg::PC) { + return UnpredictableInstruction(); + } + + const auto shift_s = ir.LeastSignificantByte(ir.GetRegister(s)); + const auto apsr_c = ir.GetCFlag(); + const auto result_carry = ir.LogicalShiftRight(ir.GetRegister(m), shift_s, apsr_c); + + ir.SetRegister(d, result_carry.result); + return true; +} + bool ThumbTranslatorVisitor::thumb32_SXTB(Reg d, SignExtendRotation rotate, Reg m) { if (d == Reg::PC || m == Reg::PC) { return UnpredictableInstruction(); diff --git a/src/frontend/A32/translate/impl/translate_thumb.h b/src/frontend/A32/translate/impl/translate_thumb.h index 388abca8..1adda49b 100644 --- a/src/frontend/A32/translate/impl/translate_thumb.h +++ b/src/frontend/A32/translate/impl/translate_thumb.h @@ -183,6 +183,7 @@ struct ThumbTranslatorVisitor final { // thumb32 data processing (register) instructions bool thumb32_LSL_reg(Reg m, Reg d, Reg s); + bool thumb32_LSR_reg(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); From abf3548b2abcc20d484d70dbd0bd92fc9c219055 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 23 Feb 2021 04:43:11 -0500 Subject: [PATCH 3/5] thumb32: Implement ASR (register) --- src/frontend/A32/decoder/thumb32.inc | 2 +- .../impl/thumb32_data_processing_register.cpp | 13 +++++++++++++ src/frontend/A32/translate/impl/translate_thumb.h | 1 + 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/frontend/A32/decoder/thumb32.inc b/src/frontend/A32/decoder/thumb32.inc index def176dc..0b234690 100644 --- a/src/frontend/A32/decoder/thumb32.inc +++ b/src/frontend/A32/decoder/thumb32.inc @@ -191,7 +191,7 @@ INST(thumb32_BLX_imm, "BLX (imm)", "11110Svvvvvvvvvv11j0jv // Data Processing (register) INST(thumb32_LSL_reg, "LSL (reg)", "111110100000mmmm1111dddd0000ssss") INST(thumb32_LSR_reg, "LSR (reg)", "111110100010mmmm1111dddd0000ssss") -//INST(thumb32_ASR_reg, "ASR (reg)", "11111010010-----1111----0000----") +INST(thumb32_ASR_reg, "ASR (reg)", "111110100100mmmm1111dddd0000ssss") //INST(thumb32_ROR_reg, "ROR (reg)", "11111010011-----1111----0000----") INST(thumb32_SXTH, "SXTH", "11111010000011111111dddd10rrmmmm") INST(thumb32_SXTAH, "SXTAH", "111110100000nnnn1111dddd10rrmmmm") 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 c30addcb..1ef9b400 100644 --- a/src/frontend/A32/translate/impl/thumb32_data_processing_register.cpp +++ b/src/frontend/A32/translate/impl/thumb32_data_processing_register.cpp @@ -11,6 +11,19 @@ static IR::U32 Rotate(A32::IREmitter& ir, Reg m, SignExtendRotation rotate) { return ir.RotateRight(ir.GetRegister(m), ir.Imm8(rotate_by), ir.Imm1(0)).result; } +bool ThumbTranslatorVisitor::thumb32_ASR_reg(Reg m, Reg d, Reg s) { + if (d == Reg::PC || m == Reg::PC || s == Reg::PC) { + return UnpredictableInstruction(); + } + + const auto shift_s = ir.LeastSignificantByte(ir.GetRegister(s)); + const auto apsr_c = ir.GetCFlag(); + const auto result_carry = ir.ArithmeticShiftRight(ir.GetRegister(m), shift_s, apsr_c); + + ir.SetRegister(d, result_carry.result); + return true; +} + bool ThumbTranslatorVisitor::thumb32_LSL_reg(Reg m, Reg d, Reg s) { if (d == Reg::PC || m == Reg::PC || s == Reg::PC) { return UnpredictableInstruction(); diff --git a/src/frontend/A32/translate/impl/translate_thumb.h b/src/frontend/A32/translate/impl/translate_thumb.h index 1adda49b..464926fc 100644 --- a/src/frontend/A32/translate/impl/translate_thumb.h +++ b/src/frontend/A32/translate/impl/translate_thumb.h @@ -182,6 +182,7 @@ struct ThumbTranslatorVisitor final { bool thumb32_BLX_imm(Imm<1> S, Imm<10> hi, Imm<1> j1, Imm<1> j2, Imm<11> lo); // 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_SXTB(Reg d, SignExtendRotation rotate, Reg m); From a7a9ed69b76d80222b34c92e3f93aca313a49c31 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 23 Feb 2021 04:46:06 -0500 Subject: [PATCH 4/5] thumb32: Implement ROR (register) --- src/frontend/A32/decoder/thumb32.inc | 2 +- .../impl/thumb32_data_processing_register.cpp | 13 +++++++++++++ src/frontend/A32/translate/impl/translate_thumb.h | 1 + 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/frontend/A32/decoder/thumb32.inc b/src/frontend/A32/decoder/thumb32.inc index 0b234690..37e6a6d4 100644 --- a/src/frontend/A32/decoder/thumb32.inc +++ b/src/frontend/A32/decoder/thumb32.inc @@ -192,7 +192,7 @@ INST(thumb32_BLX_imm, "BLX (imm)", "11110Svvvvvvvvvv11j0jv 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)", "11111010011-----1111----0000----") +INST(thumb32_ROR_reg, "ROR (reg)", "111110100110mmmm1111dddd0000ssss") 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 1ef9b400..8d80565e 100644 --- a/src/frontend/A32/translate/impl/thumb32_data_processing_register.cpp +++ b/src/frontend/A32/translate/impl/thumb32_data_processing_register.cpp @@ -50,6 +50,19 @@ bool ThumbTranslatorVisitor::thumb32_LSR_reg(Reg m, Reg d, Reg s) { return true; } +bool ThumbTranslatorVisitor::thumb32_ROR_reg(Reg m, Reg d, Reg s) { + if (d == Reg::PC || m == Reg::PC || s == Reg::PC) { + return UnpredictableInstruction(); + } + + const auto shift_s = ir.LeastSignificantByte(ir.GetRegister(s)); + const auto apsr_c = ir.GetCFlag(); + const auto result_carry = ir.RotateRight(ir.GetRegister(m), shift_s, apsr_c); + + ir.SetRegister(d, result_carry.result); + return true; +} + bool ThumbTranslatorVisitor::thumb32_SXTB(Reg d, SignExtendRotation rotate, Reg m) { if (d == Reg::PC || m == Reg::PC) { return UnpredictableInstruction(); diff --git a/src/frontend/A32/translate/impl/translate_thumb.h b/src/frontend/A32/translate/impl/translate_thumb.h index 464926fc..88fe2563 100644 --- a/src/frontend/A32/translate/impl/translate_thumb.h +++ b/src/frontend/A32/translate/impl/translate_thumb.h @@ -185,6 +185,7 @@ struct ThumbTranslatorVisitor final { 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_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); From 725d712c88ee3e5883d4ded8a2c2ae69b5c00542 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 23 Feb 2021 04:52:21 -0500 Subject: [PATCH 5/5] thumb32: Simplify register shift implementations to common function --- .../impl/thumb32_data_processing_register.cpp | 55 ++++++------------- 1 file changed, 18 insertions(+), 37 deletions(-) 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 8d80565e..97da01b2 100644 --- a/src/frontend/A32/translate/impl/thumb32_data_processing_register.cpp +++ b/src/frontend/A32/translate/impl/thumb32_data_processing_register.cpp @@ -6,61 +6,42 @@ #include "frontend/A32/translate/impl/translate_thumb.h" namespace Dynarmic::A32 { -static IR::U32 Rotate(A32::IREmitter& ir, Reg m, SignExtendRotation rotate) { +namespace { +IR::U32 Rotate(A32::IREmitter& ir, Reg m, SignExtendRotation rotate) { const u8 rotate_by = static_cast(static_cast(rotate) * 8); return ir.RotateRight(ir.GetRegister(m), ir.Imm8(rotate_by), ir.Imm1(0)).result; } -bool ThumbTranslatorVisitor::thumb32_ASR_reg(Reg m, Reg d, Reg s) { +using ShiftFunction = IR::ResultAndCarry (IREmitter::*)(const IR::U32&, const IR::U8&, const IR::U1&); + +bool ShiftInstruction(ThumbTranslatorVisitor& v, Reg m, Reg d, Reg s, ShiftFunction shift_fn) { if (d == Reg::PC || m == Reg::PC || s == Reg::PC) { - return UnpredictableInstruction(); + return v.UnpredictableInstruction(); } - const auto shift_s = ir.LeastSignificantByte(ir.GetRegister(s)); - const auto apsr_c = ir.GetCFlag(); - const auto result_carry = ir.ArithmeticShiftRight(ir.GetRegister(m), shift_s, apsr_c); + const auto shift_s = v.ir.LeastSignificantByte(v.ir.GetRegister(s)); + const auto apsr_c = v.ir.GetCFlag(); + const auto result_carry = (v.ir.*shift_fn)(v.ir.GetRegister(m), shift_s, apsr_c); - ir.SetRegister(d, result_carry.result); + v.ir.SetRegister(d, result_carry.result); return true; } +} // Anonymous namespace + +bool ThumbTranslatorVisitor::thumb32_ASR_reg(Reg m, Reg d, Reg s) { + return ShiftInstruction(*this, m, d, s, &IREmitter::ArithmeticShiftRight); +} bool ThumbTranslatorVisitor::thumb32_LSL_reg(Reg m, Reg d, Reg s) { - if (d == Reg::PC || m == Reg::PC || s == Reg::PC) { - return UnpredictableInstruction(); - } - - const auto shift_s = ir.LeastSignificantByte(ir.GetRegister(s)); - const auto apsr_c = ir.GetCFlag(); - const auto result_carry = ir.LogicalShiftLeft(ir.GetRegister(m), shift_s, apsr_c); - - ir.SetRegister(d, result_carry.result); - return true; + return ShiftInstruction(*this, m, d, s, &IREmitter::LogicalShiftLeft); } bool ThumbTranslatorVisitor::thumb32_LSR_reg(Reg m, Reg d, Reg s) { - if (d == Reg::PC || m == Reg::PC || s == Reg::PC) { - return UnpredictableInstruction(); - } - - const auto shift_s = ir.LeastSignificantByte(ir.GetRegister(s)); - const auto apsr_c = ir.GetCFlag(); - const auto result_carry = ir.LogicalShiftRight(ir.GetRegister(m), shift_s, apsr_c); - - ir.SetRegister(d, result_carry.result); - return true; + return ShiftInstruction(*this, m, d, s, &IREmitter::LogicalShiftRight); } bool ThumbTranslatorVisitor::thumb32_ROR_reg(Reg m, Reg d, Reg s) { - if (d == Reg::PC || m == Reg::PC || s == Reg::PC) { - return UnpredictableInstruction(); - } - - const auto shift_s = ir.LeastSignificantByte(ir.GetRegister(s)); - const auto apsr_c = ir.GetCFlag(); - const auto result_carry = ir.RotateRight(ir.GetRegister(m), shift_s, apsr_c); - - ir.SetRegister(d, result_carry.result); - return true; + return ShiftInstruction(*this, m, d, s, &IREmitter::RotateRight); } bool ThumbTranslatorVisitor::thumb32_SXTB(Reg d, SignExtendRotation rotate, Reg m) {