summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/arm/insts/static_inst.cc10
-rw-r--r--src/arch/arm/isa.cc2
2 files changed, 11 insertions, 1 deletions
diff --git a/src/arch/arm/insts/static_inst.cc b/src/arch/arm/insts/static_inst.cc
index aace1de2b..a7ba91e03 100644
--- a/src/arch/arm/insts/static_inst.cc
+++ b/src/arch/arm/insts/static_inst.cc
@@ -1018,7 +1018,17 @@ ArmStaticInst::getPSTATEFromPSR(ThreadContext *tc, CPSR cpsr, CPSR spsr) const
new_cpsr.ss = 0;
if (illegalExceptionReturn(tc, cpsr, spsr)) {
+ // If the SPSR specifies an illegal exception return,
+ // then PSTATE.{M, nRW, EL, SP} are unchanged and PSTATE.IL
+ // is set to 1.
new_cpsr.il = 1;
+ if (cpsr.width) {
+ new_cpsr.mode = cpsr.mode;
+ } else {
+ new_cpsr.width = cpsr.width;
+ new_cpsr.el = cpsr.el;
+ new_cpsr.sp = cpsr.sp;
+ }
} else {
new_cpsr.il = spsr.il;
if (spsr.width && badMode32((OperatingMode)(uint8_t)spsr.mode)) {
diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc
index c917abacf..5d34e188a 100644
--- a/src/arch/arm/isa.cc
+++ b/src/arch/arm/isa.cc
@@ -726,7 +726,7 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
CPSR old_cpsr = miscRegs[MISCREG_CPSR];
int old_mode = old_cpsr.mode;
CPSR cpsr = val;
- if (old_mode != cpsr.mode) {
+ if (old_mode != cpsr.mode || cpsr.il != old_cpsr.il) {
getITBPtr(tc)->invalidateMiscReg();
getDTBPtr(tc)->invalidateMiscReg();
}