From fd1a8bed393a2ef48d584fcabeee4d98eda0e3fa Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Tue, 30 Jul 2019 11:34:44 +0100 Subject: arch-arm: Rewrite MSR immediate instruction class MSR , #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 Reviewed-by: Andreas Sandberg Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/19728 Maintainer: Andreas Sandberg Tested-by: kokoro --- src/arch/arm/insts/misc64.cc | 22 ++++++++++++ src/arch/arm/insts/misc64.hh | 27 ++++++++++++++- src/arch/arm/isa/formats/aarch64.isa | 25 +++++--------- src/arch/arm/isa/insts/data64.isa | 64 +++++++++++++++++------------------ src/arch/arm/isa/templates/misc64.isa | 25 +++++++++++++- 5 files changed, 112 insertions(+), 51 deletions(-) (limited to 'src/arch') diff --git a/src/arch/arm/insts/misc64.cc b/src/arch/arm/insts/misc64.cc index 423aaca25..cf625ebef 100644 --- a/src/arch/arm/insts/misc64.cc +++ b/src/arch/arm/insts/misc64.cc @@ -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 diff --git a/src/arch/arm/insts/misc64.hh b/src/arch/arm/insts/misc64.hh index f70344bcb..741b7b5e0 100644 --- a/src/arch/arm/insts/misc64.hh +++ b/src/arch/arm/insts/misc64.hh @@ -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: diff --git a/src/arch/arm/isa/formats/aarch64.isa b/src/arch/arm/isa/formats/aarch64.isa index 15cbe90dc..144ff88ca 100644 --- a/src/arch/arm/isa/formats/aarch64.isa +++ b/src/arch/arm/isa/formats/aarch64.isa @@ -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); } diff --git a/src/arch/arm/isa/insts/data64.isa b/src/arch/arm/isa/insts/data64.isa index d348190ae..b3e03d67d 100644 --- a/src/arch/arm/isa/insts/data64.isa +++ b/src/arch/arm/isa/insts/data64.isa @@ -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( + 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(machInst, false, - mnemonic); - } - MiscDest_ud = imm; - ''', optArgs = ["IsSerializeAfter", "IsNonSpeculative"]) - - buildDataXImmInst("msrDAIFSet", ''' - if (!canWriteAArch64SysReg( - (MiscRegIndex) xc->tcBase()->flattenRegId( - RegId(MiscRegClass, dest)).index(), - Scr64, Cpsr, xc->tcBase())) { - return std::make_shared( - machInst, 0, EC_TRAPPED_MSR_MRS_64, - mnemonic); - } + ''' + 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) + + 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( - 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 diff --git a/src/arch/arm/isa/templates/misc64.isa b/src/arch/arm/isa/templates/misc64.isa index 3c830c858..ed9b4a3ae 100644 --- a/src/arch/arm/isa/templates/misc64.isa +++ b/src/arch/arm/isa/templates/misc64.isa @@ -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 { -- cgit v1.2.3