x86: mark instructions for being function call/return
authorNilay Vaish <nilay@cs.wisc.edu>
Tue, 21 May 2013 16:34:41 +0000 (11:34 -0500)
committerNilay Vaish <nilay@cs.wisc.edu>
Tue, 21 May 2013 16:34:41 +0000 (11:34 -0500)
Currently call and return instructions are marked as IsCall and IsReturn. Thus, the
branch predictor does not use RAS for these instructions. Similarly, the number of
function calls that took place is recorded as 0. This patch marks these instructions
as they should be.

src/arch/x86/isa/insts/general_purpose/control_transfer/call.py
src/arch/x86/isa/insts/general_purpose/control_transfer/xreturn.py
src/arch/x86/isa/macroop.isa

index f18a062a60409c68697b23909fccb4a9030d4d68..eaaa18208c463abd3575992c3485e0725963c580 100644 (file)
@@ -40,6 +40,7 @@ def macroop CALL_NEAR_I
 {
     # Make the default data size of calls 64 bits in 64 bit mode
     .adjust_env oszIn64Override
+    .function_call
 
     limm t1, imm
     rdip t7
@@ -53,6 +54,7 @@ def macroop CALL_NEAR_R
 {
     # Make the default data size of calls 64 bits in 64 bit mode
     .adjust_env oszIn64Override
+    .function_call
 
     rdip t1
     # Check target of call
@@ -65,6 +67,7 @@ def macroop CALL_NEAR_M
 {
     # Make the default data size of calls 64 bits in 64 bit mode
     .adjust_env oszIn64Override
+    .function_call
 
     rdip t7
     ld t1, seg, sib, disp
@@ -78,6 +81,7 @@ def macroop CALL_NEAR_P
 {
     # Make the default data size of calls 64 bits in 64 bit mode
     .adjust_env oszIn64Override
+    .function_call
 
     rdip t7
     ld t1, seg, riprel, disp
index 7ebe22e78e191ff86421c1b0e6ce915a8d8c5ace..f24b9d70e18df9c675e966ad58798f7daec3484a 100644 (file)
@@ -40,6 +40,7 @@ def macroop RET_NEAR
 {
     # Make the default data size of rets 64 bits in 64 bit mode
     .adjust_env oszIn64Override
+    .function_return
 
     ld t1, ss, [1, t0, rsp]
     # Check address of return
@@ -51,6 +52,7 @@ def macroop RET_NEAR_I
 {
     # Make the default data size of rets 64 bits in 64 bit mode
     .adjust_env oszIn64Override
+    .function_return
 
     limm t2, imm
     ld t1, ss, [1, t0, rsp]
@@ -62,6 +64,7 @@ def macroop RET_NEAR_I
 
 def macroop RET_FAR {
     .adjust_env oszIn64Override
+    .function_return
 
     # Get the return RIP
     ld t1, ss, [1, t0, rsp]
@@ -99,10 +102,10 @@ processDescriptor:
     wrdl cs, t3, t2
     wrsel cs, t2
     wrip t0, t1
-    br label("end")
+#    br label("end")
 
     # Do other stuff if they're not.
-end:
-    fault "NoFault"
+#end:
+#    fault "NoFault"
 };
 '''
index 94b17ff4c2cde2ee49691dffd14dfff97849a7f3..d510a0c7ca2a8f1daced2a0df08887e5aa17d1ef 100644 (file)
@@ -141,13 +141,21 @@ let {{
             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,
-                "serializing" : self.serializing
+                "serializing" : self.serializing,
+                "function_call" : self.function_call,
+                "function_return" : self.function_return
             }
             self.declared = False
             self.adjust_env = ""
@@ -163,6 +171,9 @@ let {{
                 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())
@@ -192,9 +203,15 @@ let {{
                 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: