Get rid of the immediate and displacement components of the EmulEnv struct and use...
authorGabe Black <gblack@eecs.umich.edu>
Tue, 19 Jun 2007 14:18:25 +0000 (14:18 +0000)
committerGabe Black <gblack@eecs.umich.edu>
Tue, 19 Jun 2007 14:18:25 +0000 (14:18 +0000)
--HG--
extra : convert_revision : 0686296ca8b72940d961ecc6051063bfda1e932d

src/arch/x86/isa/insts/data_transfer/move.py
src/arch/x86/isa/insts/data_transfer/stack_operations.py
src/arch/x86/isa/insts/logical.py
src/arch/x86/isa/macroop.isa
src/arch/x86/isa/microops/ldstop.isa
src/arch/x86/isa/operands.isa
src/arch/x86/isa_traits.hh
src/arch/x86/types.hh
src/arch/x86/utility.hh

index 9d23b24e8d8991871bb3f8bb86d503426ab60538..ff4af0af47f5a6de4b58601c3c72cb8fb9a0a19a 100644 (file)
@@ -67,11 +67,11 @@ def macroop MOV_R_M {
 };
 
 def macroop MOV_R_I {
-    limm "env.reg", "env.immediate"
+    limm "env.reg", "IMMEDIATE"
 };
 
 def macroop MOV_M_I {
-    limm "env.reg", "env.immediate"
+    limm "env.reg", "IMMEDIATE"
     #Do a store to put the register operand into memory
 };
 '''
index b7ec0ec669626275f631763dcca691def7078ecc..50b690354423801826877d8e0d57b0344614aa09 100644 (file)
 
 microcode = '''
 def macroop POP_R {
+
+    # Make the default data size of pops 64 bits in 64 bit mode
     .adjust_env "if(machInst.mode.submode == SixtyFourBitMode && env.dataSize == 4) env.dataSize = 8\;"
-    # There needs to be a load here to actually "pop" the data
+
+    ld "env.reg", 2, [0, "NUM_INTREGS", "INTREG_RSP"]
     addi "INTREG_RSP", "INTREG_RSP", "env.dataSize"
 };
 
 def macroop PUSH_R {
+
+    # Make the default data size of pops 64 bits in 64 bit mode
     .adjust_env "if(machInst.mode.submode == SixtyFourBitMode && env.dataSize == 4) env.dataSize = 8\;"
+
     subi "INTREG_RSP", "INTREG_RSP", "env.dataSize"
-    # There needs to be a store here to actually "push" the data
+    st "env.reg", 2, [0, "NUM_INTREGS", "INTREG_RSP"]
 };
 '''
 #let {{
index ec0ed97b29dc3d650b344885967a77ae9dbcdde2..824c75053ae3dc20df329c918126cf4d66557a34 100644 (file)
@@ -61,34 +61,34 @@ def macroop XOR_R_R
 
 def macroop XOR_R_I
 {
-    limm "NUM_INTREGS", "env.immediate"
-    xor "env.reg", "env.reg", "NUM_INTREGS"
+    limm "NUM_INTREGS+1", "IMMEDIATE"
+    xor "env.reg", "env.reg", "NUM_INTREGS+1"
 };
 
 def macroop XOR_M_R
 {
     #Do a load to get one of the sources
-    xor "NUM_INTREGS", "NUM_INTREGS", "env.reg"
+    xor "NUM_INTREGS+1", "NUM_INTREGS+1", "env.reg"
     #Do a store to write the destination
 };
 
 def macroop XOR_R_M
 {
     #Do a load to get one of the sources
-    xor "env.reg", "env.reg", "NUM_INTREGS"
+    xor "env.reg", "env.reg", "NUM_INTREGS+1"
 };
 
 def macroop AND_R_I
 {
-    limm "NUM_INTREGS", "env.immediate"
-    and "env.reg", "env.reg", "NUM_INTREGS"
+    limm "NUM_INTREGS+1", "IMMEDIATE"
+    and "env.reg", "env.reg", "NUM_INTREGS+1"
 };
 
 def macroop AND_M_I
 {
     #Do a load to get one of the sources
-    limm "NUM_INTREGS", "env.immediate"
-    and "NUM_INTREGS", "NUM_INTREGS", "NUM_INTREGS+1"
+    limm "NUM_INTREGS+1", "IMMEDIATE"
+    and "NUM_INTREGS+1", "NUM_INTREGS+1", "NUM_INTREGS+2"
     #Do a store to write the destination
 };
 '''
