x86: mark instructions for being function call/return

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.
This commit is contained in:
Nilay Vaish
2013-05-21 11:34:41 -05:00
parent fba40864aa
commit 30fe807316
3 changed files with 28 additions and 4 deletions

View 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

View 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"
};
'''

View 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: