x86: add op class for int and fp microops in isa description
Currently all the integer microops are marked as IntAluOp and the floating point microops are marked as FloatAddOp. This patch adds support for marking different microops differently. Now IntMultOp, IntDivOp, FloatDivOp, FloatMultOp, FloatCvtOp, FloatSqrtOp classes will be used as well. This will help in providing different latencies for different op class.
This commit is contained in:
parent
5b49c3d255
commit
fba40864aa
2 changed files with 42 additions and 13 deletions
|
@ -108,7 +108,7 @@ let {{
|
|||
|
||||
class FpOpMeta(type):
|
||||
def buildCppClasses(self, name, Name, suffix, \
|
||||
code, flag_code, cond_check, else_code):
|
||||
code, flag_code, cond_check, else_code, op_class):
|
||||
|
||||
# Globals to stick the output in
|
||||
global header_output
|
||||
|
@ -122,7 +122,7 @@ let {{
|
|||
# a version without it and fix up this version to use it.
|
||||
if flag_code is not "" or cond_check is not "true":
|
||||
self.buildCppClasses(name, Name, suffix,
|
||||
code, "", "true", else_code)
|
||||
code, "", "true", else_code, op_class)
|
||||
suffix = "Flags" + suffix
|
||||
|
||||
base = "X86ISA::FpOp"
|
||||
|
@ -133,13 +133,15 @@ let {{
|
|||
"flag_code" : flag_code,
|
||||
"cond_check" : cond_check,
|
||||
"else_code" : else_code,
|
||||
"top_code" : "TOP = (TOP + spm + 8) % 8;"})
|
||||
"top_code" : "TOP = (TOP + spm + 8) % 8;",
|
||||
"op_class" : op_class})
|
||||
iop = InstObjParams(name, Name + suffix, base,
|
||||
{"code" : code,
|
||||
"flag_code" : flag_code,
|
||||
"cond_check" : cond_check,
|
||||
"else_code" : else_code,
|
||||
"top_code" : ";"})
|
||||
"top_code" : ";",
|
||||
"op_class" : op_class})
|
||||
|
||||
# Generate the actual code (finally!)
|
||||
header_output += MicroFpOpDeclare.subst(iop_top)
|
||||
|
@ -165,10 +167,11 @@ let {{
|
|||
flag_code = cls.flag_code
|
||||
cond_check = cls.cond_check
|
||||
else_code = cls.else_code
|
||||
op_class = cls.op_class
|
||||
|
||||
# Set up the C++ classes
|
||||
mcls.buildCppClasses(cls, name, Name, "",
|
||||
code, flag_code, cond_check, else_code)
|
||||
code, flag_code, cond_check, else_code, op_class)
|
||||
|
||||
# Hook into the microassembler dict
|
||||
global microopClasses
|
||||
|
@ -185,6 +188,7 @@ let {{
|
|||
flag_code = ""
|
||||
cond_check = "true"
|
||||
else_code = ";"
|
||||
op_class = "FloatAddOp"
|
||||
|
||||
def __init__(self, dest, src1, spm=0, \
|
||||
SetStatus=False, dataSize="env.dataSize"):
|
||||
|
@ -218,6 +222,7 @@ let {{
|
|||
flag_code = ""
|
||||
cond_check = "true"
|
||||
else_code = ";"
|
||||
op_class = "FloatAddOp"
|
||||
|
||||
def __init__(self, dest, src1, src2, spm=0, \
|
||||
SetStatus=False, dataSize="env.dataSize"):
|
||||
|
@ -253,20 +258,25 @@ let {{
|
|||
|
||||
class Sqrtfp(FpBinaryOp):
|
||||
code = 'FpDestReg = sqrt(FpSrcReg2);'
|
||||
op_class = 'FloatSqrtOp'
|
||||
|
||||
class Cosfp(FpUnaryOp):
|
||||
code = 'FpDestReg = cos(FpSrcReg1);'
|
||||
op_class = 'FloatSqrtOp'
|
||||
|
||||
class Sinfp(FpUnaryOp):
|
||||
code = 'FpDestReg = sin(FpSrcReg1);'
|
||||
op_class = 'FloatSqrtOp'
|
||||
|
||||
class Tanfp(FpUnaryOp):
|
||||
code = 'FpDestReg = tan(FpSrcReg1);'
|
||||
op_class = 'FloatSqrtOp'
|
||||
|
||||
|
||||
# Conversion microops
|
||||
class ConvOp(FpBinaryOp):
|
||||
abstract = True
|
||||
op_class = 'FloatCvtOp'
|
||||
def __init__(self, dest, src1):
|
||||
super(ConvOp, self).__init__(dest, src1, \
|
||||
"InstRegIndex(FLOATREG_MICROFP0)")
|
||||
|
@ -303,9 +313,11 @@ let {{
|
|||
|
||||
class mulfp(FpBinaryOp):
|
||||
code = 'FpDestReg = FpSrcReg1 * FpSrcReg2;'
|
||||
op_class = 'FloatMultOp'
|
||||
|
||||
class divfp(FpBinaryOp):
|
||||
code = 'FpDestReg = FpSrcReg1 / FpSrcReg2;'
|
||||
op_class = 'FloatDivOp'
|
||||
|
||||
class subfp(FpBinaryOp):
|
||||
code = 'FpDestReg = FpSrcReg1 - FpSrcReg2;'
|
||||
|
@ -314,12 +326,14 @@ let {{
|
|||
code = '''
|
||||
FpDestReg = FpSrcReg2 * (log(FpSrcReg1) / log(2));
|
||||
'''
|
||||
op_class = 'FloatSqrtOp'
|
||||
|
||||
class PremFp(FpBinaryOp):
|
||||
code = '''
|
||||
FpDestReg = fmod(FpSrcReg1, FpSrcReg2);
|
||||
DPRINTF(X86, "src1: %lf, src2: %lf, dest: %lf\\n", FpSrcReg1, FpSrcReg2, FpDestReg);
|
||||
'''
|
||||
op_class = 'FloatDivOp'
|
||||
|
||||
class Compfp(FpBinaryOp):
|
||||
def __init__(self, src1, src2, spm=0, setStatus=False, \
|
||||
|
@ -347,6 +361,7 @@ let {{
|
|||
else if(FpSrcReg1 == FpSrcReg2)
|
||||
ccFlagBits = ccFlagBits | ZFBit;
|
||||
'''
|
||||
op_class = 'FloatCmpOp'
|
||||
|
||||
class absfp(FpUnaryOp):
|
||||
code = 'FpDestReg = fabs(FpSrcReg1);'
|
||||
|
|
|
@ -229,7 +229,8 @@ let {{
|
|||
|
||||
class RegOpMeta(type):
|
||||
def buildCppClasses(self, name, Name, suffix, code, big_code, \
|
||||
flag_code, cond_check, else_code, cond_control_flag_init):
|
||||
flag_code, cond_check, else_code, cond_control_flag_init,
|
||||
op_class):
|
||||
|
||||
# Globals to stick the output in
|
||||
global header_output
|
||||
|
@ -257,7 +258,8 @@ let {{
|
|||
matcher.sub(src2_name, flag_code),
|
||||
matcher.sub(src2_name, cond_check),
|
||||
matcher.sub(src2_name, else_code),
|
||||
matcher.sub(src2_name, cond_control_flag_init))
|
||||
matcher.sub(src2_name, cond_control_flag_init),
|
||||
op_class)
|
||||
imm_name = "%simm8" % match.group("prefix")
|
||||
self.buildCppClasses(name + "i", Name, suffix + "Imm",
|
||||
matcher.sub(imm_name, code),
|
||||
|
@ -265,14 +267,15 @@ let {{
|
|||
matcher.sub(imm_name, flag_code),
|
||||
matcher.sub(imm_name, cond_check),
|
||||
matcher.sub(imm_name, else_code),
|
||||
matcher.sub(imm_name, cond_control_flag_init))
|
||||
matcher.sub(imm_name, cond_control_flag_init),
|
||||
op_class)
|
||||
return
|
||||
|
||||
# If there's something optional to do with flags, generate
|
||||
# a version without it and fix up this version to use it.
|
||||
if flag_code != "" or cond_check != "true":
|
||||
self.buildCppClasses(name, Name, suffix,
|
||||
code, big_code, "", "true", else_code, "")
|
||||
code, big_code, "", "true", else_code, "", op_class)
|
||||
suffix = "Flags" + suffix
|
||||
|
||||
# If psrc1 or psrc2 is used, we need to actually insert code to
|
||||
|
@ -315,15 +318,16 @@ let {{
|
|||
"flag_code" : flag_code,
|
||||
"cond_check" : cond_check,
|
||||
"else_code" : else_code,
|
||||
"cond_control_flag_init" : cond_control_flag_init})]
|
||||
"cond_control_flag_init" : cond_control_flag_init,
|
||||
"op_class" : op_class})]
|
||||
if big_code != "":
|
||||
iops += [InstObjParams(name, Name + suffix + "Big", base,
|
||||
{"code" : big_code,
|
||||
"flag_code" : flag_code,
|
||||
"cond_check" : cond_check,
|
||||
"else_code" : else_code,
|
||||
"cond_control_flag_init" :
|
||||
cond_control_flag_init})]
|
||||
"cond_control_flag_init" : cond_control_flag_init,
|
||||
"op_class" : op_class})]
|
||||
|
||||
# Generate the actual code (finally!)
|
||||
for iop in iops:
|
||||
|
@ -349,11 +353,12 @@ let {{
|
|||
cond_check = cls.cond_check
|
||||
else_code = cls.else_code
|
||||
cond_control_flag_init = cls.cond_control_flag_init
|
||||
op_class = cls.op_class
|
||||
|
||||
# Set up the C++ classes
|
||||
mcls.buildCppClasses(cls, name, Name, "", code, big_code,
|
||||
flag_code, cond_check, else_code,
|
||||
cond_control_flag_init)
|
||||
cond_control_flag_init, op_class)
|
||||
|
||||
# Hook into the microassembler dict
|
||||
global microopClasses
|
||||
|
@ -381,6 +386,7 @@ let {{
|
|||
cond_check = "true"
|
||||
else_code = ";"
|
||||
cond_control_flag_init = ""
|
||||
op_class = "IntAluOp"
|
||||
|
||||
def __init__(self, dest, src1, op2, flags = None, dataSize = "env.dataSize"):
|
||||
self.dest = dest
|
||||
|
@ -538,6 +544,8 @@ let {{
|
|||
big_code = 'DestReg = result = (psrc1 ^ op2) & mask(dataSize * 8)'
|
||||
|
||||
class Mul1s(WrRegOp):
|
||||
op_class = 'IntMultOp'
|
||||
|
||||
code = '''
|
||||
ProdLow = psrc1 * op2;
|
||||
int halfSize = (dataSize * 8) / 2;
|
||||
|
@ -568,6 +576,8 @@ let {{
|
|||
'''
|
||||
|
||||
class Mul1u(WrRegOp):
|
||||
op_class = 'IntMultOp'
|
||||
|
||||
code = '''
|
||||
ProdLow = psrc1 * op2;
|
||||
int halfSize = (dataSize * 8) / 2;
|
||||
|
@ -605,6 +615,8 @@ let {{
|
|||
|
||||
# One or two bit divide
|
||||
class Div1(WrRegOp):
|
||||
op_class = 'IntDivOp'
|
||||
|
||||
code = '''
|
||||
//These are temporaries so that modifying them later won't make
|
||||
//the ISA parser think they're also sources.
|
||||
|
@ -629,6 +641,8 @@ let {{
|
|||
|
||||
# Step divide
|
||||
class Div2(RegOp):
|
||||
op_class = 'IntDivOp'
|
||||
|
||||
divCode = '''
|
||||
uint64_t dividend = Remainder;
|
||||
uint64_t divisor = Divisor;
|
||||
|
|
Loading…
Reference in a new issue