diff options
Diffstat (limited to 'src/arch/arm/isa')
-rw-r--r-- | src/arch/arm/isa/formats/mem.isa | 7 | ||||
-rw-r--r-- | src/arch/arm/isa/formats/uncond.isa | 7 | ||||
-rw-r--r-- | src/arch/arm/isa/insts/str.isa | 6 |
3 files changed, 18 insertions, 2 deletions
diff --git a/src/arch/arm/isa/formats/mem.isa b/src/arch/arm/isa/formats/mem.isa index 1a30fbb9d..50e3e358f 100644 --- a/src/arch/arm/isa/formats/mem.isa +++ b/src/arch/arm/isa/formats/mem.isa @@ -282,7 +282,12 @@ def format Thumb32SrsRfe() {{ } } else { const uint32_t mode = bits(machInst, 4, 0); - if (badMode32((OperatingMode)mode)) + // We check at decode stage if the mode exists even + // if the checking is re-done by Srs::execute. + // This is done because we will otherwise panic if + // trying to read the banked stack pointer of an + // unrecognized mode. + if (unknownMode32((OperatingMode)mode)) return new Unknown(machInst); if (!add && !wb) { return new %(srs)s(machInst, mode, diff --git a/src/arch/arm/isa/formats/uncond.isa b/src/arch/arm/isa/formats/uncond.isa index c376cd9ce..e0b07ab5a 100644 --- a/src/arch/arm/isa/formats/uncond.isa +++ b/src/arch/arm/isa/formats/uncond.isa @@ -166,7 +166,12 @@ def format ArmUnconditional() {{ const uint32_t val = ((machInst >> 20) & 0x5); if (val == 0x4) { const uint32_t mode = bits(machInst, 4, 0); - if (badMode32((OperatingMode)mode)) + // We check at decode stage if the mode exists even + // if the checking is re-done by Srs::execute. + // This is done because we will otherwise panic if + // trying to read the banked stack pointer of an + // unrecognized mode. + if (unknownMode32((OperatingMode)mode)) return new Unknown(machInst); switch (bits(machInst, 24, 21)) { case 0x2: diff --git a/src/arch/arm/isa/insts/str.isa b/src/arch/arm/isa/insts/str.isa index 1c697d3ff..c165eaf1a 100644 --- a/src/arch/arm/isa/insts/str.isa +++ b/src/arch/arm/isa/insts/str.isa @@ -112,6 +112,12 @@ let {{ if self.add: wbDiff = 8 accCode = ''' + + auto tc = xc->tcBase(); + if (badMode32(tc, static_cast<OperatingMode>(regMode))) { + return undefinedFault32(tc, opModeToEL(currOpMode(tc))); + } + CPSR cpsr = Cpsr; Mem_ud = (uint64_t)cSwap(LR_uw, cpsr.e) | ((uint64_t)cSwap(Spsr_uw, cpsr.e) << 32); |