misc: Merge branch v20.1.0.3 hotfix into develop
[gem5.git] / src / arch / x86 / isa / microops / specop.isa
index ad14b54a323524d51a1823e933116d53dab21b5d..aad171a56c9dd18bdfdcb842fb134d9193d4e4c6 100644 (file)
@@ -1,43 +1,26 @@
 // Copyright (c) 2007-2008 The Hewlett-Packard Development Company
+// Copyright (c) 2011 Mark D. Hill and David A. Wood
 // All rights reserved.
 //
-// Redistribution and use of this software in source and binary forms,
-// with or without modification, are permitted provided that the
-// following conditions are met:
+// The license below extends only to copyright in the software and shall
+// not be construed as granting a license to any other intellectual
+// property including but not limited to intellectual property relating
+// to a hardware implementation of the functionality of the software
+// licensed hereunder.  You may use the software subject to the license
+// terms below provided that you ensure that this notice is replicated
+// unmodified and in its entirety in all distributions of the software,
+// modified or unmodified, in source code or in binary form.
 //
-// The software must be used only for Non-Commercial Use which means any
-// use which is NOT directed to receiving any direct monetary
-// compensation for, or commercial advantage from such use.  Illustrative
-// examples of non-commercial use are academic research, personal study,
-// teaching, education and corporate research & development.
-// Illustrative examples of commercial use are distributing products for
-// commercial advantage and providing services using the software for
-// commercial advantage.
-//
-// If you wish to use this software or functionality therein that may be
-// covered by patents for commercial use, please contact:
-//     Director of Intellectual Property Licensing
-//     Office of Strategy and Technology
-//     Hewlett-Packard Company
-//     1501 Page Mill Road
-//     Palo Alto, California  94304
-//
-// Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.  Redistributions
-// in binary form must reproduce the above copyright notice, this list of
-// conditions and the following disclaimer in the documentation and/or
-// other materials provided with the distribution.  Neither the name of
-// the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met: redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer;
+// redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution;
+// neither the name of the copyright holders nor the names of its
 // contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.  No right of
-// sublicense is granted herewith.  Derivatives of the software and
-// output created using the software may be prepared, but only for
-// Non-Commercial Uses.  Derivatives of the software may be shared with
-// others provided: (i) the others agree to abide by the list of
-// conditions herein which includes the Non-Commercial Use restrictions;
-// and (ii) such Derivatives of the software include the above copyright
-// notice to acknowledge the contribution from this software where
-// applicable, this list of conditions and the disclaimer below.
+// this software without specific prior written permission.
 //
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -50,8 +33,6 @@
 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Authors: Gabe Black
 
 //////////////////////////////////////////////////////////////////////////
 //
@@ -68,36 +49,28 @@ output header {{
 
       public:
         MicroFaultBase(ExtMachInst _machInst, const char * instMnem,
-                bool isMicro, bool isDelayed, bool isFirst, bool isLast,
-                Fault _fault, uint8_t _cc);
-
-        MicroFaultBase(ExtMachInst _machInst, const char * instMnem,
-                Fault _fault, uint8_t _cc);
+                uint64_t setFlags, Fault _fault, uint8_t _cc);
 
         std::string generateDisassembly(Addr pc,
-                const SymbolTable *symtab) const;
+                const Loader::SymbolTable *symtab) const override;
     };
 
     class MicroHalt : public X86ISA::X86MicroopBase
     {
       public:
         MicroHalt(ExtMachInst _machInst, const char * instMnem,
-                bool isMicro, bool isDelayed, bool isFirst, bool isLast) :
-            X86MicroopBase(_machInst, "halt", instMnem,
-                    isMicro, isDelayed, isFirst, isLast, No_OpClass)
-        {
-        }
-
-        MicroHalt(ExtMachInst _machInst, const char * instMnem) :
+                uint64_t setFlags) :
             X86MicroopBase(_machInst, "halt", instMnem,
-                    false, false, false, false, No_OpClass)
+                           setFlags | (ULL(1) << StaticInst::IsNonSpeculative) |
+                           (ULL(1) << StaticInst::IsQuiesce),
+                           No_OpClass)
         {
         }
 
