Add in incomplete pick and merge functions which read and write pieces of registers...
authorGabe Black <gblack@eecs.umich.edu>
Mon, 18 Jun 2007 14:15:00 +0000 (14:15 +0000)
committerGabe Black <gblack@eecs.umich.edu>
Mon, 18 Jun 2007 14:15:00 +0000 (14:15 +0000)
--HG--
extra : convert_revision : 56332b3999a9079b1bd305ee2826abdf593367e1

src/arch/x86/isa/base.isa
src/arch/x86/isa/microops/limmop.isa
src/arch/x86/isa/microops/regop.isa
src/arch/x86/isa_traits.hh

index eba24f709c22eef8e13370390217fc0b7781dcec..d9bd87f2d7e605c25e79e45e7c67f66301046681 100644 (file)
@@ -95,6 +95,14 @@ output header {{
         /**
          * Base class for all X86 static instructions.
          */
+        BitUnion64(X86IntReg)
+            Bitfield<63,0> R;
+            Bitfield<31,0> E;
+            Bitfield<15,0> X;
+            Bitfield<15,8> H;
+            Bitfield<7, 0> L;
+        EndBitUnion(X86IntReg)
+
         class X86StaticInst : public StaticInst
         {
           protected:
@@ -114,10 +122,50 @@ output header {{
 
             inline uint64_t merge(uint64_t into, uint64_t val, int size) const
             {
-                //FIXME This needs to be significantly more sophisticated
+                X86IntReg reg;
+                reg = into;
+                //FIXME This needs to be handle high bytes as well
+                switch(size)
+                {
+                  case 1:
+                    reg.L = val;
+                    break;
+                  case 2:
+                    reg.X = val;
+                    break;
+                  case 4:
+                    //XXX Check if this should be zeroed or sign extended
+                    reg = 0;
+                    reg.E = val;
+                    break;
+                  case 8:
+                    reg.R = val;
+                    break;
+                  default:
+                    panic("Tried to merge with unrecognized size %d.\n", size);
+                }
                 return val;
             }
 
+            inline uint64_t pick(uint64_t from, int size)
+            {
+                X86IntReg reg;
+                reg = from;
+                switch(size)
+                {
+                  case 1:
+                    return reg.L;
+                  case 2:
+                    return reg.E;
+                  case 4:
+                    return reg.X;
+                  case 8:
+                    return reg.R;
+                  default:
+                    panic("Tried to pick with unrecognized size %d.\n", size);
+                }
+            }
+
         };
 }};
 
@@ -128,6 +176,12 @@ output decoder {{
             ccprintf(os, "\t%s   ", mnemonic);
         }
 
+        inline void printMnemonic(std::ostream &os,
+                const char * instMnemonic, const char * mnemonic)
+        {
+            ccprintf(os, "\t%s : %s   ", instMnemonic, mnemonic);
+        }
+
         void
         X86StaticInst::printSrcReg(std::ostream &os, int reg) const
         {
@@ -197,6 +251,8 @@ output decoder {{
                   case INTREG_R15W:
                     ccprintf(os, "r15");
                     break;
+                  default:
+                    ccprintf(os, "t%d", reg - NUM_INTREGS);
                 }
             } else if (reg < Ctrl_Base_DepTag) {
                 ccprintf(os, "%%f%d", reg - FP_Base_DepTag);
index c76c074b1ad0201ae95aa642435c0db70dac74d7..141d7523f023bdca0007ab218fc97704b8c1261e 100644 (file)
@@ -79,6 +79,9 @@ def template MicroLimmOpDeclare {{
         const uint64_t imm;
         void buildMe();
 
+        std::string generateDisassembly(Addr pc,
+            const SymbolTable *symtab) const;
+
       public:
         %(class_name)s(ExtMachInst _machInst,
                 const char * instMnem,
@@ -93,6 +96,20 @@ def template MicroLimmOpDeclare {{
     };
 }};
 
+def template MicroLimmOpDisassembly {{
+    std::string %(class_name)s::generateDisassembly(Addr pc,
+            const SymbolTable *symtab) const
+    {
+        std::stringstream response;
+
+        printMnemonic(response, instMnem, mnemonic);
+        printReg(response, dest);
+        response << ", ";
+        ccprintf(response, "%#x", imm);
+        return response.str();
+    }
+}};
+
 def template MicroLimmOpConstructor {{
 
     inline void %(class_name)s::buildMe()
@@ -148,5 +165,6 @@ let {{
             {"code" : "DestReg = imm;"})
     header_output += MicroLimmOpDeclare.subst(iop)
     decoder_output += MicroLimmOpConstructor.subst(iop)
+    decoder_output += MicroLimmOpDisassembly.subst(iop)
     exec_output += MicroLimmOpExecute.subst(iop)
 }};
index a99194c5e7c7ccc0a6d3e89a11993cb865bdcc89..d5fb25cb59ce96503917d2ebf4a895c7d5107544 100644 (file)
 //
 //////////////////////////////////////////////////////////////////////////
 
+output header {{
+    /**
+     * Base classes for RegOps which provides a generateDisassembly method.
+     */
+    class RegOp : public X86MicroopBase
+    {
+      protected:
+        const RegIndex src1;
+        const RegIndex src2;
+        const RegIndex dest;
+        const bool setStatus;
+        const uint8_t dataSize;
+        const uint8_t ext;
+
+        // Constructor
+        RegOp(ExtMachInst _machInst,
+                const char *mnem, const char *_instMnem,
+                bool isMicro, bool isDelayed,
+                bool isFirst, bool isLast,
+                RegIndex _src1, RegIndex _src2, RegIndex _dest,
+                bool _setStatus, uint8_t _dataSize, uint8_t _ext,
+                OpClass __opClass) :
+            X86MicroopBase(_machInst, mnem, _instMnem,
+                    isMicro, isDelayed, isFirst, isLast,
+                    __opClass),
+            src1(_src1), src2(_src2), dest(_dest),
+            setStatus(_setStatus), dataSize(_dataSize), ext(_ext)
+        {
+        }
+
+        std::string generateDisassembly(Addr pc,
+            const SymbolTable *symtab) const;
+    };
+
+    class RegOpImm : public X86MicroopBase
+    {
+      protected:
+        const RegIndex src1;
+        const uint8_t imm8;
+        const RegIndex dest;
+        const bool setStatus;
+        const uint8_t dataSize;
+        const uint8_t ext;
+
+        // Constructor
+        RegOpImm(ExtMachInst _machInst,
+                const char * mnem, const char *_instMnem,
+                bool isMicro, bool isDelayed,
+                bool isFirst, bool isLast,
+                RegIndex _src1, uint8_t _imm8, RegIndex _dest,
+                bool _setStatus, uint8_t _dataSize, uint8_t _ext,
+                OpClass __opClass) :
+            X86MicroopBase(_machInst, mnem, _instMnem,
+                    isMicro, isDelayed, isFirst, isLast,
+                    __opClass),
+            src1(_src1), imm8(_imm8), dest(_dest),
+            setStatus(_setStatus), dataSize(_dataSize), ext(_ext)
+        {
+        }
+
+        std::string generateDisassembly(Addr pc,
+            const SymbolTable *symtab) const;
+    };
+}};
+
+output decoder {{
+    std::string RegOp::generateDisassembly(Addr pc,
+            const SymbolTable *symtab) const
+    {
+        std::stringstream response;
+
+        printMnemonic(response, instMnem, mnemonic);
+        printReg(response, dest);
+        response << ", ";
+        printReg(response, src1);
+        response << ", ";
+        printReg(response, src2);
+        return response.str();
+    }
+
+    std::string RegOpImm::generateDisassembly(Addr pc,
+            const SymbolTable *symtab) const
+    {
+        std::stringstream response;
+
+        printMnemonic(response, instMnem, mnemonic);
+        printReg(response, dest);
+        response << ", ";
+        printReg(response, src1);
+        ccprintf(response, ", %#x", imm8);
+        return response.str();
+    }
+}};
+
 def template MicroRegOpExecute {{
         Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
                 Trace::InstRecord *traceData) const
@@ -101,12 +195,6 @@ def template MicroRegOpDeclare {{
     class %(class_name)s : public %(base_class)s
     {
       protected:
-        const RegIndex src1;
-        const RegIndex src2;
-        const RegIndex dest;
-        const bool setStatus;
-        const uint8_t dataSize;
-        const uint8_t ext;
         void buildMe();
 
       public:
@@ -130,12 +218,6 @@ def template MicroRegOpImmDeclare {{
     class %(class_name)sImm : public %(base_class)s
     {
       protected:
-        const RegIndex src1;
-        const uint8_t imm8;
-        const RegIndex dest;
-        const bool setStatus;
-        const uint8_t dataSize;
-        const uint8_t ext;
         void buildMe();
 
       public:
@@ -166,9 +248,9 @@ def template MicroRegOpConstructor {{
             RegIndex _src1, RegIndex _src2, RegIndex _dest,
             bool _setStatus, uint8_t _dataSize, uint8_t _ext) :
         %(base_class)s(machInst, "%(mnemonic)s", instMnem,
-                false, false, false, false, %(op_class)s),
-                src1(_src1), src2(_src2), dest(_dest),
-                setStatus(_setStatus), dataSize(_dataSize), ext(_ext)
+                false, false, false, false,
+                _src1, _src2, _dest, _setStatus, _dataSize, _ext,
+                %(op_class)s)
     {
         buildMe();
     }
@@ -179,9 +261,9 @@ def template MicroRegOpConstructor {{
             RegIndex _src1, RegIndex _src2, RegIndex _dest,
             bool _setStatus, uint8_t _dataSize, uint8_t _ext) :
         %(base_class)s(machInst, "%(mnemonic)s", instMnem,
-                isMicro, isDelayed, isFirst, isLast, %(op_class)s),
-                src1(_src1), src2(_src2), dest(_dest),
-                setStatus(_setStatus), dataSize(_dataSize), ext(_ext)
+                isMicro, isDelayed, isFirst, isLast,
+                _src1, _src2, _dest, _setStatus, _dataSize, _ext,
+                %(op_class)s)
     {
         buildMe();
     }
@@ -199,9 +281,9 @@ def template MicroRegOpImmConstructor {{
             RegIndex _src1, uint8_t _imm8, RegIndex _dest,
             bool _setStatus, uint8_t _dataSize, uint8_t _ext) :
         %(base_class)s(machInst, "%(mnemonic)s", instMnem,
-                false, false, false, false, %(op_class)s),
-                src1(_src1), imm8(_imm8), dest(_dest),
-                setStatus(_setStatus), dataSize(_dataSize), ext(_ext)
+                false, false, false, false,
+                _src1, _imm8, _dest, _setStatus, _dataSize, _ext,
+                %(op_class)s)
     {
         buildMe();
     }
@@ -212,9 +294,9 @@ def template MicroRegOpImmConstructor {{
             RegIndex _src1, uint8_t _imm8, RegIndex _dest,
             bool _setStatus, uint8_t _dataSize, uint8_t _ext) :
         %(base_class)s(machInst, "%(mnemonic)s", instMnem,
-                isMicro, isDelayed, isFirst, isLast, %(op_class)s),
-                src1(_src1), imm8(_imm8), dest(_dest),
-                setStatus(_setStatus), dataSize(_dataSize), ext(_ext)
+                isMicro, isDelayed, isFirst, isLast,
+                _src1, _imm8, _dest, _setStatus, _dataSize, _ext,
+                %(op_class)s)
     {
         buildMe();
     }
@@ -227,7 +309,7 @@ let {{
             self.src1 = src1
             self.src2 = src2
             self.setStatus = False
-            self.dataSize = 1
+            self.dataSize = "env.dataSize"
             self.ext = 0
 
         def getAllocator(self, *microFlags):
@@ -249,7 +331,7 @@ let {{
             self.src1 = src1
             self.imm8 = imm8
             self.setStatus = False
-            self.dataSize = 1
+            self.dataSize = "env.dataSize"
             self.ext = 0
 
         def getAllocator(self, *microFlags):
@@ -290,7 +372,7 @@ let {{
         immCode = matcher.sub("imm8", code)
 
         # Build up the all register version of this micro op
-        iop = InstObjParams(name, Name, 'X86MicroopBase', {"code" : regCode})
+        iop = InstObjParams(name, Name, 'RegOp', {"code" : regCode})
         header_output += MicroRegOpDeclare.subst(iop)
         decoder_output += MicroRegOpConstructor.subst(iop)
         exec_output += MicroRegOpExecute.subst(iop)
@@ -305,7 +387,7 @@ let {{
 
         # Build up the immediate version of this micro op
         iop = InstObjParams(name + "i", Name,
-                'X86MicroopBase', {"code" : immCode})
+                'RegOpImm', {"code" : immCode})
         header_output += MicroRegOpImmDeclare.subst(iop)
         decoder_output += MicroRegOpImmConstructor.subst(iop)
         exec_output += MicroRegOpImmExecute.subst(iop)
index 5a625f741121eb32054703bb5a298e988faebdba..7aba6248af9eb7c3c01f17fa370147a075b3be40 100644 (file)
@@ -81,8 +81,8 @@ namespace X86ISA
 
     // These enumerate all the registers for dependence tracking.
     enum DependenceTags {
-        //The number of microcode registers needs to be added to this
-        FP_Base_DepTag = 16,
+        //There are 16 microcode registers at the moment
+        FP_Base_DepTag = 32,
         Ctrl_Base_DepTag =
             FP_Base_DepTag +
             //mmx/x87 registers