X86: Take advantage of new PCState syntax.
[gem5.git] / src / arch / x86 / isa / specialize.isa
index 5165ea206cfbc39e78351c84fa90d5b87ac098d6..779abefc7f59db329869b2b5119b29056c166197 100644 (file)
@@ -3,43 +3,25 @@
 // Copyright (c) 2007 The Hewlett-Packard Development Company
 // 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
@@ -86,8 +68,17 @@ let {{
 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))
+        env.memoryInst = True
+        normEnv = copy.copy(env)
+        normEnv.addToDisassembly(
+                '''printMem(out, env.seg, env.scale, env.index, env.base,
+                    machInst.displacement, env.addressSize, false);''')
+        normBlocks = specializeInst(Name + "_M", copy.copy(opTypes), normEnv)
+        ripEnv = copy.copy(env)
+        ripEnv.addToDisassembly(
+                '''printMem(out, env.seg, 1, 0, 0,
+                    machInst.displacement, env.addressSize, true);''')
+        ripBlocks = specializeInst(Name + "_P", copy.copy(opTypes), ripEnv)
 
         blocks = OutputBlocks()
         blocks.append(normBlocks)
@@ -114,7 +105,8 @@ let {{
             self.reg = match.group("reg")
             self.tag = match.group("tag")
             self.size = match.group("size")
-            self.rsize = match.group("rsize")
+            if not self.size:
+                self.size = match.group("rsize")
 
     ModRMRegIndex = "(MODRM_REG | (REX_R << 3))"
     ModRMRMIndex = "(MODRM_RM | (REX_B << 3))"
@@ -129,55 +121,117 @@ let {{
             opType = OpType(opTypes[0])
             opTypes.pop(0)
 
+            if opType.tag not in ("I", "J", "P", "PR", "Q", "V", "VR", "W"):
+                if opType.size:
+                    env.setSize(opType.size)
+
             if opType.reg:
                 #Figure out what to do with fixed register operands
                 #This is the index to use, so we should stick it some place.
                 if opType.reg in ("A", "B", "C", "D"):
-                    env.addReg("INTREG_R%sX | (REX_B << 3)" % opType.reg)
+                    regString = "INTREG_R%sX" % opType.reg
                 else:
-                    env.addReg("INTREG_R%s | (REX_B << 3)" % opType.reg)
-                if opType.size:
-                    if opType.rsize in ("l", "h", "b"):
-                        print "byte"
-                    elif opType.rsize == "x":
-                        print "word"
-                    else:
-                        print "Didn't recognize fixed register size %s!" % opType.rsize
+                    regString = "INTREG_R%s" % opType.reg
+                env.addReg(regString)
+                env.addToDisassembly(
+                        "printReg(out, %s, regSize);\n" % regString)
                 Name += "_R"
             elif opType.tag == "B":
                 # This refers to registers whose index is encoded as part of the opcode
+                env.addToDisassembly(
+                        "printReg(out, %s, regSize);\n" % InstRegIndex)
                 Name += "_R"
                 env.addReg(InstRegIndex)
             elif opType.tag == "M":
                 # This refers to memory. The macroop constructor sets up modrm
                 # addressing. Non memory modrm settings should cause an error.
-                Name += "_M"
                 env.doModRM = True
+                return doRipRelativeDecode(Name, opTypes, env)
             elif opType.tag == None or opType.size == None:
                 raise Exception, "Problem parsing operand tag: %s" % opType.tag
-            elif opType.tag in ("C", "D", "G", "P", "S", "T", "V"):
+            elif opType.tag == "C":
+                # A control register indexed by the "reg" field
+                env.addReg(ModRMRegIndex)
+                env.addToDisassembly(
+                        "ccprintf(out, \"CR%%d\", %s);\n" % ModRMRegIndex)
+                Name += "_C"
+            elif opType.tag == "D":
+                # A debug register indexed by the "reg" field
+                env.addReg(ModRMRegIndex)
+                env.addToDisassembly(
+                        "ccprintf(out, \"DR%%d\", %s);\n" % ModRMRegIndex)
+                Name += "_D"
+            elif opType.tag == "S":
+                # A segment selector register indexed by the "reg" field
+                env.addReg(ModRMRegIndex)
+                env.addToDisassembly(
+                        "printSegment(out, %s);\n" % ModRMRegIndex)
+                Name += "_S"
+            elif opType.tag in ("G", "P", "T", "V"):
                 # Use the "reg" field of the ModRM byte to select the register
                 env.addReg(ModRMRegIndex)
-                Name += "_R"
+                env.addToDisassembly(
+                        "printReg(out, %s, regSize);\n" % ModRMRegIndex)
+                if opType.tag == "P":
+                    Name += "_MMX"
+                elif opType.tag == "V":
+                    Name += "_XMM"
+                else:
+                    Name += "_R"
             elif opType.tag in ("E", "Q", "W"):
                 # This might refer to memory or to a register. We need to
                 # divide it up farther.
                 regEnv = copy.copy(env)
                 regEnv.addReg(ModRMRMIndex)
+                regEnv.addToDisassembly(
+                        "printReg(out, %s, regSize);\n" % ModRMRMIndex)
                 # This refers to memory. The macroop constructor should set up
                 # modrm addressing.
                 memEnv = copy.copy(env)
                 memEnv.doModRM = True
+                regSuffix = "_R"
+                if opType.tag == "Q":
+                    regSuffix = "_MMX"
+                elif opType.tag == "W":
+                    regSuffix = "_XMM"
                 return doSplitDecode("MODRM_MOD",
-                    {"3" : (specializeInst, Name + "_R", copy.copy(opTypes), regEnv)},
-                           (doRipRelativeDecode, Name, copy.copy(opTypes), memEnv))
+                    {"3" : (specializeInst, Name + regSuffix,
+                            copy.copy(opTypes), regEnv)},
+                           (doRipRelativeDecode, Name,
+                            copy.copy(opTypes), memEnv))
             elif opType.tag in ("I", "J"):
                 # Immediates
+                env.addToDisassembly(
+                        "ccprintf(out, \"%#x\", machInst.immediate);\n")
                 Name += "_I"
+            elif opType.tag == "O":
+                # Immediate containing a memory offset
+                Name += "_MI"
             elif opType.tag in ("PR", "R", "VR"):
                 # Non register modrm settings should cause an error
                 env.addReg(ModRMRMIndex)
-                Name += "_R"
+                env.addToDisassembly(
+                        "printReg(out, %s, regSize);\n" % ModRMRMIndex)
+                if opType.tag == "PR":
+                    Name += "_MMX"
+                elif opType.tag == "VR":
+                    Name += "_XMM"
+                else:
+                    Name += "_R"
+            elif opType.tag in ("X", "Y"):
+                # This type of memory addressing is for string instructions.
+                # They'll use the right index and segment internally.
+                if opType.tag == "X":
+                    env.addToDisassembly(
+                            '''printMem(out, env.seg,
+                                1, X86ISA::ZeroReg, X86ISA::INTREG_RSI, 0,
+                                env.addressSize, false);''')
+                else:
+                    env.addToDisassembly(
+                            '''printMem(out, SEGMENT_REG_ES,
+                                1, X86ISA::ZeroReg, X86ISA::INTREG_RDI, 0,
+                                env.addressSize, false);''')
+                Name += "_M"
             else:
                 raise Exception, "Unrecognized tag %s." % opType.tag