arch-arm: Generate MSR/MRS iss within trapping logic

The iss field is only used when the MSR/MRS instruction
gets trapped. Rather than generating it at decode time,
we generate the value within the trap method instead

This avoids the confusion of having a MSR/MRS register
instruction storing an immediate field

Later patches will change this even further by generating the
iss field on the fly ONLY if the instruction gets trapped

Change-Id: I97fdcf54d9643ea79a1f9d052073320ee68109fd
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/61670
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Richard Cooper <richard.cooper@arm.com>
This commit is contained in:
Giacomo Travaglini
2022-07-14 00:49:26 +01:00
parent 6217ac737b
commit 25bdb73b9f
9 changed files with 98 additions and 67 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011-2013,2018, 2021 ARM Limited
* Copyright (c) 2011-2013,2018, 2021-2022 Arm Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -58,6 +58,12 @@ SysDC64::generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const
}
uint32_t
SysDC64::iss() const
{
const MiscRegNum64 &misc_reg = encodeAArch64SysReg(dest);
return _iss(misc_reg, base);
}
void
Memory64::startDisassembly(std::ostream &os) const

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011-2013,2017-2019, 2021 ARM Limited
* Copyright (c) 2011-2013,2017-2019, 2021-2022 Arm Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -54,19 +54,20 @@ class SysDC64 : public MiscRegOp64
protected:
RegIndex base;
MiscRegIndex dest;
uint64_t imm;
// This is used for fault handling only
mutable Addr faultAddr;
SysDC64(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
RegIndex _base, MiscRegIndex _dest, uint64_t _imm)
RegIndex _base, MiscRegIndex _dest)
: MiscRegOp64(mnem, _machInst, __opClass, false),
base(_base), dest(_dest), imm(_imm), faultAddr(0)
base(_base), dest(_dest), faultAddr(0)
{}
std::string generateDisassembly(
Addr pc, const loader::SymbolTable *symtab) const override;
uint32_t iss() const override;
};
class MightBeMicro64 : public ArmStaticInst

View File

