Attention is currently required from: Richard Cooper.
Hello Richard Cooper,
I'd like you to do a code review.
Please visit
https://gem5-review.googlesource.com/c/public/gem5/+/70719?usp=email
to review the following change.
Change subject: arch-arm: Implement FEAT_FLAGM(2)
......................................................................
arch-arm: Implement FEAT_FLAGM(2)
Change-Id: I21f1eb91ad9acb019a776a7d5edd38754571a62e
Signed-off-by: Giacomo Travaglini <giacomo.travagl...@arm.com>
Reviewed-by: Richard Cooper <richard.coo...@arm.com>
---
M src/arch/arm/ArmISA.py
M src/arch/arm/ArmSystem.py
M src/arch/arm/insts/misc64.cc
M src/arch/arm/insts/misc64.hh
M src/arch/arm/isa/formats/aarch64.isa
M src/arch/arm/isa/insts/misc64.isa
M src/arch/arm/isa/templates/misc64.isa
M src/arch/arm/regs/misc.cc
8 files changed, 239 insertions(+), 4 deletions(-)
diff --git a/src/arch/arm/ArmISA.py b/src/arch/arm/ArmISA.py
index e73046d..37970dc 100644
--- a/src/arch/arm/ArmISA.py
+++ b/src/arch/arm/ArmISA.py
@@ -58,6 +58,10 @@
"FEAT_FCMA",
"FEAT_JSCVT",
"FEAT_PAuth",
+ # Armv8.4
+ "FEAT_FLAGM",
+ # Armv8.5
+ "FEAT_FLAGM2",
# Armv9.2
"FEAT_SME",
# Other
diff --git a/src/arch/arm/ArmSystem.py b/src/arch/arm/ArmSystem.py
index 9e2da8e..e08108f 100644
--- a/src/arch/arm/ArmSystem.py
+++ b/src/arch/arm/ArmSystem.py
@@ -85,6 +85,9 @@
# Armv8.4
"FEAT_SEL2",
"FEAT_TLBIOS",
+ "FEAT_FLAGM",
+ # Armv8.5
+ "FEAT_FLAGM2",
# Armv9.2
"FEAT_SME", # Optional in Armv9.2
# Others
@@ -164,6 +167,9 @@
# Armv8.4
"FEAT_SEL2",
"FEAT_TLBIOS",
+ "FEAT_FLAGM",
+ # Armv8.5
+ "FEAT_FLAGM2",
# Armv9.2
"FEAT_SME",
]
@@ -194,11 +200,15 @@
class Armv84(Armv83):
- extensions = Armv83.extensions + ["FEAT_SEL2", "FEAT_TLBIOS"]
+ extensions = Armv83.extensions +
["FEAT_SEL2", "FEAT_TLBIOS", "FEAT_FLAGM"]
-class Armv92(Armv84):
- extensions = Armv84.extensions + ["FEAT_SME"]
+class Armv85(Armv84):
+ extensions = Armv84.extensions + ["FEAT_FLAGM2"]
+
+
+class Armv92(Armv85):
+ extensions = Armv85.extensions + ["FEAT_SME"]
class ArmSystem(System):
diff --git a/src/arch/arm/insts/misc64.cc b/src/arch/arm/insts/misc64.cc
index c7423d9..4f573fc 100644
--- a/src/arch/arm/insts/misc64.cc
+++ b/src/arch/arm/insts/misc64.cc
@@ -55,6 +55,27 @@
}
std::string
+RegOp64::generateDisassembly(Addr pc, const loader::SymbolTable *symtab)
const
+{
+ std::stringstream ss;
+ printMnemonic(ss, "", false);
+ printIntReg(ss, op1);
+ return ss.str();
+}
+
+std::string
+RegImmImmOp64::generateDisassembly(Addr pc, const loader::SymbolTable
*symtab) const
+{
+ std::stringstream ss;
+ printMnemonic(ss, "", false);
+ printIntReg(ss, op1);
+ ccprintf(ss, "#0x%x", imm1);
+ ss << ", ";
+ ccprintf(ss, "#0x%x", imm2);
+ return ss.str();
+}
+
+std::string
RegRegImmImmOp64::generateDisassembly(
Addr pc, const loader::SymbolTable *symtab) const
{
diff --git a/src/arch/arm/insts/misc64.hh b/src/arch/arm/insts/misc64.hh
index b7b66c2..3a67210 100644
--- a/src/arch/arm/insts/misc64.hh
+++ b/src/arch/arm/insts/misc64.hh
@@ -57,6 +57,38 @@
Addr pc, const loader::SymbolTable *symtab) const override;
};
+class RegOp64 : public ArmISA::ArmStaticInst
+{
+ protected:
+ RegIndex op1;
+
+ RegOp64(const char *mnem, ArmISA::ExtMachInst _machInst,
+ OpClass __opClass, RegIndex _op1) :
+ ArmISA::ArmStaticInst(mnem, _machInst, __opClass), op1(_op1)
+ {}
+
+ std::string generateDisassembly(
+ Addr pc, const loader::SymbolTable *symtab) const override;
+};
+
+class RegImmImmOp64 : public ArmISA::ArmStaticInst
+{
+ protected:
+ RegIndex op1;
+ uint64_t imm1;
+ uint64_t imm2;
+
+ RegImmImmOp64(const char *mnem, ArmISA::ExtMachInst _machInst,
+ OpClass __opClass, RegIndex _op1,
+ uint64_t _imm1, uint64_t _imm2) :
+ ArmISA::ArmStaticInst(mnem, _machInst, __opClass),
+ op1(_op1), imm1(_imm1), imm2(_imm2)
+ {}
+
+ std::string generateDisassembly(
+ Addr pc, const loader::SymbolTable *symtab) const override;
+};
+
class RegRegImmImmOp64 : public ArmISA::ArmStaticInst
{
protected:
diff --git a/src/arch/arm/isa/formats/aarch64.isa
b/src/arch/arm/isa/formats/aarch64.isa
index 0aafa9e..9ad2de2 100644
--- a/src/arch/arm/isa/formats/aarch64.isa
+++ b/src/arch/arm/isa/formats/aarch64.isa
@@ -424,6 +424,15 @@
// MSR immediate: moving immediate value to
selected
// bits of the PSTATE
switch (op1 << 3 | op2) {
+ case 0x0:
+ // CFINV
+ return new Cfinv(machInst);
+ case 0x1:
+ // XAFLAG
+ return new Xaflag(machInst);
+ case 0x2:
+ // AXFLAG
+ return new Axflag(machInst);
case 0x3:
// UAO
return new MsrImm64(
@@ -2081,6 +2090,26 @@
}
StaticInstPtr
+ decodeRotIntoFlags(ExtMachInst machInst)
+ {
+ RegIndex rn = (RegIndex)(uint8_t)bits(machInst, 9, 5);
+ uint8_t imm6 = bits(machInst, 20, 15);
+ uint8_t mask = bits(machInst, 3, 0);
+ return new Rmif(machInst, rn, imm6, mask);
+ }
+
+ StaticInstPtr
+ decodeEvalIntoFlags(ExtMachInst machInst)
+ {
+ RegIndex rn = (RegIndex)(uint8_t)bits(machInst, 9, 5);
+ int sz = bits(machInst, 14);
+ if (sz)
+ return new Setf16(machInst, rn);
+ else
+ return new Setf8(machInst, rn);
+ }
+
+ StaticInstPtr
decodeCondCompare(ExtMachInst machInst)
{
if ((bits(machInst, 4) == 1) ||
@@ -2328,7 +2357,16 @@
switch (bits(machInst, 23, 22)) {
case 0x0:
- return decodeAddSubWithCarry(machInst);
+ switch (bits(machInst, 11, 10)) {
+ case 0b00:
+ return decodeAddSubWithCarry(machInst);
+ case 0b01:
+ return decodeRotIntoFlags(machInst);
+ case 0b10:
+ return decodeEvalIntoFlags(machInst);
+ default: // 0b11
+ return new Unknown64(machInst);
+ }
case 0x1:
return decodeCondCompare(machInst);
case 0x2:
diff --git a/src/arch/arm/isa/insts/misc64.isa
b/src/arch/arm/isa/insts/misc64.isa
index abe30fc..46d72d2 100644
--- a/src/arch/arm/isa/insts/misc64.isa
+++ b/src/arch/arm/isa/insts/misc64.isa
@@ -248,4 +248,81 @@
header_output += ImmOp64Declare.subst(hltIop)
decoder_output += SemihostConstructor64.subst(hltIop)
exec_output += BasicExecute.subst(hltIop)
+
+ flagmCheckCode = '''
+ if (!HaveExt(xc->tcBase(), ArmExtension::FEAT_FLAGM)) {
+ return std::make_shared<UndefinedInstruction>(
+ machInst, true);
+ }
+ '''
+ cfinvCode = 'CondCodesC = ~CondCodesC'
+ cfinvIop = ArmInstObjParams("cfinv", "Cfinv", "ArmStaticInst",
+ flagmCheckCode + cfinvCode)
+ header_output += BasicDeclare.subst(cfinvIop)
+ decoder_output += BasicConstructor64.subst(cfinvIop)
+ exec_output += BasicExecute.subst(cfinvIop)
+
+ axflagCode = '''
+ bool z = CondCodesNZ || CondCodesV;
+ bool c = CondCodesC && !CondCodesV;
+ CondCodesNZ = z; // This implies zeroing PSTATE.N
+ CondCodesC = c;
+ CondCodesV = 0;
+ '''
+ axflagIop = ArmInstObjParams("axflag", "Axflag", "ArmStaticInst",
+ flagmCheckCode + axflagCode)
+ header_output += BasicDeclare.subst(axflagIop)
+ decoder_output += BasicConstructor64.subst(axflagIop)
+ exec_output += BasicExecute.subst(axflagIop)
+
+ xaflagCode = '''
+ const RegVal nz = CondCodesNZ;
+ const RegVal n = !CondCodesC && !bits(nz, 0);
+ const RegVal z = CondCodesC && bits(nz, 0);
+ const RegVal c = CondCodesC || bits(nz, 0);
+ const RegVal v = !CondCodesC && bits(nz, 0);
+
+ CondCodesNZ = (n << 1) | z;
+ CondCodesC = c;
+ CondCodesV = v;
+ '''
+ xaflagIop = ArmInstObjParams("xaflag", "Xaflag", "ArmStaticInst",
+ flagmCheckCode + xaflagCode)
+ header_output += BasicDeclare.subst(xaflagIop)
+ decoder_output += BasicConstructor64.subst(xaflagIop)
+ exec_output += BasicExecute.subst(xaflagIop)
+
+ rmifCode = '''
+ RegVal tmp = XOp1 << imm1;
+ int nz = CondCodesNZ;
+ if (bits(imm2, 0)) CondCodesV = bits(tmp, 0);
+ if (bits(imm2, 1)) CondCodesC = bits(tmp, 1);
+ if (bits(imm2, 2)) nz = insertBits(nz, 0, bits(tmp, 2));
+ if (bits(imm2, 3)) nz = insertBits(nz, 1, bits(tmp, 3));
+
+ CondCodesNZ = nz;
+ '''
+ rmifIop = ArmInstObjParams("rmif", "Rmif", "RegImmImmOp64",
+ flagmCheckCode + rmifCode)
+ header_output += RegImmImmOp64Declare.subst(rmifIop)
+ decoder_output += RegImmImmOp64Constructor.subst(rmifIop)
+ exec_output += BasicExecute.subst(rmifIop)
+
+ setfCode = '''
+ const int msb = %d;
+ RegVal tmp = Op1;
+ CondCodesNZ = (bits(tmp, msb) << 1) | (bits(tmp, msb, 0) ? 0 : 1);
+ CondCodesV = bits(tmp, msb) ^ bits(tmp, msb + 1);
+ '''
+ setf8Iop = ArmInstObjParams("setf8", "Setf8", "RegOp64",
+ flagmCheckCode + setfCode % 7)
+ header_output += RegOp64Declare.subst(setf8Iop)
+ decoder_output += RegOp64Constructor.subst(setf8Iop)
+ exec_output += BasicExecute.subst(setf8Iop)
+
+ setf16Iop = ArmInstObjParams("setf16", "Setf16", "RegOp64",
+ flagmCheckCode + setfCode % 15)
+ header_output += RegOp64Declare.subst(setf16Iop)
+ decoder_output += RegOp64Constructor.subst(setf16Iop)
+ exec_output += BasicExecute.subst(setf16Iop)
}};
diff --git a/src/arch/arm/isa/templates/misc64.isa
b/src/arch/arm/isa/templates/misc64.isa
index af6b4c6..a2024f7 100644
--- a/src/arch/arm/isa/templates/misc64.isa
+++ b/src/arch/arm/isa/templates/misc64.isa
@@ -58,6 +58,56 @@
}
}};
+def template RegOp64Declare {{
+class %(class_name)s : public %(base_class)s
+{
+ private:
+ %(reg_idx_arr_decl)s;
+
+ public:
+ // Constructor
+ %(class_name)s(ExtMachInst machInst, RegIndex _op1);
+
+ Fault execute(ExecContext *, trace::InstRecord *) const override;
+};
+}};
+
+def template RegOp64Constructor {{
+ %(class_name)s::%(class_name)s(ExtMachInst machInst, RegIndex _op1) :
+ %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _op1)
+ {
+ %(set_reg_idx_arr)s;
+ %(constructor)s;
+ }
+}};
+
+def template RegImmImmOp64Declare {{
+class %(class_name)s : public %(base_class)s
+{
+ private:
+ %(reg_idx_arr_decl)s;
+
+ public:
+ // Constructor
+ %(class_name)s(ExtMachInst machInst,
+ RegIndex _op1,
+ uint64_t _imm1, uint64_t _imm2);
+ Fault execute(ExecContext *, trace::InstRecord *) const override;
+};
+}};
+
+def template RegImmImmOp64Constructor {{
+ %(class_name)s::%(class_name)s(ExtMachInst machInst,
+ RegIndex _op1,
+ uint64_t _imm1, uint64_t _imm2) :
+ %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
+ _op1, _imm1, _imm2)
+ {
+ %(set_reg_idx_arr)s;
+ %(constructor)s;
+ }
+}};
+
def template RegRegImmImmOp64Declare {{
class %(class_name)s : public %(base_class)s
{
diff --git a/src/arch/arm/regs/misc.cc b/src/arch/arm/regs/misc.cc
index ec5670e..9e633c0 100644
--- a/src/arch/arm/regs/misc.cc
+++ b/src/arch/arm/regs/misc.cc
@@ -3891,6 +3891,9 @@
isar0_el1.rdm = release->has(ArmExtension::FEAT_RDM) ? 0x1 : 0x0;
isar0_el1.tme = release->has(ArmExtension::TME) ? 0x1 : 0x0;
isar0_el1.tlb = release->has(ArmExtension::FEAT_TLBIOS) ? 0x1 :
0x0;
+ isar0_el1.ts = release->has(ArmExtension::FEAT_FLAGM2) ?
+ 0x2 : release->has(ArmExtension::FEAT_FLAGM) ?
+ 0x1 : 0x0;
return isar0_el1;
}())
.faultRead(EL1, HCR_TRAP(tid3))
--
To view, visit
https://gem5-review.googlesource.com/c/public/gem5/+/70719?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I21f1eb91ad9acb019a776a7d5edd38754571a62e
Gerrit-Change-Number: 70719
Gerrit-PatchSet: 1
Gerrit-Owner: Giacomo Travaglini <giacomo.travagl...@arm.com>
Gerrit-Reviewer: Richard Cooper <richard.coo...@arm.com>
Gerrit-Attention: Richard Cooper <richard.coo...@arm.com>
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org