Implement rip relative addressing and put in some missing loads and stores.
authorGabe Black <gblack@eecs.umich.edu>
Wed, 20 Jun 2007 19:08:04 +0000 (19:08 +0000)
committerGabe Black <gblack@eecs.umich.edu>
Wed, 20 Jun 2007 19:08:04 +0000 (19:08 +0000)
--HG--
extra : convert_revision : 99053414cef40f13c5226871a72909b2622d8c26

src/arch/x86/isa/formats/multi.isa
src/arch/x86/isa/insts/arithmetic/add_and_subtract.py
src/arch/x86/isa/insts/compare_and_test/test.py
src/arch/x86/isa/insts/data_transfer/move.py
src/arch/x86/isa/insts/load_effective_address.py
src/arch/x86/isa/insts/logical.py
src/arch/x86/isa/specialize.isa

index 37b28fe647d9d2252e9aad1cab1e019f964af624..97777f7277c90c34ed07fdf4415f71f4fba7a24f 100644 (file)
@@ -70,8 +70,8 @@ def format Inst(*opTypeSet) {{
 def format MultiInst(switchVal, *opTypeSets) {{
     switcher = {}
     for (count, opTypeSet) in zip(xrange(len(opTypeSets)), opTypeSets):
-        switcher[count] = (Name, opTypeSet, EmulEnv())
-    blocks = doSplitDecode(specializeInst, switchVal, switcher)
+        switcher[count] = (specializeInst, Name, opTypeSet, EmulEnv())
+    blocks = doSplitDecode(switchVal, switcher)
     (header_output, decoder_output,
      decode_block, exec_output) = blocks.makeList()
 }};
index 349c2bb46d2f6c1395a2cf1095d0672f8fd51020..de66f70f36cd1f7be4072622f5b8e238324b1476 100644 (file)
@@ -61,9 +61,21 @@ def macroop SUB_R_I
 
 def macroop SUB_M_I
 {
-    #Load into t1
+    ld "NUM_INTREGS+1", 3, ["env.scale", "env.index", "env.base"], \
+        "DISPLACEMENT"
     subi "NUM_INTREGS+1", "NUM_INTREGS+1", "IMMEDIATE"
-    #save from t1
+    st "NUM_INTREGS+1", 3, ["env.scale", "env.index", "env.base"], \
+        "DISPLACEMENT"
+};
+
+def macroop SUB_P_I
+{
+    rdip "NUM_INTREGS+7"
+    ld "NUM_INTREGS+1", 3, ["env.scale", "env.index", "env.base"], \
+        "DISPLACEMENT"
+    subi "NUM_INTREGS+1", "NUM_INTREGS+1", "IMMEDIATE"
+    st "NUM_INTREGS+1", 3, ["env.scale", "env.index", "env.base"], \
+        "DISPLACEMENT"
 };
 '''
 #let {{
index 36abab5d1f2026717734faa1644f84d9e0e78d54..7b4ab0781be1d81f6e47753334cbe8f98e79e0cf 100644 (file)
@@ -61,6 +61,14 @@ def macroop TEST_M_R
     and "NUM_INTREGS", "NUM_INTREGS+1", "env.reg"
 };
 
+def macroop TEST_P_R
+{
+    rdip "NUM_INTREGS+7"
+    ld "NUM_INTREGS+1", 3, ["env.scale", "env.index", "env.base"], \
+        "DISPLACEMENT"
+    and "NUM_INTREGS", "NUM_INTREGS+1", "env.reg"
+};
+
 def macroop TEST_R_R
 {
     and "NUM_INTREGS", "env.reg", "env.regm"
@@ -74,6 +82,15 @@ def macroop TEST_M_I
     and "NUM_INTREGS", "NUM_INTREGS+1", "NUM_INTREGS+2"
 };
 
+def macroop TEST_P_I
+{
+    rdip "NUM_INTREGS+7"
+    ld "NUM_INTREGS+1", 3, ["env.scale", "env.index", "env.base"], \
+        "DISPLACEMENT"
+    limm "NUM_INTREGS+2", "IMMEDIATE"
+    and "NUM_INTREGS", "NUM_INTREGS+1", "NUM_INTREGS+2"
+};
+
 def macroop TEST_R_I
 {
     limm "NUM_INTREGS+1", "IMMEDIATE"
index c674329ea98695d7fdc04aabe276bf2f068ec726..662b2c3732e2e1e5dce78e6ae1958c024d093640 100644 (file)
@@ -62,17 +62,35 @@ def macroop MOV_M_R {
     st "env.reg", 3, ["env.scale", "env.index", "env.base"], "DISPLACEMENT"
 };
 
+def macroop MOV_P_R {
+    rdip "NUM_INTREGS+7"
+    st "env.reg", 3, ["env.scale", "env.index", "env.base"], "DISPLACEMENT"
+};
+
 def macroop MOV_R_M {
     ld "env.reg", 3, ["env.scale", "env.index", "env.base"], "DISPLACEMENT"
 };
 
+def macroop MOV_R_P {
+    rdip "NUM_INTREGS+7"
+    ld "env.reg", 3, ["env.scale", "env.index", "env.base"], "DISPLACEMENT"
+};
+
 def macroop MOV_R_I {
     limm "env.reg", "IMMEDIATE"
 };
 
 def macroop MOV_M_I {
-    limm "env.reg", "IMMEDIATE"
-    #Do a store to put the register operand into memory
+    limm "NUM_INTREGS+1", "IMMEDIATE"
+    st "NUM_INTREGS+1", 3, ["env.scale", "env.index", "env.base"], \
+        "DISPLACEMENT"
+};
+
+def macroop MOV_P_I {
+    rdip "NUM_INTREGS+7"
+    limm "NUM_INTREGS+1", "IMMEDIATE"
+    st "NUM_INTREGS+1", 3, ["env.scale", "env.index", "env.base"], \
+        "DISPLACEMENT"
 };
 
 def macroop MOVSXD_R_R {
@@ -80,8 +98,16 @@ def macroop MOVSXD_R_R {
 };
 
 def macroop MOVSXD_R_M {
-    #Do a load to fill the register operand from memory
-    sext "env.reg", "env.regm", "env.dataSize"
+    ld "NUM_INTREGS+1", 3, ["env.scale", "env.index", "env.base"], \
+        "DISPLACEMENT"
+    sext "env.reg", "NUM_INTREGS+1", "env.dataSize"
+};
+
+def macroop MOVSXD_R_P {
+    rdip "NUM_INTREGS+7"
+    ld "NUM_INTREGS+1", 3, ["env.scale", "env.index", "env.base"], \
+        "DISPLACEMENT"
+    sext "env.reg", "NUM_INTREGS+1", "env.dataSize"
 };
 '''
 #let {{
index ac32638a0fb60b4e10d5fa6029d53b3a7b4dacf1..f5f92ddbfb23dd8c2e58ac050cbc94325b2b8a2e 100644 (file)
@@ -57,4 +57,9 @@ microcode = '''
 def macroop LEA_R_M {
     lea "env.reg", 3, ["env.scale", "env.index", "env.base"], "DISPLACEMENT"
 };
+
+def macroop LEA_R_P {
+    rdip "NUM_INTREGS+7"
+    lea "env.reg", 3, ["env.scale", "env.index", "env.base"], "DISPLACEMENT"
+};
 '''
index 0b7c412085c8326941340e780745fc155f2a1306..d02bfd5862c2eb70d85abf0d0083b5ee87d73d74 100644 (file)
@@ -67,14 +67,35 @@ def macroop XOR_R_I
 
 def macroop XOR_M_R
 {
-    #Do a load to get one of the sources
+    ld "NUM_INTREGS+1", 3, ["env.scale", "env.index", "env.base"], \
+        "DISPLACEMENT"
     xor "NUM_INTREGS+1", "NUM_INTREGS+1", "env.reg"
-    #Do a store to write the destination
+    st "NUM_INTREGS+1", 3, ["env.scale", "env.index", "env.base"], \
+        "DISPLACEMENT"
+};
+
+def macroop XOR_P_R
+{
+    rdip "NUM_INTREGS+7"
+    ld "NUM_INTREGS+1", 3, ["env.scale", "env.index", "env.base"], \
+        "DISPLACEMENT"
+    xor "NUM_INTREGS+1", "NUM_INTREGS+1", "env.reg"
+    st "NUM_INTREGS+1", 3, ["env.scale", "env.index", "env.base"], \
+        "DISPLACEMENT"
 };
 
 def macroop XOR_R_M
 {
-    #Do a load to get one of the sources
+    ld "NUM_INTREGS+1", 3, ["env.scale", "env.index", "env.base"], \
+        "DISPLACEMENT"
+    xor "env.reg", "env.reg", "NUM_INTREGS+1"
+};
+
+def macroop XOR_R_P
+{
+    rdip "NUM_INTREGS+7"
+    ld "NUM_INTREGS+1", 3, ["env.scale", "env.index", "env.base"], \
+        "DISPLACEMENT"
     xor "env.reg", "env.reg", "NUM_INTREGS+1"
 };
 
@@ -86,10 +107,23 @@ def macroop AND_R_I
 
 def macroop AND_M_I
 {
-    #Do a load to get one of the sources
+    ld "NUM_INTREGS+2", 3, ["env.scale", "env.index", "env.base"], \
+        "DISPLACEMENT"
+    limm "NUM_INTREGS+1", "IMMEDIATE"
+    and "NUM_INTREGS+2", "NUM_INTREGS+2", "NUM_INTREGS+1"
+    st "NUM_INTREGS+2", 3, ["env.scale", "env.index", "env.base"], \
+        "DISPLACEMENT"
+};
+
+def macroop AND_P_I
+{
+    rdip "NUM_INTREGS+7"
+    ld "NUM_INTREGS+2", 3, ["env.scale", "env.index", "env.base"], \
+        "DISPLACEMENT"
     limm "NUM_INTREGS+1", "IMMEDIATE"
-    and "NUM_INTREGS+1", "NUM_INTREGS+1", "NUM_INTREGS+2"
-    #Do a store to write the destination
+    and "NUM_INTREGS+2", "NUM_INTREGS+2", "NUM_INTREGS+1"
+    st "NUM_INTREGS+2", 3, ["env.scale", "env.index", "env.base"], \
+        "DISPLACEMENT"
 };
 '''
 #let {{
index 10e57ba182c5c6e45432121b19cc9e78dcf19d3c..3183f32ba97a5ecf344b69e9de3fe1f6c1da6222 100644 (file)
 let {{
     # This code builds up a decode block which decodes based on switchval.
     # vals is a dict which matches case values with what should be decoded to.
-    # builder is called on the exploded contents of "vals" values to generate
-    # whatever code should be used.
-    def doSplitDecode(builder, switchVal, vals, default = None):
+    # Each element of the dict is a list containing a function and then the
+    # arguments to pass to it.
+    def doSplitDecode(switchVal, vals, default = None):
         blocks = OutputBlocks()
         blocks.decode_block = 'switch(%s) {\n' % switchVal
         for (val, todo) in vals.items():
-            new_blocks = builder(*todo)
+            new_blocks = todo[0](*todo[1:])
             new_blocks.decode_block = \
                 '\tcase %s: %s\n' % (val, new_blocks.decode_block)
             blocks.append(new_blocks)
         if default:
-            new_blocks = builder(*default)
+            new_blocks = default[0](*default[1:])
             new_blocks.decode_block = \
                 '\tdefault: %s\n' % new_blocks.decode_block
             blocks.append(new_blocks)
@@ -83,6 +83,27 @@ let {{
         return blocks
 }};
 
+let {{
+    def doRipRelativeDecode(Name, opTypes, env):
+        # print "RIPing %s with opTypes %s" % (Name, opTypes)
+        normBlocks = specializeInst(Name + "_M", copy.copy(opTypes), copy.copy(env))
+        ripBlocks = specializeInst(Name + "_P", copy.copy(opTypes), copy.copy(env))
+
+        blocks = OutputBlocks()
+        blocks.append(normBlocks)
+        blocks.append(ripBlocks)
+
+        blocks.decode_block = '''
+        if(machInst.modRM.mod == 0 &&
+          machInst.modRM.rm == 5 &&
+          machInst.mode.submode == SixtyFourBitMode)
+        { %s }
+        else
+        { %s }''' % \
+         (ripBlocks.decode_block, normBlocks.decode_block)
+        return blocks
+}};
+
 let {{
     class OpType(object):
         parser = re.compile(r"(?P<tag>[A-Z]+)(?P<size>[a-z]*)|(r(?P<reg>[A-Z0-9]+)(?P<rsize>[a-z]*))")
@@ -142,9 +163,9 @@ let {{
                 # modrm addressing.
                 memEnv = copy.copy(env)
                 memEnv.doModRM = True
-                return doSplitDecode(specializeInst, "MODRM_MOD",
-                    {"3" : (Name + "_R", copy.copy(opTypes), regEnv)},
-                           (Name + "_M", copy.copy(opTypes), memEnv))
+                return doSplitDecode("MODRM_MOD",
+                    {"3" : (specializeInst, Name + "_R", copy.copy(opTypes), regEnv)},
+                           (doRipRelativeDecode, Name, copy.copy(opTypes), memEnv))
             elif opType.tag in ("I", "J"):
                 # Immediates
                 Name += "_I"