diff --git a/src/frontend/A32/translate/translate_thumb.cpp b/src/frontend/A32/translate/translate_thumb.cpp index 7f9a3fcc..e6e36e25 100644 --- a/src/frontend/A32/translate/translate_thumb.cpp +++ b/src/frontend/A32/translate/translate_thumb.cpp @@ -38,11 +38,12 @@ struct ThumbTranslatorVisitor final { return false; } + // LSLS , , # bool thumb16_LSL_imm(Imm5 imm5, Reg m, Reg d) { - u8 shift_n = imm5; - // LSLS , , # - auto cpsr_c = ir.GetCFlag(); - auto result = ir.LogicalShiftLeft(ir.GetRegister(m), ir.Imm8(shift_n), cpsr_c); + const u8 shift_n = imm5; + const auto cpsr_c = ir.GetCFlag(); + const auto result = ir.LogicalShiftLeft(ir.GetRegister(m), ir.Imm8(shift_n), cpsr_c); + ir.SetRegister(d, result.result); ir.SetNFlag(ir.MostSignificantBit(result.result)); ir.SetZFlag(ir.IsZero(result.result)); @@ -50,11 +51,12 @@ struct ThumbTranslatorVisitor final { return true; } + // LSRS , , # bool thumb16_LSR_imm(Imm5 imm5, Reg m, Reg d) { - u8 shift_n = imm5 != 0 ? imm5 : 32; - // LSRS , , # - auto cpsr_c = ir.GetCFlag(); - auto result = ir.LogicalShiftRight(ir.GetRegister(m), ir.Imm8(shift_n), cpsr_c); + const u8 shift_n = imm5 != 0 ? imm5 : 32; + const auto cpsr_c = ir.GetCFlag(); + const auto result = ir.LogicalShiftRight(ir.GetRegister(m), ir.Imm8(shift_n), cpsr_c); + ir.SetRegister(d, result.result); ir.SetNFlag(ir.MostSignificantBit(result.result)); ir.SetZFlag(ir.IsZero(result.result)); @@ -62,11 +64,12 @@ struct ThumbTranslatorVisitor final { return true; } + // ASRS , , # bool thumb16_ASR_imm(Imm5 imm5, Reg m, Reg d) { - u8 shift_n = imm5 != 0 ? imm5 : 32; - // ASRS , , # - auto cpsr_c = ir.GetCFlag(); - auto result = ir.ArithmeticShiftRight(ir.GetRegister(m), ir.Imm8(shift_n), cpsr_c); + const u8 shift_n = imm5 != 0 ? imm5 : 32; + const auto cpsr_c = ir.GetCFlag(); + const auto result = ir.ArithmeticShiftRight(ir.GetRegister(m), ir.Imm8(shift_n), cpsr_c); + ir.SetRegister(d, result.result); ir.SetNFlag(ir.MostSignificantBit(result.result)); ir.SetZFlag(ir.IsZero(result.result)); @@ -74,10 +77,10 @@ struct ThumbTranslatorVisitor final { return true; } + // ADDS , , + // Note that it is not possible to encode Rd == R15. bool thumb16_ADD_reg_t1(Reg m, Reg n, Reg d) { - // ADDS , , - // Note that it is not possible to encode Rd == R15. - auto result = ir.AddWithCarry(ir.GetRegister(n), ir.GetRegister(m), ir.Imm1(0)); + const auto result = ir.AddWithCarry(ir.GetRegister(n), ir.GetRegister(m), ir.Imm1(0)); ir.SetRegister(d, result.result); ir.SetNFlag(ir.MostSignificantBit(result.result)); ir.SetZFlag(ir.IsZero(result.result)); @@ -86,10 +89,10 @@ struct ThumbTranslatorVisitor final { return true; } + // SUBS , , + // Note that it is not possible to encode Rd == R15. bool thumb16_SUB_reg(Reg m, Reg n, Reg d) { - // SUBS , , - // Note that it is not possible to encode Rd == R15. - auto result = ir.SubWithCarry(ir.GetRegister(n), ir.GetRegister(m), ir.Imm1(1)); + const auto result = ir.SubWithCarry(ir.GetRegister(n), ir.GetRegister(m), ir.Imm1(1)); ir.SetRegister(d, result.result); ir.SetNFlag(ir.MostSignificantBit(result.result)); ir.SetZFlag(ir.IsZero(result.result)); @@ -98,11 +101,12 @@ struct ThumbTranslatorVisitor final { return true; } + // ADDS , , # + // Rd can never encode R15. bool thumb16_ADD_imm_t1(Imm3 imm3, Reg n, Reg d) { - u32 imm32 = imm3 & 0x7; - // ADDS , , # - // Rd can never encode R15. - auto result = ir.AddWithCarry(ir.GetRegister(n), ir.Imm32(imm32), ir.Imm1(0)); + const u32 imm32 = imm3 & 0x7; + const auto result = ir.AddWithCarry(ir.GetRegister(n), ir.Imm32(imm32), ir.Imm1(0)); + ir.SetRegister(d, result.result); ir.SetNFlag(ir.MostSignificantBit(result.result)); ir.SetZFlag(ir.IsZero(result.result)); @@ -111,11 +115,12 @@ struct ThumbTranslatorVisitor final { return true; } + // SUBS , , # + // Rd can never encode R15. bool thumb16_SUB_imm_t1(Imm3 imm3, Reg n, Reg d) { - u32 imm32 = imm3 & 0x7; - // SUBS , , # - // Rd can never encode R15. - auto result = ir.SubWithCarry(ir.GetRegister(n), ir.Imm32(imm32), ir.Imm1(1)); + const u32 imm32 = imm3 & 0x7; + const auto result = ir.SubWithCarry(ir.GetRegister(n), ir.Imm32(imm32), ir.Imm1(1)); + ir.SetRegister(d, result.result); ir.SetNFlag(ir.MostSignificantBit(result.result)); ir.SetZFlag(ir.IsZero(result.result)); @@ -124,21 +129,23 @@ struct ThumbTranslatorVisitor final { return true; } + // MOVS , # + // Rd can never encode R15. bool thumb16_MOV_imm(Reg d, Imm8 imm8) { - u32 imm32 = imm8 & 0xFF; - // MOVS , # - // Rd can never encode R15. - auto result = ir.Imm32(imm32); + const u32 imm32 = imm8 & 0xFF; + const auto result = ir.Imm32(imm32); + ir.SetRegister(d, result); ir.SetNFlag(ir.MostSignificantBit(result)); ir.SetZFlag(ir.IsZero(result)); return true; } + // CMP , # bool thumb16_CMP_imm(Reg n, Imm8 imm8) { - u32 imm32 = imm8 & 0xFF; - // CMP , # - auto result = ir.SubWithCarry(ir.GetRegister(n), ir.Imm32(imm32), ir.Imm1(1)); + const u32 imm32 = imm8 & 0xFF; + const auto result = ir.SubWithCarry(ir.GetRegister(n), ir.Imm32(imm32), ir.Imm1(1)); + ir.SetNFlag(ir.MostSignificantBit(result.result)); ir.SetZFlag(ir.IsZero(result.result)); ir.SetCFlag(result.carry); @@ -146,12 +153,14 @@ struct ThumbTranslatorVisitor final { return true; } + // ADDS , # + // Rd can never encode R15. bool thumb16_ADD_imm_t2(Reg d_n, Imm8 imm8) { - u32 imm32 = imm8 & 0xFF; - Reg d = d_n, n = d_n; - // ADDS , # - // Rd can never encode R15. - auto result = ir.AddWithCarry(ir.GetRegister(n), ir.Imm32(imm32), ir.Imm1(0)); + const u32 imm32 = imm8 & 0xFF; + const Reg d = d_n; + const Reg n = d_n; + const auto result = ir.AddWithCarry(ir.GetRegister(n), ir.Imm32(imm32), ir.Imm1(0)); + ir.SetRegister(d, result.result); ir.SetNFlag(ir.MostSignificantBit(result.result)); ir.SetZFlag(ir.IsZero(result.result)); @@ -160,12 +169,14 @@ struct ThumbTranslatorVisitor final { return true; } + // SUBS , , # + // Rd can never encode R15. bool thumb16_SUB_imm_t2(Reg d_n, Imm8 imm8) { - u32 imm32 = imm8 & 0xFF; - Reg d = d_n, n = d_n; - // SUBS , , # - // Rd can never encode R15. - auto result = ir.SubWithCarry(ir.GetRegister(n), ir.Imm32(imm32), ir.Imm1(1)); + const u32 imm32 = imm8 & 0xFF; + const Reg d = d_n; + const Reg n = d_n; + const auto result = ir.SubWithCarry(ir.GetRegister(n), ir.Imm32(imm32), ir.Imm1(1)); + ir.SetRegister(d, result.result); ir.SetNFlag(ir.MostSignificantBit(result.result)); ir.SetZFlag(ir.IsZero(result.result)); @@ -174,34 +185,40 @@ struct ThumbTranslatorVisitor final { return true; } + // ANDS , + // Note that it is not possible to encode Rdn == R15. bool thumb16_AND_reg(Reg m, Reg d_n) { - const Reg d = d_n, n = d_n; - // ANDS , - // Note that it is not possible to encode Rdn == R15. - auto result = ir.And(ir.GetRegister(n), ir.GetRegister(m)); + const Reg d = d_n; + const Reg n = d_n; + const auto result = ir.And(ir.GetRegister(n), ir.GetRegister(m)); + ir.SetRegister(d, result); ir.SetNFlag(ir.MostSignificantBit(result)); ir.SetZFlag(ir.IsZero(result)); return true; } + // EORS , + // Note that it is not possible to encode Rdn == R15. bool thumb16_EOR_reg(Reg m, Reg d_n) { - const Reg d = d_n, n = d_n; - // EORS , - // Note that it is not possible to encode Rdn == R15. - auto result = ir.Eor(ir.GetRegister(n), ir.GetRegister(m)); + const Reg d = d_n; + const Reg n = d_n; + const auto result = ir.Eor(ir.GetRegister(n), ir.GetRegister(m)); + ir.SetRegister(d, result); ir.SetNFlag(ir.MostSignificantBit(result)); ir.SetZFlag(ir.IsZero(result)); return true; } + // LSLS , bool thumb16_LSL_reg(Reg m, Reg d_n) { - const Reg d = d_n, n = d_n; - // LSLS , - auto shift_n = ir.LeastSignificantByte(ir.GetRegister(m)); - auto apsr_c = ir.GetCFlag(); - auto result_carry = ir.LogicalShiftLeft(ir.GetRegister(n), shift_n, apsr_c); + const Reg d = d_n; + const Reg n = d_n; + const auto shift_n = ir.LeastSignificantByte(ir.GetRegister(m)); + const auto apsr_c = ir.GetCFlag(); + const auto result_carry = ir.LogicalShiftLeft(ir.GetRegister(n), shift_n, apsr_c); + ir.SetRegister(d, result_carry.result); ir.SetNFlag(ir.MostSignificantBit(result_carry.result)); ir.SetZFlag(ir.IsZero(result_carry.result)); @@ -209,12 +226,14 @@ struct ThumbTranslatorVisitor final { return true; } + // LSRS , bool thumb16_LSR_reg(Reg m, Reg d_n) { - const Reg d = d_n, n = d_n; - // LSRS , - auto shift_n = ir.LeastSignificantByte(ir.GetRegister(m)); - auto cpsr_c = ir.GetCFlag(); - auto result = ir.LogicalShiftRight(ir.GetRegister(n), shift_n, cpsr_c); + const Reg d = d_n; + const Reg n = d_n; + const auto shift_n = ir.LeastSignificantByte(ir.GetRegister(m)); + const auto cpsr_c = ir.GetCFlag(); + const auto result = ir.LogicalShiftRight(ir.GetRegister(n), shift_n, cpsr_c); + ir.SetRegister(d, result.result); ir.SetNFlag(ir.MostSignificantBit(result.result)); ir.SetZFlag(ir.IsZero(result.result)); @@ -222,12 +241,14 @@ struct ThumbTranslatorVisitor final { return true; } + // ASRS , bool thumb16_ASR_reg(Reg m, Reg d_n) { - const Reg d = d_n, n = d_n; - // ASRS , - auto shift_n = ir.LeastSignificantByte(ir.GetRegister(m)); - auto cpsr_c = ir.GetCFlag(); - auto result = ir.ArithmeticShiftRight(ir.GetRegister(n), shift_n, cpsr_c); + const Reg d = d_n; + const Reg n = d_n; + const auto shift_n = ir.LeastSignificantByte(ir.GetRegister(m)); + const auto cpsr_c = ir.GetCFlag(); + const auto result = ir.ArithmeticShiftRight(ir.GetRegister(n), shift_n, cpsr_c); + ir.SetRegister(d, result.result); ir.SetNFlag(ir.MostSignificantBit(result.result)); ir.SetZFlag(ir.IsZero(result.result)); @@ -235,12 +256,14 @@ struct ThumbTranslatorVisitor final { return true; } + // ADCS , + // Note that it is not possible to encode Rd == R15. bool thumb16_ADC_reg(Reg m, Reg d_n) { - Reg d = d_n, n = d_n; - // ADCS , - // Note that it is not possible to encode Rd == R15. - auto aspr_c = ir.GetCFlag(); - auto result = ir.AddWithCarry(ir.GetRegister(n), ir.GetRegister(m), aspr_c); + const Reg d = d_n; + const Reg n = d_n; + const auto aspr_c = ir.GetCFlag(); + const auto result = ir.AddWithCarry(ir.GetRegister(n), ir.GetRegister(m), aspr_c); + ir.SetRegister(d, result.result); ir.SetNFlag(ir.MostSignificantBit(result.result)); ir.SetZFlag(ir.IsZero(result.result)); @@ -249,12 +272,14 @@ struct ThumbTranslatorVisitor final { return true; } + // SBCS , + // Note that it is not possible to encode Rd == R15. bool thumb16_SBC_reg(Reg m, Reg d_n) { - Reg d = d_n, n = d_n; - // SBCS , - // Note that it is not possible to encode Rd == R15. - auto aspr_c = ir.GetCFlag(); - auto result = ir.SubWithCarry(ir.GetRegister(n), ir.GetRegister(m), aspr_c); + const Reg d = d_n; + const Reg n = d_n; + const auto aspr_c = ir.GetCFlag(); + const auto result = ir.SubWithCarry(ir.GetRegister(n), ir.GetRegister(m), aspr_c); + ir.SetRegister(d, result.result); ir.SetNFlag(ir.MostSignificantBit(result.result)); ir.SetZFlag(ir.IsZero(result.result)); @@ -263,12 +288,14 @@ struct ThumbTranslatorVisitor final { return true; } + // RORS , bool thumb16_ROR_reg(Reg m, Reg d_n) { - Reg d = d_n, n = d_n; - // RORS , - auto shift_n = ir.LeastSignificantByte(ir.GetRegister(m)); - auto cpsr_c = ir.GetCFlag(); - auto result = ir.RotateRight(ir.GetRegister(n), shift_n, cpsr_c); + const Reg d = d_n; + const Reg n = d_n; + const auto shift_n = ir.LeastSignificantByte(ir.GetRegister(m)); + const auto cpsr_c = ir.GetCFlag(); + const auto result = ir.RotateRight(ir.GetRegister(n), shift_n, cpsr_c); + ir.SetRegister(d, result.result); ir.SetNFlag(ir.MostSignificantBit(result.result)); ir.SetZFlag(ir.IsZero(result.result)); @@ -276,18 +303,18 @@ struct ThumbTranslatorVisitor final { return true; } + // TST , bool thumb16_TST_reg(Reg m, Reg n) { - // TST , - auto result = ir.And(ir.GetRegister(n), ir.GetRegister(m)); + const auto result = ir.And(ir.GetRegister(n), ir.GetRegister(m)); ir.SetNFlag(ir.MostSignificantBit(result)); ir.SetZFlag(ir.IsZero(result)); return true; } + // RSBS , , #0 + // Rd can never encode R15. bool thumb16_RSB_imm(Reg n, Reg d) { - // RSBS , , #0 - // Rd can never encode R15. - auto result = ir.SubWithCarry(ir.Imm32(0), ir.GetRegister(n), ir.Imm1(1)); + const auto result = ir.SubWithCarry(ir.Imm32(0), ir.GetRegister(n), ir.Imm1(1)); ir.SetRegister(d, result.result); ir.SetNFlag(ir.MostSignificantBit(result.result)); ir.SetZFlag(ir.IsZero(result.result)); @@ -296,9 +323,9 @@ struct ThumbTranslatorVisitor final { return true; } + // CMP , bool thumb16_CMP_reg_t1(Reg m, Reg n) { - // CMP , - auto result = ir.SubWithCarry(ir.GetRegister(n), ir.GetRegister(m), ir.Imm1(1)); + const auto result = ir.SubWithCarry(ir.GetRegister(n), ir.GetRegister(m), ir.Imm1(1)); ir.SetNFlag(ir.MostSignificantBit(result.result)); ir.SetZFlag(ir.IsZero(result.result)); ir.SetCFlag(result.carry); @@ -306,9 +333,9 @@ struct ThumbTranslatorVisitor final { return true; } + // CMN , bool thumb16_CMN_reg(Reg m, Reg n) { - // CMN , - auto result = ir.AddWithCarry(ir.GetRegister(n), ir.GetRegister(m), ir.Imm1(0)); + const auto result = ir.AddWithCarry(ir.GetRegister(n), ir.GetRegister(m), ir.Imm1(0)); ir.SetNFlag(ir.MostSignificantBit(result.result)); ir.SetZFlag(ir.IsZero(result.result)); ir.SetCFlag(result.carry); @@ -316,57 +343,65 @@ struct ThumbTranslatorVisitor final { return true; } + // ORRS , + // Rd cannot encode R15. bool thumb16_ORR_reg(Reg m, Reg d_n) { - Reg d = d_n, n = d_n; - // ORRS , - // Rd cannot encode R15. - auto result = ir.Or(ir.GetRegister(m), ir.GetRegister(n)); + const Reg d = d_n; + const Reg n = d_n; + const auto result = ir.Or(ir.GetRegister(m), ir.GetRegister(n)); + ir.SetRegister(d, result); ir.SetNFlag(ir.MostSignificantBit(result)); ir.SetZFlag(ir.IsZero(result)); return true; } + // MULS , , + // Rd cannot encode R15. bool thumb16_MUL_reg(Reg n, Reg d_m) { - Reg d = d_m, m = d_m; - // MULS , , - // Rd cannot encode R15. - auto result = ir.Mul(ir.GetRegister(m), ir.GetRegister(n)); + const Reg d = d_m; + const Reg m = d_m; + const auto result = ir.Mul(ir.GetRegister(m), ir.GetRegister(n)); + ir.SetRegister(d, result); ir.SetNFlag(ir.MostSignificantBit(result)); ir.SetZFlag(ir.IsZero(result)); return true; } + // BICS , + // Rd cannot encode R15. bool thumb16_BIC_reg(Reg m, Reg d_n) { - Reg d = d_n, n = d_n; - // BICS , - // Rd cannot encode R15. - auto result = ir.And(ir.GetRegister(n), ir.Not(ir.GetRegister(m))); + const Reg d = d_n; + const Reg n = d_n; + const auto result = ir.And(ir.GetRegister(n), ir.Not(ir.GetRegister(m))); + ir.SetRegister(d, result); ir.SetNFlag(ir.MostSignificantBit(result)); ir.SetZFlag(ir.IsZero(result)); return true; } + // MVNS , + // Rd cannot encode R15. bool thumb16_MVN_reg(Reg m, Reg d) { - // MVNS , - // Rd cannot encode R15. - auto result = ir.Not(ir.GetRegister(m)); + const auto result = ir.Not(ir.GetRegister(m)); ir.SetRegister(d, result); ir.SetNFlag(ir.MostSignificantBit(result)); ir.SetZFlag(ir.IsZero(result)); return true; } + // ADD , bool thumb16_ADD_reg_t2(bool d_n_hi, Reg m, Reg d_n_lo) { - Reg d_n = d_n_hi ? (d_n_lo + 8) : d_n_lo; - Reg d = d_n, n = d_n; + const Reg d_n = d_n_hi ? (d_n_lo + 8) : d_n_lo; + const Reg n = d_n; if (n == Reg::PC && m == Reg::PC) { return UnpredictableInstruction(); } - // ADD , - auto result = ir.AddWithCarry(ir.GetRegister(n), ir.GetRegister(m), ir.Imm1(0)); + + const Reg d = d_n; + const auto result = ir.AddWithCarry(ir.GetRegister(n), ir.GetRegister(m), ir.Imm1(0)); if (d == Reg::PC) { ir.ALUWritePC(result.result); // Return to dispatch as we can't predict what PC is going to be. Stop compilation. @@ -378,15 +413,17 @@ struct ThumbTranslatorVisitor final { } } + // CMP , bool thumb16_CMP_reg_t2(bool n_hi, Reg m, Reg n_lo) { - Reg n = n_hi ? (n_lo + 8) : n_lo; + const Reg n = n_hi ? (n_lo + 8) : n_lo; if (n < Reg::R8 && m < Reg::R8) { return UnpredictableInstruction(); - } else if (n == Reg::PC || m == Reg::PC) { + } + if (n == Reg::PC || m == Reg::PC) { return UnpredictableInstruction(); } - // CMP , - auto result = ir.SubWithCarry(ir.GetRegister(n), ir.GetRegister(m), ir.Imm1(1)); + + const auto result = ir.SubWithCarry(ir.GetRegister(n), ir.GetRegister(m), ir.Imm1(1)); ir.SetNFlag(ir.MostSignificantBit(result.result)); ir.SetZFlag(ir.IsZero(result.result)); ir.SetCFlag(result.carry); @@ -394,10 +431,11 @@ struct ThumbTranslatorVisitor final { return true; } + // MOV , bool thumb16_MOV_reg(bool d_hi, Reg m, Reg d_lo) { - Reg d = d_hi ? (d_lo + 8) : d_lo; - // MOV , - auto result = ir.GetRegister(m); + const Reg d = d_hi ? (d_lo + 8) : d_lo; + const auto result = ir.GetRegister(m); + if (d == Reg::PC) { ir.ALUWritePC(result); ir.SetTerm(IR::Term::FastDispatchHint{}); @@ -408,276 +446,305 @@ struct ThumbTranslatorVisitor final { } } + // LDR ,