20 template <
typename TArg0,
typename TArg1>
22 const TArg0 &rm,
const TArg1 &rn,
24 auto apsr = ictx.cpua.template ReadSpecialRegister<SpecialRegisterId::kApsr>();
25 const auto m = ictx.cpua.ReadRegister(rm.Get());
26 const auto n = ictx.cpua.ReadRegister(rn.Get());
28 const auto shifted = Alu32::Shift(m,
static_cast<SRType
>(shift_res.type), shift_res.value,
29 (apsr & ApsrRegister::kCMsk) == ApsrRegister::kCMsk);
31 const auto result = Alu32::AddWithCarry(n, ~shifted,
true);
32 const auto op_res =
OpResult{result.value, result.carry_out, result.overflow};
33 PostExecSetFlags::Call(ictx, op_res);
34 PostExecAdvancePcAndIt::Call(ictx, iflags);
35 return Ok(kNoInstrExecFlags);
46 template <
typename TArg0,
typename TArg1>
48 const TArg0 &rm,
const TArg1 &rn,
50 auto apsr = ictx.cpua.template ReadSpecialRegister<SpecialRegisterId::kApsr>();
51 const auto m = ictx.cpua.ReadRegister(rm.Get());
52 const auto n = ictx.cpua.ReadRegister(rn.Get());
54 const auto r_shift_c = Alu32::Shift_C(m, shift_res.type, shift_res.value,
55 (apsr & ApsrRegister::kCMsk) == ApsrRegister::kCMsk);
56 const auto result = Alu32::AND(n, r_shift_c.result);
59 OpResult{result, r_shift_c.carry_out, (apsr & ApsrRegister::kVMsk) == ApsrRegister::kVMsk};
61 PostExecSetFlags::Call(ictx, op_res);
62 PostExecAdvancePcAndIt::Call(ictx, iflags);
63 return Ok(kNoInstrExecFlags);
74 template <
typename TArg0,
typename TArg1>
76 const TArg0 &rm,
const TArg1 &rn,
78 auto apsr = ictx.cpua.template ReadSpecialRegister<SpecialRegisterId::kApsr>();
79 const auto m = ictx.cpua.ReadRegister(rm.Get());
80 const auto n = ictx.cpua.ReadRegister(rn.Get());
82 const auto r_shift_c = Alu32::Shift_C(m, shift_res.type, shift_res.value,
83 (apsr & ApsrRegister::kCMsk) == ApsrRegister::kCMsk);
84 const auto result = Alu32::EOR(n, r_shift_c.result);
86 OpResult{result, r_shift_c.carry_out, (apsr & ApsrRegister::kVMsk) == ApsrRegister::kVMsk};
88 PostExecSetFlags::Call(ictx, op_res);
89 PostExecAdvancePcAndIt::Call(ictx, iflags);
90 return Ok(kNoInstrExecFlags);
94template <
typename TOp,
typename TInstrContext>
class TernaryNullInstrWithShift {
96 using It =
typename TInstrContext::It;
97 using Pc =
typename TInstrContext::Pc;
99 template <
typename TArg0,
typename TArg1>
101 const TArg0 &rm,
const TArg1 &rn,
104 if (!condition_passed) {
105 PostExecAdvancePcAndIt::Call(ictx, iflags);
117 TernaryNullInstrWithShift() =
delete;
122 ~TernaryNullInstrWithShift() =
delete;
128 TernaryNullInstrWithShift(
const TernaryNullInstrWithShift &r_src) =
delete;
134 TernaryNullInstrWithShift &operator=(
const TernaryNullInstrWithShift &r_src) =
delete;
140 TernaryNullInstrWithShift(TernaryNullInstrWithShift &&r_src) =
delete;
146 TernaryNullInstrWithShift &operator=(TernaryNullInstrWithShift &&r_src) =
delete;
#define TRY_ASSIGN(NAME, OUT_TYPE, CALL)
Try to assign a value to a variable and return an error if the assignment fails.
Definition result.h:123