arch-arm: Rewrite MSR immediate instruction class
MSR <pstatefield>, #imm is used for setting a PSTATE field using an immediate. Current implementation has the following flaws: * There is no base MSR immediate definition: all the existing PSTATE fields have a different class definition * Those implementation make use of a generic data64 base class which results in a wrong disassembly (pstate register is printed as an integer register). This patch is fixing this by defining a new base class (MiscRegImmOp64) and new related templates. In this way, we aim to ease addition of new PSTATE fields (in ARMv8.x) Change-Id: I71b630ff32abe1b105bbb3ab5781c6589b67d419 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/+/19728 Maintainer: Andreas Sandberg <andreas.sandberg@arm.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -35,6 +35,7 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Gabe Black
|
||||
* Giacomo Travaglini
|
||||
*/
|
||||
|
||||
#include "arch/arm/insts/misc64.hh"
|
||||
@@ -321,6 +322,27 @@ MiscRegOp64::checkEL3Trap(ThreadContext *tc, const MiscRegIndex misc_reg,
|
||||
return trap_to_mon;
|
||||
}
|
||||
|
||||
RegVal
|
||||
MiscRegImmOp64::miscRegImm() const
|
||||
{
|
||||
if (dest == MISCREG_SPSEL) {
|
||||
return imm & 0x1;
|
||||
} else {
|
||||
panic("Not a valid PSTATE field register\n");
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
MiscRegImmOp64::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
printMnemonic(ss);
|
||||
printMiscReg(ss, dest);
|
||||
ss << ", ";
|
||||
ccprintf(ss, "#0x%x", imm);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string
|
||||
MiscRegRegImmOp64::generateDisassembly(
|
||||
Addr pc, const SymbolTable *symtab) const
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2013,2017-2018 ARM Limited
|
||||
* Copyright (c) 2011-2013,2017-2019 ARM Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
@@ -35,6 +35,7 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Gabe Black
|
||||
* Giacomo Travaglini
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ARM_INSTS_MISC64_HH__
|
||||
@@ -142,6 +143,30 @@ class MiscRegOp64 : public ArmStaticInst
|
||||
|
||||
};
|
||||
|
||||
class MiscRegImmOp64 : public MiscRegOp64
|
||||
{
|
||||
protected:
|
||||
MiscRegIndex dest;
|
||||
uint32_t imm;
|
||||
|
||||
MiscRegImmOp64(const char *mnem, ExtMachInst _machInst,
|
||||
OpClass __opClass, MiscRegIndex _dest,
|
||||
uint32_t _imm) :
|
||||
MiscRegOp64(mnem, _machInst, __opClass, false),
|
||||
dest(_dest), imm(_imm)
|
||||
{}
|
||||
|
||||
/** Returns the "register view" of the immediate field.
|
||||
* as if it was a MSR PSTATE REG instruction.
|
||||
* This means basically shifting and masking depending on
|
||||
* which PSTATE field is being set/cleared.
|
||||
*/
|
||||
RegVal miscRegImm() const;
|
||||
|
||||
std::string generateDisassembly(
|
||||
Addr pc, const SymbolTable *symtab) const override;
|
||||
};
|
||||
|
||||
class MiscRegRegImmOp64 : public MiscRegOp64
|
||||
{
|
||||
protected:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2011-2018 ARM Limited
|
||||
// Copyright (c) 2011-2019 ARM Limited
|
||||
// All rights reserved
|
||||
//
|
||||
// The license below extends only to copyright in the software and shall
|
||||
@@ -389,28 +389,21 @@ namespace Aarch64
|
||||
return new Unknown64(machInst);
|
||||
}
|
||||
} else if (crn == 0x4) {
|
||||
// MSR immediate
|
||||
// MSR immediate: moving immediate value to selected
|
||||
// bits of the PSTATE
|
||||
switch (op1 << 3 | op2) {
|
||||
case 0x5:
|
||||
// SP
|
||||
return new MsrSP64(machInst,
|
||||
(IntRegIndex) MISCREG_SPSEL,
|
||||
INTREG_ZERO,
|
||||
crm & 0x1);
|
||||
return new MsrImm64(
|
||||
machInst, MISCREG_SPSEL, crm);
|
||||
case 0x1e:
|
||||
// DAIFSet
|
||||
return new MsrDAIFSet64(
|
||||
machInst,
|
||||
(IntRegIndex) MISCREG_DAIF,
|
||||
INTREG_ZERO,
|
||||
crm);
|
||||
return new MsrImmDAIFSet64(
|
||||
machInst, MISCREG_DAIF, crm);
|
||||
case 0x1f:
|
||||
// DAIFClr
|
||||
return new MsrDAIFClr64(
|
||||
machInst,
|
||||
(IntRegIndex) MISCREG_DAIF,
|
||||
INTREG_ZERO,
|
||||
crm);
|
||||
return new MsrImmDAIFClr64(
|
||||
machInst, MISCREG_DAIF, crm);
|
||||
default:
|
||||
return new Unknown64(machInst);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// -*- mode:c++ -*-
|
||||
|
||||
// Copyright (c) 2011-2013, 2016-2018 ARM Limited
|
||||
// Copyright (c) 2011-2013, 2016-2019 ARM Limited
|
||||
// All rights reserved
|
||||
//
|
||||
// The license below extends only to copyright in the software and shall
|
||||
@@ -509,45 +509,43 @@ let {{
|
||||
exec_output += DCStore64InitiateAcc.subst(msrDCIVACIop);
|
||||
exec_output += Store64CompleteAcc.subst(msrDCIVACIop);
|
||||
|
||||
def buildMsrImmInst(mnem, inst_name, code):
|
||||
global header_output, decoder_output, exec_output
|
||||
msrImmPermission = '''
|
||||
if (!canWriteAArch64SysReg(
|
||||
(MiscRegIndex) xc->tcBase()->flattenRegId(
|
||||
RegId(MiscRegClass, dest)).index(),
|
||||
Scr64, Cpsr, xc->tcBase())) {
|
||||
return std::make_shared<UndefinedInstruction>(
|
||||
machInst, 0, EC_TRAPPED_MSR_MRS_64,
|
||||
mnemonic);
|
||||
}
|
||||
|
||||
buildDataXImmInst("msrSP", '''
|
||||
if (!canWriteAArch64SysReg(
|
||||
(MiscRegIndex) xc->tcBase()->flattenRegId(
|
||||
RegId(MiscRegClass, dest)).index(),
|
||||
Scr64, Cpsr, xc->tcBase())) {
|
||||
return std::make_shared<UndefinedInstruction>(machInst, false,
|
||||
mnemonic);
|
||||
}
|
||||
MiscDest_ud = imm;
|
||||
''', optArgs = ["IsSerializeAfter", "IsNonSpeculative"])
|
||||
'''
|
||||
msrIop = InstObjParams("msr", inst_name, "MiscRegImmOp64",
|
||||
msrImmPermission + code,
|
||||
["IsSerializeAfter", "IsNonSpeculative"])
|
||||
header_output += MiscRegOp64Declare.subst(msrIop)
|
||||
decoder_output += MiscRegOp64Constructor.subst(msrIop)
|
||||
exec_output += BasicExecute.subst(msrIop)
|
||||
|
||||
buildDataXImmInst("msrDAIFSet", '''
|
||||
if (!canWriteAArch64SysReg(
|
||||
(MiscRegIndex) xc->tcBase()->flattenRegId(
|
||||
RegId(MiscRegClass, dest)).index(),
|
||||
Scr64, Cpsr, xc->tcBase())) {
|
||||
return std::make_shared<UndefinedInstruction>(
|
||||
machInst, 0, EC_TRAPPED_MSR_MRS_64,
|
||||
mnemonic);
|
||||
}
|
||||
buildMsrImmInst("msr", "MsrImm64", '''
|
||||
// Mask and shift immediate (depending on PSTATE field)
|
||||
// before assignment
|
||||
MiscDest_ud = miscRegImm();
|
||||
''')
|
||||
|
||||
buildMsrImmInst("msr", "MsrImmDAIFSet64", '''
|
||||
CPSR cpsr = Cpsr;
|
||||
cpsr.daif = cpsr.daif | imm;
|
||||
Cpsr = cpsr;
|
||||
''', optArgs = ["IsSerializeAfter", "IsNonSpeculative"])
|
||||
''')
|
||||
|
||||
buildDataXImmInst("msrDAIFClr", '''
|
||||
if (!canWriteAArch64SysReg(
|
||||
(MiscRegIndex) xc->tcBase()->flattenRegId(
|
||||
RegId(MiscRegClass, dest)).index(),
|
||||
Scr64, Cpsr, xc->tcBase())) {
|
||||
return std::make_shared<UndefinedInstruction>(
|
||||
machInst, 0, EC_TRAPPED_MSR_MRS_64,
|
||||
mnemonic);
|
||||
}
|
||||
buildMsrImmInst("msr", "MsrImmDAIFClr64", '''
|
||||
CPSR cpsr = Cpsr;
|
||||
cpsr.daif = cpsr.daif & ~imm;
|
||||
Cpsr = cpsr;
|
||||
''', optArgs = ["IsSerializeAfter", "IsNonSpeculative"])
|
||||
''')
|
||||
|
||||
def buildDataXCompInst(mnem, instType, suffix, code):
|
||||
global header_output, decoder_output, exec_output
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// -*- mode:c++ -*-
|
||||
|
||||
// Copyright (c) 2011,2017-2018 ARM Limited
|
||||
// Copyright (c) 2011,2017-2019 ARM Limited
|
||||
// All rights reserved
|
||||
//
|
||||
// The license below extends only to copyright in the software and shall
|
||||
@@ -109,6 +109,29 @@ def template RegRegRegImmOp64Constructor {{
|
||||
}
|
||||
}};
|
||||
|
||||
def template MiscRegOp64Declare {{
|
||||
class %(class_name)s : public %(base_class)s
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
%(class_name)s(ExtMachInst machInst, MiscRegIndex _dest,
|
||||
uint64_t _imm);
|
||||
|
||||
Fault execute(ExecContext *, Trace::InstRecord *) const override;
|
||||
};
|
||||
}};
|
||||
|
||||
def template MiscRegOp64Constructor {{
|
||||
%(class_name)s::%(class_name)s(ExtMachInst machInst,
|
||||
MiscRegIndex _dest,
|
||||
uint64_t _imm)
|
||||
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
|
||||
_dest, _imm)
|
||||
{
|
||||
%(constructor)s;
|
||||
}
|
||||
}};
|
||||
|
||||
def template MiscRegRegOp64Declare {{
|
||||
class %(class_name)s : public %(base_class)s
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user