diff options
Diffstat (limited to 'src/arch/x86/isa/microops/regop.isa')
-rw-r--r-- | src/arch/x86/isa/microops/regop.isa | 36 |
1 files changed, 30 insertions, 6 deletions
diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 6d68f4fe9..28689c84b 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -258,13 +258,18 @@ let {{ # If op2 is used anywhere, make register and immediate versions # of this code. - matcher = re.compile("op2(?P<typeQual>\\.\\w+)?") - if matcher.search(allCode): + matcher = re.compile("(?<!\\w)(?P<prefix>s?)op2(?P<typeQual>\\.\\w+)?") + match = matcher.search(allCode) + if match: + typeQual = "" + if match.group("typeQual"): + typeQual = match.group("typeQual") + src2_name = "%spsrc2%s" % (match.group("prefix"), typeQual) self.buildCppClasses(name, Name, suffix, - matcher.sub("psrc2", code), - matcher.sub("psrc2", flag_code), - matcher.sub("psrc2", cond_check), - matcher.sub("psrc2", else_code)) + matcher.sub(src2_name, code), + matcher.sub(src2_name, flag_code), + matcher.sub(src2_name, cond_check), + matcher.sub(src2_name, else_code)) self.buildCppClasses(name + "i", Name, suffix + "Imm", matcher.sub("imm8", code), matcher.sub("imm8", flag_code), @@ -462,6 +467,11 @@ let {{ class Mulel(FlagRegOp): code = 'DestReg = merge(DestReg, psrc1 * op2, dataSize);' + # Neither of these is quite correct because it assumes that right shifting + # a signed or unsigned value does sign or zero extension respectively. + # The C standard says that what happens on a right shift with a 1 in the + # MSB position is undefined. On x86 and under likely most compilers the + # "right thing" happens, but this isn't a guarantee. class Muleh(FlagRegOp): code = ''' int halfSize = (dataSize * 8) / 2; @@ -476,6 +486,20 @@ let {{ DestReg = merge(DestReg, result, dataSize); ''' + class Mulehs(FlagRegOp): + code = ''' + int halfSize = (dataSize * 8) / 2; + int64_t spsrc1_h = spsrc1 >> halfSize; + int64_t spsrc1_l = spsrc1 & mask(halfSize); + int64_t spsrc2_h = sop2 >> halfSize; + int64_t spsrc2_l = sop2 & mask(halfSize); + int64_t result = + ((spsrc1_l * spsrc2_h + spsrc1_h * spsrc2_l + + ((spsrc1_l * spsrc2_l) >> halfSize)) >> halfSize) + + spsrc1_h * spsrc2_h; + DestReg = merge(DestReg, result, dataSize); + ''' + class Div1(FlagRegOp): code = ''' int halfSize = (dataSize * 8) / 2; |