ir_emitter: Remove 32-bit-only SubWithCarry

This commit is contained in:
SachinVin 2021-05-28 22:03:35 +05:30 committed by merry
parent 776208742b
commit a626a2ec63
7 changed files with 64 additions and 166 deletions

View file

@ -381,10 +381,7 @@ bool TranslatorVisitor::arm_CMP_imm(Cond cond, Reg n, int rotate, Imm<8> imm8) {
const u32 imm32 = ArmExpandImm(rotate, imm8);
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);
ir.SetVFlag(result.overflow);
ir.SetCpsrNZCV(ir.NZCVFrom(result));
return true;
}
@ -397,10 +394,7 @@ bool TranslatorVisitor::arm_CMP_reg(Cond cond, Reg n, Imm<5> imm5, ShiftType shi
const auto shifted = EmitImmShift(ir.GetRegister(m), shift, imm5, ir.GetCFlag());
const auto result = ir.SubWithCarry(ir.GetRegister(n), shifted.result, ir.Imm1(1));
ir.SetNFlag(ir.MostSignificantBit(result.result));
ir.SetZFlag(ir.IsZero(result.result));
ir.SetCFlag(result.carry);
ir.SetVFlag(result.overflow);
ir.SetCpsrNZCV(ir.NZCVFrom(result));
return true;
}
@ -419,10 +413,7 @@ bool TranslatorVisitor::arm_CMP_rsr(Cond cond, Reg n, Reg s, ShiftType shift, Re
const auto shifted = EmitRegShift(ir.GetRegister(m), shift, shift_n, carry_in);
const auto result = ir.SubWithCarry(ir.GetRegister(n), shifted.result, ir.Imm1(1));
ir.SetNFlag(ir.MostSignificantBit(result.result));
ir.SetZFlag(ir.IsZero(result.result));
ir.SetCFlag(result.carry);
ir.SetVFlag(result.overflow);
ir.SetCpsrNZCV(ir.NZCVFrom(result));
return true;
}
@ -774,17 +765,14 @@ bool TranslatorVisitor::arm_RSB_imm(Cond cond, bool S, Reg n, Reg d, int rotate,
return UnpredictableInstruction();
}
ir.ALUWritePC(result.result);
ir.ALUWritePC(result);
ir.SetTerm(IR::Term::ReturnToDispatch{});
return false;
}
ir.SetRegister(d, result.result);
ir.SetRegister(d, result);
if (S) {
ir.SetNFlag(ir.MostSignificantBit(result.result));
ir.SetZFlag(ir.IsZero(result.result));
ir.SetCFlag(result.carry);
ir.SetVFlag(result.overflow);
ir.SetCpsrNZCV(ir.NZCVFrom(result));
}
return true;
@ -804,17 +792,14 @@ bool TranslatorVisitor::arm_RSB_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5
return UnpredictableInstruction();
}
ir.ALUWritePC(result.result);
ir.ALUWritePC(result);
ir.SetTerm(IR::Term::ReturnToDispatch{});
return false;
}
ir.SetRegister(d, result.result);
ir.SetRegister(d, result);
if (S) {
ir.SetNFlag(ir.MostSignificantBit(result.result));
ir.SetZFlag(ir.IsZero(result.result));
ir.SetCFlag(result.carry);
ir.SetVFlag(result.overflow);
ir.SetCpsrNZCV(ir.NZCVFrom(result));
}
return true;
@ -835,12 +820,9 @@ bool TranslatorVisitor::arm_RSB_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, Shif
const auto shifted = EmitRegShift(ir.GetRegister(m), shift, shift_n, carry_in);
const auto result = ir.SubWithCarry(shifted.result, ir.GetRegister(n), ir.Imm1(1));
ir.SetRegister(d, result.result);
ir.SetRegister(d, result);
if (S) {
ir.SetNFlag(ir.MostSignificantBit(result.result));
ir.SetZFlag(ir.IsZero(result.result));
ir.SetCFlag(result.carry);
ir.SetVFlag(result.overflow);
ir.SetCpsrNZCV(ir.NZCVFrom(result));
}
return true;
@ -860,17 +842,14 @@ bool TranslatorVisitor::arm_RSC_imm(Cond cond, bool S, Reg n, Reg d, int rotate,
return UnpredictableInstruction();
}
ir.ALUWritePC(result.result);
ir.ALUWritePC(result);
ir.SetTerm(IR::Term::ReturnToDispatch{});
return false;
}
ir.SetRegister(d, result.result);
ir.SetRegister(d, result);
if (S) {
ir.SetNFlag(ir.MostSignificantBit(result.result));
ir.SetZFlag(ir.IsZero(result.result));
ir.SetCFlag(result.carry);
ir.SetVFlag(result.overflow);
ir.SetCpsrNZCV(ir.NZCVFrom(result));
}
return true;
@ -889,17 +868,14 @@ bool TranslatorVisitor::arm_RSC_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5
return UnpredictableInstruction();
}
ir.ALUWritePC(result.result);
ir.ALUWritePC(result);
ir.SetTerm(IR::Term::ReturnToDispatch{});
return false;
}
ir.SetRegister(d, result.result);
ir.SetRegister(d, result);
if (S) {
ir.SetNFlag(ir.MostSignificantBit(result.result));
ir.SetZFlag(ir.IsZero(result.result));
ir.SetCFlag(result.carry);
ir.SetVFlag(result.overflow);
ir.SetCpsrNZCV(ir.NZCVFrom(result));
}
return true;
@ -920,12 +896,9 @@ bool TranslatorVisitor::arm_RSC_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, Shif
const auto shifted = EmitRegShift(ir.GetRegister(m), shift, shift_n, carry_in);
const auto result = ir.SubWithCarry(shifted.result, ir.GetRegister(n), ir.GetCFlag());
ir.SetRegister(d, result.result);
ir.SetRegister(d, result);
if (S) {
ir.SetNFlag(ir.MostSignificantBit(result.result));
ir.SetZFlag(ir.IsZero(result.result));
ir.SetCFlag(result.carry);
ir.SetVFlag(result.overflow);
ir.SetCpsrNZCV(ir.NZCVFrom(result));
}
return true;
@ -945,17 +918,14 @@ bool TranslatorVisitor::arm_SBC_imm(Cond cond, bool S, Reg n, Reg d, int rotate,
return UnpredictableInstruction();
}
ir.ALUWritePC(result.result);
ir.ALUWritePC(result);
ir.SetTerm(IR::Term::ReturnToDispatch{});
return false;
}
ir.SetRegister(d, result.result);
ir.SetRegister(d, result);
if (S) {
ir.SetNFlag(ir.MostSignificantBit(result.result));
ir.SetZFlag(ir.IsZero(result.result));
ir.SetCFlag(result.carry);
ir.SetVFlag(result.overflow);
ir.SetCpsrNZCV(ir.NZCVFrom(result));
}
return true;
@ -975,17 +945,14 @@ bool TranslatorVisitor::arm_SBC_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5
return UnpredictableInstruction();
}
ir.ALUWritePC(result.result);
ir.ALUWritePC(result);
ir.SetTerm(IR::Term::ReturnToDispatch{});
return false;
}
ir.SetRegister(d, result.result);
ir.SetRegister(d, result);
if (S) {
ir.SetNFlag(ir.MostSignificantBit(result.result));
ir.SetZFlag(ir.IsZero(result.result));
ir.SetCFlag(result.carry);
ir.SetVFlag(result.overflow);
ir.SetCpsrNZCV(ir.NZCVFrom(result));
}
return true;
@ -1006,12 +973,9 @@ bool TranslatorVisitor::arm_SBC_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, Shif
const auto shifted = EmitRegShift(ir.GetRegister(m), shift, shift_n, carry_in);
const auto result = ir.SubWithCarry(ir.GetRegister(n), shifted.result, ir.GetCFlag());
ir.SetRegister(d, result.result);
ir.SetRegister(d, result);
if (S) {
ir.SetNFlag(ir.MostSignificantBit(result.result));
ir.SetZFlag(ir.IsZero(result.result));
ir.SetCFlag(result.carry);
ir.SetVFlag(result.overflow);
ir.SetCpsrNZCV(ir.NZCVFrom(result));
}
return true;
@ -1031,17 +995,14 @@ bool TranslatorVisitor::arm_SUB_imm(Cond cond, bool S, Reg n, Reg d, int rotate,
return UnpredictableInstruction();
}
ir.ALUWritePC(result.result);
ir.ALUWritePC(result);
ir.SetTerm(IR::Term::ReturnToDispatch{});
return false;
}
ir.SetRegister(d, result.result);
ir.SetRegister(d, result);
if (S) {
ir.SetNFlag(ir.MostSignificantBit(result.result));
ir.SetZFlag(ir.IsZero(result.result));
ir.SetCFlag(result.carry);
ir.SetVFlag(result.overflow);
ir.SetCpsrNZCV(ir.NZCVFrom(result));
}
return true;
@ -1061,17 +1022,14 @@ bool TranslatorVisitor::arm_SUB_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5
return UnpredictableInstruction();
}
ir.ALUWritePC(result.result);
ir.ALUWritePC(result);
ir.SetTerm(IR::Term::ReturnToDispatch{});
return false;
}
ir.SetRegister(d, result.result);
ir.SetRegister(d, result);
if (S) {
ir.SetNFlag(ir.MostSignificantBit(result.result));
ir.SetZFlag(ir.IsZero(result.result));
ir.SetCFlag(result.carry);
ir.SetVFlag(result.overflow);
ir.SetCpsrNZCV(ir.NZCVFrom(result));
}
return true;
@ -1091,12 +1049,9 @@ bool TranslatorVisitor::arm_SUB_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, Shif
const auto shifted = EmitRegShift(ir.GetRegister(m), shift, shift_n, carry_in);
const auto result = ir.SubWithCarry(ir.GetRegister(n), shifted.result, ir.Imm1(1));
ir.SetRegister(d, result.result);
ir.SetRegister(d, result);
if (S) {
ir.SetNFlag(ir.MostSignificantBit(result.result));
ir.SetZFlag(ir.IsZero(result.result));
ir.SetCFlag(result.carry);
ir.SetVFlag(result.overflow);
ir.SetCpsrNZCV(ir.NZCVFrom(result));
}
return true;

