Giacomo Travaglini has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/70719?usp=email )

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>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/70719
Maintainer: Jason Lowe-Power <power...@gmail.com>
Reviewed-by: Jason Lowe-Power <power...@gmail.com>
Tested-by: kokoro <noreply+kok...@google.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/process.cc
M src/arch/arm/regs/misc.cc
9 files changed, 244 insertions(+), 4 deletions(-)

Approvals:
  Jason Lowe-Power: Looks good to me, approved; Looks good to me, approved
  kokoro: Regressions pass




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/process.cc b/src/arch/arm/process.cc
index 9b0f3b2..b2378cc 100644
--- a/src/arch/arm/process.cc
+++ b/src/arch/arm/process.cc
@@ -314,6 +314,11 @@

     uint64_t hwcap = 0;

+    ThreadContext *tc = system->threads[contextIds[0]];
+
+    const AA64ISAR0 isa_r0 = tc->readMiscReg(MISCREG_ID_AA64ISAR0_EL1);
+    hwcap |= (isa_r0.ts >= 2) ? Arm_Flagm2 : Arm_None;
+
     return hwcap;
 }

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: merged
Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I21f1eb91ad9acb019a776a7d5edd38754571a62e
Gerrit-Change-Number: 70719
Gerrit-PatchSet: 3
Gerrit-Owner: Giacomo Travaglini <giacomo.travagl...@arm.com>
Gerrit-Reviewer: Andreas Sandberg <andreas.sandb...@arm.com>
Gerrit-Reviewer: Giacomo Travaglini <giacomo.travagl...@arm.com>
Gerrit-Reviewer: Jason Lowe-Power <power...@gmail.com>
Gerrit-Reviewer: Richard Cooper <richard.coo...@arm.com>
Gerrit-Reviewer: kokoro <noreply+kok...@google.com>
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org

Reply via email to