arch-arm: ERET from AArch64 to AArch32 ignore MSBs
authorGiacomo Travaglini <giacomo.travaglini@arm.com>
Fri, 9 Feb 2018 11:31:05 +0000 (11:31 +0000)
committerGiacomo Travaglini <giacomo.travaglini@arm.com>
Wed, 14 Mar 2018 10:33:48 +0000 (10:33 +0000)
The 32 most significant bits of ELR_ELx must be ignored when returning
from AArch64 to AArch32.

Change-Id: I412d72908997916404e16e9eeca2789a9c529e58
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/8881
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>

src/arch/arm/isa/insts/branch64.isa

index 64457b8c0a74d67c5ee373ca5ec9001300533758..8ef9f934e437e382f0936209ce5e7cf4b1c04d36 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode:c++ -*-
 
-// Copyright (c) 2011-2013, 2016 ARM Limited
+// Copyright (c) 2011-2013, 2016,2018 ARM Limited
 // All rights reserved
 //
 // The license below extends only to copyright in the software and shall
@@ -120,12 +120,19 @@ let {{
                                                                   mnemonic);
                     break;
                 }
-                if (spsr.width && (newPc & mask(2))) {
-                    // To avoid PC Alignment fault when returning to AArch32
-                    if (spsr.t)
-                        newPc = newPc & ~mask(1);
-                    else
-                        newPc = newPc & ~mask(2);
+                if (spsr.width) {
+                    // Exception return to AArch32.
+                    // 32 most significant bits are ignored
+                    newPc &= mask(32);
+
+                    if (newPc & mask(2)) {
+                        // Mask bits to avoid PC Alignment fault when returning
+                        // to AArch32
+                        if (spsr.t)
+                            newPc = newPc & ~mask(1);
+                        else
+                            newPc = newPc & ~mask(2);
+                    }
                 }
 
                 CPSR new_cpsr = getPSTATEFromPSR(xc->tcBase(), cpsr, spsr);