X86: make use of register predication
The patch introduces two predicates for condition code registers -- one tests if a register needs to be read, the other tests whether a register needs to be written to. These predicates are evaluated twice -- during construction of the microop and during its execution. Register reads and writes are elided depending on how the predicates evaluate.
This commit is contained in:
parent
6369df59c8
commit
f47c2f6415
2 changed files with 188 additions and 135 deletions
|
@ -438,40 +438,43 @@ let {{
|
|||
flag_code = '''
|
||||
//Don't have genFlags handle the OF or CF bits
|
||||
uint64_t mask = CFBit | ECFBit | OFBit;
|
||||
uint64_t newFlags = genFlags(ccFlagBits | dfBit | ezfBit,
|
||||
ext & ~mask, result, psrc1, op2);
|
||||
ezfBit = newFlags & EZFBit;
|
||||
dfBit = newFlags & DFBit;
|
||||
ccFlagBits = newFlags & ccFlagMask;
|
||||
uint64_t newFlags = genFlags(PredccFlagBits | PreddfBit |
|
||||
PredezfBit, ext & ~mask, result, psrc1, op2);
|
||||
PredezfBit = newFlags & EZFBit;
|
||||
PreddfBit = newFlags & DFBit;
|
||||
PredccFlagBits = newFlags & ccFlagMask;
|
||||
|
||||
//If a logic microop wants to set these, it wants to set them to 0.
|
||||
cfofBits = cfofBits & ~((CFBit | OFBit) & ext);
|
||||
ecfBit = ecfBit & ~(ECFBit & ext);
|
||||
PredcfofBits = PredcfofBits & ~((CFBit | OFBit) & ext);
|
||||
PredecfBit = PredecfBit & ~(ECFBit & ext);
|
||||
'''
|
||||
|
||||
class FlagRegOp(RegOp):
|
||||
abstract = True
|
||||
flag_code = '''
|
||||
uint64_t newFlags = genFlags(ccFlagBits | cfofBits | dfBit |
|
||||
ecfBit | ezfBit, ext, result, psrc1, op2);
|
||||
cfofBits = newFlags & cfofMask;
|
||||
ecfBit = newFlags & ECFBit;
|
||||
ezfBit = newFlags & EZFBit;
|
||||
dfBit = newFlags & DFBit;
|
||||
ccFlagBits = newFlags & ccFlagMask;
|
||||
uint64_t newFlags = genFlags(PredccFlagBits | PredcfofBits |
|
||||
PreddfBit | PredecfBit | PredezfBit,
|
||||
ext, result, psrc1, op2);
|
||||
|
||||
PredcfofBits = newFlags & cfofMask;
|
||||
PredecfBit = newFlags & ECFBit;
|
||||
PredezfBit = newFlags & EZFBit;
|
||||
PreddfBit = newFlags & DFBit;
|
||||
PredccFlagBits = newFlags & ccFlagMask;
|
||||
'''
|
||||
|
||||
class SubRegOp(RegOp):
|
||||
abstract = True
|
||||
flag_code = '''
|
||||
uint64_t newFlags = genFlags(ccFlagBits | cfofBits | dfBit |
|
||||
ecfBit | ezfBit, ext, result, psrc1,
|
||||
~op2, true);
|
||||
cfofBits = newFlags & cfofMask;
|
||||
ecfBit = newFlags & ECFBit;
|
||||
ezfBit = newFlags & EZFBit;
|
||||
dfBit = newFlags & DFBit;
|
||||
ccFlagBits = newFlags & ccFlagMask;
|
||||
uint64_t newFlags = genFlags(PredccFlagBits | PredcfofBits |
|
||||
PreddfBit | PredecfBit | PredezfBit,
|
||||
ext, result, psrc1, ~op2, true);
|
||||
|
||||
PredcfofBits = newFlags & cfofMask;
|
||||
PredecfBit = newFlags & ECFBit;
|
||||
PredezfBit = newFlags & EZFBit;
|
||||
PreddfBit = newFlags & DFBit;
|
||||
PredccFlagBits = newFlags & ccFlagMask;
|
||||
'''
|
||||
|
||||
class CondRegOp(RegOp):
|
||||
|
@ -556,11 +559,11 @@ let {{
|
|||
flag_code = '''
|
||||
if ((-ProdHi & mask(dataSize * 8)) !=
|
||||
bits(ProdLow, dataSize * 8 - 1)) {
|
||||
cfofBits = cfofBits | (ext & (CFBit | OFBit));
|
||||
ecfBit = ecfBit | (ext & ECFBit);
|
||||
PredcfofBits = PredcfofBits | (ext & (CFBit | OFBit));
|
||||
PredecfBit = PredecfBit | (ext & ECFBit);
|
||||
} else {
|
||||
cfofBits = cfofBits & ~(ext & (CFBit | OFBit));
|
||||
ecfBit = ecfBit & ~(ext & ECFBit);
|
||||
PredcfofBits = PredcfofBits & ~(ext & (CFBit | OFBit));
|
||||
PredecfBit = PredecfBit & ~(ext & ECFBit);
|
||||
}
|
||||
'''
|
||||
|
||||
|
@ -579,11 +582,11 @@ let {{
|
|||
'''
|
||||
flag_code = '''
|
||||
if (ProdHi) {
|
||||
cfofBits = cfofBits | (ext & (CFBit | OFBit));
|
||||
ecfBit = ecfBit | (ext & ECFBit);
|
||||
PredcfofBits = PredcfofBits | (ext & (CFBit | OFBit));
|
||||
PredecfBit = PredecfBit | (ext & ECFBit);
|
||||
} else {
|
||||
cfofBits = cfofBits & ~(ext & (CFBit | OFBit));
|
||||
ecfBit = ecfBit & ~(ext & ECFBit);
|
||||
PredcfofBits = PredcfofBits & ~(ext & (CFBit | OFBit));
|
||||
PredecfBit = PredecfBit & ~(ext & ECFBit);
|
||||
}
|
||||
'''
|
||||
|
||||
|
@ -682,9 +685,9 @@ let {{
|
|||
big_code = divCode % "DestReg = remaining & mask(dataSize * 8);"
|
||||
flag_code = '''
|
||||
if (remaining == 0)
|
||||
ezfBit = ezfBit | (ext & EZFBit);
|
||||
PredezfBit = PredezfBit | (ext & EZFBit);
|
||||
else
|
||||
ezfBit = ezfBit & ~(ext & EZFBit);
|
||||
PredezfBit = PredezfBit & ~(ext & EZFBit);
|
||||
'''
|
||||
|
||||
class Divq(RdRegOp):
|
||||
|
@ -715,8 +718,8 @@ let {{
|
|||
if (shiftAmt) {
|
||||
//Zero out any flags we might modify. This way we only have to
|
||||
//worry about setting them.
|
||||
cfofBits = cfofBits & ~(ext & (CFBit | OFBit));
|
||||
ecfBit = ecfBit & ~(ext & ECFBit);
|
||||
PredcfofBits = PredcfofBits & ~(ext & (CFBit | OFBit));
|
||||
PredecfBit = PredecfBit & ~(ext & ECFBit);
|
||||
|
||||
int CFBits = 0;
|
||||
//Figure out if we -would- set the CF bits if requested.
|
||||
|
@ -727,20 +730,22 @@ let {{
|
|||
|
||||
//If some combination of the CF bits need to be set, set them.
|
||||
if ((ext & (CFBit | ECFBit)) && CFBits) {
|
||||
cfofBits = cfofBits | (ext & CFBit);
|
||||
ecfBit = ecfBit | (ext & ECFBit);
|
||||
PredcfofBits = PredcfofBits | (ext & CFBit);
|
||||
PredecfBit = PredecfBit | (ext & ECFBit);
|
||||
}
|
||||
|
||||
//Figure out what the OF bit should be.
|
||||
if ((ext & OFBit) && (CFBits ^ bits(DestReg, dataSize * 8 - 1)))
|
||||
cfofBits = cfofBits | OFBit;
|
||||
PredcfofBits = PredcfofBits | OFBit;
|
||||
|
||||
//Use the regular mechanisms to calculate the other flags.
|
||||
uint64_t newFlags = genFlags(ccFlagBits | dfBit | ezfBit,
|
||||
ext & ~(CFBit | ECFBit | OFBit), DestReg, psrc1, op2);
|
||||
ezfBit = newFlags & EZFBit;
|
||||
dfBit = newFlags & DFBit;
|
||||
ccFlagBits = newFlags & ccFlagMask;
|
||||
uint64_t newFlags = genFlags(PredccFlagBits | PreddfBit |
|
||||
PredezfBit, ext & ~(CFBit | ECFBit | OFBit),
|
||||
DestReg, psrc1, op2);
|
||||
|
||||
PredezfBit = newFlags & EZFBit;
|
||||
PreddfBit = newFlags & DFBit;
|
||||
PredccFlagBits = newFlags & ccFlagMask;
|
||||
}
|
||||
'''
|
||||
|
||||
|
@ -763,27 +768,29 @@ let {{
|
|||
if (shiftAmt) {
|
||||
//Zero out any flags we might modify. This way we only have to
|
||||
//worry about setting them.
|
||||
cfofBits = cfofBits & ~(ext & (CFBit | OFBit));
|
||||
ecfBit = ecfBit & ~(ext & ECFBit);
|
||||
PredcfofBits = PredcfofBits & ~(ext & (CFBit | OFBit));
|
||||
PredecfBit = PredecfBit & ~(ext & ECFBit);
|
||||
|
||||
//If some combination of the CF bits need to be set, set them.
|
||||
if ((ext & (CFBit | ECFBit)) &&
|
||||
shiftAmt <= dataSize * 8 &&
|
||||
bits(SrcReg1, shiftAmt - 1)) {
|
||||
cfofBits = cfofBits | (ext & CFBit);
|
||||
ecfBit = ecfBit | (ext & ECFBit);
|
||||
PredcfofBits = PredcfofBits | (ext & CFBit);
|
||||
PredecfBit = PredecfBit | (ext & ECFBit);
|
||||
}
|
||||
|
||||
//Figure out what the OF bit should be.
|
||||
if ((ext & OFBit) && bits(SrcReg1, dataSize * 8 - 1))
|
||||
cfofBits = cfofBits | OFBit;
|
||||
PredcfofBits = PredcfofBits | OFBit;
|
||||
|
||||
//Use the regular mechanisms to calculate the other flags.
|
||||
uint64_t newFlags = genFlags(ccFlagBits | dfBit | ezfBit,
|
||||
ext & ~(CFBit | ECFBit | OFBit), DestReg, psrc1, op2);
|
||||
ezfBit = newFlags & EZFBit;
|
||||
dfBit = newFlags & DFBit;
|
||||
ccFlagBits = newFlags & ccFlagMask;
|
||||
uint64_t newFlags = genFlags(PredccFlagBits | PreddfBit |
|
||||
PredezfBit, ext & ~(CFBit | ECFBit | OFBit),
|
||||
DestReg, psrc1, op2);
|
||||
|
||||
PredezfBit = newFlags & EZFBit;
|
||||
PreddfBit = newFlags & DFBit;
|
||||
PredccFlagBits = newFlags & ccFlagMask;
|
||||
}
|
||||
'''
|
||||
|
||||
|
@ -808,24 +815,26 @@ let {{
|
|||
if (shiftAmt) {
|
||||
//Zero out any flags we might modify. This way we only have to
|
||||
//worry about setting them.
|
||||
cfofBits = cfofBits & ~(ext & (CFBit | OFBit));
|
||||
ecfBit = ecfBit & ~(ext & ECFBit);
|
||||
PredcfofBits = PredcfofBits & ~(ext & (CFBit | OFBit));
|
||||
PredecfBit = PredecfBit & ~(ext & ECFBit);
|
||||
|
||||
//If some combination of the CF bits need to be set, set them.
|
||||
uint8_t effectiveShift =
|
||||
(shiftAmt <= dataSize * 8) ? shiftAmt : (dataSize * 8);
|
||||
if ((ext & (CFBit | ECFBit)) &&
|
||||
bits(SrcReg1, effectiveShift - 1)) {
|
||||
cfofBits = cfofBits | (ext & CFBit);
|
||||
ecfBit = ecfBit | (ext & ECFBit);
|
||||
PredcfofBits = PredcfofBits | (ext & CFBit);
|
||||
PredecfBit = PredecfBit | (ext & ECFBit);
|
||||
}
|
||||
|
||||
//Use the regular mechanisms to calculate the other flags.
|
||||
uint64_t newFlags = genFlags(ccFlagBits | dfBit | ezfBit,
|
||||
ext & ~(CFBit | ECFBit | OFBit), DestReg, psrc1, op2);
|
||||
ezfBit = newFlags & EZFBit;
|
||||
dfBit = newFlags & DFBit;
|
||||
ccFlagBits = newFlags & ccFlagMask;
|
||||
uint64_t newFlags = genFlags(PredccFlagBits | PreddfBit |
|
||||
PredezfBit, ext & ~(CFBit | ECFBit | OFBit),
|
||||
DestReg, psrc1, op2);
|
||||
|
||||
PredezfBit = newFlags & EZFBit;
|
||||
PreddfBit = newFlags & DFBit;
|
||||
PredccFlagBits = newFlags & ccFlagMask;
|
||||
}
|
||||
'''
|
||||
|
||||
|
@ -846,28 +855,30 @@ let {{
|
|||
if (shiftAmt) {
|
||||
//Zero out any flags we might modify. This way we only have to
|
||||
//worry about setting them.
|
||||
cfofBits = cfofBits & ~(ext & (CFBit | OFBit));
|
||||
ecfBit = ecfBit & ~(ext & ECFBit);
|
||||
PredcfofBits = PredcfofBits & ~(ext & (CFBit | OFBit));
|
||||
PredecfBit = PredecfBit & ~(ext & ECFBit);
|
||||
|
||||
//Find the most and second most significant bits of the result.
|
||||
int msb = bits(DestReg, dataSize * 8 - 1);
|
||||
int smsb = bits(DestReg, dataSize * 8 - 2);
|
||||
//If some combination of the CF bits need to be set, set them.
|
||||
if ((ext & (CFBit | ECFBit)) && msb) {
|
||||
cfofBits = cfofBits | (ext & CFBit);
|
||||
ecfBit = ecfBit | (ext & ECFBit);
|
||||
PredcfofBits = PredcfofBits | (ext & CFBit);
|
||||
PredecfBit = PredecfBit | (ext & ECFBit);
|
||||
}
|
||||
|
||||
//Figure out what the OF bit should be.
|
||||
if ((ext & OFBit) && (msb ^ smsb))
|
||||
cfofBits = cfofBits | OFBit;
|
||||
PredcfofBits = PredcfofBits | OFBit;
|
||||
|
||||
//Use the regular mechanisms to calculate the other flags.
|
||||
uint64_t newFlags = genFlags(ccFlagBits | dfBit | ezfBit,
|
||||
ext & ~(CFBit | ECFBit | OFBit), DestReg, psrc1, op2);
|
||||
ezfBit = newFlags & EZFBit;
|
||||
dfBit = newFlags & DFBit;
|
||||
ccFlagBits = newFlags & ccFlagMask;
|
||||
uint64_t newFlags = genFlags(PredccFlagBits | PreddfBit |
|
||||
PredezfBit, ext & ~(CFBit | ECFBit | OFBit),
|
||||
DestReg, psrc1, op2);
|
||||
|
||||
PredezfBit = newFlags & EZFBit;
|
||||
PreddfBit = newFlags & DFBit;
|
||||
PredccFlagBits = newFlags & ccFlagMask;
|
||||
}
|
||||
'''
|
||||
|
||||
|
@ -892,28 +903,30 @@ let {{
|
|||
int origCFBit = (cfofBits & CFBit) ? 1 : 0;
|
||||
//Zero out any flags we might modify. This way we only have to
|
||||
//worry about setting them.
|
||||
cfofBits = cfofBits & ~(ext & (CFBit | OFBit));
|
||||
ecfBit = ecfBit & ~(ext & ECFBit);
|
||||
PredcfofBits = PredcfofBits & ~(ext & (CFBit | OFBit));
|
||||
PredecfBit = PredecfBit & ~(ext & ECFBit);
|
||||
|
||||
//Figure out what the OF bit should be.
|
||||
if ((ext & OFBit) && (origCFBit ^
|
||||
bits(SrcReg1, dataSize * 8 - 1))) {
|
||||
cfofBits = cfofBits | OFBit;
|
||||
PredcfofBits = PredcfofBits | OFBit;
|
||||
}
|
||||
//If some combination of the CF bits need to be set, set them.
|
||||
if ((ext & (CFBit | ECFBit)) &&
|
||||
(realShiftAmt == 0) ? origCFBit :
|
||||
bits(SrcReg1, realShiftAmt - 1)) {
|
||||
cfofBits = cfofBits | (ext & CFBit);
|
||||
ecfBit = ecfBit | (ext & ECFBit);
|
||||
PredcfofBits = PredcfofBits | (ext & CFBit);
|
||||
PredecfBit = PredecfBit | (ext & ECFBit);
|
||||
}
|
||||
|
||||
//Use the regular mechanisms to calculate the other flags.
|
||||
uint64_t newFlags = genFlags(ccFlagBits | dfBit | ezfBit,
|
||||
ext & ~(CFBit | ECFBit | OFBit), DestReg, psrc1, op2);
|
||||
ezfBit = newFlags & EZFBit;
|
||||
dfBit = newFlags & DFBit;
|
||||
ccFlagBits = newFlags & ccFlagMask;
|
||||
uint64_t newFlags = genFlags(PredccFlagBits | PreddfBit |
|
||||
PredezfBit, ext & ~(CFBit | ECFBit | OFBit),
|
||||
DestReg, psrc1, op2);
|
||||
|
||||
PredezfBit = newFlags & EZFBit;
|
||||
PreddfBit = newFlags & DFBit;
|
||||
PredccFlagBits = newFlags & ccFlagMask;
|
||||
}
|
||||
'''
|
||||
|
||||
|
@ -935,28 +948,30 @@ let {{
|
|||
if (shiftAmt) {
|
||||
//Zero out any flags we might modify. This way we only have to
|
||||
//worry about setting them.
|
||||
cfofBits = cfofBits & ~(ext & (CFBit | OFBit));
|
||||
ecfBit = ecfBit & ~(ext & ECFBit);
|
||||
PredcfofBits = PredcfofBits & ~(ext & (CFBit | OFBit));
|
||||
PredecfBit = PredecfBit & ~(ext & ECFBit);
|
||||
|
||||
//The CF bits, if set, would be set to the lsb of the result.
|
||||
int lsb = DestReg & 0x1;
|
||||
int msb = bits(DestReg, dataSize * 8 - 1);
|
||||
//If some combination of the CF bits need to be set, set them.
|
||||
if ((ext & (CFBit | ECFBit)) && lsb) {
|
||||
cfofBits = cfofBits | (ext & CFBit);
|
||||
ecfBit = ecfBit | (ext & ECFBit);
|
||||
PredcfofBits = PredcfofBits | (ext & CFBit);
|
||||
PredecfBit = PredecfBit | (ext & ECFBit);
|
||||
}
|
||||
|
||||
//Figure out what the OF bit should be.
|
||||
if ((ext & OFBit) && (msb ^ lsb))
|
||||
cfofBits = cfofBits | OFBit;
|
||||
PredcfofBits = PredcfofBits | OFBit;
|
||||
|
||||
//Use the regular mechanisms to calculate the other flags.
|
||||
uint64_t newFlags = genFlags(ccFlagBits | dfBit | ezfBit,
|
||||
ext & ~(CFBit | ECFBit | OFBit), DestReg, psrc1, op2);
|
||||
ezfBit = newFlags & EZFBit;
|
||||
dfBit = newFlags & DFBit;
|
||||
ccFlagBits = newFlags & ccFlagMask;
|
||||
uint64_t newFlags = genFlags(PredccFlagBits | PreddfBit |
|
||||
PredezfBit, ext & ~(CFBit | ECFBit | OFBit),
|
||||
DestReg, psrc1, op2);
|
||||
|
||||
PredezfBit = newFlags & EZFBit;
|
||||
PreddfBit = newFlags & DFBit;
|
||||
PredccFlagBits = newFlags & ccFlagMask;
|
||||
}
|
||||
'''
|
||||
|
||||
|
@ -983,28 +998,30 @@ let {{
|
|||
int origCFBit = (cfofBits & CFBit) ? 1 : 0;
|
||||
//Zero out any flags we might modify. This way we only have to
|
||||
//worry about setting them.
|
||||
cfofBits = cfofBits & ~(ext & (CFBit | OFBit));
|
||||
ecfBit = ecfBit & ~(ext & ECFBit);
|
||||
PredcfofBits = PredcfofBits & ~(ext & (CFBit | OFBit));
|
||||
PredecfBit = PredecfBit & ~(ext & ECFBit);
|
||||
|
||||
int msb = bits(DestReg, dataSize * 8 - 1);
|
||||
int CFBits = bits(SrcReg1, dataSize * 8 - realShiftAmt);
|
||||
//If some combination of the CF bits need to be set, set them.
|
||||
if ((ext & (CFBit | ECFBit)) &&
|
||||
(realShiftAmt == 0) ? origCFBit : CFBits) {
|
||||
cfofBits = cfofBits | (ext & CFBit);
|
||||
ecfBit = ecfBit | (ext & ECFBit);
|
||||
PredcfofBits = PredcfofBits | (ext & CFBit);
|
||||
PredecfBit = PredecfBit | (ext & ECFBit);
|
||||
}
|
||||
|
||||
//Figure out what the OF bit should be.
|
||||
if ((ext & OFBit) && (msb ^ CFBits))
|
||||
cfofBits = cfofBits | OFBit;
|
||||
PredcfofBits = PredcfofBits | OFBit;
|
||||
|
||||
//Use the regular mechanisms to calculate the other flags.
|
||||
uint64_t newFlags = genFlags(ccFlagBits | dfBit | ezfBit,
|
||||
ext & ~(CFBit | ECFBit | OFBit), DestReg, psrc1, op2);
|
||||
ezfBit = newFlags & EZFBit;
|
||||
dfBit = newFlags & DFBit;
|
||||
ccFlagBits = newFlags & ccFlagMask;
|
||||
uint64_t newFlags = genFlags(PredccFlagBits | PreddfBit |
|
||||
PredezfBit, ext & ~(CFBit | ECFBit | OFBit),
|
||||
DestReg, psrc1, op2);
|
||||
|
||||
PredezfBit = newFlags & EZFBit;
|
||||
PreddfBit = newFlags & DFBit;
|
||||
PredccFlagBits = newFlags & ccFlagMask;
|
||||
}
|
||||
'''
|
||||
|
||||
|
@ -1032,8 +1049,8 @@ let {{
|
|||
if (shiftAmt) {
|
||||
//Zero out any flags we might modify. This way we only have to
|
||||
//worry about setting them.
|
||||
cfofBits = cfofBits & ~(ext & (CFBit | OFBit));
|
||||
ecfBit = ecfBit & ~(ext & ECFBit);
|
||||
PredcfofBits = PredcfofBits & ~(ext & (CFBit | OFBit));
|
||||
PredecfBit = PredecfBit & ~(ext & ECFBit);
|
||||
int CFBits = 0;
|
||||
|
||||
//Figure out if we -would- set the CF bits if requested.
|
||||
|
@ -1048,21 +1065,23 @@ let {{
|
|||
|
||||
//If some combination of the CF bits need to be set, set them.
|
||||
if ((ext & (CFBit | ECFBit)) && CFBits) {
|
||||
cfofBits = cfofBits | (ext & CFBit);
|
||||
ecfBit = ecfBit | (ext & ECFBit);
|
||||
PredcfofBits = PredcfofBits | (ext & CFBit);
|
||||
PredecfBit = PredecfBit | (ext & ECFBit);
|
||||
}
|
||||
|
||||
//Figure out what the OF bit should be.
|
||||
if ((ext & OFBit) && (bits(SrcReg1, dataBits - 1) ^
|
||||
bits(result, dataBits - 1)))
|
||||
cfofBits = cfofBits | OFBit;
|
||||
PredcfofBits = PredcfofBits | OFBit;
|
||||
|
||||
//Use the regular mechanisms to calculate the other flags.
|
||||
uint64_t newFlags = genFlags(ccFlagBits | dfBit | ezfBit,
|
||||
ext & ~(CFBit | ECFBit | OFBit), DestReg, psrc1, op2);
|
||||
ezfBit = newFlags & EZFBit;
|
||||
dfBit = newFlags & DFBit;
|
||||
ccFlagBits = newFlags & ccFlagMask;
|
||||
uint64_t newFlags = genFlags(PredccFlagBits | PreddfBit |
|
||||
PredezfBit, ext & ~(CFBit | ECFBit | OFBit),
|
||||
DestReg, psrc1, op2);
|
||||
|
||||
PredezfBit = newFlags & EZFBit;
|
||||
PreddfBit = newFlags & DFBit;
|
||||
PredccFlagBits = newFlags & ccFlagMask;
|
||||
}
|
||||
'''
|
||||
|
||||
|
@ -1096,8 +1115,8 @@ let {{
|
|||
if (shiftAmt) {
|
||||
//Zero out any flags we might modify. This way we only have to
|
||||
//worry about setting them.
|
||||
cfofBits = cfofBits & ~(ext & (CFBit | OFBit));
|
||||
ecfBit = ecfBit & ~(ext & ECFBit);
|
||||
PredcfofBits = PredcfofBits & ~(ext & (CFBit | OFBit));
|
||||
PredecfBit = PredecfBit & ~(ext & ECFBit);
|
||||
int CFBits = 0;
|
||||
|
||||
//If some combination of the CF bits need to be set, set them.
|
||||
|
@ -1112,21 +1131,23 @@ let {{
|
|||
|
||||
//If some combination of the CF bits need to be set, set them.
|
||||
if ((ext & (CFBit | ECFBit)) && CFBits) {
|
||||
cfofBits = cfofBits | (ext & CFBit);
|
||||
ecfBit = ecfBit | (ext & ECFBit);
|
||||
PredcfofBits = PredcfofBits | (ext & CFBit);
|
||||
PredecfBit = PredecfBit | (ext & ECFBit);
|
||||
}
|
||||
|
||||
//Figure out what the OF bit should be.
|
||||
if ((ext & OFBit) && (bits(SrcReg1, dataBits - 1) ^
|
||||
bits(result, dataBits - 1)))
|
||||
cfofBits = cfofBits | OFBit;
|
||||
PredcfofBits = PredcfofBits | OFBit;
|
||||
|
||||
//Use the regular mechanisms to calculate the other flags.
|
||||
uint64_t newFlags = genFlags(ccFlagBits | dfBit | ezfBit,
|
||||
ext & ~(CFBit | ECFBit | OFBit), DestReg, psrc1, op2);
|
||||
ezfBit = newFlags & EZFBit;
|
||||
dfBit = newFlags & DFBit;
|
||||
ccFlagBits = newFlags & ccFlagMask;
|
||||
uint64_t newFlags = genFlags(PredccFlagBits | PreddfBit |
|
||||
PredezfBit, ext & ~(CFBit | ECFBit | OFBit),
|
||||
DestReg, psrc1, op2);
|
||||
|
||||
PredezfBit = newFlags & EZFBit;
|
||||
PreddfBit = newFlags & DFBit;
|
||||
PredccFlagBits = newFlags & ccFlagMask;
|
||||
}
|
||||
'''
|
||||
|
||||
|
@ -1244,15 +1265,15 @@ let {{
|
|||
|
||||
flag_code = '''
|
||||
if (!sign_bit) {
|
||||
ccFlagBits = ccFlagBits & ~(ext & (ZFBit));
|
||||
cfofBits = cfofBits & ~(ext & (CFBit));
|
||||
ecfBit = ecfBit & ~(ext & ECFBit);
|
||||
ezfBit = ezfBit & ~(ext & EZFBit);
|
||||
PredccFlagBits = PredccFlagBits & ~(ext & (ZFBit));
|
||||
PredcfofBits = PredcfofBits & ~(ext & (CFBit));
|
||||
PredecfBit = PredecfBit & ~(ext & ECFBit);
|
||||
PredezfBit = PredezfBit & ~(ext & EZFBit);
|
||||
} else {
|
||||
ccFlagBits = ccFlagBits | (ext & (ZFBit));
|
||||
cfofBits = cfofBits | (ext & (CFBit));
|
||||
ecfBit = ecfBit | (ext & ECFBit);
|
||||
ezfBit = ezfBit | (ext & EZFBit);
|
||||
PredccFlagBits = PredccFlagBits | (ext & (ZFBit));
|
||||
PredcfofBits = PredcfofBits | (ext & (CFBit));
|
||||
PredecfBit = PredecfBit | (ext & ECFBit);
|
||||
PredezfBit = PredezfBit | (ext & EZFBit);
|
||||
}
|
||||
'''
|
||||
|
||||
|
@ -1535,12 +1556,12 @@ let {{
|
|||
'''
|
||||
flag_code = '''
|
||||
// Check for a NULL selector and set ZF,EZF appropriately.
|
||||
ccFlagBits = ccFlagBits & ~(ext & ZFBit);
|
||||
ezfBit = ezfBit & ~(ext & EZFBit);
|
||||
PredccFlagBits = PredccFlagBits & ~(ext & ZFBit);
|
||||
PredezfBit = PredezfBit & ~(ext & EZFBit);
|
||||
|
||||
if (!selector.si && !selector.ti) {
|
||||
ccFlagBits = ccFlagBits | (ext & ZFBit);
|
||||
ezfBit = ezfBit | (ext & EZFBit);
|
||||
PredccFlagBits = PredccFlagBits | (ext & ZFBit);
|
||||
PredezfBit = PredezfBit | (ext & EZFBit);
|
||||
}
|
||||
'''
|
||||
|
||||
|
|
|
@ -116,13 +116,45 @@ def operands {{
|
|||
(None, None, 'IsControl'), 50),
|
||||
'nuIP': ('PCState', 'uqw', 'nupc',
|
||||
(None, None, 'IsControl'), 50),
|
||||
# This holds the condition code portion of the flag register. The
|
||||
# nccFlagBits version holds the rest.
|
||||
# These registers hold the condition code portion of the flag
|
||||
# register. The nccFlagBits version holds the rest.
|
||||
'ccFlagBits': intReg('INTREG_PSEUDO(0)', 60),
|
||||
'cfofBits': intReg('INTREG_PSEUDO(1)', 61),
|
||||
'dfBit': intReg('INTREG_PSEUDO(2)', 62),
|
||||
'ecfBit': intReg('INTREG_PSEUDO(3)', 63),
|
||||
'ezfBit': intReg('INTREG_PSEUDO(4)', 64),
|
||||
|
||||
# These Pred registers are to be used where reading the portions of
|
||||
# condition code registers is possibly optional, depending on how the
|
||||
# check evaluates. There are two checks being specified, one tests if
|
||||
# a register needs to be read, the other tests whether the register
|
||||
# needs to be written to. It is unlikely that these would need to be
|
||||
# used in the actual operation of the instruction. It is expected
|
||||
# that these are used only in the flag code.
|
||||
|
||||
# Rationale behind the checks: at times, we need to partially update
|
||||
# the condition code bits in a register. So we read the register even
|
||||
# in the case when the all the bits will be written, or none of the
|
||||
# bits will be written. The read predicate checks if any of the bits
|
||||
# would be retained, the write predicate checks if any of the bits
|
||||
# are being written.
|
||||
|
||||
'PredccFlagBits': ('IntReg', 'uqw', 'INTREG_PSEUDO(0)', 'IsInteger',
|
||||
60, None, None, '''(((ext & (PFBit | AFBit | ZFBit | SFBit
|
||||
)) != (PFBit | AFBit | ZFBit | SFBit )) &&
|
||||
((ext & (PFBit | AFBit | ZFBit | SFBit )) != 0))''',
|
||||
'((ext & (PFBit | AFBit | ZFBit | SFBit )) != 0)'),
|
||||
'PredcfofBits': ('IntReg', 'uqw', 'INTREG_PSEUDO(1)', 'IsInteger',
|
||||
61, None, None, '''(((ext & CFBit) == 0 ||
|
||||
(ext & OFBit) == 0) && ((ext & (CFBit | OFBit)) != 0))''',
|
||||
'((ext & (CFBit | OFBit)) != 0)'),
|
||||
'PreddfBit': ('IntReg', 'uqw', 'INTREG_PSEUDO(2)', 'IsInteger',
|
||||
62, None, None, '(false)', '((ext & DFBit) != 0)'),
|
||||
'PredecfBit': ('IntReg', 'uqw', 'INTREG_PSEUDO(3)', 'IsInteger',
|
||||
63, None, None, '(false)', '((ext & ECFBit) != 0)'),
|
||||
'PredezfBit': ('IntReg', 'uqw', 'INTREG_PSEUDO(4)', 'IsInteger',
|
||||
64, None, None, '(false)', '((ext & EZFBit) != 0)'),
|
||||
|
||||
# These register should needs to be more protected so that later
|
||||
# instructions don't map their indexes with an old value.
|
||||
'nccFlagBits': controlReg('MISCREG_RFLAGS', 65),
|
||||
|
|
Loading…
Reference in a new issue