View file

@ -74,12 +74,9 @@ bool TranslatorVisitor::thumb16_ADD_reg_t1(Reg m, Reg n, Reg d) {
bool TranslatorVisitor::thumb16_SUB_reg(Reg m, Reg n, Reg d) {
const auto result = ir.SubWithCarry(ir.GetRegister(n), ir.GetRegister(m), ir.Imm1(1));
ir.SetRegister(d, result.result);
ir.SetRegister(d, result);
if (!ir.current_location.IT().IsInITBlock()) {
ir.SetNFlag(ir.MostSignificantBit(result.result));
ir.SetZFlag(ir.IsZero(result.result));
ir.SetCFlag(result.carry);
ir.SetVFlag(result.overflow);
ir.SetCpsrNZCV(ir.NZCVFrom(result));
}
return true;
}
@ -103,12 +100,9 @@ bool TranslatorVisitor::thumb16_SUB_imm_t1(Imm<3> imm3, Reg n, Reg d) {
const u32 imm32 = imm3.ZeroExtend();
const auto result = ir.SubWithCarry(ir.GetRegister(n), ir.Imm32(imm32), ir.Imm1(1));
ir.SetRegister(d, result.result);
ir.SetRegister(d, result);
if (!ir.current_location.IT().IsInITBlock()) {
ir.SetNFlag(ir.MostSignificantBit(result.result));
ir.SetZFlag(ir.IsZero(result.result));
ir.SetCFlag(result.carry);
ir.SetVFlag(result.overflow);
ir.SetCpsrNZCV(ir.NZCVFrom(result));
}
return true;
}
@ -132,10 +126,7 @@ bool TranslatorVisitor::thumb16_CMP_imm(Reg n, Imm<8> imm8) {
const u32 imm32 = imm8.ZeroExtend();
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);
ir.SetVFlag(result.overflow);
ir.SetCpsrNZCV(ir.NZCVFrom(result));
return true;
}
@ -162,12 +153,9 @@ bool TranslatorVisitor::thumb16_SUB_imm_t2(Reg d_n, Imm<8> imm8) {
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.SetRegister(d, result);
if (!ir.current_location.IT().IsInITBlock()) {
ir.SetNFlag(ir.MostSignificantBit(result.result));
ir.SetZFlag(ir.IsZero(result.result));
ir.SetCFlag(result.carry);
ir.SetVFlag(result.overflow);
ir.SetCpsrNZCV(ir.NZCVFrom(result));
}
return true;
}
@ -276,12 +264,9 @@ bool TranslatorVisitor::thumb16_SBC_reg(Reg m, Reg 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.SetRegister(d, result);
if (!ir.current_location.IT().IsInITBlock()) {
ir.SetNFlag(ir.MostSignificantBit(result.result));
ir.SetZFlag(ir.IsZero(result.result));
ir.SetCFlag(result.carry);
ir.SetVFlag(result.overflow);
ir.SetCpsrNZCV(ir.NZCVFrom(result));
}
return true;
}
@ -315,12 +300,9 @@ bool TranslatorVisitor::thumb16_TST_reg(Reg m, Reg n) {
// Rd can never encode R15.
bool TranslatorVisitor::thumb16_RSB_imm(Reg n, Reg d) {
const auto result = ir.SubWithCarry(ir.Imm32(0), ir.GetRegister(n), ir.Imm1(1));
ir.SetRegister(d, result.result);
ir.SetRegister(d, result);
if (!ir.current_location.IT().IsInITBlock()) {
ir.SetNFlag(ir.MostSignificantBit(result.result));
ir.SetZFlag(ir.IsZero(result.result));
ir.SetCFlag(result.carry);
ir.SetVFlag(result.overflow);
ir.SetCpsrNZCV(ir.NZCVFrom(result));
}
return true;
}
@ -328,10 +310,7 @@ bool TranslatorVisitor::thumb16_RSB_imm(Reg n, Reg d) {
// CMP <Rn>, <Rm>
bool TranslatorVisitor::thumb16_CMP_reg_t1(Reg m, Reg n) {
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);
ir.SetVFlag(result.overflow);
ir.SetCpsrNZCV(ir.NZCVFrom(result));
return true;
}
@ -436,10 +415,7 @@ bool TranslatorVisitor::thumb16_CMP_reg_t2(bool n_hi, Reg m, Reg n_lo) {
}
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);
ir.SetVFlag(result.overflow);
ir.SetCpsrNZCV(ir.NZCVFrom(result));
return true;
}
@ -677,7 +653,7 @@ bool TranslatorVisitor::thumb16_SUB_sp(Imm<7> imm7) {
const Reg d = Reg::SP;
const auto result = ir.SubWithCarry(ir.GetRegister(Reg::SP), ir.Imm32(imm32), ir.Imm1(1));
ir.SetRegister(d, result.result);
ir.SetRegister(d, result);
return true;
}

