X86: Split Condition Code register

This patch moves the ECF and EZF bits to individual registers (ecfBit and
ezfBit) and the CF and OF bits to cfofFlag registers. This is being done
so as to lower the read after write dependencies on the the condition code
register. Ultimately we will have the following registers [ZAPS], [OF],
[CF], [ECF], [EZF] and [DF]. Note that this is only one part of the
solution for lowering the dependencies. The other part will check whether
or not the condition code register needs to be actually read. This would
be done through a separate patch.
This commit is contained in:
Nilay Vaish 2012-05-22 11:29:53 -05:00
parent 16a559c9c6
commit 4d4d212ae9
9 changed files with 251 additions and 116 deletions

View file

@ -141,7 +141,8 @@ let {{
{"code": "", {"code": "",
"func": func, "func": func,
"func_num": "GenericISA::M5DebugFault::%s" % func_num, "func_num": "GenericISA::M5DebugFault::%s" % func_num,
"cond_test": "checkCondition(ccFlagBits, cc)"}) "cond_test": "checkCondition(ccFlagBits | cfofBits | \
ecfBit | ezfBit, cc)"})
exec_output += MicroDebugExecute.subst(iop) exec_output += MicroDebugExecute.subst(iop)
header_output += MicroDebugDeclare.subst(iop) header_output += MicroDebugDeclare.subst(iop)
decoder_output += MicroDebugConstructor.subst(iop) decoder_output += MicroDebugConstructor.subst(iop)

View file

