arch-arm: Fix MSR/MRS disassemble

This patch is fixing the Aarch64 MSR/MRS disassemble, which was
previously printing unexisting integer registers as source/destination
operands rather than the system register name

Change-Id: Iac9d5f2f2fea85abd9a398320ef7aa4844d43c0e
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/5861
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
diff --git a/src/arch/arm/insts/misc64.cc b/src/arch/arm/insts/misc64.cc
index 465bafa..b40de02 100644
--- a/src/arch/arm/insts/misc64.cc
+++ b/src/arch/arm/insts/misc64.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2013 ARM Limited
+ * Copyright (c) 2011-2013,2017 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -53,7 +53,7 @@
 
 std::string
 RegRegRegImmOp64::generateDisassembly(
-        Addr pc, const SymbolTable *symtab) const
+    Addr pc, const SymbolTable *symtab) const
 {
     std::stringstream ss;
     printMnemonic(ss, "", false);
@@ -71,3 +71,27 @@
 {
     return csprintf("%-10s (inst %#08x)", "unknown", machInst);
 }
+
+std::string
+MiscRegRegImmOp64::generateDisassembly(
+    Addr pc, const SymbolTable *symtab) const
+{
+    std::stringstream ss;
+    printMnemonic(ss);
+    printMiscReg(ss, dest);
+    ss << ", ";
+    printIntReg(ss, op1);
+    return ss.str();
+}
+
+std::string
+RegMiscRegImmOp64::generateDisassembly(
+    Addr pc, const SymbolTable *symtab) const
+{
+    std::stringstream ss;
+    printMnemonic(ss);
+    printIntReg(ss, dest);
+    ss << ", ";
+    printMiscReg(ss, op1);
+    return ss.str();
+}
diff --git a/src/arch/arm/insts/misc64.hh b/src/arch/arm/insts/misc64.hh
index 5a0e182..384d946 100644
--- a/src/arch/arm/insts/misc64.hh
+++ b/src/arch/arm/insts/misc64.hh
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2013 ARM Limited
+ * Copyright (c) 2011-2013,2017 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -89,4 +89,38 @@
     std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
 };
 
+class MiscRegRegImmOp64 : public ArmStaticInst
+{
+  protected:
+    MiscRegIndex dest;
+    IntRegIndex op1;
+    uint32_t imm;
+
+    MiscRegRegImmOp64(const char *mnem, ExtMachInst _machInst,
+                      OpClass __opClass, MiscRegIndex _dest,
+                      IntRegIndex _op1, uint32_t _imm) :
+        ArmStaticInst(mnem, _machInst, __opClass),
+        dest(_dest), op1(_op1), imm(_imm)
+    {}
+
+    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+class RegMiscRegImmOp64 : public ArmStaticInst
+{
+  protected:
+    IntRegIndex dest;
+    MiscRegIndex op1;
+    uint32_t imm;
+
+    RegMiscRegImmOp64(const char *mnem, ExtMachInst _machInst,
+                      OpClass __opClass, IntRegIndex _dest,
+                      MiscRegIndex _op1, uint32_t _imm) :
+        ArmStaticInst(mnem, _machInst, __opClass),
+        dest(_dest), op1(_op1), imm(_imm)
+    {}
+
+    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
 #endif
diff --git a/src/arch/arm/isa/formats/aarch64.isa b/src/arch/arm/isa/formats/aarch64.isa
index 2c33e24..d640caf 100644
--- a/src/arch/arm/isa/formats/aarch64.isa
+++ b/src/arch/arm/isa/formats/aarch64.isa
@@ -369,12 +369,13 @@
                             return new Dczva(machInst, rt, (IntRegIndex) miscReg, iss);
 
                         if (read) {
-                            StaticInstPtr si = new Mrs64(machInst, rt, (IntRegIndex) miscReg, iss);
+                            StaticInstPtr si = new Mrs64(machInst, rt, miscReg, iss);
                             if (miscRegInfo[miscReg][MISCREG_UNVERIFIABLE])
                                 si->setFlag(StaticInst::IsUnverifiable);
                             return si;
-                        } else
-                            return new Msr64(machInst, (IntRegIndex) miscReg, rt, iss);
+                        } else {
+                            return new Msr64(machInst, miscReg, rt, iss);
+                        }
                     } else if (miscRegInfo[miscReg][MISCREG_WARN_NOT_FAIL]) {
                         std::string full_mnem = csprintf("%s %s",
                             read ? "mrs" : "msr", miscRegName[miscReg]);
diff --git a/src/arch/arm/isa/insts/data64.isa b/src/arch/arm/isa/insts/data64.isa
index d0ee439..887130f 100644
--- a/src/arch/arm/isa/insts/data64.isa
+++ b/src/arch/arm/isa/insts/data64.isa
@@ -351,15 +351,21 @@
         }
     '''
 
-    buildDataXImmInst("mrs", '''
+    mrsCode = '''
         MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()->
             flattenRegId(RegId(MiscRegClass, op1)).index();
         CPSR cpsr = Cpsr;
         ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
         %s
         XDest = MiscOp1_ud;
-    ''' % (msrMrs64EnabledCheckCode % ('Read', 'true'),),
-        ["IsSerializeBefore"])
+    ''' % (msrMrs64EnabledCheckCode % ('Read', 'true'),)
+
+    mrsIop = InstObjParams("mrs", "Mrs64", "RegMiscRegImmOp64",
+                           mrsCode,
+                           ["IsSerializeBefore"])
+    header_output += RegMiscRegOp64Declare.subst(mrsIop)
+    decoder_output += RegMiscRegOp64Constructor.subst(mrsIop)
+    exec_output += BasicExecute.subst(mrsIop)
 
     buildDataXRegInst("mrsNZCV", 1, '''
         CPSR cpsr = 0;