View file

@ -209,12 +209,9 @@ bool TranslatorVisitor::thumb32_SBC_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Re
const auto imm32 = ThumbExpandImm(i, imm3, imm8);
const auto result = ir.SubWithCarry(ir.GetRegister(n), ir.Imm32(imm32), ir.GetCFlag());
ir.SetRegister(d, result.result);
ir.SetRegister(d, result);
if (S) {
ir.SetNFlag(ir.MostSignificantBit(result.result));
ir.SetZFlag(ir.IsZero(result.result));
ir.SetCFlag(result.carry);
ir.SetVFlag(result.overflow);
ir.SetCpsrNZCV(ir.NZCVFrom(result));
}
return true;
}
@ -227,10 +224,7 @@ bool TranslatorVisitor::thumb32_CMP_imm(Imm<1> i, Reg n, Imm<3> imm3, Imm<8> imm
const auto imm32 = ThumbExpandImm(i, imm3, imm8);
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);
ir.SetVFlag(result.overflow);
ir.SetCpsrNZCV(ir.NZCVFrom(result));
return true;
}
@ -243,12 +237,9 @@ bool TranslatorVisitor::thumb32_SUB_imm_1(Imm<1> i, bool S, Reg n, Imm<3> imm3,
const auto imm32 = ThumbExpandImm(i, imm3, imm8);
const auto result = ir.SubWithCarry(ir.GetRegister(n), ir.Imm32(imm32), ir.Imm1(1));
ir.SetRegister(d, result.result);
ir.SetRegister(d, result);
if (S) {
ir.SetNFlag(ir.MostSignificantBit(result.result));
ir.SetZFlag(ir.IsZero(result.result));
ir.SetCFlag(result.carry);
ir.SetVFlag(result.overflow);
ir.SetCpsrNZCV(ir.NZCVFrom(result));
}
return true;
}
@ -261,12 +252,9 @@ bool TranslatorVisitor::thumb32_RSB_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Re
const auto imm32 = ThumbExpandImm(i, imm3, imm8);
const auto result = ir.SubWithCarry(ir.Imm32(imm32), ir.GetRegister(n), ir.Imm1(1));
ir.SetRegister(d, result.result);
ir.SetRegister(d, result);
if (S) {
ir.SetNFlag(ir.MostSignificantBit(result.result));
ir.SetZFlag(ir.IsZero(result.result));
ir.SetCFlag(result.carry);
ir.SetVFlag(result.overflow);
ir.SetCpsrNZCV(ir.NZCVFrom(result));
}
return true;
}

