summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/arm/isa.hh18
-rw-r--r--src/arch/arm/isa/insts/data64.isa12
-rw-r--r--src/arch/arm/miscregs.cc6
-rw-r--r--src/arch/arm/miscregs.hh6
4 files changed, 38 insertions, 4 deletions
diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh
index 5e337c223..ff889fa7d 100644
--- a/src/arch/arm/isa.hh
+++ b/src/arch/arm/isa.hh
@@ -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
diff --git a/src/arch/arm/isa/insts/data64.isa b/src/arch/arm/isa/insts/data64.isa
index a2ffb9f5a..f5be4763a 100644
--- a/src/arch/arm/isa/insts/data64.isa
+++ b/src/arch/arm/isa/insts/data64.isa
@@ -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>(
diff --git a/src/arch/arm/miscregs.cc b/src/arch/arm/miscregs.cc
index cad123fcc..0bae01893 100644
--- a/src/arch/arm/miscregs.cc
+++ b/src/arch/arm/miscregs.cc
@@ -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
diff --git a/src/arch/arm/miscregs.hh b/src/arch/arm/miscregs.hh
index a95168bf3..3ce371bfe 100644
--- a/src/arch/arm/miscregs.hh
+++ b/src/arch/arm/miscregs.hh
@@ -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