X86: Make the "fault" microop predicated.
authorGabe Black <gblack@eecs.umich.edu>
Fri, 19 Oct 2007 05:40:18 +0000 (22:40 -0700)
committerGabe Black <gblack@eecs.umich.edu>
Fri, 19 Oct 2007 05:40:18 +0000 (22:40 -0700)
--HG--
extra : convert_revision : 48dae1f3c680636833c137fe6b95b37ae84e188c

src/arch/x86/isa/formats/string.isa
src/arch/x86/isa/microops/specop.isa

index b1d3c4bbe4c7ad9d80190ba0505be3f66459e6a9..cb3ebc496897bdd690d87b104b24b9659f11dc6c 100644 (file)
@@ -103,7 +103,7 @@ def format StringInst(*opTypeSet) {{
             %s
         } else if (LEGACY_REPNE) {
             // The repne prefix is illegal
-            return new MicroFault(machInst, "illprefix", new InvalidOpcode);
+            return new MicroFault(machInst, "illprefix", new InvalidOpcode, 0);
         } else {
             %s
         }
index 5c9e8dda9e2ab86a98fd69daab627f08dac355e5..ca4a6dc577009b3b0f601fb42544df6f10caf46b 100644 (file)
 //////////////////////////////////////////////////////////////////////////
 
 output header {{
-    class MicroFault : public X86ISA::X86MicroopBase
+    class MicroFaultBase : public X86ISA::X86MicroopBase
     {
       protected:
         Fault fault;
-        void buildMe();
+        uint8_t cc;
 
       public:
-        MicroFault(ExtMachInst _machInst, const char * instMnem,
+        MicroFaultBase(ExtMachInst _machInst, const char * instMnem,
                 bool isMicro, bool isDelayed, bool isFirst, bool isLast,
-                Fault _fault);
-
-        MicroFault(ExtMachInst _machInst, const char * instMnem,
-                Fault _fault);
+                Fault _fault, uint8_t _cc);
 
-        %(BasicExecDeclare)s
+        MicroFaultBase(ExtMachInst _machInst, const char * instMnem,
+                Fault _fault, uint8_t _cc);
 
         std::string generateDisassembly(Addr pc,
                 const SymbolTable *symtab) const;
     };
 }};
 
-output decoder {{
-        Fault MicroFault::execute(%(CPU_exec_context)s *xc,
+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);
+
+        %(class_name)s(ExtMachInst _machInst, const char * instMnem,
+                Fault _fault, uint8_t _cc);
+
+        %(BasicExecDeclare)s
+    };
+}};
+
+def template MicroFaultExecute {{
+        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
                 Trace::InstRecord *traceData) const
         {
-            //Return the fault we were constructed with
-            return fault;
+            %(op_decl)s;
+            %(op_rd)s;
+            if (%(cond_test)s) {
+                //Return the fault we were constructed with
+                return fault;
+            } else {
+                return NoFault;
+            }
         }
 }};
 
 output decoder {{
-    inline MicroFault::MicroFault(
-            ExtMachInst machInst, const char * instMnem, Fault _fault) :
+    inline MicroFaultBase::MicroFaultBase(
+            ExtMachInst machInst, const char * instMnem,
+            Fault _fault, uint8_t _cc) :
         X86MicroopBase(machInst, "fault", instMnem,
-                false, false, false, false, No_OpClass), fault(_fault)
+                false, false, false, false, No_OpClass),
+        fault(_fault), cc(_cc)
     {
     }
 
-    inline MicroFault::MicroFault(
+    inline MicroFaultBase::MicroFaultBase(
             ExtMachInst machInst, const char * instMnem,
             bool isMicro, bool isDelayed, bool isFirst, bool isLast,
-            Fault _fault) :
+            Fault _fault, uint8_t _cc) :
         X86MicroopBase(machInst, "fault", instMnem,
                 isMicro, isDelayed, isFirst, isLast, No_OpClass),
-                fault(_fault)
+                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,
+            Fault _fault, uint8_t _cc) :
+        %(base_class)s(machInst, instMnem, _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();
+    }
+}};
+
 output decoder {{
-    std::string MicroFault::generateDisassembly(Addr pc,
+    std::string MicroFaultBase::generateDisassembly(Addr pc,
             const SymbolTable *symtab) const
     {
         std::stringstream response;
@@ -127,14 +176,37 @@ output decoder {{
 
 let {{
     class Fault(X86Microop):
-        def __init__(self, fault):
+        className = "MicroFault"
+        def __init__(self, fault, flags=None):
             self.fault = fault
+            if flags:
+                if not isinstance(flags, (list, tuple)):
+                    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 MicroFault(machInst, mnemonic
-                    %(flags)s, %(fault)s)''' % {
+            allocator = '''new %(class_name)s(machInst, mnemonic
+                    %(flags)s, %(fault)s, %(cc)s)''' % {
+                "class_name" : self.className,
                 "flags" : self.microFlagsText(microFlags),
-                "fault" : self.fault}
+                "fault" : self.fault,
+                "cc" : self.cond}
             return allocator
+
+    iop = InstObjParams("fault", "MicroFault", "MicroFaultBase",
+            {"code": "",
+             "cond_test": "checkCondition(ccFlagBits, cc)"})
+    exec_output = MicroFaultExecute.subst(iop)
+    header_output = MicroFaultDeclare.subst(iop)
+    decoder_output = MicroFaultConstructor.subst(iop)
+    iop = InstObjParams("fault", "MicroFaultFlags", "MicroFaultBase",
+            {"code": "",
+             "cond_test": "true"})
+    exec_output += MicroFaultExecute.subst(iop)
+    header_output += MicroFaultDeclare.subst(iop)
+    decoder_output += MicroFaultConstructor.subst(iop)
     microopClasses["fault"] = Fault
 }};