ir_emitter: Remove 32-bit-only SubWithCarry
This commit is contained in:
parent
776208742b
commit
a626a2ec63
7 changed files with 64 additions and 166 deletions
|
@ -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 u32 imm32 = ArmExpandImm(rotate, imm8);
|
||||||
const auto result = ir.SubWithCarry(ir.GetRegister(n), ir.Imm32(imm32), ir.Imm1(1));
|
const auto result = ir.SubWithCarry(ir.GetRegister(n), ir.Imm32(imm32), ir.Imm1(1));
|
||||||
|
|
||||||
ir.SetNFlag(ir.MostSignificantBit(result.result));
|
ir.SetCpsrNZCV(ir.NZCVFrom(result));
|
||||||
ir.SetZFlag(ir.IsZero(result.result));
|
|
||||||
ir.SetCFlag(result.carry);
|
|
||||||
ir.SetVFlag(result.overflow);
|
|
||||||
return true;
|
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 shifted = EmitImmShift(ir.GetRegister(m), shift, imm5, ir.GetCFlag());
|
||||||
const auto result = ir.SubWithCarry(ir.GetRegister(n), shifted.result, ir.Imm1(1));
|
const auto result = ir.SubWithCarry(ir.GetRegister(n), shifted.result, ir.Imm1(1));
|
||||||
|
|
||||||
ir.SetNFlag(ir.MostSignificantBit(result.result));
|
ir.SetCpsrNZCV(ir.NZCVFrom(result));
|
||||||
ir.SetZFlag(ir.IsZero(result.result));
|
|
||||||
ir.SetCFlag(result.carry);
|
|
||||||
ir.SetVFlag(result.overflow);
|
|
||||||
return true;
|
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 shifted = EmitRegShift(ir.GetRegister(m), shift, shift_n, carry_in);
|
||||||
const auto result = ir.SubWithCarry(ir.GetRegister(n), shifted.result, ir.Imm1(1));
|
const auto result = ir.SubWithCarry(ir.GetRegister(n), shifted.result, ir.Imm1(1));
|
||||||
|
|
||||||
ir.SetNFlag(ir.MostSignificantBit(result.result));
|
ir.SetCpsrNZCV(ir.NZCVFrom(result));
|
||||||
ir.SetZFlag(ir.IsZero(result.result));
|
|
||||||
ir.SetCFlag(result.carry);
|
|
||||||
ir.SetVFlag(result.overflow);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -774,17 +765,14 @@ bool TranslatorVisitor::arm_RSB_imm(Cond cond, bool S, Reg n, Reg d, int rotate,
|
||||||
return UnpredictableInstruction();
|
return UnpredictableInstruction();
|
||||||
}
|
}
|
||||||
|
|
||||||
ir.ALUWritePC(result.result);
|
ir.ALUWritePC(result);
|
||||||
ir.SetTerm(IR::Term::ReturnToDispatch{});
|
ir.SetTerm(IR::Term::ReturnToDispatch{});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ir.SetRegister(d, result.result);
|
ir.SetRegister(d, result);
|
||||||
if (S) {
|
if (S) {
|
||||||
ir.SetNFlag(ir.MostSignificantBit(result.result));
|
ir.SetCpsrNZCV(ir.NZCVFrom(result));
|
||||||
ir.SetZFlag(ir.IsZero(result.result));
|
|
||||||
ir.SetCFlag(result.carry);
|
|
||||||
ir.SetVFlag(result.overflow);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -804,17 +792,14 @@ bool TranslatorVisitor::arm_RSB_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5
|
||||||
return UnpredictableInstruction();
|
return UnpredictableInstruction();
|
||||||
}
|
}
|
||||||
|
|
||||||
ir.ALUWritePC(result.result);
|
ir.ALUWritePC(result);
|
||||||
ir.SetTerm(IR::Term::ReturnToDispatch{});
|
ir.SetTerm(IR::Term::ReturnToDispatch{});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ir.SetRegister(d, result.result);
|
ir.SetRegister(d, result);
|
||||||
if (S) {
|
if (S) {
|
||||||
ir.SetNFlag(ir.MostSignificantBit(result.result));
|
ir.SetCpsrNZCV(ir.NZCVFrom(result));
|
||||||
ir.SetZFlag(ir.IsZero(result.result));
|
|
||||||
ir.SetCFlag(result.carry);
|
|
||||||
ir.SetVFlag(result.overflow);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
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 shifted = EmitRegShift(ir.GetRegister(m), shift, shift_n, carry_in);
|
||||||
const auto result = ir.SubWithCarry(shifted.result, ir.GetRegister(n), ir.Imm1(1));
|
const auto result = ir.SubWithCarry(shifted.result, ir.GetRegister(n), ir.Imm1(1));
|
||||||
|
|
||||||
ir.SetRegister(d, result.result);
|
ir.SetRegister(d, result);
|
||||||
if (S) {
|
if (S) {
|
||||||
ir.SetNFlag(ir.MostSignificantBit(result.result));
|
ir.SetCpsrNZCV(ir.NZCVFrom(result));
|
||||||
ir.SetZFlag(ir.IsZero(result.result));
|
|
||||||
ir.SetCFlag(result.carry);
|
|
||||||
ir.SetVFlag(result.overflow);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -860,17 +842,14 @@ bool TranslatorVisitor::arm_RSC_imm(Cond cond, bool S, Reg n, Reg d, int rotate,
|
||||||
return UnpredictableInstruction();
|
return UnpredictableInstruction();
|
||||||
}
|
}
|
||||||
|
|
||||||
ir.ALUWritePC(result.result);
|
ir.ALUWritePC(result);
|
||||||
ir.SetTerm(IR::Term::ReturnToDispatch{});
|
ir.SetTerm(IR::Term::ReturnToDispatch{});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ir.SetRegister(d, result.result);
|
ir.SetRegister(d, result);
|
||||||
if (S) {
|
if (S) {
|
||||||
ir.SetNFlag(ir.MostSignificantBit(result.result));
|
ir.SetCpsrNZCV(ir.NZCVFrom(result));
|
||||||
ir.SetZFlag(ir.IsZero(result.result));
|
|
||||||
ir.SetCFlag(result.carry);
|
|
||||||
ir.SetVFlag(result.overflow);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -889,17 +868,14 @@ bool TranslatorVisitor::arm_RSC_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5
|
||||||
return UnpredictableInstruction();
|
return UnpredictableInstruction();
|
||||||
}
|
}
|
||||||
|
|
||||||
ir.ALUWritePC(result.result);
|
ir.ALUWritePC(result);
|
||||||
ir.SetTerm(IR::Term::ReturnToDispatch{});
|
ir.SetTerm(IR::Term::ReturnToDispatch{});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ir.SetRegister(d, result.result);
|
ir.SetRegister(d, result);
|
||||||
if (S) {
|
if (S) {
|
||||||
ir.SetNFlag(ir.MostSignificantBit(result.result));
|
ir.SetCpsrNZCV(ir.NZCVFrom(result));
|
||||||
ir.SetZFlag(ir.IsZero(result.result));
|
|
||||||
ir.SetCFlag(result.carry);
|
|
||||||
ir.SetVFlag(result.overflow);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
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 shifted = EmitRegShift(ir.GetRegister(m), shift, shift_n, carry_in);
|
||||||
const auto result = ir.SubWithCarry(shifted.result, ir.GetRegister(n), ir.GetCFlag());
|
const auto result = ir.SubWithCarry(shifted.result, ir.GetRegister(n), ir.GetCFlag());
|
||||||
|
|
||||||
ir.SetRegister(d, result.result);
|
ir.SetRegister(d, result);
|
||||||
if (S) {
|
if (S) {
|
||||||
ir.SetNFlag(ir.MostSignificantBit(result.result));
|
ir.SetCpsrNZCV(ir.NZCVFrom(result));
|
||||||
ir.SetZFlag(ir.IsZero(result.result));
|
|
||||||
ir.SetCFlag(result.carry);
|
|
||||||
ir.SetVFlag(result.overflow);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -945,17 +918,14 @@ bool TranslatorVisitor::arm_SBC_imm(Cond cond, bool S, Reg n, Reg d, int rotate,
|
||||||
return UnpredictableInstruction();
|
return UnpredictableInstruction();
|
||||||
}
|
}
|
||||||
|
|
||||||
ir.ALUWritePC(result.result);
|
ir.ALUWritePC(result);
|
||||||
ir.SetTerm(IR::Term::ReturnToDispatch{});
|
ir.SetTerm(IR::Term::ReturnToDispatch{});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ir.SetRegister(d, result.result);
|
ir.SetRegister(d, result);
|
||||||
if (S) {
|
if (S) {
|
||||||
ir.SetNFlag(ir.MostSignificantBit(result.result));
|
ir.SetCpsrNZCV(ir.NZCVFrom(result));
|
||||||
ir.SetZFlag(ir.IsZero(result.result));
|
|
||||||
ir.SetCFlag(result.carry);
|
|
||||||
ir.SetVFlag(result.overflow);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -975,17 +945,14 @@ bool TranslatorVisitor::arm_SBC_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5
|
||||||
return UnpredictableInstruction();
|
return UnpredictableInstruction();
|
||||||
}
|
}
|
||||||
|
|
||||||
ir.ALUWritePC(result.result);
|
ir.ALUWritePC(result);
|
||||||
ir.SetTerm(IR::Term::ReturnToDispatch{});
|
ir.SetTerm(IR::Term::ReturnToDispatch{});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ir.SetRegister(d, result.result);
|
ir.SetRegister(d, result);
|
||||||
if (S) {
|
if (S) {
|
||||||
ir.SetNFlag(ir.MostSignificantBit(result.result));
|
ir.SetCpsrNZCV(ir.NZCVFrom(result));
|
||||||
ir.SetZFlag(ir.IsZero(result.result));
|
|
||||||
ir.SetCFlag(result.carry);
|
|
||||||
ir.SetVFlag(result.overflow);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
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 shifted = EmitRegShift(ir.GetRegister(m), shift, shift_n, carry_in);
|
||||||
const auto result = ir.SubWithCarry(ir.GetRegister(n), shifted.result, 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) {
|
if (S) {
|
||||||
ir.SetNFlag(ir.MostSignificantBit(result.result));
|
ir.SetCpsrNZCV(ir.NZCVFrom(result));
|
||||||
ir.SetZFlag(ir.IsZero(result.result));
|
|
||||||
ir.SetCFlag(result.carry);
|
|
||||||
ir.SetVFlag(result.overflow);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -1031,17 +995,14 @@ bool TranslatorVisitor::arm_SUB_imm(Cond cond, bool S, Reg n, Reg d, int rotate,
|
||||||
return UnpredictableInstruction();
|
return UnpredictableInstruction();
|
||||||
}
|
}
|
||||||
|
|
||||||
ir.ALUWritePC(result.result);
|
ir.ALUWritePC(result);
|
||||||
ir.SetTerm(IR::Term::ReturnToDispatch{});
|
ir.SetTerm(IR::Term::ReturnToDispatch{});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ir.SetRegister(d, result.result);
|
ir.SetRegister(d, result);
|
||||||
if (S) {
|
if (S) {
|
||||||
ir.SetNFlag(ir.MostSignificantBit(result.result));
|
ir.SetCpsrNZCV(ir.NZCVFrom(result));
|
||||||
ir.SetZFlag(ir.IsZero(result.result));
|
|
||||||
ir.SetCFlag(result.carry);
|
|
||||||
ir.SetVFlag(result.overflow);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -1061,17 +1022,14 @@ bool TranslatorVisitor::arm_SUB_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5
|
||||||
return UnpredictableInstruction();
|
return UnpredictableInstruction();
|
||||||
}
|
}
|
||||||
|
|
||||||
ir.ALUWritePC(result.result);
|
ir.ALUWritePC(result);
|
||||||
ir.SetTerm(IR::Term::ReturnToDispatch{});
|
ir.SetTerm(IR::Term::ReturnToDispatch{});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ir.SetRegister(d, result.result);
|
ir.SetRegister(d, result);
|
||||||
if (S) {
|
if (S) {
|
||||||
ir.SetNFlag(ir.MostSignificantBit(result.result));
|
ir.SetCpsrNZCV(ir.NZCVFrom(result));
|
||||||
ir.SetZFlag(ir.IsZero(result.result));
|
|
||||||
ir.SetCFlag(result.carry);
|
|
||||||
ir.SetVFlag(result.overflow);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
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 shifted = EmitRegShift(ir.GetRegister(m), shift, shift_n, carry_in);
|
||||||
const auto result = ir.SubWithCarry(ir.GetRegister(n), shifted.result, ir.Imm1(1));
|
const auto result = ir.SubWithCarry(ir.GetRegister(n), shifted.result, ir.Imm1(1));
|
||||||
|
|
||||||
ir.SetRegister(d, result.result);
|
ir.SetRegister(d, result);
|
||||||
if (S) {
|
if (S) {
|
||||||
ir.SetNFlag(ir.MostSignificantBit(result.result));
|
ir.SetCpsrNZCV(ir.NZCVFrom(result));
|
||||||
ir.SetZFlag(ir.IsZero(result.result));
|
|
||||||
ir.SetCFlag(result.carry);
|
|
||||||
ir.SetVFlag(result.overflow);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -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) {
|
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));
|
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()) {
|
if (!ir.current_location.IT().IsInITBlock()) {
|
||||||
ir.SetNFlag(ir.MostSignificantBit(result.result));
|
ir.SetCpsrNZCV(ir.NZCVFrom(result));
|
||||||
ir.SetZFlag(ir.IsZero(result.result));
|
|
||||||
ir.SetCFlag(result.carry);
|
|
||||||
ir.SetVFlag(result.overflow);
|
|
||||||
}
|
}
|
||||||
return true;
|
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 u32 imm32 = imm3.ZeroExtend();
|
||||||
const auto result = ir.SubWithCarry(ir.GetRegister(n), ir.Imm32(imm32), ir.Imm1(1));
|
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()) {
|
if (!ir.current_location.IT().IsInITBlock()) {
|
||||||
ir.SetNFlag(ir.MostSignificantBit(result.result));
|
ir.SetCpsrNZCV(ir.NZCVFrom(result));
|
||||||
ir.SetZFlag(ir.IsZero(result.result));
|
|
||||||
ir.SetCFlag(result.carry);
|
|
||||||
ir.SetVFlag(result.overflow);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -132,10 +126,7 @@ bool TranslatorVisitor::thumb16_CMP_imm(Reg n, Imm<8> imm8) {
|
||||||
const u32 imm32 = imm8.ZeroExtend();
|
const u32 imm32 = imm8.ZeroExtend();
|
||||||
const auto result = ir.SubWithCarry(ir.GetRegister(n), ir.Imm32(imm32), ir.Imm1(1));
|
const auto result = ir.SubWithCarry(ir.GetRegister(n), ir.Imm32(imm32), ir.Imm1(1));
|
||||||
|
|
||||||
ir.SetNFlag(ir.MostSignificantBit(result.result));
|
ir.SetCpsrNZCV(ir.NZCVFrom(result));
|
||||||
ir.SetZFlag(ir.IsZero(result.result));
|
|
||||||
ir.SetCFlag(result.carry);
|
|
||||||
ir.SetVFlag(result.overflow);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,12 +153,9 @@ bool TranslatorVisitor::thumb16_SUB_imm_t2(Reg d_n, Imm<8> imm8) {
|
||||||
const Reg n = d_n;
|
const Reg n = d_n;
|
||||||
const auto result = ir.SubWithCarry(ir.GetRegister(n), ir.Imm32(imm32), ir.Imm1(1));
|
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()) {
|
if (!ir.current_location.IT().IsInITBlock()) {
|
||||||
ir.SetNFlag(ir.MostSignificantBit(result.result));
|
ir.SetCpsrNZCV(ir.NZCVFrom(result));
|
||||||
ir.SetZFlag(ir.IsZero(result.result));
|
|
||||||
ir.SetCFlag(result.carry);
|
|
||||||
ir.SetVFlag(result.overflow);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -276,12 +264,9 @@ bool TranslatorVisitor::thumb16_SBC_reg(Reg m, Reg d_n) {
|
||||||
const auto aspr_c = ir.GetCFlag();
|
const auto aspr_c = ir.GetCFlag();
|
||||||
const auto result = ir.SubWithCarry(ir.GetRegister(n), ir.GetRegister(m), aspr_c);
|
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()) {
|
if (!ir.current_location.IT().IsInITBlock()) {
|
||||||
ir.SetNFlag(ir.MostSignificantBit(result.result));
|
ir.SetCpsrNZCV(ir.NZCVFrom(result));
|
||||||
ir.SetZFlag(ir.IsZero(result.result));
|
|
||||||
ir.SetCFlag(result.carry);
|
|
||||||
ir.SetVFlag(result.overflow);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -315,12 +300,9 @@ bool TranslatorVisitor::thumb16_TST_reg(Reg m, Reg n) {
|
||||||
// Rd can never encode R15.
|
// Rd can never encode R15.
|
||||||
bool TranslatorVisitor::thumb16_RSB_imm(Reg n, Reg d) {
|
bool TranslatorVisitor::thumb16_RSB_imm(Reg n, Reg d) {
|
||||||
const 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.SetRegister(d, result);
|
||||||
if (!ir.current_location.IT().IsInITBlock()) {
|
if (!ir.current_location.IT().IsInITBlock()) {
|
||||||
ir.SetNFlag(ir.MostSignificantBit(result.result));
|
ir.SetCpsrNZCV(ir.NZCVFrom(result));
|
||||||
ir.SetZFlag(ir.IsZero(result.result));
|
|
||||||
ir.SetCFlag(result.carry);
|
|
||||||
ir.SetVFlag(result.overflow);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -328,10 +310,7 @@ bool TranslatorVisitor::thumb16_RSB_imm(Reg n, Reg d) {
|
||||||
// CMP <Rn>, <Rm>
|
// CMP <Rn>, <Rm>
|
||||||
bool TranslatorVisitor::thumb16_CMP_reg_t1(Reg m, Reg n) {
|
bool TranslatorVisitor::thumb16_CMP_reg_t1(Reg m, Reg n) {
|
||||||
const 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.SetCpsrNZCV(ir.NZCVFrom(result));
|
||||||
ir.SetZFlag(ir.IsZero(result.result));
|
|
||||||
ir.SetCFlag(result.carry);
|
|
||||||
ir.SetVFlag(result.overflow);
|
|
||||||
return true;
|
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));
|
const auto result = ir.SubWithCarry(ir.GetRegister(n), ir.GetRegister(m), ir.Imm1(1));
|
||||||
ir.SetNFlag(ir.MostSignificantBit(result.result));
|
ir.SetCpsrNZCV(ir.NZCVFrom(result));
|
||||||
ir.SetZFlag(ir.IsZero(result.result));
|
|
||||||
ir.SetCFlag(result.carry);
|
|
||||||
ir.SetVFlag(result.overflow);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -677,7 +653,7 @@ bool TranslatorVisitor::thumb16_SUB_sp(Imm<7> imm7) {
|
||||||
const Reg d = Reg::SP;
|
const Reg d = Reg::SP;
|
||||||
const auto result = ir.SubWithCarry(ir.GetRegister(Reg::SP), ir.Imm32(imm32), ir.Imm1(1));
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 imm32 = ThumbExpandImm(i, imm3, imm8);
|
||||||
const auto result = ir.SubWithCarry(ir.GetRegister(n), ir.Imm32(imm32), ir.GetCFlag());
|
const auto result = ir.SubWithCarry(ir.GetRegister(n), ir.Imm32(imm32), ir.GetCFlag());
|
||||||
|
|
||||||
ir.SetRegister(d, result.result);
|
ir.SetRegister(d, result);
|
||||||
if (S) {
|
if (S) {
|
||||||
ir.SetNFlag(ir.MostSignificantBit(result.result));
|
ir.SetCpsrNZCV(ir.NZCVFrom(result));
|
||||||
ir.SetZFlag(ir.IsZero(result.result));
|
|
||||||
ir.SetCFlag(result.carry);
|
|
||||||
ir.SetVFlag(result.overflow);
|
|
||||||
}
|
}
|
||||||
return true;
|
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 imm32 = ThumbExpandImm(i, imm3, imm8);
|
||||||
const auto result = ir.SubWithCarry(ir.GetRegister(n), ir.Imm32(imm32), ir.Imm1(1));
|
const auto result = ir.SubWithCarry(ir.GetRegister(n), ir.Imm32(imm32), ir.Imm1(1));
|
||||||
|
|
||||||
ir.SetNFlag(ir.MostSignificantBit(result.result));
|
ir.SetCpsrNZCV(ir.NZCVFrom(result));
|
||||||
ir.SetZFlag(ir.IsZero(result.result));
|
|
||||||
ir.SetCFlag(result.carry);
|
|
||||||
ir.SetVFlag(result.overflow);
|
|
||||||
return true;
|
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 imm32 = ThumbExpandImm(i, imm3, imm8);
|
||||||
const auto result = ir.SubWithCarry(ir.GetRegister(n), ir.Imm32(imm32), ir.Imm1(1));
|
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) {
|
if (S) {
|
||||||
ir.SetNFlag(ir.MostSignificantBit(result.result));
|
ir.SetCpsrNZCV(ir.NZCVFrom(result));
|
||||||
ir.SetZFlag(ir.IsZero(result.result));
|
|
||||||
ir.SetCFlag(result.carry);
|
|
||||||
ir.SetVFlag(result.overflow);
|
|
||||||
}
|
}
|
||||||
return true;
|
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 imm32 = ThumbExpandImm(i, imm3, imm8);
|
||||||
const auto result = ir.SubWithCarry(ir.Imm32(imm32), ir.GetRegister(n), ir.Imm1(1));
|
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) {
|
if (S) {
|
||||||
ir.SetNFlag(ir.MostSignificantBit(result.result));
|
ir.SetCpsrNZCV(ir.NZCVFrom(result));
|
||||||
ir.SetZFlag(ir.IsZero(result.result));
|
|
||||||
ir.SetCFlag(result.carry);
|
|
||||||
ir.SetVFlag(result.overflow);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 reg_n = ir.GetRegister(n);
|
||||||
const auto result = ir.SubWithCarry(reg_n, ir.Imm32(imm), ir.Imm1(1));
|
const auto result = ir.SubWithCarry(reg_n, ir.Imm32(imm), ir.Imm1(1));
|
||||||
|
|
||||||
ir.SetRegister(d, result.result);
|
ir.SetRegister(d, result);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 shifted = EmitImmShift(ir.GetRegister(m), type, imm3, imm2, ir.GetCFlag());
|
||||||
const auto result = ir.SubWithCarry(ir.GetRegister(n), shifted.result, 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) {
|
if (S) {
|
||||||
ir.SetNFlag(ir.MostSignificantBit(result.result));
|
ir.SetCpsrNZCV(ir.NZCVFrom(result));
|
||||||
ir.SetZFlag(ir.IsZero(result.result));
|
|
||||||
ir.SetCFlag(result.carry);
|
|
||||||
ir.SetVFlag(result.overflow);
|
|
||||||
}
|
}
|
||||||
return true;
|
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 shifted = EmitImmShift(ir.GetRegister(m), type, imm3, imm2, ir.GetCFlag());
|
||||||
const auto result = ir.SubWithCarry(ir.GetRegister(n), shifted.result, ir.Imm1(1));
|
const auto result = ir.SubWithCarry(ir.GetRegister(n), shifted.result, ir.Imm1(1));
|
||||||
|
|
||||||
ir.SetNFlag(ir.MostSignificantBit(result.result));
|
ir.SetCpsrNZCV(ir.NZCVFrom(result));
|
||||||
ir.SetZFlag(ir.IsZero(result.result));
|
|
||||||
ir.SetCFlag(result.carry);
|
|
||||||
ir.SetVFlag(result.overflow);
|
|
||||||
return true;
|
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 shifted = EmitImmShift(ir.GetRegister(m), type, imm3, imm2, ir.GetCFlag());
|
||||||
const auto result = ir.SubWithCarry(ir.GetRegister(n), shifted.result, ir.Imm1(1));
|
const auto result = ir.SubWithCarry(ir.GetRegister(n), shifted.result, ir.Imm1(1));
|
||||||
ir.SetRegister(d, result.result);
|
ir.SetRegister(d, result);
|
||||||
if (S) {
|
if (S) {
|
||||||
ir.SetNFlag(ir.MostSignificantBit(result.result));
|
ir.SetCpsrNZCV(ir.NZCVFrom(result));
|
||||||
ir.SetZFlag(ir.IsZero(result.result));
|
|
||||||
ir.SetCFlag(result.carry);
|
|
||||||
ir.SetVFlag(result.overflow);
|
|
||||||
}
|
}
|
||||||
return true;
|
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 shifted = EmitImmShift(ir.GetRegister(m), type, imm3, imm2, ir.GetCFlag());
|
||||||
const auto result = ir.SubWithCarry(shifted.result, ir.GetRegister(n), ir.Imm1(1));
|
const auto result = ir.SubWithCarry(shifted.result, ir.GetRegister(n), ir.Imm1(1));
|
||||||
ir.SetRegister(d, result.result);
|
ir.SetRegister(d, result);
|
||||||
if (S) {
|
if (S) {
|
||||||
ir.SetNFlag(ir.MostSignificantBit(result.result));
|
ir.SetCpsrNZCV(ir.NZCVFrom(result));
|
||||||
ir.SetZFlag(ir.IsZero(result.result));
|
|
||||||
ir.SetCFlag(result.carry);
|
|
||||||
ir.SetVFlag(result.overflow);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
U32U64 IREmitter::SubWithCarry(const U32U64& a, const U32U64& b, const U1& carry_in) {
|
||||||
ASSERT(a.GetType() == b.GetType());
|
ASSERT(a.GetType() == b.GetType());
|
||||||
if (a.GetType() == Type::U32) {
|
if (a.GetType() == Type::U32) {
|
||||||
|
|
|
@ -134,7 +134,6 @@ public:
|
||||||
U32U64 ArithmeticShiftRightMasked(const U32U64& value_in, const U32U64& shift_amount);
|
U32U64 ArithmeticShiftRightMasked(const U32U64& value_in, const U32U64& shift_amount);
|
||||||
U32U64 RotateRightMasked(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);
|
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 AddWithCarry(const U32U64& a, const U32U64& b, const U1& carry_in);
|
||||||
U32U64 SubWithCarry(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);
|
U32U64 Add(const U32U64& a, const U32U64& b);
|
||||||
|
|
Loading…
Reference in a new issue