18template <
typename TInstrContext>
class Clz1Op {
20 template <
typename TDest,
typename TArg1>
22 const TDest &rd,
const TArg1 &rm) {
23 using It =
typename TInstrContext::It;
24 using Pc =
typename TInstrContext::Pc;
26 const auto m = ictx.cpua.ReadRegister(rm.Get());
27 const u32 result = Bm32::CountLeadingZeros(m);
28 const auto op_res =
OpResult{result,
false,
false};
31 Pc::ALUWritePC(ictx.cpua, op_res.value);
32 It::ITAdvance(ictx.cpua);
33 return Ok(kNoInstrExecFlags);
35 PostExecWriteRegPcExcluded::Call(ictx, rd, op_res.value);
38 PostExecOptionalSetFlags::Call(ictx, iflags, op_res);
39 PostExecAdvancePcAndIt::Call(ictx, iflags);
40 return Ok(kNoInstrExecFlags);
49template <
typename TInstrContext>
class Mov1Op {
51 template <
typename TDest,
typename TArg1>
53 const TDest &rd,
const TArg1 &rm) {
54 using It =
typename TInstrContext::It;
55 using Pc =
typename TInstrContext::Pc;
57 auto apsr = ictx.cpua.template ReadSpecialRegister<SpecialRegisterId::kApsr>();
58 const auto m = ictx.cpua.ReadRegister(rm.Get());
59 const auto op_res =
OpResult{m, (apsr & ApsrRegister::kCMsk) == ApsrRegister::kCMsk,
60 (apsr & ApsrRegister::kVMsk) == ApsrRegister::kVMsk};
63 Pc::ALUWritePC(ictx.cpua, op_res.value);
64 It::ITAdvance(ictx.cpua);
65 return Ok(kNoInstrExecFlags);
67 PostExecWriteRegPcExcluded::Call(ictx, rd, op_res.value);
69 PostExecOptionalSetFlags::Call(ictx, iflags, op_res);
70 PostExecAdvancePcAndIt::Call(ictx, iflags);
71 return Ok(kNoInstrExecFlags);
80template <
typename TInstrContext>
class Rrx1Op {
82 template <
typename TDest,
typename TArg1>
84 const TDest &rd,
const TArg1 &rm) {
85 using It =
typename TInstrContext::It;
86 using Pc =
typename TInstrContext::Pc;
88 auto apsr = ictx.cpua.template ReadSpecialRegister<SpecialRegisterId::kApsr>();
89 const auto m = ictx.cpua.ReadRegister(rm.Get());
90 auto r_rrx = Alu32::Shift_C(m, SRType::SRType_RRX, 1U,
91 (apsr & ApsrRegister::kCMsk) == ApsrRegister::kCMsk);
93 const auto op_res =
OpResult{r_rrx.result, r_rrx.carry_out,
94 (apsr & ApsrRegister::kVMsk) == ApsrRegister::kVMsk};
97 Pc::ALUWritePC(ictx.cpua, op_res.value);
98 It::ITAdvance(ictx.cpua);
99 return Ok(kNoInstrExecFlags);
101 PostExecWriteRegPcExcluded::Call(ictx, rd, op_res.value);
103 PostExecOptionalSetFlags::Call(ictx, iflags, op_res);
104 PostExecAdvancePcAndIt::Call(ictx, iflags);
105 return Ok(kNoInstrExecFlags);
109template <
typename TOp,
typename TInstrContext>
class UnaryInstr {
111 using It =
typename TInstrContext::It;
112 using Pc =
typename TInstrContext::Pc;
114 template <
typename TDest,
typename TArg1>
116 const TDest &rd,
const TArg1 &rm) {
118 if (!condition_passed) {
119 PostExecAdvancePcAndIt::Call(ictx, iflags);
131 UnaryInstr() =
delete;
136 ~UnaryInstr() =
delete;
142 UnaryInstr(
const UnaryInstr &r_src) =
delete;
148 UnaryInstr &operator=(
const UnaryInstr &r_src) =
delete;
154 UnaryInstr(UnaryInstr &&r_src) =
delete;
160 UnaryInstr &operator=(UnaryInstr &&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