@ -215,7 +215,8 @@ let {{
spm, SetStatus, dataSize) spm, SetStatus, dataSize)
code = 'FpDestReg_uqw = FpSrcReg1_uqw;' code = 'FpDestReg_uqw = FpSrcReg1_uqw;'
else_code = 'FpDestReg_uqw = FpDestReg_uqw;' else_code = 'FpDestReg_uqw = FpDestReg_uqw;'
cond_check = "checkCondition(ccFlagBits, src2)" cond_check = "checkCondition(ccFlagBits | cfofBits | ecfBit | ezfBit, \
src2)"
class Xorfp(FpOp): class Xorfp(FpOp):
code = 'FpDestReg_uqw = FpSrcReg1_uqw ^ FpSrcReg2_uqw;' code = 'FpDestReg_uqw = FpSrcReg1_uqw ^ FpSrcReg2_uqw;'
@ -283,12 +284,15 @@ let {{
// Less than 0 0 1 // Less than 0 0 1
// Equal 1 0 0 // Equal 1 0 0
// OF = SF = AF = 0 // OF = SF = AF = 0
ccFlagBits = ccFlagBits & ~(OFBit | SFBit | AFBit | ccFlagBits = ccFlagBits & ~(SFBit | AFBit | ZFBit | PFBit);
ZFBit | PFBit | CFBit); cfofBits = cfofBits & ~(OFBit | CFBit);
if (std::isnan(FpSrcReg1) || std::isnan(FpSrcReg2))
ccFlagBits = ccFlagBits | (ZFBit | PFBit | CFBit); if (std::isnan(FpSrcReg1) || std::isnan(FpSrcReg2)) {
ccFlagBits = ccFlagBits | (ZFBit | PFBit);
cfofBits = cfofBits | CFBit;
}
else if(FpSrcReg1 < FpSrcReg2) else if(FpSrcReg1 < FpSrcReg2)
ccFlagBits = ccFlagBits | CFBit; cfofBits = cfofBits | CFBit;
else if(FpSrcReg1 == FpSrcReg2) else if(FpSrcReg1 == FpSrcReg2)
ccFlagBits = ccFlagBits | ZFBit; ccFlagBits = ccFlagBits | ZFBit;
''' '''

View file

@ -1490,12 +1490,15 @@ let {{
// Less than 0 0 1 // Less than 0 0 1
// Equal 1 0 0 // Equal 1 0 0
// OF = SF = AF = 0 // OF = SF = AF = 0
ccFlagBits = ccFlagBits & ~(OFBit | SFBit | AFBit | ccFlagBits = ccFlagBits & ~(SFBit | AFBit | ZFBit | PFBit);
ZFBit | PFBit | CFBit); cfofBits = cfofBits & ~(OFBit | CFBit);
if (std::isnan(arg1) || std::isnan(arg2))
ccFlagBits = ccFlagBits | (ZFBit | PFBit | CFBit); if (std::isnan(arg1) || std::isnan(arg2)) {
ccFlagBits = ccFlagBits | (ZFBit | PFBit);
cfofBits = cfofBits | CFBit;
}
else if(arg1 < arg2) else if(arg1 < arg2)
ccFlagBits = ccFlagBits | CFBit; cfofBits = cfofBits | CFBit;
else if(arg1 == arg2) else if(arg1 == arg2)
ccFlagBits = ccFlagBits | ZFBit; ccFlagBits = ccFlagBits | ZFBit;
''' '''

View file

@ -438,26 +438,42 @@ let {{
flag_code = ''' flag_code = '''
//Don't have genFlags handle the OF or CF bits //Don't have genFlags handle the OF or CF bits
uint64_t mask = CFBit | ECFBit | OFBit; uint64_t mask = CFBit | ECFBit | OFBit;
ccFlagBits = genFlags(ccFlagBits, ext & ~mask, result, psrc1, op2); uint64_t newFlags = genFlags(ccFlagBits | ezfBit, ext & ~mask,
result, psrc1, op2);
ezfBit = newFlags & EZFBit;
ccFlagBits = newFlags & ccFlagMask;
//If a logic microop wants to set these, it wants to set them to 0. //If a logic microop wants to set these, it wants to set them to 0.
ccFlagBits &= ~(CFBit & ext); cfofBits = cfofBits & ~((CFBit | OFBit) & ext);
ccFlagBits &= ~(ECFBit & ext); ecfBit = ecfBit & ~(ECFBit & ext);
ccFlagBits &= ~(OFBit & ext);
''' '''
class FlagRegOp(RegOp): class FlagRegOp(RegOp):
abstract = True abstract = True
flag_code = \ flag_code = '''
"ccFlagBits = genFlags(ccFlagBits, ext, result, psrc1, op2);" uint64_t newFlags = genFlags(ccFlagBits | cfofBits | ecfBit |
ezfBit, ext, result, psrc1, op2);
cfofBits = newFlags & cfofMask;
ecfBit = newFlags & ECFBit;
ezfBit = newFlags & EZFBit;
ccFlagBits = newFlags & ccFlagMask;
'''
class SubRegOp(RegOp): class SubRegOp(RegOp):
abstract = True abstract = True
flag_code = \ flag_code = '''
"ccFlagBits = genFlags(ccFlagBits, ext, result, psrc1, ~op2, true);" uint64_t newFlags = genFlags(ccFlagBits | cfofBits | ecfBit |
ezfBit, ext, result, psrc1, ~op2, true);
cfofBits = newFlags & cfofMask;
ecfBit = newFlags & ECFBit;
ezfBit = newFlags & EZFBit;
ccFlagBits = newFlags & ccFlagMask;
'''
class CondRegOp(RegOp): class CondRegOp(RegOp):
abstract = True abstract = True
cond_check = "checkCondition(ccFlagBits, ext)" cond_check = "checkCondition(ccFlagBits | cfofBits | ecfBit | ezfBit, \
ext)"
cond_control_flag_init = "flags[IsCondControl] = flags[IsControl];" cond_control_flag_init = "flags[IsCondControl] = flags[IsControl];"
class RdRegOp(RegOp): class RdRegOp(RegOp):
@ -484,21 +500,21 @@ let {{
class Adc(FlagRegOp): class Adc(FlagRegOp):
code = ''' code = '''
CCFlagBits flags = ccFlagBits; CCFlagBits flags = cfofBits;
DestReg = merge(DestReg, result = (psrc1 + op2 + flags.cf), dataSize); DestReg = merge(DestReg, result = (psrc1 + op2 + flags.cf), dataSize);
''' '''
big_code = ''' big_code = '''
CCFlagBits flags = ccFlagBits; CCFlagBits flags = cfofBits;
DestReg = result = (psrc1 + op2 + flags.cf) & mask(dataSize * 8); DestReg = result = (psrc1 + op2 + flags.cf) & mask(dataSize * 8);
''' '''
class Sbb(SubRegOp): class Sbb(SubRegOp):
code = ''' code = '''
CCFlagBits flags = ccFlagBits; CCFlagBits flags = cfofBits;
DestReg = merge(DestReg, result = (psrc1 - op2 - flags.cf), dataSize); DestReg = merge(DestReg, result = (psrc1 - op2 - flags.cf), dataSize);
''' '''
big_code = ''' big_code = '''
CCFlagBits flags = ccFlagBits; CCFlagBits flags = cfofBits;
DestReg = result = (psrc1 - op2 - flags.cf) & mask(dataSize * 8); DestReg = result = (psrc1 - op2 - flags.cf) & mask(dataSize * 8);
''' '''
@ -536,9 +552,11 @@ let {{
flag_code = ''' flag_code = '''
if ((-ProdHi & mask(dataSize * 8)) != if ((-ProdHi & mask(dataSize * 8)) !=
bits(ProdLow, dataSize * 8 - 1)) { bits(ProdLow, dataSize * 8 - 1)) {
ccFlagBits = ccFlagBits | (ext & (CFBit | OFBit | ECFBit)); cfofBits = cfofBits | (ext & (CFBit | OFBit));
ecfBit = ecfBit | (ext & ECFBit);
} else { } else {
ccFlagBits = ccFlagBits & ~(ext & (CFBit | OFBit | ECFBit)); cfofBits = cfofBits & ~(ext & (CFBit | OFBit));
ecfBit = ecfBit & ~(ext & ECFBit);
} }
''' '''
@ -557,9 +575,11 @@ let {{
''' '''
flag_code = ''' flag_code = '''
if (ProdHi) { if (ProdHi) {
ccFlagBits = ccFlagBits | (ext & (CFBit | OFBit | ECFBit)); cfofBits = cfofBits | (ext & (CFBit | OFBit));
ecfBit = ecfBit | (ext & ECFBit);
} else { } else {
ccFlagBits = ccFlagBits & ~(ext & (CFBit | OFBit | ECFBit)); cfofBits = cfofBits & ~(ext & (CFBit | OFBit));
ecfBit = ecfBit & ~(ext & ECFBit);
} }
''' '''
@ -658,9 +678,9 @@ let {{
big_code = divCode % "DestReg = remaining & mask(dataSize * 8);" big_code = divCode % "DestReg = remaining & mask(dataSize * 8);"
flag_code = ''' flag_code = '''
if (remaining == 0) if (remaining == 0)
ccFlagBits = ccFlagBits | (ext & EZFBit); ezfBit = ezfBit | (ext & EZFBit);
else else
ccFlagBits = ccFlagBits & ~(ext & EZFBit); ezfBit = ezfBit & ~(ext & EZFBit);
''' '''
class Divq(RdRegOp): class Divq(RdRegOp):
@ -691,22 +711,31 @@ let {{
if (shiftAmt) { if (shiftAmt) {
//Zero out any flags we might modify. This way we only have to //Zero out any flags we might modify. This way we only have to
//worry about setting them. //worry about setting them.
ccFlagBits = ccFlagBits & ~(ext & (CFBit | ECFBit | OFBit)); cfofBits = cfofBits & ~(ext & (CFBit | OFBit));
ecfBit = ecfBit & ~(ext & ECFBit);
int CFBits = 0; int CFBits = 0;
//Figure out if we -would- set the CF bits if requested. //Figure out if we -would- set the CF bits if requested.
if (shiftAmt <= dataSize * 8 && if (shiftAmt <= dataSize * 8 &&
bits(SrcReg1, dataSize * 8 - shiftAmt)) { bits(SrcReg1, dataSize * 8 - shiftAmt)) {
CFBits = 1; CFBits = 1;
} }
//If some combination of the CF bits need to be set, set them. //If some combination of the CF bits need to be set, set them.
if ((ext & (CFBit | ECFBit)) && CFBits) if ((ext & (CFBit | ECFBit)) && CFBits) {
ccFlagBits = ccFlagBits | (ext & (CFBit | ECFBit)); cfofBits = cfofBits | (ext & CFBit);
ecfBit = ecfBit | (ext & ECFBit);
}
//Figure out what the OF bit should be. //Figure out what the OF bit should be.
if ((ext & OFBit) && (CFBits ^ bits(DestReg, dataSize * 8 - 1))) if ((ext & OFBit) && (CFBits ^ bits(DestReg, dataSize * 8 - 1)))
ccFlagBits = ccFlagBits | OFBit; cfofBits = cfofBits | OFBit;
//Use the regular mechanisms to calculate the other flags. //Use the regular mechanisms to calculate the other flags.
ccFlagBits = genFlags(ccFlagBits, ext & ~(CFBit | ECFBit | OFBit), uint64_t newFlags = genFlags(ccFlagBits | ezfBit,
DestReg, psrc1, op2); ext & ~(CFBit | ECFBit | OFBit), DestReg, psrc1, op2);
ezfBit = newFlags & EZFBit;
ccFlagBits = newFlags & ccFlagMask;
} }
''' '''
@ -729,19 +758,26 @@ let {{
if (shiftAmt) { if (shiftAmt) {
//Zero out any flags we might modify. This way we only have to //Zero out any flags we might modify. This way we only have to
//worry about setting them. //worry about setting them.
ccFlagBits = ccFlagBits & ~(ext & (CFBit | ECFBit | OFBit)); cfofBits = cfofBits & ~(ext & (CFBit | OFBit));
ecfBit = ecfBit & ~(ext & ECFBit);
//If some combination of the CF bits need to be set, set them. //If some combination of the CF bits need to be set, set them.
if ((ext & (CFBit | ECFBit)) && if ((ext & (CFBit | ECFBit)) &&
shiftAmt <= dataSize * 8 && shiftAmt <= dataSize * 8 &&
bits(SrcReg1, shiftAmt - 1)) { bits(SrcReg1, shiftAmt - 1)) {
ccFlagBits = ccFlagBits | (ext & (CFBit | ECFBit)); cfofBits = cfofBits | (ext & CFBit);
ecfBit = ecfBit | (ext & ECFBit);
} }
//Figure out what the OF bit should be. //Figure out what the OF bit should be.
if ((ext & OFBit) && bits(SrcReg1, dataSize * 8 - 1)) if ((ext & OFBit) && bits(SrcReg1, dataSize * 8 - 1))
ccFlagBits = ccFlagBits | OFBit; cfofBits = cfofBits | OFBit;
//Use the regular mechanisms to calculate the other flags. //Use the regular mechanisms to calculate the other flags.
ccFlagBits = genFlags(ccFlagBits, ext & ~(CFBit | ECFBit | OFBit), uint64_t newFlags = genFlags(ccFlagBits | ezfBit,
DestReg, psrc1, op2); ext & ~(CFBit | ECFBit | OFBit), DestReg, psrc1, op2);
ezfBit = newFlags & EZFBit;
ccFlagBits = newFlags & ccFlagMask;
} }
''' '''
@ -766,17 +802,23 @@ let {{
if (shiftAmt) { if (shiftAmt) {
//Zero out any flags we might modify. This way we only have to //Zero out any flags we might modify. This way we only have to
//worry about setting them. //worry about setting them.
ccFlagBits = ccFlagBits & ~(ext & (CFBit | ECFBit | OFBit)); cfofBits = cfofBits & ~(ext & (CFBit | OFBit));
ecfBit = ecfBit & ~(ext & ECFBit);
//If some combination of the CF bits need to be set, set them. //If some combination of the CF bits need to be set, set them.
uint8_t effectiveShift = uint8_t effectiveShift =
(shiftAmt <= dataSize * 8) ? shiftAmt : (dataSize * 8); (shiftAmt <= dataSize * 8) ? shiftAmt : (dataSize * 8);
if ((ext & (CFBit | ECFBit)) && if ((ext & (CFBit | ECFBit)) &&
bits(SrcReg1, effectiveShift - 1)) { bits(SrcReg1, effectiveShift - 1)) {
ccFlagBits = ccFlagBits | (ext & (CFBit | ECFBit)); cfofBits = cfofBits | (ext & CFBit);
ecfBit = ecfBit | (ext & ECFBit);
} }
//Use the regular mechanisms to calculate the other flags. //Use the regular mechanisms to calculate the other flags.
ccFlagBits = genFlags(ccFlagBits, ext & ~(CFBit | ECFBit | OFBit), uint64_t newFlags = genFlags(ccFlagBits | ezfBit,
DestReg, psrc1, op2); ext & ~(CFBit | ECFBit | OFBit), DestReg, psrc1, op2);
ezfBit = newFlags & EZFBit;
ccFlagBits = newFlags & ccFlagMask;
} }
''' '''
@ -797,19 +839,27 @@ let {{
if (shiftAmt) { if (shiftAmt) {
//Zero out any flags we might modify. This way we only have to //Zero out any flags we might modify. This way we only have to
//worry about setting them. //worry about setting them.
ccFlagBits = ccFlagBits & ~(ext & (CFBit | ECFBit | OFBit)); cfofBits = cfofBits & ~(ext & (CFBit | OFBit));
ecfBit = ecfBit & ~(ext & ECFBit);
//Find the most and second most significant bits of the result. //Find the most and second most significant bits of the result.
int msb = bits(DestReg, dataSize * 8 - 1); int msb = bits(DestReg, dataSize * 8 - 1);
int smsb = bits(DestReg, dataSize * 8 - 2); int smsb = bits(DestReg, dataSize * 8 - 2);
//If some combination of the CF bits need to be set, set them. //If some combination of the CF bits need to be set, set them.
if ((ext & (CFBit | ECFBit)) && msb) if ((ext & (CFBit | ECFBit)) && msb) {
ccFlagBits = ccFlagBits | (ext & (CFBit | ECFBit)); cfofBits = cfofBits | (ext & CFBit);
ecfBit = ecfBit | (ext & ECFBit);
}
//Figure out what the OF bit should be. //Figure out what the OF bit should be.
if ((ext & OFBit) && (msb ^ smsb)) if ((ext & OFBit) && (msb ^ smsb))
ccFlagBits = ccFlagBits | OFBit; cfofBits = cfofBits | OFBit;
//Use the regular mechanisms to calculate the other flags. //Use the regular mechanisms to calculate the other flags.
ccFlagBits = genFlags(ccFlagBits, ext & ~(CFBit | ECFBit | OFBit), uint64_t newFlags = genFlags(ccFlagBits | ezfBit,
DestReg, psrc1, op2); ext & ~(CFBit | ECFBit | OFBit), DestReg, psrc1, op2);
ezfBit = newFlags & EZFBit;
ccFlagBits = newFlags & ccFlagMask;
} }
''' '''
@ -819,7 +869,7 @@ let {{
(op2 & ((dataSize == 8) ? mask(6) : mask(5))); (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
uint8_t realShiftAmt = shiftAmt % (dataSize * 8 + 1); uint8_t realShiftAmt = shiftAmt % (dataSize * 8 + 1);
if (realShiftAmt) { if (realShiftAmt) {
CCFlagBits flags = ccFlagBits; CCFlagBits flags = cfofBits;
uint64_t top = flags.cf << (dataSize * 8 - realShiftAmt); uint64_t top = flags.cf << (dataSize * 8 - realShiftAmt);
if (realShiftAmt > 1) if (realShiftAmt > 1)
top |= psrc1 << (dataSize * 8 - realShiftAmt + 1); top |= psrc1 << (dataSize * 8 - realShiftAmt + 1);
@ -831,24 +881,30 @@ let {{
flag_code = ''' flag_code = '''
// If the shift amount is zero, no flags should be modified. // If the shift amount is zero, no flags should be modified.
if (shiftAmt) { if (shiftAmt) {
int origCFBit = (ccFlagBits & CFBit) ? 1 : 0; int origCFBit = (cfofBits & CFBit) ? 1 : 0;
//Zero out any flags we might modify. This way we only have to //Zero out any flags we might modify. This way we only have to
//worry about setting them. //worry about setting them.
ccFlagBits = ccFlagBits & ~(ext & (CFBit | ECFBit | OFBit)); cfofBits = cfofBits & ~(ext & (CFBit | OFBit));
ecfBit = ecfBit & ~(ext & ECFBit);
//Figure out what the OF bit should be. //Figure out what the OF bit should be.
if ((ext & OFBit) && (origCFBit ^ if ((ext & OFBit) && (origCFBit ^
bits(SrcReg1, dataSize * 8 - 1))) { bits(SrcReg1, dataSize * 8 - 1))) {
ccFlagBits = ccFlagBits | OFBit; cfofBits = cfofBits | OFBit;
} }
//If some combination of the CF bits need to be set, set them. //If some combination of the CF bits need to be set, set them.
if ((ext & (CFBit | ECFBit)) && if ((ext & (CFBit | ECFBit)) &&
(realShiftAmt == 0) ? origCFBit : (realShiftAmt == 0) ? origCFBit :
bits(SrcReg1, realShiftAmt - 1)) { bits(SrcReg1, realShiftAmt - 1)) {
ccFlagBits = ccFlagBits | (ext & (CFBit | ECFBit)); cfofBits = cfofBits | (ext & CFBit);
ecfBit = ecfBit | (ext & ECFBit);
} }
//Use the regular mechanisms to calculate the other flags. //Use the regular mechanisms to calculate the other flags.
ccFlagBits = genFlags(ccFlagBits, ext & ~(CFBit | ECFBit | OFBit), uint64_t newFlags = genFlags(ccFlagBits | ezfBit,
DestReg, psrc1, op2); ext & ~(CFBit | ECFBit | OFBit), DestReg, psrc1, op2);
ezfBit = newFlags & EZFBit;
ccFlagBits = newFlags & ccFlagMask;
} }
''' '''
@ -870,19 +926,27 @@ let {{
if (shiftAmt) { if (shiftAmt) {
//Zero out any flags we might modify. This way we only have to //Zero out any flags we might modify. This way we only have to
//worry about setting them. //worry about setting them.
ccFlagBits = ccFlagBits & ~(ext & (CFBit | ECFBit | OFBit)); cfofBits = cfofBits & ~(ext & (CFBit | OFBit));
ecfBit = ecfBit & ~(ext & ECFBit);
//The CF bits, if set, would be set to the lsb of the result. //The CF bits, if set, would be set to the lsb of the result.
int lsb = DestReg & 0x1; int lsb = DestReg & 0x1;
int msb = bits(DestReg, dataSize * 8 - 1); int msb = bits(DestReg, dataSize * 8 - 1);
//If some combination of the CF bits need to be set, set them. //If some combination of the CF bits need to be set, set them.
if ((ext & (CFBit | ECFBit)) && lsb) if ((ext & (CFBit | ECFBit)) && lsb) {
ccFlagBits = ccFlagBits | (ext & (CFBit | ECFBit)); cfofBits = cfofBits | (ext & CFBit);
ecfBit = ecfBit | (ext & ECFBit);
}
//Figure out what the OF bit should be. //Figure out what the OF bit should be.
if ((ext & OFBit) && (msb ^ lsb)) if ((ext & OFBit) && (msb ^ lsb))
ccFlagBits = ccFlagBits | OFBit; cfofBits = cfofBits | OFBit;
//Use the regular mechanisms to calculate the other flags. //Use the regular mechanisms to calculate the other flags.
ccFlagBits = genFlags(ccFlagBits, ext & ~(CFBit | ECFBit | OFBit), uint64_t newFlags = genFlags(ccFlagBits | ezfBit,
DestReg, psrc1, op2); ext & ~(CFBit | ECFBit | OFBit), DestReg, psrc1, op2);
ezfBit = newFlags & EZFBit;
ccFlagBits = newFlags & ccFlagMask;
} }
''' '''
@ -892,7 +956,7 @@ let {{
(op2 & ((dataSize == 8) ? mask(6) : mask(5))); (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
uint8_t realShiftAmt = shiftAmt % (dataSize * 8 + 1); uint8_t realShiftAmt = shiftAmt % (dataSize * 8 + 1);
if (realShiftAmt) { if (realShiftAmt) {
CCFlagBits flags = ccFlagBits; CCFlagBits flags = cfofBits;
uint64_t top = psrc1 << realShiftAmt; uint64_t top = psrc1 << realShiftAmt;
uint64_t bottom = flags.cf << (realShiftAmt - 1); uint64_t bottom = flags.cf << (realShiftAmt - 1);
if(shiftAmt > 1) if(shiftAmt > 1)
@ -906,22 +970,30 @@ let {{
flag_code = ''' flag_code = '''
// If the shift amount is zero, no flags should be modified. // If the shift amount is zero, no flags should be modified.
if (shiftAmt) { if (shiftAmt) {
int origCFBit = (ccFlagBits & CFBit) ? 1 : 0; int origCFBit = (cfofBits & CFBit) ? 1 : 0;
//Zero out any flags we might modify. This way we only have to //Zero out any flags we might modify. This way we only have to
//worry about setting them. //worry about setting them.
ccFlagBits = ccFlagBits & ~(ext & (CFBit | ECFBit | OFBit)); cfofBits = cfofBits & ~(ext & (CFBit | OFBit));
ecfBit = ecfBit & ~(ext & ECFBit);
int msb = bits(DestReg, dataSize * 8 - 1); int msb = bits(DestReg, dataSize * 8 - 1);
int CFBits = bits(SrcReg1, dataSize * 8 - realShiftAmt); int CFBits = bits(SrcReg1, dataSize * 8 - realShiftAmt);
//If some combination of the CF bits need to be set, set them. //If some combination of the CF bits need to be set, set them.
if ((ext & (CFBit | ECFBit)) && if ((ext & (CFBit | ECFBit)) &&
(realShiftAmt == 0) ? origCFBit : CFBits) (realShiftAmt == 0) ? origCFBit : CFBits) {
ccFlagBits = ccFlagBits | (ext & (CFBit | ECFBit)); cfofBits = cfofBits | (ext & CFBit);
ecfBit = ecfBit | (ext & ECFBit);
}
//Figure out what the OF bit should be. //Figure out what the OF bit should be.
if ((ext & OFBit) && (msb ^ CFBits)) if ((ext & OFBit) && (msb ^ CFBits))
ccFlagBits = ccFlagBits | OFBit; cfofBits = cfofBits | OFBit;
//Use the regular mechanisms to calculate the other flags. //Use the regular mechanisms to calculate the other flags.
ccFlagBits = genFlags(ccFlagBits, ext & ~(CFBit | ECFBit | OFBit), uint64_t newFlags = genFlags(ccFlagBits | ezfBit,
DestReg, psrc1, op2); ext & ~(CFBit | ECFBit | OFBit), DestReg, psrc1, op2);
ezfBit = newFlags & EZFBit;
ccFlagBits = newFlags & ccFlagMask;
} }
''' '''
@ -949,8 +1021,10 @@ let {{
if (shiftAmt) { if (shiftAmt) {
//Zero out any flags we might modify. This way we only have to //Zero out any flags we might modify. This way we only have to
//worry about setting them. //worry about setting them.
ccFlagBits = ccFlagBits & ~(ext & (CFBit | ECFBit | OFBit)); cfofBits = cfofBits & ~(ext & (CFBit | OFBit));
ecfBit = ecfBit & ~(ext & ECFBit);
int CFBits = 0; int CFBits = 0;
//Figure out if we -would- set the CF bits if requested. //Figure out if we -would- set the CF bits if requested.
if ((realShiftAmt == 0 && if ((realShiftAmt == 0 &&
bits(DoubleBits, 0)) || bits(DoubleBits, 0)) ||
@ -960,16 +1034,23 @@ let {{
bits(DoubleBits, 2 * dataBits - realShiftAmt))) { bits(DoubleBits, 2 * dataBits - realShiftAmt))) {
CFBits = 1; CFBits = 1;
} }
//If some combination of the CF bits need to be set, set them. //If some combination of the CF bits need to be set, set them.
if ((ext & (CFBit | ECFBit)) && CFBits) if ((ext & (CFBit | ECFBit)) && CFBits) {
ccFlagBits = ccFlagBits | (ext & (CFBit | ECFBit)); cfofBits = cfofBits | (ext & CFBit);
ecfBit = ecfBit | (ext & ECFBit);
}
//Figure out what the OF bit should be. //Figure out what the OF bit should be.
if ((ext & OFBit) && (bits(SrcReg1, dataBits - 1) ^ if ((ext & OFBit) && (bits(SrcReg1, dataBits - 1) ^
bits(result, dataBits - 1))) bits(result, dataBits - 1)))
ccFlagBits = ccFlagBits | OFBit; cfofBits = cfofBits | OFBit;
//Use the regular mechanisms to calculate the other flags. //Use the regular mechanisms to calculate the other flags.
ccFlagBits = genFlags(ccFlagBits, ext & ~(CFBit | ECFBit | OFBit), uint64_t newFlags = genFlags(ccFlagBits | ezfBit,
DestReg, psrc1, op2); ext & ~(CFBit | ECFBit | OFBit), DestReg, psrc1, op2);
ezfBit = newFlags & EZFBit;
ccFlagBits = newFlags & ccFlagMask;
} }
''' '''
@ -1003,8 +1084,10 @@ let {{
if (shiftAmt) { if (shiftAmt) {
//Zero out any flags we might modify. This way we only have to //Zero out any flags we might modify. This way we only have to
//worry about setting them. //worry about setting them.
ccFlagBits = ccFlagBits & ~(ext & (CFBit | ECFBit | OFBit)); cfofBits = cfofBits & ~(ext & (CFBit | OFBit));
ecfBit = ecfBit & ~(ext & ECFBit);
int CFBits = 0; int CFBits = 0;
//If some combination of the CF bits need to be set, set them. //If some combination of the CF bits need to be set, set them.
if ((realShiftAmt == 0 && if ((realShiftAmt == 0 &&
bits(DoubleBits, dataBits - 1)) || bits(DoubleBits, dataBits - 1)) ||
@ -1014,16 +1097,23 @@ let {{
bits(DoubleBits, realShiftAmt - dataBits - 1))) { bits(DoubleBits, realShiftAmt - dataBits - 1))) {
CFBits = 1; CFBits = 1;
} }
//If some combination of the CF bits need to be set, set them. //If some combination of the CF bits need to be set, set them.
if ((ext & (CFBit | ECFBit)) && CFBits) if ((ext & (CFBit | ECFBit)) && CFBits) {
ccFlagBits = ccFlagBits | (ext & (CFBit | ECFBit)); cfofBits = cfofBits | (ext & CFBit);
ecfBit = ecfBit | (ext & ECFBit);
}
//Figure out what the OF bit should be. //Figure out what the OF bit should be.
if ((ext & OFBit) && (bits(SrcReg1, dataBits - 1) ^ if ((ext & OFBit) && (bits(SrcReg1, dataBits - 1) ^
bits(result, dataBits - 1))) bits(result, dataBits - 1)))
ccFlagBits = ccFlagBits | OFBit; cfofBits = cfofBits | OFBit;
//Use the regular mechanisms to calculate the other flags. //Use the regular mechanisms to calculate the other flags.
ccFlagBits = genFlags(ccFlagBits, ext & ~(CFBit | ECFBit | OFBit), uint64_t newFlags = genFlags(ccFlagBits | ezfBit,
DestReg, psrc1, op2); ext & ~(CFBit | ECFBit | OFBit), DestReg, psrc1, op2);
ezfBit = newFlags & EZFBit;
ccFlagBits = newFlags & ccFlagMask;
} }
''' '''
@ -1035,14 +1125,25 @@ let {{
else_code = "NRIP = NRIP;" else_code = "NRIP = NRIP;"
class Wruflags(WrRegOp): class Wruflags(WrRegOp):
code = 'ccFlagBits = psrc1 ^ op2' code = '''
uint64_t newFlags = psrc1 ^ op2;
cfofBits = newFlags & cfofMask;
ecfBit = newFlags & ECFBit;
ezfBit = newFlags & EZFBit;
ccFlagBits = newFlags & ccFlagMask;
'''
class Wrflags(WrRegOp): class Wrflags(WrRegOp):
code = ''' code = '''
MiscReg newFlags = psrc1 ^ op2; MiscReg newFlags = psrc1 ^ op2;
MiscReg userFlagMask = 0xDD5; MiscReg userFlagMask = 0xDD5;
// Get only the user flags // Get only the user flags
ccFlagBits = newFlags & userFlagMask; ccFlagBits = newFlags & ccFlagMask;
cfofBits = newFlags & cfofMask;
ecfBit = 0;
ezfBit = 0;
// Get everything else // Get everything else
nccFlagBits = newFlags & ~userFlagMask; nccFlagBits = newFlags & ~userFlagMask;
''' '''
@ -1051,24 +1152,26 @@ let {{
code = 'DestReg = NRIP - CSBase;' code = 'DestReg = NRIP - CSBase;'
class Ruflags(RdRegOp): class Ruflags(RdRegOp):
code = 'DestReg = ccFlagBits' code = 'DestReg = ccFlagBits | cfofBits | ecfBit | ezfBit;'
class Rflags(RdRegOp): class Rflags(RdRegOp):
code = 'DestReg = ccFlagBits | nccFlagBits' code = '''
DestReg = ccFlagBits | cfofBits | ecfBit | ezfBit | nccFlagBits;
'''
class Ruflag(RegOp): class Ruflag(RegOp):
code = ''' code = '''
int flag = bits(ccFlagBits, imm8); int flag = bits(ccFlagBits | cfofBits | ecfBit | ezfBit, imm8);
DestReg = merge(DestReg, flag, dataSize); DestReg = merge(DestReg, flag, dataSize);
ccFlagBits = (flag == 0) ? (ccFlagBits | EZFBit) : ezfBit = (flag == 0) ? EZFBit : 0;
(ccFlagBits & ~EZFBit);
''' '''
big_code = ''' big_code = '''
int flag = bits(ccFlagBits, imm8); int flag = bits(ccFlagBits | cfofBits | ecfBit | ezfBit, imm8);
DestReg = flag & mask(dataSize * 8); DestReg = flag & mask(dataSize * 8);
ccFlagBits = (flag == 0) ? (ccFlagBits | EZFBit) : ezfBit = (flag == 0) ? EZFBit : 0;
(ccFlagBits & ~EZFBit);
''' '''
def __init__(self, dest, imm, flags=None, \ def __init__(self, dest, imm, flags=None, \
dataSize="env.dataSize"): dataSize="env.dataSize"):
super(Ruflag, self).__init__(dest, \ super(Ruflag, self).__init__(dest, \
@ -1077,20 +1180,24 @@ let {{
class Rflag(RegOp): class Rflag(RegOp):
code = ''' code = '''
MiscReg flagMask = 0x3F7FDD5; MiscReg flagMask = 0x3F7FDD5;
MiscReg flags = (nccFlagBits | ccFlagBits) & flagMask; MiscReg flags = (nccFlagBits | ccFlagBits | cfofBits |
ecfBit | ezfBit) & flagMask;
int flag = bits(flags, imm8); int flag = bits(flags, imm8);
DestReg = merge(DestReg, flag, dataSize); DestReg = merge(DestReg, flag, dataSize);
ccFlagBits = (flag == 0) ? (ccFlagBits | EZFBit) : ezfBit = (flag == 0) ? EZFBit : 0;
(ccFlagBits & ~EZFBit);
''' '''
big_code = ''' big_code = '''
MiscReg flagMask = 0x3F7FDD5; MiscReg flagMask = 0x3F7FDD5;
MiscReg flags = (nccFlagBits | ccFlagBits) & flagMask; MiscReg flags = (nccFlagBits | ccFlagBits | cfofBits |
ecfBit | ezfBit) & flagMask;
int flag = bits(flags, imm8); int flag = bits(flags, imm8);
DestReg = flag & mask(dataSize * 8); DestReg = flag & mask(dataSize * 8);
ccFlagBits = (flag == 0) ? (ccFlagBits | EZFBit) : ezfBit = (flag == 0) ? EZFBit : 0;
(ccFlagBits & ~EZFBit);
''' '''
def __init__(self, dest, imm, flags=None, \ def __init__(self, dest, imm, flags=None, \
dataSize="env.dataSize"): dataSize="env.dataSize"):
super(Rflag, self).__init__(dest, \ super(Rflag, self).__init__(dest, \
@ -1106,6 +1213,7 @@ let {{
val = sign_bit ? (val | ~maskVal) : (val & maskVal); val = sign_bit ? (val | ~maskVal) : (val & maskVal);
DestReg = merge(DestReg, val, dataSize); DestReg = merge(DestReg, val, dataSize);
''' '''
big_code = ''' big_code = '''
IntReg val = psrc1; IntReg val = psrc1;
// Mask the bit position so that it wraps. // Mask the bit position so that it wraps.
@ -1115,13 +1223,19 @@ let {{
val = sign_bit ? (val | ~maskVal) : (val & maskVal); val = sign_bit ? (val | ~maskVal) : (val & maskVal);
DestReg = val & mask(dataSize * 8); DestReg = val & mask(dataSize * 8);
''' '''
flag_code = ''' flag_code = '''
if (!sign_bit) if (!sign_bit) {
ccFlagBits = ccFlagBits & ccFlagBits = ccFlagBits & ~(ext & (ZFBit));
~(ext & (CFBit | ECFBit | ZFBit | EZFBit)); cfofBits = cfofBits & ~(ext & (CFBit));
else ecfBit = ecfBit & ~(ext & ECFBit);
ccFlagBits = ccFlagBits | ezfBit = ezfBit & ~(ext & EZFBit);
(ext & (CFBit | ECFBit | ZFBit | EZFBit)); } else {
ccFlagBits = ccFlagBits | (ext & (ZFBit));
cfofBits = cfofBits | (ext & (CFBit));
ecfBit = ecfBit | (ext & ECFBit);
ezfBit = ezfBit | (ext & EZFBit);
}
''' '''
class Zext(RegOp): class Zext(RegOp):
@ -1403,9 +1517,13 @@ let {{
''' '''
flag_code = ''' flag_code = '''
// Check for a NULL selector and set ZF,EZF appropriately. // Check for a NULL selector and set ZF,EZF appropriately.
ccFlagBits = ccFlagBits & ~(ext & (ZFBit | EZFBit)); ccFlagBits = ccFlagBits & ~(ext & ZFBit);
if (!selector.si && !selector.ti) ezfBit = ezfBit & ~(ext & EZFBit);
ccFlagBits = ccFlagBits | (ext & (ZFBit | EZFBit));
if (!selector.si && !selector.ti) {
ccFlagBits = ccFlagBits | (ext & ZFBit);
ezfBit = ezfBit | (ext & EZFBit);
}
''' '''
class Wrdh(RegOp): class Wrdh(RegOp):

View file

@ -172,7 +172,8 @@ let {{
iop = InstObjParams("br", "MicroBranchFlags", "SeqOpBase", iop = InstObjParams("br", "MicroBranchFlags", "SeqOpBase",
{"code": "nuIP = target;", {"code": "nuIP = target;",
"else_code": "nuIP = nuIP;", "else_code": "nuIP = nuIP;",
"cond_test": "checkCondition(ccFlagBits, cc)", "cond_test": "checkCondition(ccFlagBits | cfofBits | \
ecfBit | ezfBit, cc)",
"cond_control_flag_init": "flags[IsCondControl] = true"}) "cond_control_flag_init": "flags[IsCondControl] = true"})
exec_output += SeqOpExecute.subst(iop) exec_output += SeqOpExecute.subst(iop)
header_output += SeqOpDeclare.subst(iop) header_output += SeqOpDeclare.subst(iop)
@ -189,7 +190,8 @@ let {{
iop = InstObjParams("eret", "EretFlags", "SeqOpBase", iop = InstObjParams("eret", "EretFlags", "SeqOpBase",
{"code": "", "else_code": "", {"code": "", "else_code": "",
"cond_test": "checkCondition(ccFlagBits, cc)", "cond_test": "checkCondition(ccFlagBits | cfofBits | \
ecfBit | ezfBit, cc)",
"cond_control_flag_init": ""}) "cond_control_flag_init": ""})
exec_output += SeqOpExecute.subst(iop) exec_output += SeqOpExecute.subst(iop)
header_output += SeqOpDeclare.subst(iop) header_output += SeqOpDeclare.subst(iop)

View file

@ -181,7 +181,8 @@ let {{
iop = InstObjParams("fault", "MicroFaultFlags", "MicroFaultBase", iop = InstObjParams("fault", "MicroFaultFlags", "MicroFaultBase",
{"code": "", {"code": "",
"cond_test": "checkCondition(ccFlagBits, cc)"}) "cond_test": "checkCondition(ccFlagBits | cfofBits | \
ecfBit | ezfBit, cc)"})
exec_output = MicroFaultExecute.subst(iop) exec_output = MicroFaultExecute.subst(iop)
header_output = MicroFaultDeclare.subst(iop) header_output = MicroFaultDeclare.subst(iop)
decoder_output = MicroFaultConstructor.subst(iop) decoder_output = MicroFaultConstructor.subst(iop)

View file

@ -119,10 +119,13 @@ def operands {{
# This holds the condition code portion of the flag register. The # This holds the condition code portion of the flag register. The
# nccFlagBits version holds the rest. # nccFlagBits version holds the rest.
'ccFlagBits': intReg('INTREG_PSEUDO(0)', 60), 'ccFlagBits': intReg('INTREG_PSEUDO(0)', 60),
'cfofBits': intReg('INTREG_PSEUDO(1)', 61),
'ecfBit': intReg('INTREG_PSEUDO(2)', 62),
'ezfBit': intReg('INTREG_PSEUDO(3)', 63),
# These register should needs to be more protected so that later # These register should needs to be more protected so that later
# instructions don't map their indexes with an old value. # instructions don't map their indexes with an old value.
'nccFlagBits': controlReg('MISCREG_RFLAGS', 61), 'nccFlagBits': controlReg('MISCREG_RFLAGS', 64),
'TOP': controlReg('MISCREG_X87_TOP', 62, ctype='ub'), 'TOP': controlReg('MISCREG_X87_TOP', 65, ctype='ub'),
# The segment base as used by memory instructions. # The segment base as used by memory instructions.
'SegBase': controlReg('MISCREG_SEG_EFF_BASE(segment)', 70), 'SegBase': controlReg('MISCREG_SEG_EFF_BASE(segment)', 70),

View file

@ -64,6 +64,9 @@ namespace X86ISA
OFBit = 1 << 11 OFBit = 1 << 11
}; };
const uint32_t cfofMask = CFBit | OFBit;
const uint32_t ccFlagMask = PFBit | AFBit | ZFBit | SFBit | DFBit;
enum RFLAGBit { enum RFLAGBit {
TFBit = 1 << 8, TFBit = 1 << 8,
IFBit = 1 << 9, IFBit = 1 << 9,

View file

@ -46,7 +46,7 @@ namespace X86ISA
{ {
const int NumMicroIntRegs = 16; const int NumMicroIntRegs = 16;
const int NumPseudoIntRegs = 1; const int NumPseudoIntRegs = 4;
//1. The condition code bits of the rflags register. //1. The condition code bits of the rflags register.
const int NumImplicitIntRegs = 6; const int NumImplicitIntRegs = 6;
//1. The lower part of the result of multiplication. //1. The lower part of the result of multiplication.