x86: Fix re-entrancy problems in x87 store instructions
[gem5.git] / src / arch / x86 / isa / macroop.isa
index 8eaf5f7867c8bbbf7fb5f6a2dcf182e1f17f9bcd..d510a0c7ca2a8f1daced2a0df08887e5aa17d1ef 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
@@ -107,7 +89,7 @@ def template MacroDeclare {{
                 std::string
                 generateDisassembly(Addr pc, const SymbolTable *symtab) const;
             };
-        };
+        }
 }};
 
 def template MacroDisassembly {{
@@ -135,7 +117,7 @@ def template MacroConstructor {{
             %(adjust_env)s;
             %(adjust_imm)s;
             %(adjust_disp)s;
-            %(do_modrm)s;
+            %(init_env)s;
             %(constructor)s;
             const char *macrocodeBlock = "%(class_name)s";
             //alloc_microops is the code that sets up the microops
@@ -157,16 +139,27 @@ let {{
             self.adjust_imm += val
         def adjustDisp(self, val):
             self.adjust_disp += val
+        def serializing(self):
+            self.serializing = True
+
+        def function_call(self):
+            self.function_call = True
+        def function_return(self):
+            self.function_return = True
+
         def __init__(self, name):
             super(X86Macroop, self).__init__(name)
             self.directives = {
                 "adjust_env" : self.setAdjustEnv,
                 "adjust_imm" : self.adjustImm,
-                "adjust_disp" : self.adjustDisp
+                "adjust_disp" : self.adjustDisp,
+                "serializing" : self.serializing,
+                "function_call" : self.function_call,
+                "function_return" : self.function_return
             }
             self.declared = False
             self.adjust_env = ""
-            self.doModRM = ""
+            self.init_env = ""
             self.adjust_imm = '''
                 uint64_t adjustedImm = IMMEDIATE;
                 //This is to pacify gcc in case the immediate isn't used.
@@ -177,6 +170,10 @@ let {{
                 //This is to pacify gcc in case the displacement isn't used.
                 adjustedDisp = adjustedDisp;
             '''
+            self.serializing = False
+            self.function_call = False
+            self.function_return = False
+
         def getAllocator(self, env):
             return "new X86Macroop::%s(machInst, %s)" % \
                     (self.name, env.getAllocator())
@@ -203,11 +200,25 @@ let {{
             allocMicroops = ''
             micropc = 0
             for op in self.microops:
-                isLast = (micropc == numMicroops - 1)
+                flags = ["IsMicroop"]
+                if micropc == numMicroops - 1:
+                    flags.append("IsLastMicroop")
+
+                    if self.serializing:
+                        flags.append("IsSerializing")
+                        flags.append("IsSerializeAfter")
+
+                    if self.function_call:
+                        flags.append("IsCall")
+                    if self.function_return:
+                        flags.append("IsReturn")
+                else:
+                    flags.append("IsDelayedCommit")
+                if micropc == 0:
+                    flags.append("IsFirstMicroop")
                 allocMicroops += \
                     "microops[%d] = %s;\n" % \
-                    (micropc, op.getAllocator(True, not isLast,
-                                              micropc == 0, isLast))
+                    (micropc, op.getAllocator(flags))
                 micropc += 1
             if env.useStackSize:
                 useStackSize = "true"
@@ -228,7 +239,7 @@ let {{
                                  "adjust_disp" : self.adjust_disp,
                                  "disassembly" : env.disassembly,
                                  "regSize" : regSize,
-                                 "do_modrm" : self.doModRM})
+                                 "init_env" : self.initEnv})
             return MacroConstructor.subst(iop) + \
                    MacroDisassembly.subst(iop);
 }};
@@ -304,6 +315,7 @@ let {{
 
 let {{
     doModRMString = "env.doModRM(machInst);\n"
+    noModRMString = "env.setSeg(machInst);\n"
     def genMacroop(Name, env):
         blocks = OutputBlocks()
         if not macroopDict.has_key(Name):
@@ -311,7 +323,9 @@ let {{
         macroop = macroopDict[Name]
         if not macroop.declared:
             if env.doModRM:
-                macroop.doModRM = doModRMString
+                macroop.initEnv = doModRMString
+            else:
+                macroop.initEnv = noModRMString
             blocks.header_output = macroop.getDeclaration()
             blocks.decoder_output = macroop.getDefinition(env)
             macroop.declared = True