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 | |
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.
-rw-r--r-- | src/arch/arm/isa.hh | 56 | ||||
-rw-r--r-- | src/arch/arm/isa/operands.isa | 13 |
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) }}; |