diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2009-11-14 19:22:29 -0800 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2009-11-14 19:22:29 -0800 |
commit | 50b9149c7572b4cff351f2c28726226030cefdbd (patch) | |
tree | 07a61f7ea7d8ebd9e7e8041db5025232a5bba052 /src/arch/arm/isa.hh | |
parent | 4e9ce1805e3bbc6a6085502e94e0298eada77113 (diff) | |
download | gem5-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.
Diffstat (limited to 'src/arch/arm/isa.hh')
-rw-r--r-- | src/arch/arm/isa.hh | 56 |
1 files changed, 52 insertions, 4 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 |