@@ -91,9 +91,10 @@ UnknownOp64::generateDisassembly(
Fault
MiscRegOp64::trap(ThreadContext *tc, MiscRegIndex misc_reg,
ExceptionLevel el, uint32_t immediate) const
ExceptionLevel el) const
{
ExceptionClass ec = EC_TRAPPED_MSR_MRS_64;
uint32_t immediate = iss();
// Check for traps to supervisor (FP/SIMD regs)
if (el <= EL1 && checkEL1Trap(tc, misc_reg, el, ec, immediate)) {
@@ -800,6 +801,18 @@ MiscRegOp64::checkEL3Trap(ThreadContext *tc, const MiscRegIndex misc_reg,
return trap_to_mon;
}
uint32_t
MiscRegOp64::_iss(const MiscRegNum64 &misc_reg, RegIndex int_index) const
{
return miscRead |
(misc_reg.crm << 1) |
(int_index << 5) |
(misc_reg.crn << 10) |
(misc_reg.op1 << 14) |
(misc_reg.op2 << 17) |
(misc_reg.op0 << 20);
}
RegVal
MiscRegImmOp64::miscRegImm() const
{
@@ -839,6 +852,13 @@ MiscRegRegImmOp64::generateDisassembly(
return ss.str();
}
uint32_t
MiscRegRegImmOp64::iss() const
{
const MiscRegNum64 &misc_reg = encodeAArch64SysReg(dest);
return _iss(misc_reg, op1);
}
std::string
RegMiscRegImmOp64::generateDisassembly(
Addr pc, const loader::SymbolTable *symtab) const
@@ -851,6 +871,13 @@ RegMiscRegImmOp64::generateDisassembly(
return ss.str();
}
uint32_t
RegMiscRegImmOp64::iss() const
{
const MiscRegNum64 &misc_reg = encodeAArch64SysReg(op1);
return _iss(misc_reg, dest);
}
Fault
MiscRegImplDefined64::execute(ExecContext *xc,
Trace::InstRecord *traceData) const
@@ -859,7 +886,7 @@ MiscRegImplDefined64::execute(ExecContext *xc,
const CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
const ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
Fault fault = trap(tc, miscReg, el, imm);
Fault fault = trap(tc, MISCREG_IMPDEF_UNIMPL, el);
if (fault != NoFault) {
return fault;
@@ -881,6 +908,12 @@ MiscRegImplDefined64::generateDisassembly(
return csprintf("%-10s (implementation defined)", fullMnemonic.c_str());
}
uint32_t
MiscRegImplDefined64::iss() const
{
return _iss(miscReg, intReg);
}
std::string
RegNone::generateDisassembly(
Addr pc, const loader::SymbolTable *symtab) const

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011-2013,2017-2019, 2021 Arm Limited
* Copyright (c) 2011-2013,2017-2019, 2021-2022 Arm Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -133,7 +133,11 @@ class MiscRegOp64 : public ArmISA::ArmStaticInst
{}
Fault trap(ThreadContext *tc, ArmISA::MiscRegIndex misc_reg,
ArmISA::ExceptionLevel el, uint32_t immediate) const;
ArmISA::ExceptionLevel el) const;
uint32_t _iss(const ArmISA::MiscRegNum64 &misc_reg,
RegIndex int_index) const;
private:
bool checkEL1Trap(ThreadContext *tc, const ArmISA::MiscRegIndex misc_reg,
ArmISA::ExceptionLevel el, ArmISA::ExceptionClass &ec,
@@ -147,6 +151,8 @@ class MiscRegOp64 : public ArmISA::ArmStaticInst
ArmISA::ExceptionLevel el, ArmISA::ExceptionClass &ec,
uint32_t &immediate) const;
public:
virtual uint32_t iss() const { return 0; }
};
class MiscRegImmOp64 : public MiscRegOp64
@@ -178,17 +184,18 @@ class MiscRegRegImmOp64 : public MiscRegOp64
protected:
ArmISA::MiscRegIndex dest;
RegIndex op1;
uint32_t imm;
MiscRegRegImmOp64(const char *mnem, ArmISA::ExtMachInst _machInst,
OpClass __opClass, ArmISA::MiscRegIndex _dest,
RegIndex _op1, uint32_t _imm) :
RegIndex _op1) :
MiscRegOp64(mnem, _machInst, __opClass, false),
dest(_dest), op1(_op1), imm(_imm)
dest(_dest), op1(_op1)
{}
std::string generateDisassembly(
Addr pc, const loader::SymbolTable *symtab) const override;
uint32_t iss() const override;
};
class RegMiscRegImmOp64 : public MiscRegOp64
@@ -196,37 +203,38 @@ class RegMiscRegImmOp64 : public MiscRegOp64
protected:
RegIndex dest;
ArmISA::MiscRegIndex op1;
uint32_t imm;
RegMiscRegImmOp64(const char *mnem, ArmISA::ExtMachInst _machInst,
OpClass __opClass, RegIndex _dest,
ArmISA::MiscRegIndex _op1, uint32_t _imm) :
ArmISA::MiscRegIndex _op1) :
MiscRegOp64(mnem, _machInst, __opClass, true),
dest(_dest), op1(_op1), imm(_imm)
dest(_dest), op1(_op1)
{}
std::string generateDisassembly(
Addr pc, const loader::SymbolTable *symtab) const override;
uint32_t iss() const override;
};
class MiscRegImplDefined64 : public MiscRegOp64
{
protected:
const std::string fullMnemonic;
const ArmISA::MiscRegIndex miscReg;
const uint32_t imm;
const ArmISA::MiscRegNum64 miscReg;
const RegIndex intReg;
const bool warning;
public:
MiscRegImplDefined64(const char *mnem, ArmISA::ExtMachInst _machInst,
ArmISA::MiscRegIndex misc_reg, bool misc_read,
uint32_t _imm, const std::string full_mnem,
ArmISA::MiscRegNum64 &&misc_reg, RegIndex int_reg,
bool misc_read, const std::string full_mnem,
bool _warning) :
MiscRegOp64(mnem, _machInst, No_OpClass, misc_read),
fullMnemonic(full_mnem), miscReg(misc_reg), imm(_imm),
fullMnemonic(full_mnem), miscReg(misc_reg), intReg(int_reg),
warning(_warning)
{
assert(miscReg == ArmISA::MISCREG_IMPDEF_UNIMPL);
assert(decodeAArch64SysReg(miscReg) == ArmISA::MISCREG_IMPDEF_UNIMPL);
}
protected:
@@ -235,6 +243,8 @@ class MiscRegImplDefined64 : public MiscRegOp64
std::string generateDisassembly(
Addr pc, const loader::SymbolTable *symtab) const override;
uint32_t iss() const override;
};
class RegNone : public ArmISA::ArmStaticInst
@@ -257,8 +267,8 @@ class TlbiOp64 : public MiscRegRegImmOp64
protected:
TlbiOp64(const char *mnem, ArmISA::ExtMachInst _machInst,
OpClass __opClass, ArmISA::MiscRegIndex _dest,
RegIndex _op1, uint32_t _imm) :
MiscRegRegImmOp64(mnem, _machInst, __opClass, _dest, _op1, _imm)
RegIndex _op1) :
MiscRegRegImmOp64(mnem, _machInst, __opClass, _dest, _op1)
{}
void performTlbi(ExecContext *xc,

View File

@@ -483,12 +483,10 @@ namespace Aarch64
read ? "mrs" : "msr",
op0, op1, crn, crm, op2);
uint32_t iss = msrMrs64IssBuild(
read, op0, op1, crn, crm, op2, rt);
return new MiscRegImplDefined64(
read ? "mrs" : "msr",
machInst, miscReg, read, iss, full_mnemonic,
machInst, MiscRegNum64(op0, op1, crn, crm, op2),
rt, read, full_mnemonic,
miscRegInfo[miscReg][MISCREG_WARN_NOT_FAIL]);
} else if (miscRegInfo[miscReg][MISCREG_IMPLEMENTED]) {
@@ -498,26 +496,23 @@ namespace Aarch64
else
return new MsrNZCV64(machInst, miscReg, rt);
}
uint32_t iss = msrMrs64IssBuild(read, op0, op1, crn,
crm, op2, rt);
if (read) {
StaticInstPtr si = new Mrs64(machInst, rt, miscReg,
iss);
StaticInstPtr si = new Mrs64(machInst, rt, miscReg);
if (miscRegInfo[miscReg][MISCREG_UNVERIFIABLE])
si->setFlag(StaticInst::IsUnverifiable);
return si;
} else {
switch (miscReg) {
case MISCREG_DC_ZVA_Xt:
return new Dczva(machInst, rt, miscReg, iss);
return new Dczva(machInst, rt, miscReg);
case MISCREG_DC_CVAU_Xt:
return new Dccvau(machInst, rt, miscReg, iss);
return new Dccvau(machInst, rt, miscReg);
case MISCREG_DC_CVAC_Xt:
return new Dccvac(machInst, rt, miscReg, iss);
return new Dccvac(machInst, rt, miscReg);
case MISCREG_DC_CIVAC_Xt:
return new Dccivac(machInst, rt, miscReg, iss);
return new Dccivac(machInst, rt, miscReg);
case MISCREG_DC_IVAC_Xt:
return new Dcivac(machInst, rt, miscReg, iss);
return new Dcivac(machInst, rt, miscReg);
// 64-bit TLBIs split into "Local"
// and "Shareable"
case MISCREG_TLBI_ALLE3:
@@ -537,7 +532,7 @@ namespace Aarch64
case MISCREG_TLBI_IPAS2E1_Xt:
case MISCREG_TLBI_IPAS2LE1_Xt:
return new Tlbi64LocalHub(
machInst, miscReg, rt, iss);
machInst, miscReg, rt);
case MISCREG_TLBI_ALLE3IS:
case MISCREG_TLBI_ALLE2IS:
case MISCREG_TLBI_ALLE1IS:
@@ -555,9 +550,9 @@ namespace Aarch64
case MISCREG_TLBI_IPAS2E1IS_Xt:
case MISCREG_TLBI_IPAS2LE1IS_Xt:
return new Tlbi64ShareableHub(
machInst, miscReg, rt, iss, dec.dvmEnabled);
machInst, miscReg, rt, dec.dvmEnabled);
default:
return new Msr64(machInst, miscReg, rt, iss);
return new Msr64(machInst, miscReg, rt);
}
}
} else if (miscRegInfo[miscReg][MISCREG_WARN_NOT_FAIL]) {

View File

@@ -317,7 +317,7 @@ let {{
mnemonic);
}
fault = this->trap(xc->tcBase(), flat_idx, el, imm);
fault = this->trap(xc->tcBase(), flat_idx, el);
if (fault != NoFault) return fault;
'''

View File

@@ -1,6 +1,6 @@
// -*- mode:c++ -*-
// Copyright (c) 2011-2014, 2017, 2019 ARM Limited
// Copyright (c) 2011-2014, 2017, 2019, 2022 Arm Limited
// All rights reserved
//
// The license below extends only to copyright in the software and shall
@@ -291,7 +291,7 @@ def template DCStore64Declare {{
public:
/// Constructor.
%(class_name)s(ExtMachInst machInst, RegIndex _base,
MiscRegIndex _dest, uint64_t _imm);
MiscRegIndex _dest);
Fault execute(ExecContext *, Trace::InstRecord *) const override;
Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override;
@@ -308,9 +308,9 @@ def template DCStore64Declare {{
def template DCStore64Constructor {{
%(class_name)s::%(class_name)s(ExtMachInst machInst, RegIndex _base,
MiscRegIndex _dest, uint64_t _imm) :
MiscRegIndex _dest) :
%(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
_base, _dest, _imm)
_base, _dest)
{
%(set_reg_idx_arr)s;
%(constructor)s;

View File

@@ -144,7 +144,7 @@ class %(class_name)s : public %(base_class)s
public:
// Constructor
%(class_name)s(ExtMachInst machInst, MiscRegIndex _dest,
RegIndex _op1, uint64_t _imm);
RegIndex _op1);
Fault execute(ExecContext *, Trace::InstRecord *) const override;
};
@@ -152,9 +152,9 @@ class %(class_name)s : public %(base_class)s
def template MiscRegRegOp64Constructor {{
%(class_name)s::%(class_name)s(ExtMachInst machInst, MiscRegIndex _dest,
RegIndex _op1, uint64_t _imm) :
RegIndex _op1) :
%(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
_dest, _op1, _imm)
_dest, _op1)
{
%(set_reg_idx_arr)s;
%(constructor)s;
@@ -170,7 +170,7 @@ class %(class_name)s : public %(base_class)s
public:
// Constructor
%(class_name)s(ExtMachInst machInst, RegIndex _dest,
MiscRegIndex _op1, uint64_t _imm);
MiscRegIndex _op1);
Fault execute(ExecContext *, Trace::InstRecord *) const override;
};
@@ -178,9 +178,9 @@ class %(class_name)s : public %(base_class)s
def template RegMiscRegOp64Constructor {{
%(class_name)s::%(class_name)s(ExtMachInst machInst, RegIndex _dest,
MiscRegIndex _op1, uint64_t _imm) :
MiscRegIndex _op1) :
%(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
_dest, _op1, _imm)
_dest, _op1)
{
%(set_reg_idx_arr)s;
%(constructor)s;
@@ -244,7 +244,7 @@ class %(class_name)s : public %(base_class)s
public:
// Constructor
%(class_name)s(ExtMachInst machInst, MiscRegIndex _dest,
RegIndex _op1, uint64_t _imm, bool dvm_enabled);
RegIndex _op1, bool dvm_enabled);
Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override;
Fault completeAcc(PacketPtr, ExecContext *,
@@ -275,10 +275,9 @@ def template DvmDeclare {{
def template DvmTlbiConstructor {{
%(class_name)s::%(class_name)s(ExtMachInst machInst, MiscRegIndex _dest,
RegIndex _op1, uint64_t _imm,
bool dvm_enabled) :
RegIndex _op1, bool dvm_enabled) :
%(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
_dest, _op1, _imm),
_dest, _op1),
dvmEnabled(dvm_enabled)
{
%(set_reg_idx_arr)s;

View File

@@ -265,19 +265,6 @@ mcrrMrrcIssBuild(bool isRead, uint32_t crm, RegIndex rt, RegIndex rt2,
(opc1 << 16);
}
static inline uint32_t
msrMrs64IssBuild(bool isRead, uint32_t op0, uint32_t op1, uint32_t crn,
uint32_t crm, uint32_t op2, RegIndex rt)
{
return isRead |
(crm << 1) |
(rt << 5) |
(crn << 10) |
(op1 << 14) |
(op2 << 17) |
(op0 << 20);
}
Fault mcrMrc15Trap(const MiscRegIndex miscReg, ExtMachInst machInst,
ThreadContext *tc, uint32_t imm);
bool mcrMrc15TrapToHyp(const MiscRegIndex miscReg, ThreadContext *tc,