15template <
typename TStoreOp,
typename TInstrContext>
class TernaryStoreInstrWithShift {
17 using It =
typename TInstrContext::It;
18 using Pc =
typename TInstrContext::Pc;
20 template <
typename TTgt,
typename TArg0,
typename TArg1>
22 const TTgt &rt,
const TArg0 &rn,
const TArg1 &rm,
24 const bool is_index = (iflags &
static_cast<InstrFlagsSet
>(InstrFlags::kIndex)) != 0U;
25 const bool is_add = (iflags &
static_cast<InstrFlagsSet
>(InstrFlags::kAdd)) != 0U;
28 if (!condition_passed) {
29 PostExecAdvancePcAndIt::Call(ictx, iflags);
33 InstrExecFlagsSet eflags{kNoInstrExecFlags};
34 const auto n = ictx.cpua.ReadRegister(rn.Get());
35 const auto m = ictx.cpua.ReadRegister(rm.Get());
37 auto apsr = ictx.cpua.template ReadSpecialRegister<SpecialRegisterId::kApsr>();
39 auto offset = Alu32::Shift(m, shift_res.type, shift_res.value,
40 (apsr & ApsrRegister::kCMsk) == ApsrRegister::kCMsk);
42 assert(is_add ==
true);
43 const u32 offset_addr = is_add ==
true ? n + offset : n - offset;
44 const u32 address = is_index ==
true ? offset_addr : n;
46 const auto t = ictx.cpua.ReadRegister(rt.Get());
49 const bool is_wback = (iflags &
static_cast<InstrFlagsSet
>(InstrFlags::kWBack)) != 0U;
51 PostExecWriteRegPcExcluded::Call(ictx, rn, offset_addr);
53 PostExecAdvancePcAndIt::Call(ictx, iflags);
61 TernaryStoreInstrWithShift() =
delete;
66 ~TernaryStoreInstrWithShift() =
delete;
72 TernaryStoreInstrWithShift(
const TernaryStoreInstrWithShift &r_src) =
delete;
78 TernaryStoreInstrWithShift &operator=(
const TernaryStoreInstrWithShift &r_src) =
delete;
84 TernaryStoreInstrWithShift(TernaryStoreInstrWithShift &&r_src) =
delete;
90 TernaryStoreInstrWithShift &operator=(TernaryStoreInstrWithShift &&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
#define TRY(OUT_TYPE, CALL)
Try to call a function and return an error if the call fails.
Definition result.h:138