@@ -369,15 +375,22 @@
         XDest = cpsr;
     ''')
 
-    buildDataXImmInst("msr", '''
+    msrCode = '''
         MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()->
             flattenRegId(RegId(MiscRegClass, dest)).index();
         CPSR cpsr = Cpsr;
         ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
         %s
         MiscDest_ud = XOp1;
-    ''' % (msrMrs64EnabledCheckCode % ('Write', 'false'),),
-        ["IsSerializeAfter", "IsNonSpeculative"])
+    ''' % (msrMrs64EnabledCheckCode % ('Write', 'false'),)
+
+    msrIop = InstObjParams("msr", "Msr64", "MiscRegRegImmOp64",
+                           msrCode,
+                           ["IsSerializeAfter", "IsNonSpeculative"])
+    header_output += MiscRegRegOp64Declare.subst(msrIop)
+    decoder_output += MiscRegRegOp64Constructor.subst(msrIop)
+    exec_output += BasicExecute.subst(msrIop)
+
 
     buildDataXRegInst("msrNZCV", 1, '''
         CPSR cpsr = XOp1;
diff --git a/src/arch/arm/isa/templates/misc64.isa b/src/arch/arm/isa/templates/misc64.isa
index 8429979..48d5c64 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 ARM Limited
+// Copyright (c) 2011,2017 ARM Limited
 // All rights reserved
 //
 // The license below extends only to copyright in the software and shall
@@ -89,3 +89,50 @@
     }
 }};
 
+def template MiscRegRegOp64Declare {{
+class %(class_name)s : public %(base_class)s
+{
+    public:
+        // Constructor
+        %(class_name)s(ExtMachInst machInst, MiscRegIndex _dest,
+                IntRegIndex _op1, uint64_t _imm);
+
+        Fault execute(ExecContext *, Trace::InstRecord *) const;
+};
+}};
+
+def template MiscRegRegOp64Constructor {{
+    %(class_name)s::%(class_name)s(ExtMachInst machInst,
+                                          MiscRegIndex _dest,
+                                          IntRegIndex _op1,
+                                          uint64_t _imm)
+        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
+                         _dest, _op1, _imm)
+    {
+        %(constructor)s;
+    }
+}};
+
+def template RegMiscRegOp64Declare {{
+class %(class_name)s : public %(base_class)s
+{
+    public:
+        // Constructor
+        %(class_name)s(ExtMachInst machInst, IntRegIndex _dest,
+                MiscRegIndex _op1, uint64_t _imm);
+
+        Fault execute(ExecContext *, Trace::InstRecord *) const;
+};
+}};
+
+def template RegMiscRegOp64Constructor {{
+    %(class_name)s::%(class_name)s(ExtMachInst machInst,
+                                          IntRegIndex _dest,
+                                          MiscRegIndex _op1,
+                                          uint64_t _imm)
+        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
+                         _dest, _op1, _imm)
+    {
+        %(constructor)s;
+    }
+}};