View file

@ -196,7 +196,7 @@ bool TranslatorVisitor::thumb32_SUB_imm_2(Imm<1> imm1, Reg n, Imm<3> imm3, Reg d
const auto reg_n = ir.GetRegister(n);
const auto result = ir.SubWithCarry(reg_n, ir.Imm32(imm), ir.Imm1(1));
ir.SetRegister(d, result.result);
ir.SetRegister(d, result);
return true;
}

View file

@ -219,12 +219,9 @@ bool TranslatorVisitor::thumb32_SBC_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2
const auto shifted = EmitImmShift(ir.GetRegister(m), type, imm3, imm2, ir.GetCFlag());
const auto result = ir.SubWithCarry(ir.GetRegister(n), shifted.result, ir.GetCFlag());
ir.SetRegister(d, result.result);
ir.SetRegister(d, result);
if (S) {
ir.SetNFlag(ir.MostSignificantBit(result.result));
ir.SetZFlag(ir.IsZero(result.result));
ir.SetCFlag(result.carry);
ir.SetVFlag(result.overflow);
ir.SetCpsrNZCV(ir.NZCVFrom(result));
}
return true;
}
@ -237,10 +234,7 @@ bool TranslatorVisitor::thumb32_CMP_reg(Reg n, Imm<3> imm3, Imm<2> imm2, ShiftTy
const auto shifted = EmitImmShift(ir.GetRegister(m), type, imm3, imm2, ir.GetCFlag());
const auto result = ir.SubWithCarry(ir.GetRegister(n), shifted.result, ir.Imm1(1));
ir.SetNFlag(ir.MostSignificantBit(result.result));
ir.SetZFlag(ir.IsZero(result.result));
ir.SetCFlag(result.carry);
ir.SetVFlag(result.overflow);
ir.SetCpsrNZCV(ir.NZCVFrom(result));
return true;
}
@ -253,12 +247,9 @@ bool TranslatorVisitor::thumb32_SUB_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2
const auto shifted = EmitImmShift(ir.GetRegister(m), type, imm3, imm2, ir.GetCFlag());
const auto result = ir.SubWithCarry(ir.GetRegister(n), shifted.result, ir.Imm1(1));
ir.SetRegister(d, result.result);
ir.SetRegister(d, result);
if (S) {
ir.SetNFlag(ir.MostSignificantBit(result.result));
ir.SetZFlag(ir.IsZero(result.result));
ir.SetCFlag(result.carry);
ir.SetVFlag(result.overflow);
ir.SetCpsrNZCV(ir.NZCVFrom(result));
}
return true;
}
@ -270,12 +261,9 @@ bool TranslatorVisitor::thumb32_RSB_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2
const auto shifted = EmitImmShift(ir.GetRegister(m), type, imm3, imm2, ir.GetCFlag());
const auto result = ir.SubWithCarry(shifted.result, ir.GetRegister(n), ir.Imm1(1));
ir.SetRegister(d, result.result);
ir.SetRegister(d, result);
if (S) {
ir.SetNFlag(ir.MostSignificantBit(result.result));
ir.SetZFlag(ir.IsZero(result.result));
ir.SetCFlag(result.carry);
ir.SetVFlag(result.overflow);
ir.SetCpsrNZCV(ir.NZCVFrom(result));
}
return true;
}

