X86: Make logic instructions flag setting work.

The instructions now ask for the appropriate flags to be set, and the microops do the "right thing" with the CF and OF flags, namely zero them.

--HG--
extra : convert_revision : 85138a832f44c879bf8a11bd3a35b58be6272ef3
This commit is contained in:
Gabe Black
2007-07-29 13:51:40 -07:00
parent 1af50a9e8b
commit 7309d5ee45
2 changed files with 62 additions and 45 deletions

View File

@@ -56,14 +56,14 @@
microcode = '''
def macroop OR_R_R
{
or reg, reg, regm
or reg, reg, regm, flags=(OF,SF,ZF,PF,CF)
};
def macroop OR_M_I
{
limm t2, imm
ld t1, ds, [scale, index, base], disp
or t1, t1, t2
or t1, t1, t2, flags=(OF,SF,ZF,PF,CF)
st t1, ds, [scale, index, base], disp
};
@@ -72,14 +72,14 @@ def macroop OR_P_I
limm t2, imm
rdip t7
ld t1, ds, [0, t0, t7], disp
or t1, t1, t2
or t1, t1, t2, flags=(OF,SF,ZF,PF,CF)
st t1, ds, [0, t0, t7], disp
};
def macroop OR_M_R
{
ld t1, ds, [scale, index, base], disp
or t1, t1, reg
or t1, t1, reg, flags=(OF,SF,ZF,PF,CF)
st t1, ds, [scale, index, base], disp
};
@@ -87,45 +87,45 @@ def macroop OR_P_R
{
rdip t7
ld t1, ds, [0, t0, t7], disp
or t1, t1, reg
or t1, t1, reg, flags=(OF,SF,ZF,PF,CF)
st t1, ds, [0, t0, t7], disp
};
def macroop OR_R_M
{
ld t1, ds, [scale, index, base], disp
or reg, reg, t1
or reg, reg, t1, flags=(OF,SF,ZF,PF,CF)
};
def macroop OR_R_P
{
rdip t7
ld t1, ds, [0, t0, t7], disp
or reg, reg, t1
or reg, reg, t1, flags=(OF,SF,ZF,PF,CF)
};
def macroop OR_R_I
{
limm t1, imm
or reg, reg, t1
or reg, reg, t1, flags=(OF,SF,ZF,PF,CF)
};
def macroop XOR_R_R
{
xor reg, reg, regm
xor reg, reg, regm, flags=(OF,SF,ZF,PF,CF)
};
def macroop XOR_R_I
{
limm t1, imm
xor reg, reg, t1
xor reg, reg, t1, flags=(OF,SF,ZF,PF,CF)
};
def macroop XOR_M_I
{
limm t2, imm
ld t1, ds, [scale, index, base], disp
xor t1, t1, t2
xor t1, t1, t2, flags=(OF,SF,ZF,PF,CF)
st t1, ds, [scale, index, base], disp
};
@@ -134,14 +134,14 @@ def macroop XOR_P_I
limm t2, imm
rdip t7
ld t1, ds, [scale, index, base], disp
xor t1, t1, t2
xor t1, t1, t2, flags=(OF,SF,ZF,PF,CF)
st t1, ds, [scale, index, base], disp
};
def macroop XOR_M_R
{
ld t1, ds, [scale, index, base], disp
xor t1, t1, reg
xor t1, t1, reg, flags=(OF,SF,ZF,PF,CF)
st t1, ds, [scale, index, base], disp
};
@@ -149,52 +149,52 @@ def macroop XOR_P_R
{
rdip t7
ld t1, ds, [scale, index, base], disp
xor t1, t1, reg
xor t1, t1, reg, flags=(OF,SF,ZF,PF,CF)
st t1, ds, [scale, index, base], disp
};
def macroop XOR_R_M
{
ld t1, ds, [scale, index, base], disp
xor reg, reg, t1
xor reg, reg, t1, flags=(OF,SF,ZF,PF,CF)
};
def macroop XOR_R_P
{
rdip t7
ld t1, ds, [scale, index, base], disp
xor reg, reg, t1
xor reg, reg, t1, flags=(OF,SF,ZF,PF,CF)
};
def macroop AND_R_R
{
and reg, reg, regm
and reg, reg, regm, flags=(OF,SF,ZF,PF,CF)
};
def macroop AND_R_M
{
ld t1, ds, [scale, index, base], disp
and reg, reg, t1
and reg, reg, t1, flags=(OF,SF,ZF,PF,CF)
};
def macroop AND_R_P
{
rdip t7
ld t1, ds, [scale, index, base], disp
and reg, reg, t1
and reg, reg, t1, flags=(OF,SF,ZF,PF,CF)
};
def macroop AND_R_I
{
limm t1, imm
and reg, reg, t1
and reg, reg, t1, flags=(OF,SF,ZF,PF,CF)
};
def macroop AND_M_I
{
ld t2, ds, [scale, index, base], disp
limm t1, imm
and t2, t2, t1
and t2, t2, t1, flags=(OF,SF,ZF,PF,CF)
st t2, ds, [scale, index, base], disp
};
@@ -203,14 +203,14 @@ def macroop AND_P_I
rdip t7
ld t2, ds, [scale, index, base], disp
limm t1, imm
and t2, t2, t1
and t2, t2, t1, flags=(OF,SF,ZF,PF,CF)
st t2, ds, [scale, index, base], disp
};
def macroop AND_M_R
{
ld t1, ds, [scale, index, base], disp
and t1, t1, reg
and t1, t1, reg, flags=(OF,SF,ZF,PF,CF)
st t1, ds, [scale, index, base], disp
};
@@ -218,7 +218,7 @@ def macroop AND_P_R
{
rdip t7
ld t1, ds, [scale, index, base], disp
and t1, t1, reg
and t1, t1, reg, flags=(OF,SF,ZF,PF,CF)
st t1, ds, [scale, index, base], disp
};

View File

@@ -326,12 +326,24 @@ let {{
checkCCFlagBits = "checkCondition(ccFlagBits)"
genCCFlagBits = "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, SrcReg1, %s);"
genCCFlagBits = \
"ccFlagBits = genFlags(ccFlagBits, ext, DestReg, SrcReg1, op2);"
genCCFlagBitsSub = \
"ccFlagBits = genFlags(ccFlagBits, ext, DestReg, SrcReg1, ~op2, true);"
genCCFlagBitsLogic = '''
//Don't have genFlags handle the OF or CF bits
uint64_t mask = CFBit | OFBit;
ccFlagBits = genFlags(ccFlagBits, ext & ~mask, DestReg, SrcReg1, op2);
//If a logic microop wants to set these, it wants to set them to 0.
ccFlagBits &= ~(CFBit & ext);
ccFlagBits &= ~(OFBit & ext);
'''
# This creates a python representations of a microop which are a cross
# product of reg/immediate and flag/no flag versions.
def defineMicroRegOp(mnemonic, code, subtract = False, cc=False, elseCode=";"):
def defineMicroRegOp(mnemonic, code, flagCode=genCCFlagBits, \
cc=False, elseCode=";"):
Name = mnemonic
name = mnemonic.lower()
@@ -342,13 +354,7 @@ let {{
regCode = matcher.sub("SrcReg2", code)
immCode = matcher.sub("imm8", code)
if subtract:
secondSrc = "~op2, true"
else:
secondSrc = "op2"
if not cc:
flagCode = genCCFlagBits % secondSrc
condCode = "true"
else:
flagCode = ""
@@ -360,26 +366,30 @@ let {{
class RegOpChild(RegOp):
mnemonic = name
className = Name
def __init__(self, dest, src1, src2, flags=None, dataSize="env.dataSize"):
super(RegOpChild, self).__init__(dest, src1, src2, flags, dataSize)
def __init__(self, dest, src1, src2, \
flags=None, dataSize="env.dataSize"):
super(RegOpChild, self).__init__(dest, src1, src2, \
flags, dataSize)
microopClasses[name] = RegOpChild
setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode);
setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp", regCode,
flagCode = regFlagCode, condCheck = condCode, elseCode = elseCode);
flagCode=regFlagCode, condCheck=condCode, elseCode=elseCode);
class RegOpChildImm(RegOpImm):
mnemonic = name + 'i'
className = Name + 'Imm'
def __init__(self, dest, src1, src2, flags=None, dataSize="env.dataSize"):
super(RegOpChildImm, self).__init__(dest, src1, src2, flags, dataSize)
def __init__(self, dest, src1, src2, \
flags=None, dataSize="env.dataSize"):
super(RegOpChildImm, self).__init__(dest, src1, src2, \
flags, dataSize)
microopClasses[name + 'i'] = RegOpChildImm
setUpMicroRegOp(name + "i", Name + "Imm", "X86ISA::RegOpImm", immCode);
setUpMicroRegOp(name + "i", Name + "ImmFlags", "X86ISA::RegOpImm", immCode,
flagCode = immFlagCode, condCheck = condCode, elseCode = elseCode);
flagCode=immFlagCode, condCheck=condCode, elseCode=elseCode);
# This has it's own function because Wr ops have implicit destinations
def defineMicroRegOpWr(mnemonic, code, elseCode=";"):
@@ -447,7 +457,8 @@ let {{
setUpMicroRegOp(name, Name, "X86ISA::RegOpImm", code);
defineMicroRegOp('Add', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)')
defineMicroRegOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)')
defineMicroRegOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)',
flagCode = genCCFlagBitsLogic)
defineMicroRegOp('Adc', '''
CCFlagBits flags = ccFlagBits;
DestReg = merge(DestReg, SrcReg1 + op2 + flags.CF, dataSize);
@@ -455,12 +466,18 @@ let {{
defineMicroRegOp('Sbb', '''
CCFlagBits flags = ccFlagBits;
DestReg = merge(DestReg, SrcReg1 - op2 - flags.CF, dataSize);
''', True)
defineMicroRegOp('And', 'DestReg = merge(DestReg, SrcReg1 & op2, dataSize)')
defineMicroRegOp('Sub', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', True)
defineMicroRegOp('Xor', 'DestReg = merge(DestReg, SrcReg1 ^ op2, dataSize)')
# defineMicroRegOp('Cmp', 'DestReg = merge(DestReg, DestReg - op2, dataSize)', True)
defineMicroRegOp('Mul1s', 'DestReg = merge(DestReg, DestReg * op2, dataSize)')
''', flagCode = genCCFlagBitsSub)
defineMicroRegOp('And', \
'DestReg = merge(DestReg, SrcReg1 & op2, dataSize)', \
flagCode = genCCFlagBitsLogic)
defineMicroRegOp('Sub', \
'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', \
flagCode = genCCFlagBitsSub)
defineMicroRegOp('Xor', \
'DestReg = merge(DestReg, SrcReg1 ^ op2, dataSize)', \
flagCode = genCCFlagBitsLogic)
defineMicroRegOp('Mul1s', \
'DestReg = merge(DestReg, DestReg * op2, dataSize)')
defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, op2, dataSize)',
elseCode='DestReg=DestReg;', cc=True)