15template <
typename TCpuStates,
typename TSpecRegOps,
typename TLogger = NullLogger>
class RegOps {
17 using SReg = TSpecRegOps;
19 static std::string_view GetRegisterName(
const RegisterId &
id) {
20 using enum_type = std::underlying_type<RegisterId>::type;
21 const enum_type raw_id =
static_cast<enum_type
>(id);
63 auto sys_ctrl = TSpecRegOps::template ReadRegister<SpecialRegisterId::kSysCtrl>(cpus);
64 auto spsel = sys_ctrl & SysCtrlRegister::kControlSpSelMsk;
68 const auto exec_mode = sys_ctrl & SysCtrlRegister::kExecModeMsk;
71 if (exec_mode == SysCtrlRegister::kExecModeThread) {
78 assert(
false &&
"LookUpSp UNPREDICTABLE");
85 static inline u32 ReadSP(
const TCpuStates &cpus) {
89 const auto sp_reg = LookUpSP(cpus);
90 const auto sp = SReg::ReadRegister(cpus, sp_reg);
94 static inline void WriteSP(TCpuStates &cpus,
const u32 &value) {
95 const auto sp_reg = LookUpSP(cpus);
96 SReg::WriteRegister(cpus, sp_reg, value);
99 static inline me_adr_t ReadPC(
const TCpuStates &cpus) {
101 const auto ®isters = cpus.GetRegisters();
103 static_cast<me_adr_t
>(std::get<static_cast<u8>(
RegisterId::kPc)>(registers));
107 template <RegisterId Id>
static inline u32 ReadRegister(
const TCpuStates &cpus) {
108 static_assert(
static_cast<u8
>(Id) <
CountRegisters(),
"Invalid register id");
110 using enum_type = std::underlying_type<RegisterId>::type;
119 const auto ®isters = cpus.GetRegisters();
120 return registers[
static_cast<enum_type
>(Id)];
126 static inline u32 ReadRegister(
const TCpuStates &cpus,
RegisterId id) {
127 using enum_type = std::underlying_type<RegisterId>::type;
128 assert(
static_cast<enum_type
>(
id) <
CountRegisters() &&
"Invalid register id");
136 const auto ®isters = cpus.GetRegisters();
137 return registers[
static_cast<enum_type
>(id)];
144 template <RegisterId Id>
static inline void WriteRegister(TCpuStates &cpus,
const u32 &value) {
145 static_assert(
static_cast<u8
>(Id) <
CountRegisters(),
"Invalid register id");
146 static_assert(Id !=
RegisterId::kPc,
"PC is not assignable by this function");
148 using enum_type = std::underlying_type<RegisterId>::type;
152 return WriteSP(cpus, value);
155 auto ®isters = cpus.GetRegisters();
156 registers[
static_cast<enum_type
>(Id)] = value;
161 static inline void WriteRegister(TCpuStates &cpus,
RegisterId id, u32 value) {
162 using enum_type = std::underlying_type<RegisterId>::type;
164 assert(
static_cast<enum_type
>(
id) <
CountRegisters() &&
"Invalid register id");
168 return WriteSP(cpus, value);
170 assert(
false &&
"PC is not assignable by this function");
174 auto ®isters = cpus.GetRegisters();
175 registers[
static_cast<enum_type
>(id)] = value;
183 RegOps &operator=(
const RegOps &r_src) =
delete;
184 RegOps(RegOps &&r_src) =
delete;
185 RegOps &operator=(RegOps &&r_src) =
delete;
186 RegOps(
const RegOps &r_src) =
delete;