View file

@ -258,14 +258,6 @@ U32U64 IREmitter::Add(const U32U64& a, const U32U64& b) {
}
}
ResultAndCarryAndOverflow<U32> IREmitter::SubWithCarry(const U32& a, const U32& b, const U1& carry_in) {
// This is equivalent to AddWithCarry(a, Not(b), carry_in).
const auto result = Inst<U32>(Opcode::Sub32, a, b, carry_in);
const auto carry_out = Inst<U1>(Opcode::GetCarryFromOp, result);
const auto overflow = Inst<U1>(Opcode::GetOverflowFromOp, result);
return {result, carry_out, overflow};
}
U32U64 IREmitter::SubWithCarry(const U32U64& a, const U32U64& b, const U1& carry_in) {
ASSERT(a.GetType() == b.GetType());
if (a.GetType() == Type::U32) {

View file

@ -134,7 +134,6 @@ public:
U32U64 ArithmeticShiftRightMasked(const U32U64& value_in, const U32U64& shift_amount);
U32U64 RotateRightMasked(const U32U64& value_in, const U32U64& shift_amount);
ResultAndCarry<U32> RotateRightExtended(const U32& value_in, const U1& carry_in);
ResultAndCarryAndOverflow<U32> SubWithCarry(const U32& a, const U32& b, const U1& carry_in);
U32U64 AddWithCarry(const U32U64& a, const U32U64& b, const U1& carry_in);
U32U64 SubWithCarry(const U32U64& a, const U32U64& b, const U1& carry_in);
U32U64 Add(const U32U64& a, const U32U64& b);