arch-arm: Add explicit AArch64 MiscReg banking
authorGiacomo Travaglini <giacomo.travaglini@arm.com>
Thu, 29 Aug 2019 08:26:35 +0000 (09:26 +0100)
committerGiacomo Travaglini <giacomo.travaglini@arm.com>
Fri, 6 Sep 2019 20:00:34 +0000 (20:00 +0000)
Change-Id: I89836d14491a51b1573f45c8012e3ad12b107d24
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/20623
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/arch/arm/isa.hh
src/arch/arm/isa/insts/data64.isa
src/arch/arm/miscregs.cc
src/arch/arm/miscregs.hh

index 5e337c2233f24769e34d5bbbe1810f75a0208b6b..ff889fa7de8ed892f4c3199ffecf77ed42d42811 100644 (file)
@@ -183,6 +183,10 @@ namespace ArmISA
                 info[MISCREG_BANKED] = v;
                 return *this;
             }
+            chain banked64(bool v = true) const {
+                info[MISCREG_BANKED64] = v;
+                return *this;
+            }
             chain bankedChild(bool v = true) const {
                 info[MISCREG_BANKED_CHILD] = v;
                 return *this;
@@ -642,11 +646,25 @@ namespace ArmISA
                                      inSecureState(miscRegs[MISCREG_SCR],
                                                    miscRegs[MISCREG_CPSR]);
                     flat_idx += secureReg ? 2 : 1;
+                } else {
+                    flat_idx = snsBankedIndex64((MiscRegIndex)reg,
+                        !inSecureState(miscRegs[MISCREG_SCR],
+                                       miscRegs[MISCREG_CPSR]));
                 }
             }
             return flat_idx;
         }
 
+        int
+        snsBankedIndex64(MiscRegIndex reg, bool ns) const
+        {
+            int reg_as_int = static_cast<int>(reg);
+            if (miscRegInfo[reg][MISCREG_BANKED64]) {
+                reg_as_int += (haveSecurity && !ns) ? 2 : 1;
+            }
+            return reg_as_int;
+        }
+
         std::pair<int,int> getMiscIndices(int misc_reg) const
         {
             // Note: indexes of AArch64 registers are left unchanged
index a2ffb9f5a1012ae0ab13ba114a6de545a9d42724..f5be4763ac33b86d36bc4c0a91dbbbaeb5418f3b 100644 (file)
@@ -331,16 +331,18 @@ let {{
     '''
 
     msr_check_code = '''
+        auto pre_flat = (MiscRegIndex)snsBankedIndex64(dest, xc->tcBase());
         MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()->
-            flattenRegId(RegId(MiscRegClass, dest)).index();
+            flattenRegId(RegId(MiscRegClass, pre_flat)).index();
         CPSR cpsr = Cpsr;
         ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
         %s
     ''' % (msrMrs64EnabledCheckCode % ('Write'),)
 
     mrs_check_code = '''
+        auto pre_flat = (MiscRegIndex)snsBankedIndex64(op1, xc->tcBase());
         MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()->
-            flattenRegId(RegId(MiscRegClass, op1)).index();
+            flattenRegId(RegId(MiscRegClass, pre_flat)).index();
         CPSR cpsr = Cpsr;
         ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
         %s
@@ -509,8 +511,10 @@ let {{
     def buildMsrImmInst(mnem, inst_name, code):
         global header_output, decoder_output, exec_output
         msrImmPermission = '''
-            auto misc_index = (MiscRegIndex) xc->tcBase()->flattenRegId(
-               RegId(MiscRegClass, dest)).index();
+            auto pre_flat =
+                (MiscRegIndex)snsBankedIndex64(dest, xc->tcBase());
+            MiscRegIndex misc_index = (MiscRegIndex) xc->tcBase()->
+                flattenRegId(RegId(MiscRegClass, pre_flat)).index();
 
             if (!miscRegInfo[misc_index][MISCREG_IMPLEMENTED]) {
                     return std::make_shared<UndefinedInstruction>(
index cad123fcce1b1b41a561a747b2cce115e548d368..0bae0189311d8d144010a53d4a69eeea0df66139 100644 (file)
@@ -1075,6 +1075,12 @@ snsBankedIndex(MiscRegIndex reg, ThreadContext *tc, bool ns)
     return reg_as_int;
 }
 
+int
+snsBankedIndex64(MiscRegIndex reg, ThreadContext *tc)
+{
+    SCR scr = tc->readMiscReg(MISCREG_SCR);
+    return tc->getIsaPtr()->snsBankedIndex64(reg, scr.ns);
+}
 
 /**
  * If the reg is a child reg of a banked set, then the parent is the last
index a95168bf37c2289998be6f79b19e9d5004de3a01..3ce371bfe531ecfcece30db789f8a070d52eebca 100644 (file)
@@ -949,6 +949,9 @@ namespace ArmISA
         MISCREG_BANKED,  // True if the register is banked between the two
                          // security states, and this is the parent node of the
                          // two banked registers
+        MISCREG_BANKED64, // True if the register is banked between the two
+                          // security states, and this is the parent node of
+                          // the two banked registers. Used in AA64 only.
         MISCREG_BANKED_CHILD, // The entry is one of the child registers that
                               // forms a banked set of regs (along with the
                               // other child regs)
@@ -1941,6 +1944,9 @@ namespace ArmISA
     int
     snsBankedIndex(MiscRegIndex reg, ThreadContext *tc, bool ns);
 
+    int
+    snsBankedIndex64(MiscRegIndex reg, ThreadContext *tc);
+
     // Takes a misc reg index and returns the root reg if its one of a set of
     // banked registers
     void