19 template <
typename TDest,
typename TArg0>
21 const TDest &rd,
const TArg0 &rn,
const u32 &imm) {
22 const auto n = ictx.cpua.ReadRegister(rn.Get());
23 const auto result = Alu32::AddWithCarry(n, imm,
false);
24 const auto op_res =
OpResult{result.value, result.carry_out, result.overflow};
25 PostExecWriteRegPcExcluded::Call(ictx, rd, op_res.value);
26 PostExecOptionalSetFlags::Call(ictx, iflags, op_res);
27 PostExecAdvancePcAndIt::Call(ictx, iflags);
28 return Ok(kNoInstrExecFlags);
39 template <
typename TDest,
typename TArg0>
41 const TDest &rd,
const TArg0 &rn,
const u32 &imm) {
42 const auto n = ictx.cpua.ReadRegister(rn.Get());
43 auto apsr = ictx.cpua.template ReadSpecialRegister<SpecialRegisterId::kApsr>();
45 Alu32::AddWithCarry(n, imm, (apsr & ApsrRegister::kCMsk) == ApsrRegister::kCMsk);
46 const auto op_res =
OpResult{result.value, result.carry_out, result.overflow};
48 PostExecWriteRegPcExcluded::Call(ictx, rd, op_res.value);
49 PostExecOptionalSetFlags::Call(ictx, iflags, op_res);
50 PostExecAdvancePcAndIt::Call(ictx, iflags);
51 return Ok(kNoInstrExecFlags);
62 template <
typename TDest,
typename TArg0>
64 const TDest &rd,
const TArg0 &rn,
const u32 &imm) {
65 const auto n = ictx.cpua.ReadRegister(rn.Get());
66 const auto result = Alu32::AddWithCarry(n, ~imm,
true);
67 const auto op_res =
OpResult{result.value, result.carry_out, result.overflow};
69 PostExecWriteRegPcExcluded::Call(ictx, rd, op_res.value);
70 PostExecOptionalSetFlags::Call(ictx, iflags, op_res);
71 PostExecAdvancePcAndIt::Call(ictx, iflags);
72 return Ok(kNoInstrExecFlags);
83 template <
typename TDest,
typename TArg0>
85 const TDest &rd,
const TArg0 &rn,
const u32 &imm) {
86 const auto n = ictx.cpua.ReadRegister(rn.Get());
87 auto apsr = ictx.cpua.template ReadSpecialRegister<SpecialRegisterId::kApsr>();
89 Alu32::AddWithCarry(n, ~imm, (apsr & ApsrRegister::kCMsk) == ApsrRegister::kCMsk);
90 const auto op_res =
OpResult{result.value, result.carry_out, result.overflow};
92 PostExecWriteRegPcExcluded::Call(ictx, rd, op_res.value);
93 PostExecOptionalSetFlags::Call(ictx, iflags, op_res);
94 PostExecAdvancePcAndIt::Call(ictx, iflags);
95 return Ok(kNoInstrExecFlags);
106 template <
typename TDest,
typename TArg0>
108 const TDest &rd,
const TArg0 &rn,
const u32 &imm) {
109 const auto n = ictx.cpua.ReadRegister(rn.Get());
110 const auto result = Alu32::AddWithCarry(~n, imm,
true);
111 const auto op_res =
OpResult{result.value, result.carry_out, result.overflow};
112 PostExecWriteRegPcExcluded::Call(ictx, rd, op_res.value);
114 PostExecOptionalSetFlags::Call(ictx, iflags, op_res);
115 PostExecAdvancePcAndIt::Call(ictx, iflags);
116 return Ok(kNoInstrExecFlags);
120template <
typename TOp,
typename TInstrContext>
class BinaryInstrWithImm {
122 using It =
typename TInstrContext::It;
123 using Pc =
typename TInstrContext::Pc;
125 template <
typename TDest,
typename TArg0>
127 const TDest &rd,
const TArg0 &rn,
const u32 &imm) {
130 if (!condition_passed) {
131 PostExecAdvancePcAndIt::Call(ictx, iflags);
143 BinaryInstrWithImm() =
delete;
148 ~BinaryInstrWithImm() =
delete;
154 BinaryInstrWithImm(
const BinaryInstrWithImm &r_src) =
delete;
160 BinaryInstrWithImm &operator=(
const BinaryInstrWithImm &r_src) =
delete;
166 BinaryInstrWithImm(BinaryInstrWithImm &&r_src) =
delete;
172 BinaryInstrWithImm &operator=(BinaryInstrWithImm &&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