X86: Make signed multiplication do something different from unsigned.
--HG-- extra : convert_revision : 333c4a3464d708d4d8cea88931259ab96c2f75ed
This commit is contained in:
parent
5052e2cb10
commit
7f079149f1
2 changed files with 33 additions and 9 deletions
|
@ -134,7 +134,7 @@ def macroop IMUL_B_P
|
||||||
|
|
||||||
def macroop IMUL_R
|
def macroop IMUL_R
|
||||||
{
|
{
|
||||||
muleh t1, rax, reg
|
mulehs t1, rax, reg
|
||||||
mulel rax, rax, reg
|
mulel rax, rax, reg
|
||||||
mov rdx, rdx, t1
|
mov rdx, rdx, t1
|
||||||
};
|
};
|
||||||
|
@ -142,7 +142,7 @@ def macroop IMUL_R
|
||||||
def macroop IMUL_M
|
def macroop IMUL_M
|
||||||
{
|
{
|
||||||
ld t1, seg, sib, disp
|
ld t1, seg, sib, disp
|
||||||
muleh rdx, rax, t1
|
mulehs rdx, rax, t1
|
||||||
mulel rax, rax, t1
|
mulel rax, rax, t1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -150,7 +150,7 @@ def macroop IMUL_P
|
||||||
{
|
{
|
||||||
rdip t7
|
rdip t7
|
||||||
ld t1, seg, riprel, disp
|
ld t1, seg, riprel, disp
|
||||||
muleh rdx, rax, t1
|
mulehs rdx, rax, t1
|
||||||
mulel rax, rax, t1
|
mulel rax, rax, t1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -258,13 +258,18 @@ let {{
|
||||||
|
|
||||||
# If op2 is used anywhere, make register and immediate versions
|
# If op2 is used anywhere, make register and immediate versions
|
||||||
# of this code.
|
# of this code.
|
||||||
matcher = re.compile("op2(?P<typeQual>\\.\\w+)?")
|
matcher = re.compile("(?<!\\w)(?P<prefix>s?)op2(?P<typeQual>\\.\\w+)?")
|
||||||
if matcher.search(allCode):
|
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,
|
self.buildCppClasses(name, Name, suffix,
|
||||||
matcher.sub("psrc2", code),
|
matcher.sub(src2_name, code),
|
||||||
matcher.sub("psrc2", flag_code),
|
matcher.sub(src2_name, flag_code),
|
||||||
matcher.sub("psrc2", cond_check),
|
matcher.sub(src2_name, cond_check),
|
||||||
matcher.sub("psrc2", else_code))
|
matcher.sub(src2_name, else_code))
|
||||||
self.buildCppClasses(name + "i", Name, suffix + "Imm",
|
self.buildCppClasses(name + "i", Name, suffix + "Imm",
|
||||||
matcher.sub("imm8", code),
|
matcher.sub("imm8", code),
|
||||||
matcher.sub("imm8", flag_code),
|
matcher.sub("imm8", flag_code),
|
||||||
|
@ -462,6 +467,11 @@ let {{
|
||||||
class Mulel(FlagRegOp):
|
class Mulel(FlagRegOp):
|
||||||
code = 'DestReg = merge(DestReg, psrc1 * op2, dataSize);'
|
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):
|
class Muleh(FlagRegOp):
|
||||||
code = '''
|
code = '''
|
||||||
int halfSize = (dataSize * 8) / 2;
|
int halfSize = (dataSize * 8) / 2;
|
||||||
|
@ -476,6 +486,20 @@ let {{
|
||||||
DestReg = merge(DestReg, result, dataSize);
|
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):
|
class Div1(FlagRegOp):
|
||||||
code = '''
|
code = '''
|
||||||
int halfSize = (dataSize * 8) / 2;
|
int halfSize = (dataSize * 8) / 2;
|
||||||
|
|
Loading…
Reference in a new issue