-        %(BasicExecDeclare)s
+        Fault execute(ExecContext *, Trace::InstRecord *) const override;
 
         std::string generateDisassembly(Addr pc,
-                const SymbolTable *symtab) const;
+                const Loader::SymbolTable *symtab) const override;
     };
 }};
 
@@ -105,21 +78,18 @@ def template MicroFaultDeclare {{
     class %(class_name)s : public %(base_class)s
     {
       private:
-        void buildMe();
-      public:
-        %(class_name)s(ExtMachInst _machInst, const char * instMnem,
-                bool isMicro, bool isDelayed, bool isFirst, bool isLast,
-                Fault _fault, uint8_t _cc);
+        %(reg_idx_arr_decl)s;
 
+      public:
         %(class_name)s(ExtMachInst _machInst, const char * instMnem,
-                Fault _fault, uint8_t _cc);
+                uint64_t setFlags, Fault _fault, uint8_t _cc);
 
-        %(BasicExecDeclare)s
+        Fault execute(ExecContext *, Trace::InstRecord *) const override;
     };
 }};
 
 def template MicroFaultExecute {{
-        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+        Fault %(class_name)s::execute(ExecContext *xc,
                 Trace::InstRecord *traceData) const
         {
             %(op_decl)s;
@@ -135,8 +105,7 @@ def template MicroFaultExecute {{
 
 output exec {{
     Fault
-    MicroHalt::execute(%(CPU_exec_context)s *xc,
-            Trace::InstRecord * traceData) const
+    MicroHalt::execute(ExecContext *xc, Trace::InstRecord * traceData) const
     {
         xc->tcBase()->suspend();
         return NoFault;
@@ -144,55 +113,30 @@ output exec {{
 }};
 
 output decoder {{
-    inline MicroFaultBase::MicroFaultBase(
+    MicroFaultBase::MicroFaultBase(
             ExtMachInst machInst, const char * instMnem,
-            Fault _fault, uint8_t _cc) :
-        X86MicroopBase(machInst, "fault", instMnem,
-                false, false, false, false, No_OpClass),
-        fault(_fault), cc(_cc)
-    {
-    }
-
-    inline MicroFaultBase::MicroFaultBase(
-            ExtMachInst machInst, const char * instMnem,
-            bool isMicro, bool isDelayed, bool isFirst, bool isLast,
-            Fault _fault, uint8_t _cc) :
-        X86MicroopBase(machInst, "fault", instMnem,
-                isMicro, isDelayed, isFirst, isLast, No_OpClass),
+            uint64_t setFlags, Fault _fault, uint8_t _cc) :
+        X86MicroopBase(machInst, "fault", instMnem, setFlags, No_OpClass),
                 fault(_fault), cc(_cc)
     {
     }
 }};
 
 def template MicroFaultConstructor {{
-
-    inline void %(class_name)s::buildMe()
-    {
-        %(constructor)s;
-    }
-
-    inline %(class_name)s::%(class_name)s(
-            ExtMachInst machInst, const char * instMnem,
+    %(class_name)s::%(class_name)s(
+            ExtMachInst machInst, const char * instMnem, uint64_t setFlags,
             Fault _fault, uint8_t _cc) :
-        %(base_class)s(machInst, instMnem, _fault, _cc)
+        %(base_class)s(machInst, instMnem, setFlags, _fault, _cc)
     {
-        buildMe();
-    }
-
-    inline %(class_name)s::%(class_name)s(
-            ExtMachInst machInst, const char * instMnem,
-            bool isMicro, bool isDelayed, bool isFirst, bool isLast,
-            Fault _fault, uint8_t _cc) :
-        %(base_class)s(machInst, instMnem,
-                isMicro, isDelayed, isFirst, isLast, _fault, _cc)
-    {
-        buildMe();
+        %(set_reg_idx_arr)s;
+        %(constructor)s;
     }
 }};
 
 output decoder {{
-    std::string MicroFaultBase::generateDisassembly(Addr pc,
-            const SymbolTable *symtab) const
+    std::string
+    MicroFaultBase::generateDisassembly(
+            Addr pc, const Loader::SymbolTable *symtab) const
     {
         std::stringstream response;
 
@@ -205,8 +149,9 @@ output decoder {{
         return response.str();
     }
 
-    std::string MicroHalt::generateDisassembly(Addr pc,
-            const SymbolTable *symtab) const
+    std::string
+    MicroHalt::generateDisassembly(
+            Addr pc, const Loader::SymbolTable *symtab) const
     {
         std::stringstream response;
 
@@ -223,14 +168,14 @@ let {{
             self.fault = fault
             if flags:
                 if not isinstance(flags, (list, tuple)):
-                    raise Exception, "flags must be a list or tuple of flags"
+                    raise Exception("flags must be a list or tuple of flags")
                 self.cond = " | ".join(flags)
                 self.className += "Flags"
             else:
                 self.cond = "0"
 
-        def getAllocator(self, *microFlags):
-            allocator = '''new %(class_name)s(machInst, mnemonic
+        def getAllocator(self, microFlags):
+            allocator = '''new %(class_name)s(machInst, macrocodeBlock,
                     %(flags)s, %(fault)s, %(cc)s)''' % {
                 "class_name" : self.className,
                 "flags" : self.microFlagsText(microFlags),
@@ -240,7 +185,8 @@ let {{
 
     iop = InstObjParams("fault", "MicroFaultFlags", "MicroFaultBase",
             {"code": "",
-             "cond_test": "checkCondition(ccFlagBits, cc)"})
+             "cond_test": "checkCondition(ccFlagBits | cfofBits | dfBit | \
+                                          ecfBit | ezfBit, cc)"})
     exec_output = MicroFaultExecute.subst(iop)
     header_output = MicroFaultDeclare.subst(iop)
     decoder_output = MicroFaultConstructor.subst(iop)
@@ -253,12 +199,70 @@ let {{
     microopClasses["fault"] = Fault
 
     class Halt(X86Microop):
+        className = "MicroHalt"
         def __init__(self):
             pass
 
-        def getAllocator(self, *microFlags):
-            return "new MicroHalt(machInst, mnemonic %s)" % \
+        def getAllocator(self, microFlags):
+            return "new MicroHalt(machInst, macrocodeBlock, %s)" % \
                     self.microFlagsText(microFlags)
 
     microopClasses["halt"] = Halt
 }};
+
+def template MicroFenceOpDeclare {{
+    class %(class_name)s : public X86ISA::X86MicroopBase
+    {
+      private:
+        %(reg_idx_arr_decl)s;
+
+      public:
+        %(class_name)s(ExtMachInst _machInst,
+                const char * instMnem,
+                uint64_t setFlags);
+
+        Fault execute(ExecContext *, Trace::InstRecord *) const override;
+    };
+}};
+
+def template MicroFenceOpConstructor {{
+    %(class_name)s::%(class_name)s(
+            ExtMachInst machInst, const char * instMnem, uint64_t setFlags) :
+        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
+                setFlags, %(op_class)s)
+    {
+        %(set_reg_idx_arr)s;
+        %(constructor)s;
+    }
+}};
+
+let {{
+    class MfenceOp(X86Microop):
+        def __init__(self):
+            self.className = "Mfence"
+            self.mnemonic = "mfence"
+            self.instFlags = "| (1ULL << StaticInst::IsReadBarrier)" + \
+                             "| (1ULL << StaticInst::IsWriteBarrier)"
+
+        def getAllocator(self, microFlags):
+            allocString = '''
+                    (StaticInstPtr)(new %(class_name)s(machInst,
+                        macrocodeBlock, %(flags)s))
+            '''
+            allocator = allocString % {
+                "class_name" : self.className,
+                "mnemonic" : self.mnemonic,
+                "flags" : self.microFlagsText(microFlags) + self.instFlags}
+            return allocator
+
+    microopClasses["mfence"] = MfenceOp
+}};
+
+let {{
+    # Build up the all register version of this micro op
+    iop = InstObjParams("mfence", "Mfence", 'X86MicroopBase',
+            {"code" : ""})
+    header_output += MicroFenceOpDeclare.subst(iop)
+    decoder_output += MicroFenceOpConstructor.subst(iop)
+    exec_output += BasicExecute.subst(iop)
+}};