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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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]) {
|
||||
|
||||
@@ -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;
|
||||
'''
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user