index 2d928d7c9a347919f84868cba8049be972caad74..0cc818409e6915b2a35a879eb5c4f96ace1e6ab3 100644 (file)
@@ -189,17 +189,18 @@ output header {{
     {
         X86ISA::RegIndex reg;
         X86ISA::RegIndex regm;
-        uint64_t immediate;
-        uint64_t displacement;
-        int addressSize;
+        uint8_t scale;
+        X86ISA::RegIndex index;
+        X86ISA::RegIndex base;
         int dataSize;
+        int addressSize;
+        int stackSize;
 
         EmulEnv(X86ISA::RegIndex _reg, X86ISA::RegIndex _regm,
-                uint64_t _immediate, uint64_t _displacement,
-                int _addressSize, int _dataSize) :
+                int _dataSize, int _addressSize, int _stackSize) :
             reg(_reg), regm(_regm),
-            immediate(_immediate), displacement(_displacement),
-            addressSize(_addressSize), dataSize(_dataSize)
+            dataSize(_dataSize), addressSize(_addressSize),
+            stackSize(_stackSize)
         {;}
     };
 }};
@@ -211,17 +212,15 @@ let {{
             self.regUsed = False
             self.regm = "0"
             self.regmUsed = False
-            self.immediate = "IMMEDIATE"
-            self.displacement = "DISPLACEMENT"
             self.addressSize = "ADDRSIZE"
             self.dataSize = "OPSIZE"
+            self.stackSize = "STACKSIZE"
         def getAllocator(self):
             return '''EmulEnv(%(reg)s,
                               %(regm)s,
-                              %(immediate)s,
-                              %(displacement)s,
+                              %(dataSize)s,
                               %(addressSize)s,
-                              %(dataSize)s)''' % \
+                              %(stackSize)s)''' % \
                 self.__dict__
         def addReg(self, reg):
             if not self.regUsed:
index 7e164fa828b18e3a877db9f5507b0acc5ed68382..38b690e6a4eb456517e0466e287eb56284856b62 100644 (file)
 //
 //////////////////////////////////////////////////////////////////////////
 
-def template MicroLdStOpDeclare {{
-    class %(class_name)s : public X86MicroopBase
+
+// Load templates
+
+output header {{
+    /**
+     * Base class for load and store ops
+     */
+    class LdStOp : public X86MicroopBase
     {
       protected:
         const uint8_t scale;
@@ -71,6 +77,195 @@ def template MicroLdStOpDeclare {{
         const RegIndex data;
         const uint8_t dataSize;
         const uint8_t addressSize;
+
+        //Constructor
+        LdStOp(ExtMachInst _machInst,
+                const char * mnem, const char * _instMnem,
+                bool isMicro, bool isDelayed, bool isFirst, bool isLast,
+                uint8_t _scale, RegIndex _index, RegIndex _base,
+                uint64_t _disp, uint8_t _segment,
+                RegIndex _data,
+                uint8_t _dataSize, uint8_t _addressSize,
+                OpClass __opClass) :
+        X86MicroopBase(machInst, mnem, _instMnem,
+                isMicro, isDelayed, isFirst, isLast, __opClass),
+                scale(_scale), index(_index), base(_base),
+                disp(_disp), segment(_segment),
+                data(_data),
+                dataSize(_dataSize), addressSize(_addressSize)
+        {}
+
+        std::string generateDisassembly(Addr pc,
+            const SymbolTable *symtab) const;
+    };
+}};
+
+output decoder {{
+    std::string LdStOp::generateDisassembly(Addr pc,
+            const SymbolTable *symtab) const
+    {
+        std::stringstream response;
+
+        printMnemonic(response, instMnem, mnemonic);
+        printReg(response, data);
+        response << ", ";
+        printSegment(response, segment);
+        ccprintf(response, ":[%d*", scale);
+        printReg(response, index);
+        response << " + ";
+        printReg(response, base);
+        ccprintf(response, " + %#x]", disp);
+        return response.str();
+    }
+}};
+
+def template MicroLoadExecute {{
+    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+          Trace::InstRecord *traceData) const
+    {
+        Fault fault = NoFault;
+        Addr EA;
+
+        %(op_decl)s;
+        %(op_rd)s;
+        %(ea_code)s;
+        DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
+
+        fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, 0);
+        if(fault == NoFault)
+        {
+            %(code)s;
+        }
+        if(fault == NoFault)
+        {
+            %(op_wb)s;
+        }
+
+        return fault;
+    }
+}};
+
+def template MicroLoadInitiateAcc {{
+    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
+            Trace::InstRecord * traceData) const
+    {
+        Fault fault = NoFault;
+        Addr EA;
+
+        %(op_decl)s;
+        %(op_rd)s;
+        %(ea_code)s;
+        DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
+
+        fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, 0);
+
+        return fault;
+    }
+}};
+
+def template MicroLoadCompleteAcc {{
+    Fault %(class_name)s::completeAcc(PacketPtr pkt,
+            %(CPU_exec_context)s * xc,
+            Trace::InstRecord * traceData) const
+    {
+        Fault fault = NoFault;
+
+        %(op_decl)s;
+        %(op_rd)s;
+
+        Mem = pkt->get<typeof(Mem)>();
+        %(code)s;
+
+        if(fault == NoFault)
+        {
+            %(op_wb)s;
+        }
+
+        return fault;
+    }
+}};
+
+// Store templates
+
+def template MicroStoreExecute {{
+    Fault %(class_name)s::execute(%(CPU_exec_context)s * xc,
+            Trace::InstRecord *traceData) const
+    {
+        Fault fault = NoFault;
+
+        Addr EA;
+        %(op_decl)s;
+        %(op_rd)s;
+        %(ea_code)s;
+        DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
+
+        %(code)s;
+
+        if(fault == NoFault)
+        {
+            fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem,
+                    EA, 0, 0);
+        }
+        if(fault == NoFault)
+        {
+            %(op_wb)s;
+        }
+
+        return fault;
+    }
+}};
+
+def template MicroStoreInitiateAcc {{
+    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
+            Trace::InstRecord * traceData) const
+    {
+        Fault fault = NoFault;
+
+        Addr EA;
+        %(op_decl)s;
+        %(op_rd)s;
+        %(ea_code)s;
+        DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
+
+        %(code)s;
+
+        if(fault == NoFault)
+        {
+            fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem,
+                    EA, 0, 0);
+        }
+        if(fault == NoFault)
+        {
+            %(op_wb)s;
+        }
+        return fault;
+    }
+}};
+
+def template MicroStoreCompleteAcc {{
+    Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc,
+            Trace::InstRecord * traceData) const
+    {
+        return NoFault;
+    }
+}};
+
+// Common templates
+
+//This delcares the initiateAcc function in memory operations
+def template InitiateAccDeclare {{
+    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
+}};
+
+//This declares the completeAcc function in memory operations
+def template CompleteAccDeclare {{
+    Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
+}};
+
+def template MicroLdStOpDeclare {{
+    class %(class_name)s : public %(base_class)s
+    {
+      protected:
         void buildMe();
 
       public:
@@ -90,6 +285,10 @@ def template MicroLdStOpDeclare {{
                 uint8_t _dataSize, uint8_t _addressSize);
 
         %(BasicExecDeclare)s
+
+        %(InitiateAccDeclare)s
+
+        %(CompleteAccDeclare)s
     };
 }};
 
@@ -107,11 +306,10 @@ def template MicroLdStOpConstructor {{
             RegIndex _data,
             uint8_t _dataSize, uint8_t _addressSize) :
         %(base_class)s(machInst, "%(mnemonic)s", instMnem,
-                false, false, false, false, %(op_class)s),
-                scale(_scale), index(_index), base(_base),
-                disp(_disp), segment(_segment),
-                data(_data),
-                dataSize(_dataSize), addressSize(_addressSize)
+                false, false, false, false,
+                _scale, _index, _base,
+                _disp, _segment, _data,
+                _dataSize, _addressSize, %(op_class)s)
     {
         buildMe();
     }
@@ -120,17 +318,106 @@ def template MicroLdStOpConstructor {{
             ExtMachInst machInst, const char * instMnem,
             bool isMicro, bool isDelayed, bool isFirst, bool isLast,
             uint8_t _scale, RegIndex _index, RegIndex _base,
-            uint64_t _disp, uint8_t segment,
-            RegIndex data,
-            uint8_t dataSize, uint8_t addressSize) :
+            uint64_t _disp, uint8_t _segment,
+            RegIndex _data,
+            uint8_t _dataSize, uint8_t _addressSize) :
         %(base_class)s(machInst, "%(mnemonic)s", instMnem,
-                isMicro, isDelayed, isFirst, isLast, %(op_class)s),
-                scale(_scale), index(_index), base(_base),
-                disp(_disp), segment(_segment),
-                data(_data),
-                dataSize(_dataSize), addressSize(_addressSize)
+                isMicro, isDelayed, isFirst, isLast,
+                _scale, _index, _base,
+                _disp, _segment, _data,
+                _dataSize, _addressSize, %(op_class)s)
     {
         buildMe();
     }
 }};
 
+let {{
+    class LdStOp(X86Microop):
+        def __init__(self, data, segment, addr, disp):
+            self.data = data
+            [self.scale, self.index, self.base] = addr
+            self.disp = disp
+            self.segment = segment
+            self.dataSize = "env.dataSize"
+            self.addressSize = "env.addressSize"
+
+        def getAllocator(self, *microFlags):
+            allocator = '''new %(class_name)s(machInst, mnemonic
+                    %(flags)s, %(scale)s, %(index)s, %(base)s,
+                    %(disp)s, %(segment)s, %(data)s,
+                    %(dataSize)s, %(addressSize)s)''' % {
+                "class_name" : self.className,
+                "flags" : self.microFlagsText(microFlags),
+                "scale" : self.scale, "index" : self.index,
+                "base" : self.base,
+                "disp" : self.disp,
+                "segment" : self.segment, "data" : self.data,
+                "dataSize" : self.dataSize, "addressSize" : self.addressSize}
+            return allocator
+}};
+
+let {{
+
+    # Make these empty strings so that concatenating onto
+    # them will always work.
+    header_output = ""
+    decoder_output = ""
+    exec_output = ""
+
+    calculateEA = "EA = scale * Index + Base + disp;"
+
+    def defineMicroLoadOp(mnemonic, code):
+        global header_output
+        global decoder_output
+        global exec_output
+        global microopClasses
+        Name = mnemonic
+        name = mnemonic.lower()
+
+        # Build up the all register version of this micro op
+        iop = InstObjParams(name, Name, 'LdStOp',
+                {"code": code, "ea_code": calculateEA})
+        header_output += MicroLdStOpDeclare.subst(iop)
+        decoder_output += MicroLdStOpConstructor.subst(iop)
+        exec_output += MicroLoadExecute.subst(iop)
+        exec_output += MicroLoadInitiateAcc.subst(iop)
+        exec_output += MicroLoadCompleteAcc.subst(iop)
+
+        class LoadOp(LdStOp):
+            def __init__(self, data, segment, addr, disp = 0):
+                super(LoadOp, self).__init__(data, segment, addr, disp)
+                self.className = Name
+                self.mnemonic = name
+
+        microopClasses[name] = LoadOp
+
+    defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);')
+
+    def defineMicroStoreOp(mnemonic, code):
+        global header_output
+        global decoder_output
+        global exec_output
+        global microopClasses
+        Name = mnemonic
+        name = mnemonic.lower()
+
+        # Build up the all register version of this micro op
+        iop = InstObjParams(name, Name, 'LdStOp',
+                {"code": code, "ea_code": calculateEA})
+        header_output += MicroLdStOpDeclare.subst(iop)
+        decoder_output += MicroLdStOpConstructor.subst(iop)
+        exec_output += MicroStoreExecute.subst(iop)
+        exec_output += MicroStoreInitiateAcc.subst(iop)
+        exec_output += MicroStoreCompleteAcc.subst(iop)
+
+        class StoreOp(LdStOp):
+            def __init__(self, data, addr, segment):
+                super(LoadOp, self).__init__(data, addr, segment)
+                self.className = Name
+                self.mnemonic = name
+
+        microopClasses[name] = StoreOp
+
+    defineMicroLoadOp('St', 'Mem = Data;')
+}};
+
index 1564c23e9a7d47599aa85c56bf0d617f1ed478b4..b2ac17d667d7804c8a05c1f7aab00ea31a0c97df 100644 (file)
@@ -99,7 +99,9 @@ def operands {{
         'DestReg':       ('IntReg', 'uqw', 'dest', 'IsInteger', 1),
         'SrcReg1':       ('IntReg', 'uqw', 'src1', 'IsInteger', 2),
         'SrcReg2':       ('IntReg', 'uqw', 'src2', 'IsInteger', 3),
-        'IntRegOp0':     ('IntReg', 'udw', 'param0', 'IsInteger', 1),
-        'IntRegOp1':     ('IntReg', 'udw', 'param1', 'IsInteger', 2),
-        'IntRegOp2':     ('IntReg', 'udw', 'param2', 'IsInteger', 2),
+        'Base':          ('IntReg', 'uqw', 'base', 'IsInteger', 4),
+        'Index':         ('IntReg', 'uqw', 'index', 'IsInteger', 5),
+        'Data':          ('IntReg', 'uqw', 'data', 'IsInteger', 6),
+        'RIP':           ('NPC', 'uqw', None, (None, None, 'IsControl'), 10),
+        'Mem':           ('Mem', 'uqw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 100)
 }};
index 7aba6248af9eb7c3c01f17fa370147a075b3be40..4c02ee35e18bc3c0b3589d776f24853b0f55142f 100644 (file)
@@ -93,7 +93,7 @@ namespace X86ISA
 
     // semantically meaningful register indices
     //There is no such register in X86
-    const int ZeroReg = 0;
+    const int ZeroReg = NUM_INTREGS;
     const int StackPointerReg = INTREG_RSP;
     //X86 doesn't seem to have a link register
     const int ReturnAddressReg = 0;
index fc9f1d82b15a29503193385714ea57defce1742d..298dff80b239383b27d1e5aae0cb6fe9c0f3a02a 100644 (file)
@@ -169,6 +169,8 @@ namespace X86ISA
         uint8_t opSize;
         //The effective address size.
         uint8_t addrSize;
+        //The effective stack size.
+        uint8_t stackSize;
 
         //Mode information
         OperatingMode mode;
@@ -193,8 +195,6 @@ namespace X86ISA
     inline static bool
         operator == (const ExtMachInst &emi1, const ExtMachInst &emi2)
     {
-        if(emi1.mode != emi2.mode)
-            return false;
         if(emi1.legacy != emi2.legacy)
             return false;
         if(emi1.rex != emi2.rex)
@@ -215,6 +215,14 @@ namespace X86ISA
             return false;
         if(emi1.displacement != emi2.displacement)
             return false;
+        if(emi1.mode != emi2.mode)
+            return false;
+        if(emi1.opSize != emi2.opSize)
+            return false;
+        if(emi1.addrSize != emi2.addrSize)
+            return false;
+        if(emi1.stackSize != emi2.stackSize)
+            return false;
         return true;
     }
 
index ed401a519b3e4fdba3cefa40bb4c61ad80ad3d5b..3f3f1cca3fbf4822b71b8c9be2af068d2e586b6e 100644 (file)
@@ -79,7 +79,8 @@ namespace __hash_namespace {
                     ((uint64_t)emi.opcode.prefixB << 8) |
                     ((uint64_t)emi.opcode.op)) ^
                     emi.immediate ^ emi.displacement ^
-                    emi.mode ^ emi.opSize;
+                    emi.mode ^
+                    emi.opSize ^ emi.addrSize ^ emi.stackSize;
         };
     };
 }