summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2009-11-14 19:22:29 -0800
committerGabe Black <gblack@eecs.umich.edu>2009-11-14 19:22:29 -0800
commit50b9149c7572b4cff351f2c28726226030cefdbd (patch)
tree07a61f7ea7d8ebd9e7e8041db5025232a5bba052
parent4e9ce1805e3bbc6a6085502e94e0298eada77113 (diff)
downloadgem5-50b9149c7572b4cff351f2c28726226030cefdbd.tar.xz
ARM: Hook up the moded versions of the SPSR.
These registers can be accessed directly, or through MISCREG_SPSR which will act as whichever SPSR is appropriate for the current mode.
-rw-r--r--src/arch/arm/isa.hh56
-rw-r--r--src/arch/arm/isa/operands.isa13
2 files changed, 59 insertions, 10 deletions
diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh
index a270f046b..905eb0183 100644
--- a/src/arch/arm/isa.hh
+++ b/src/arch/arm/isa.hh
@@ -100,20 +100,69 @@ namespace ArmISA
readMiscRegNoEffect(int misc_reg)
{
assert(misc_reg < NumMiscRegs);
+ if (misc_reg == MISCREG_SPSR) {
+ CPSR cpsr = miscRegs[MISCREG_CPSR];
+ switch (cpsr.mode) {
+ case MODE_USER:
+ return miscRegs[MISCREG_SPSR];
+ case MODE_FIQ:
+ return miscRegs[MISCREG_SPSR_FIQ];
+ case MODE_IRQ:
+ return miscRegs[MISCREG_SPSR_IRQ];
+ case MODE_SVC:
+ return miscRegs[MISCREG_SPSR_SVC];
+ case MODE_MON:
+ return miscRegs[MISCREG_SPSR_MON];
+ case MODE_ABORT:
+ return miscRegs[MISCREG_SPSR_ABT];
+ case MODE_UNDEFINED:
+ return miscRegs[MISCREG_SPSR_UND];
+ default:
+ return miscRegs[MISCREG_SPSR];
+ }
+ }
return miscRegs[misc_reg];
}
MiscReg
readMiscReg(int misc_reg, ThreadContext *tc)
{
- assert(misc_reg < NumMiscRegs);
- return miscRegs[misc_reg];
+ return readMiscRegNoEffect(misc_reg);
}
void
setMiscRegNoEffect(int misc_reg, const MiscReg &val)
{
assert(misc_reg < NumMiscRegs);
+ if (misc_reg == MISCREG_SPSR) {
+ CPSR cpsr = miscRegs[MISCREG_CPSR];
+ switch (cpsr.mode) {
+ case MODE_USER:
+ miscRegs[MISCREG_SPSR] = val;
+ return;
+ case MODE_FIQ:
+ miscRegs[MISCREG_SPSR_FIQ] = val;
+ return;
+ case MODE_IRQ:
+ miscRegs[MISCREG_SPSR_IRQ] = val;
+ return;
+ case MODE_SVC:
+ miscRegs[MISCREG_SPSR_SVC] = val;
+ return;
+ case MODE_MON:
+ miscRegs[MISCREG_SPSR_MON] = val;
+ return;
+ case MODE_ABORT:
+ miscRegs[MISCREG_SPSR_ABT] = val;
+ return;
+ case MODE_UNDEFINED:
+ miscRegs[MISCREG_SPSR_UND] = val;
+ return;
+ default:
+ miscRegs[MISCREG_SPSR] = val;
+ return;
+ }
+ }
miscRegs[misc_reg] = val;
}
@@ -123,8 +172,7 @@ namespace ArmISA
if (misc_reg == MISCREG_CPSR) {
updateRegMap(val);
}
- assert(misc_reg < NumMiscRegs);
- miscRegs[misc_reg] = val;
+ return setMiscRegNoEffect(misc_reg, val);
}
int
diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa
index 5ae0b8912..fe085cdac 100644
--- a/src/arch/arm/isa/operands.isa
+++ b/src/arch/arm/isa/operands.isa
@@ -82,11 +82,12 @@ def operands {{
'Mem': ('Mem', 'uw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 30),
'Cpsr': ('ControlReg', 'uw', 'MISCREG_CPSR', 'IsInteger', 40),
- 'Fpsr': ('ControlReg', 'uw', 'MISCREG_FPSR', 'IsInteger', 41),
- 'Fpsid': ('ControlReg', 'uw', 'MISCREG_FPSID', 'IsInteger', 42),
- 'Fpscr': ('ControlReg', 'uw', 'MISCREG_FPSCR', 'IsInteger', 43),
- 'Fpexc': ('ControlReg', 'uw', 'MISCREG_FPEXC', 'IsInteger', 44),
- 'NPC': ('NPC', 'uw', None, (None, None, 'IsControl'), 45),
- 'NNPC': ('NNPC', 'uw', None, (None, None, 'IsControl'), 46)
+ 'Spsr': ('ControlReg', 'uw', 'MISCREG_SPSR', 'IsInteger', 41),
+ 'Fpsr': ('ControlReg', 'uw', 'MISCREG_FPSR', 'IsInteger', 42),
+ 'Fpsid': ('ControlReg', 'uw', 'MISCREG_FPSID', 'IsInteger', 43),
+ 'Fpscr': ('ControlReg', 'uw', 'MISCREG_FPSCR', 'IsInteger', 44),
+ 'Fpexc': ('ControlReg', 'uw', 'MISCREG_FPEXC', 'IsInteger', 45),
+ 'NPC': ('NPC', 'uw', None, (None, None, 'IsControl'), 50),
+ 'NNPC': ('NNPC', 'uw', None, (None, None, 'IsControl'), 51)
}};