Files
matar/src/cpu/cpu.cc
2023-08-27 21:40:55 +05:30

105 lines
2.5 KiB
C++

#include "cpu.hh"
#include "cpu/utility.hh"
#include <algorithm>
#include <cstdio>
/* change modes */
void
Cpu::chg_mode(Mode from, Mode to) {
if (from == to)
return;
/* TODO: replace visible registers with view once I understand how to
* concatenate views */
#define STORE_BANKED(mode, MODE) \
std::copy(gpr + GPR_##MODE##_BANKED_FIRST, \
gpr + GPR_##MODE##_BANKED_FIRST + GPR_##MODE##_BANKED_COUNT, \
gpr_banked.mode)
switch (from) {
case Mode::Fiq:
STORE_BANKED(fiq, FIQ);
spsr_banked.fiq = spsr;
break;
case Mode::Supervisor:
STORE_BANKED(svc, SVC);
spsr_banked.svc = spsr;
break;
case Mode::Abort:
STORE_BANKED(abt, ABT);
spsr_banked.abt = spsr;
break;
case Mode::Irq:
STORE_BANKED(irq, IRQ);
spsr_banked.irq = spsr;
break;
case Mode::Undefined:
STORE_BANKED(und, UND);
spsr_banked.und = spsr;
break;
case Mode::User:
case Mode::System:
STORE_BANKED(old, SYS_USR);
break;
}
#define RESTORE_BANKED(mode, MODE) \
std::copy(gpr_banked.mode, \
gpr_banked.mode + GPR_##MODE##_BANKED_COUNT, \
gpr + GPR_##MODE##_BANKED_FIRST)
switch (to) {
case Mode::Fiq:
RESTORE_BANKED(fiq, FIQ);
spsr = spsr_banked.fiq;
break;
case Mode::Supervisor:
RESTORE_BANKED(svc, SVC);
spsr = spsr_banked.svc;
break;
case Mode::Abort:
RESTORE_BANKED(abt, ABT);
spsr = spsr_banked.abt;
break;
case Mode::Irq:
RESTORE_BANKED(irq, IRQ);
spsr = spsr_banked.irq;
break;
case Mode::Undefined:
RESTORE_BANKED(und, UND);
spsr = spsr_banked.und;
break;
case Mode::User:
case Mode::System:
STORE_BANKED(old, SYS_USR);
break;
}
#undef RESTORE_BANKED
cpsr.set_mode(to);
}
// set register
inline uint32_t&
Cpu::operator[](size_t idx) {
// avoid unneeded complexity like index checks
return gpr[idx];
}
// get register
inline const uint32_t&
Cpu::operator[](size_t idx) const {
return gpr[idx];
}