18template <
typename TInstrContext>
class VariadicLoadInstr {
20 using It =
typename TInstrContext::It;
21 using Pc =
typename TInstrContext::Pc;
23 using ExcTrig =
typename TInstrContext::ExcTrig;
25 template <
typename TArg0>
27 const TArg0 &rn,
const u32 ®isters) {
30 if (!condition_passed) {
31 PostExecAdvancePcAndIt::Call(ictx, iflags);
35 const auto n = ictx.cpua.ReadRegister(rn.Get());
36 auto address =
static_cast<me_adr_t
>(n);
38 for (u32 rid = 0U; rid <= 14U; ++rid) {
39 const u32 bm = 0x1U << rid;
40 if ((registers & bm) != 0U) {
42 ictx.bus.template ReadOrRaise<u32>(ictx.cpua, address,
43 BusExceptionType::kRaisePreciseDataBusError));
44 ictx.cpua.WriteRegister(
static_cast<RegisterId>(rid), rdat);
45 address +=
static_cast<me_adr_t
>(4U);
51 ictx.bus.template ReadOrRaise<u32>(ictx.cpua, address,
52 BusExceptionType::kRaisePreciseDataBusError));
57 PostExecAdvancePcAndIt::Call(ictx, iflags);
64 const bool is_wback = (iflags &
static_cast<InstrFlagsSet
>(InstrFlags::kWBack)) != 0U;
65 const auto n_mask = 1U <<
static_cast<u32
>(rn.Get());
66 const bool is_rn_in_set = (registers & n_mask) != 0;
68 if ((is_wback) && (!is_rn_in_set)) {
70 const auto wback_val = n + 4U * regcount;
73 ictx.cpua.WriteRegister(rn.Get(), wback_val);
83 VariadicLoadInstr() =
delete;
88 ~VariadicLoadInstr() =
delete;
94 VariadicLoadInstr(
const VariadicLoadInstr &r_src) =
delete;
100 VariadicLoadInstr &operator=(
const VariadicLoadInstr &r_src) =
delete;
106 VariadicLoadInstr(VariadicLoadInstr &&r_src) =
delete;
112 VariadicLoadInstr &operator=(VariadicLoadInstr &&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