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:
@@ -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
|
||||
|
||||
@@ -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"
|
||||
};
|
||||
'''
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user