diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/arch/x86/isa/microops/debug.isa | 3 | ||||
-rw-r--r-- | src/arch/x86/isa/microops/fpop.isa | 16 | ||||
-rw-r--r-- | src/arch/x86/isa/microops/mediaop.isa | 13 | ||||
-rw-r--r-- | src/arch/x86/isa/microops/regop.isa | 314 | ||||
-rw-r--r-- | src/arch/x86/isa/microops/seqop.isa | 6 | ||||
-rw-r--r-- | src/arch/x86/isa/microops/specop.isa | 3 | ||||
-rw-r--r-- | src/arch/x86/isa/operands.isa | 7 | ||||
-rw-r--r-- | src/arch/x86/regs/misc.hh | 3 | ||||
-rw-r--r-- | src/arch/x86/x86_traits.hh | 2 |
9 files changed, 251 insertions, 116 deletions
diff --git a/src/arch/x86/isa/microops/debug.isa b/src/arch/x86/isa/microops/debug.isa index 220c1af97..2d6af8356 100644 --- a/src/arch/x86/isa/microops/debug.isa +++ b/src/arch/x86/isa/microops/debug.isa @@ -141,7 +141,8 @@ let {{ {"code": "", "func": func, "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) header_output += MicroDebugDeclare.subst(iop) decoder_output += MicroDebugConstructor.subst(iop) diff --git a/src/arch/x86/isa/microops/fpop.isa b/src/arch/x86/isa/microops/fpop.isa index 01f26b0f5..08a74173c 100644 --- a/src/arch/x86/isa/microops/fpop.isa +++ b/src/arch/x86/isa/microops/fpop.isa @@ -215,7 +215,8 @@ let {{ spm, SetStatus, dataSize) code = 'FpDestReg_uqw = FpSrcReg1_uqw;' else_code = 'FpDestReg_uqw = FpDestReg_uqw;' - cond_check = "checkCondition(ccFlagBits, src2)" + cond_check = "checkCondition(ccFlagBits | cfofBits | ecfBit | ezfBit, \ + src2)" class Xorfp(FpOp): code = 'FpDestReg_uqw = FpSrcReg1_uqw ^ FpSrcReg2_uqw;' @@ -283,12 +284,15 @@ let {{ // Less than 0 0 1 // Equal 1 0 0 // OF = SF = AF = 0 - ccFlagBits = ccFlagBits & ~(OFBit | SFBit | AFBit | - ZFBit | PFBit | CFBit); - if (std::isnan(FpSrcReg1) || std::isnan(FpSrcReg2)) - ccFlagBits = ccFlagBits | (ZFBit | PFBit | CFBit); + ccFlagBits = ccFlagBits & ~(SFBit | AFBit | ZFBit | PFBit); + cfofBits = cfofBits & ~(OFBit | CFBit); + + if (std::isnan(FpSrcReg1) || std::isnan(FpSrcReg2)) { + ccFlagBits = ccFlagBits | (ZFBit | PFBit); + cfofBits = cfofBits | CFBit; + } else if(FpSrcReg1 < FpSrcReg2) - ccFlagBits = ccFlagBits | CFBit; + cfofBits = cfofBits | CFBit; else if(FpSrcReg1 == FpSrcReg2) ccFlagBits = ccFlagBits | ZFBit; ''' diff --git a/src/arch/x86/isa/microops/mediaop.isa b/src/arch/x86/isa/microops/mediaop.isa index 0c4827990..7178f1f52 100644 --- a/src/arch/x86/isa/microops/mediaop.isa +++ b/src/arch/x86/isa/microops/mediaop.isa @@ -1490,12 +1490,15 @@ let {{ // Less than 0 0 1 // Equal 1 0 0 // OF = SF = AF = 0 - ccFlagBits = ccFlagBits & ~(OFBit | SFBit | AFBit | - ZFBit | PFBit | CFBit); - if (std::isnan(arg1) || std::isnan(arg2)) - ccFlagBits = ccFlagBits | (ZFBit | PFBit | CFBit); + ccFlagBits = ccFlagBits & ~(SFBit | AFBit | ZFBit | PFBit); + cfofBits = cfofBits & ~(OFBit | CFBit); + + if (std::isnan(arg1) || std::isnan(arg2)) { + ccFlagBits = ccFlagBits | (ZFBit | PFBit); + cfofBits = cfofBits | CFBit; + } else if(arg1 < arg2) - ccFlagBits = ccFlagBits | CFBit; + cfofBits = cfofBits | CFBit; else if(arg1 == arg2) ccFlagBits = ccFlagBits | ZFBit; ''' diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 79ec27f07..cb1d577d7 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -438,26 +438,42 @@ let {{ flag_code = ''' //Don't have genFlags handle the OF or CF bits 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. - ccFlagBits &= ~(CFBit & ext); - ccFlagBits &= ~(ECFBit & ext); - ccFlagBits &= ~(OFBit & ext); + cfofBits = cfofBits & ~((CFBit | OFBit) & ext); + ecfBit = ecfBit & ~(ECFBit & ext); ''' class FlagRegOp(RegOp): abstract = True - flag_code = \ - "ccFlagBits = genFlags(ccFlagBits, ext, result, psrc1, op2);" + flag_code = ''' + 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): abstract = True - flag_code = \ - "ccFlagBits = genFlags(ccFlagBits, ext, result, psrc1, ~op2, true);" + flag_code = ''' + 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): abstract = True - cond_check = "checkCondition(ccFlagBits, ext)" + cond_check = "checkCondition(ccFlagBits | cfofBits | ecfBit | ezfBit, \ + ext)" cond_control_flag_init = "flags[IsCondControl] = flags[IsControl];" class RdRegOp(RegOp): @@ -484,21 +500,21 @@ let {{ class Adc(FlagRegOp): code = ''' - CCFlagBits flags = ccFlagBits; + CCFlagBits flags = cfofBits; DestReg = merge(DestReg, result = (psrc1 + op2 + flags.cf), dataSize); ''' big_code = ''' - CCFlagBits flags = ccFlagBits; + CCFlagBits flags = cfofBits; DestReg = result = (psrc1 + op2 + flags.cf) & mask(dataSize * 8); ''' class Sbb(SubRegOp): code = ''' - CCFlagBits flags = ccFlagBits; + CCFlagBits flags = cfofBits; DestReg = merge(DestReg, result = (psrc1 - op2 - flags.cf), dataSize); ''' big_code = ''' - CCFlagBits flags = ccFlagBits; + CCFlagBits flags = cfofBits; DestReg = result = (psrc1 - op2 - flags.cf) & mask(dataSize * 8); ''' @@ -536,9 +552,11 @@ let {{ flag_code = ''' if ((-ProdHi & mask(dataSize * 8)) != bits(ProdLow, dataSize * 8 - 1)) { - ccFlagBits = ccFlagBits | (ext & (CFBit | OFBit | ECFBit)); + cfofBits = cfofBits | (ext & (CFBit | OFBit)); + ecfBit = ecfBit | (ext & ECFBit); } else { - ccFlagBits = ccFlagBits & ~(ext & (CFBit | OFBit | ECFBit)); + cfofBits = cfofBits & ~(ext & (CFBit | OFBit)); + ecfBit = ecfBit & ~(ext & ECFBit); } ''' @@ -557,9 +575,11 @@ let {{ ''' flag_code = ''' if (ProdHi) { - ccFlagBits = ccFlagBits | (ext & (CFBit | OFBit | ECFBit)); + cfofBits = cfofBits | (ext & (CFBit | OFBit)); + ecfBit = ecfBit | (ext & ECFBit); } 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);" flag_code = ''' if (remaining == 0) - ccFlagBits = ccFlagBits | (ext & EZFBit); + ezfBit = ezfBit | (ext & EZFBit); else - ccFlagBits = ccFlagBits & ~(ext & EZFBit); + ezfBit = ezfBit & ~(ext & EZFBit); ''' class Divq(RdRegOp): @@ -691,22 +711,31 @@ let {{ if (shiftAmt) { //Zero out any flags we might modify. This way we only have to //worry about setting them. - ccFlagBits = ccFlagBits & ~(ext & (CFBit | ECFBit | OFBit)); + cfofBits = cfofBits & ~(ext & (CFBit | OFBit)); + ecfBit = ecfBit & ~(ext & ECFBit); + int CFBits = 0; //Figure out if we -would- set the CF bits if requested. if (shiftAmt <= dataSize * 8 && bits(SrcReg1, dataSize * 8 - shiftAmt)) { CFBits = 1; } + //If some combination of the CF bits need to be set, set them. - if ((ext & (CFBit | ECFBit)) && CFBits) - ccFlagBits = ccFlagBits | (ext & (CFBit | ECFBit)); + if ((ext & (CFBit | ECFBit)) && CFBits) { + cfofBits = cfofBits | (ext & CFBit); + ecfBit = ecfBit | (ext & ECFBit); + } + //Figure out what the OF bit should be. if ((ext & OFBit) && (CFBits ^ bits(DestReg, dataSize * 8 - 1))) - ccFlagBits = ccFlagBits | OFBit; + cfofBits = cfofBits | OFBit; + //Use the regular mechanisms to calculate the other flags. - ccFlagBits = genFlags(ccFlagBits, ext & ~(CFBit | ECFBit | OFBit), - DestReg, psrc1, op2); + uint64_t newFlags = genFlags(ccFlagBits | ezfBit, + ext & ~(CFBit | ECFBit | OFBit), DestReg, psrc1, op2); + ezfBit = newFlags & EZFBit; + ccFlagBits = newFlags & ccFlagMask; } ''' @@ -729,19 +758,26 @@ let {{ if (shiftAmt) { //Zero out any flags we might modify. This way we only have to //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 ((ext & (CFBit | ECFBit)) && shiftAmt <= dataSize * 8 && 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. if ((ext & OFBit) && bits(SrcReg1, dataSize * 8 - 1)) - ccFlagBits = ccFlagBits | OFBit; + cfofBits = cfofBits | OFBit; + //Use the regular mechanisms to calculate the other flags. - ccFlagBits = genFlags(ccFlagBits, ext & ~(CFBit | ECFBit | OFBit), - DestReg, psrc1, op2); + uint64_t newFlags = genFlags(ccFlagBits | ezfBit, + ext & ~(CFBit | ECFBit | OFBit), DestReg, psrc1, op2); + ezfBit = newFlags & EZFBit; + ccFlagBits = newFlags & ccFlagMask; } ''' @@ -766,17 +802,23 @@ let {{ if (shiftAmt) { //Zero out any flags we might modify. This way we only have to //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. uint8_t effectiveShift = (shiftAmt <= dataSize * 8) ? shiftAmt : (dataSize * 8); if ((ext & (CFBit | ECFBit)) && 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. - ccFlagBits = genFlags(ccFlagBits, ext & ~(CFBit | ECFBit | OFBit), - DestReg, psrc1, op2); + uint64_t newFlags = genFlags(ccFlagBits | ezfBit, + ext & ~(CFBit | ECFBit | OFBit), DestReg, psrc1, op2); + ezfBit = newFlags & EZFBit; + ccFlagBits = newFlags & ccFlagMask; } ''' @@ -797,19 +839,27 @@ let {{ if (shiftAmt) { //Zero out any flags we might modify. This way we only have to //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. 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) - ccFlagBits = ccFlagBits | (ext & (CFBit | ECFBit)); + if ((ext & (CFBit | ECFBit)) && msb) { + cfofBits = cfofBits | (ext & CFBit); + ecfBit = ecfBit | (ext & ECFBit); + } + //Figure out what the OF bit should be. if ((ext & OFBit) && (msb ^ smsb)) - ccFlagBits = ccFlagBits | OFBit; + cfofBits = cfofBits | OFBit; + //Use the regular mechanisms to calculate the other flags. - ccFlagBits = genFlags(ccFlagBits, ext & ~(CFBit | ECFBit | OFBit), - DestReg, psrc1, op2); + uint64_t newFlags = genFlags(ccFlagBits | ezfBit, + 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))); uint8_t realShiftAmt = shiftAmt % (dataSize * 8 + 1); if (realShiftAmt) { - CCFlagBits flags = ccFlagBits; + CCFlagBits flags = cfofBits; uint64_t top = flags.cf << (dataSize * 8 - realShiftAmt); if (realShiftAmt > 1) top |= psrc1 << (dataSize * 8 - realShiftAmt + 1); @@ -831,24 +881,30 @@ let {{ flag_code = ''' // If the shift amount is zero, no flags should be modified. 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 //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. if ((ext & OFBit) && (origCFBit ^ 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 ((ext & (CFBit | ECFBit)) && (realShiftAmt == 0) ? origCFBit : 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. - ccFlagBits = genFlags(ccFlagBits, ext & ~(CFBit | ECFBit | OFBit), - DestReg, psrc1, op2); + uint64_t newFlags = genFlags(ccFlagBits | ezfBit, + ext & ~(CFBit | ECFBit | OFBit), DestReg, psrc1, op2); + ezfBit = newFlags & EZFBit; + ccFlagBits = newFlags & ccFlagMask; } ''' @@ -870,19 +926,27 @@ let {{ if (shiftAmt) { //Zero out any flags we might modify. This way we only have to //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. 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) - ccFlagBits = ccFlagBits | (ext & (CFBit | ECFBit)); + if ((ext & (CFBit | ECFBit)) && lsb) { + cfofBits = cfofBits | (ext & CFBit); + ecfBit = ecfBit | (ext & ECFBit); + } + //Figure out what the OF bit should be. if ((ext & OFBit) && (msb ^ lsb)) - ccFlagBits = ccFlagBits | OFBit; + cfofBits = cfofBits | OFBit; + //Use the regular mechanisms to calculate the other flags. - ccFlagBits = genFlags(ccFlagBits, ext & ~(CFBit | ECFBit | OFBit), - DestReg, psrc1, op2); + uint64_t newFlags = genFlags(ccFlagBits | ezfBit, + 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))); uint8_t realShiftAmt = shiftAmt % (dataSize * 8 + 1); if (realShiftAmt) { - CCFlagBits flags = ccFlagBits; + CCFlagBits flags = cfofBits; uint64_t top = psrc1 << realShiftAmt; uint64_t bottom = flags.cf << (realShiftAmt - 1); if(shiftAmt > 1) @@ -906,22 +970,30 @@ let {{ flag_code = ''' // If the shift amount is zero, no flags should be modified. 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 //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 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) - ccFlagBits = ccFlagBits | (ext & (CFBit | ECFBit)); + (realShiftAmt == 0) ? origCFBit : CFBits) { + cfofBits = cfofBits | (ext & CFBit); + ecfBit = ecfBit | (ext & ECFBit); + } + //Figure out what the OF bit should be. if ((ext & OFBit) && (msb ^ CFBits)) - ccFlagBits = ccFlagBits | OFBit; + cfofBits = cfofBits | OFBit; + //Use the regular mechanisms to calculate the other flags. - ccFlagBits = genFlags(ccFlagBits, ext & ~(CFBit | ECFBit | OFBit), - DestReg, psrc1, op2); + uint64_t newFlags = genFlags(ccFlagBits | ezfBit, + ext & ~(CFBit | ECFBit | OFBit), DestReg, psrc1, op2); + ezfBit = newFlags & EZFBit; + ccFlagBits = newFlags & ccFlagMask; } ''' @@ -949,8 +1021,10 @@ let {{ if (shiftAmt) { //Zero out any flags we might modify. This way we only have to //worry about setting them. - ccFlagBits = ccFlagBits & ~(ext & (CFBit | ECFBit | OFBit)); + cfofBits = cfofBits & ~(ext & (CFBit | OFBit)); + ecfBit = ecfBit & ~(ext & ECFBit); int CFBits = 0; + //Figure out if we -would- set the CF bits if requested. if ((realShiftAmt == 0 && bits(DoubleBits, 0)) || @@ -960,16 +1034,23 @@ let {{ bits(DoubleBits, 2 * dataBits - realShiftAmt))) { CFBits = 1; } + //If some combination of the CF bits need to be set, set them. - if ((ext & (CFBit | ECFBit)) && CFBits) - ccFlagBits = ccFlagBits | (ext & (CFBit | ECFBit)); + if ((ext & (CFBit | ECFBit)) && CFBits) { + cfofBits = cfofBits | (ext & CFBit); + ecfBit = ecfBit | (ext & ECFBit); + } + //Figure out what the OF bit should be. if ((ext & OFBit) && (bits(SrcReg1, dataBits - 1) ^ bits(result, dataBits - 1))) - ccFlagBits = ccFlagBits | OFBit; + cfofBits = cfofBits | OFBit; + //Use the regular mechanisms to calculate the other flags. - ccFlagBits = genFlags(ccFlagBits, ext & ~(CFBit | ECFBit | OFBit), - DestReg, psrc1, op2); + uint64_t newFlags = genFlags(ccFlagBits | ezfBit, + ext & ~(CFBit | ECFBit | OFBit), DestReg, psrc1, op2); + ezfBit = newFlags & EZFBit; + ccFlagBits = newFlags & ccFlagMask; } ''' @@ -1003,8 +1084,10 @@ let {{ if (shiftAmt) { //Zero out any flags we might modify. This way we only have to //worry about setting them. - ccFlagBits = ccFlagBits & ~(ext & (CFBit | ECFBit | OFBit)); + cfofBits = cfofBits & ~(ext & (CFBit | OFBit)); + ecfBit = ecfBit & ~(ext & ECFBit); int CFBits = 0; + //If some combination of the CF bits need to be set, set them. if ((realShiftAmt == 0 && bits(DoubleBits, dataBits - 1)) || @@ -1014,16 +1097,23 @@ let {{ bits(DoubleBits, realShiftAmt - dataBits - 1))) { CFBits = 1; } + //If some combination of the CF bits need to be set, set them. - if ((ext & (CFBit | ECFBit)) && CFBits) - ccFlagBits = ccFlagBits | (ext & (CFBit | ECFBit)); + if ((ext & (CFBit | ECFBit)) && CFBits) { + cfofBits = cfofBits | (ext & CFBit); + ecfBit = ecfBit | (ext & ECFBit); + } + //Figure out what the OF bit should be. if ((ext & OFBit) && (bits(SrcReg1, dataBits - 1) ^ bits(result, dataBits - 1))) - ccFlagBits = ccFlagBits | OFBit; + cfofBits = cfofBits | OFBit; + //Use the regular mechanisms to calculate the other flags. - ccFlagBits = genFlags(ccFlagBits, ext & ~(CFBit | ECFBit | OFBit), - DestReg, psrc1, op2); + uint64_t newFlags = genFlags(ccFlagBits | ezfBit, + ext & ~(CFBit | ECFBit | OFBit), DestReg, psrc1, op2); + ezfBit = newFlags & EZFBit; + ccFlagBits = newFlags & ccFlagMask; } ''' @@ -1035,14 +1125,25 @@ let {{ else_code = "NRIP = NRIP;" 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): code = ''' MiscReg newFlags = psrc1 ^ op2; MiscReg userFlagMask = 0xDD5; + // Get only the user flags - ccFlagBits = newFlags & userFlagMask; + ccFlagBits = newFlags & ccFlagMask; + cfofBits = newFlags & cfofMask; + ecfBit = 0; + ezfBit = 0; + // Get everything else nccFlagBits = newFlags & ~userFlagMask; ''' @@ -1051,24 +1152,26 @@ let {{ code = 'DestReg = NRIP - CSBase;' class Ruflags(RdRegOp): - code = 'DestReg = ccFlagBits' + code = 'DestReg = ccFlagBits | cfofBits | ecfBit | ezfBit;' class Rflags(RdRegOp): - code = 'DestReg = ccFlagBits | nccFlagBits' + code = ''' + DestReg = ccFlagBits | cfofBits | ecfBit | ezfBit | nccFlagBits; + ''' class Ruflag(RegOp): code = ''' - int flag = bits(ccFlagBits, imm8); + int flag = bits(ccFlagBits | cfofBits | ecfBit | ezfBit, imm8); DestReg = merge(DestReg, flag, dataSize); - ccFlagBits = (flag == 0) ? (ccFlagBits | EZFBit) : - (ccFlagBits & ~EZFBit); + ezfBit = (flag == 0) ? EZFBit : 0; ''' + big_code = ''' - int flag = bits(ccFlagBits, imm8); + int flag = bits(ccFlagBits | cfofBits | ecfBit | ezfBit, imm8); DestReg = flag & mask(dataSize * 8); - ccFlagBits = (flag == 0) ? (ccFlagBits | EZFBit) : - (ccFlagBits & ~EZFBit); + ezfBit = (flag == 0) ? EZFBit : 0; ''' + def __init__(self, dest, imm, flags=None, \ dataSize="env.dataSize"): super(Ruflag, self).__init__(dest, \ @@ -1077,20 +1180,24 @@ let {{ class Rflag(RegOp): code = ''' MiscReg flagMask = 0x3F7FDD5; - MiscReg flags = (nccFlagBits | ccFlagBits) & flagMask; + MiscReg flags = (nccFlagBits | ccFlagBits | cfofBits | + ecfBit | ezfBit) & flagMask; + int flag = bits(flags, imm8); DestReg = merge(DestReg, flag, dataSize); - ccFlagBits = (flag == 0) ? (ccFlagBits | EZFBit) : - (ccFlagBits & ~EZFBit); + ezfBit = (flag == 0) ? EZFBit : 0; ''' + big_code = ''' MiscReg flagMask = 0x3F7FDD5; - MiscReg flags = (nccFlagBits | ccFlagBits) & flagMask; + MiscReg flags = (nccFlagBits | ccFlagBits | cfofBits | + ecfBit | ezfBit) & flagMask; + int flag = bits(flags, imm8); DestReg = flag & mask(dataSize * 8); - ccFlagBits = (flag == 0) ? (ccFlagBits | EZFBit) : - (ccFlagBits & ~EZFBit); + ezfBit = (flag == 0) ? EZFBit : 0; ''' + def __init__(self, dest, imm, flags=None, \ dataSize="env.dataSize"): super(Rflag, self).__init__(dest, \ @@ -1106,6 +1213,7 @@ let {{ val = sign_bit ? (val | ~maskVal) : (val & maskVal); DestReg = merge(DestReg, val, dataSize); ''' + big_code = ''' IntReg val = psrc1; // Mask the bit position so that it wraps. @@ -1115,13 +1223,19 @@ let {{ val = sign_bit ? (val | ~maskVal) : (val & maskVal); DestReg = val & mask(dataSize * 8); ''' + flag_code = ''' - if (!sign_bit) - ccFlagBits = ccFlagBits & - ~(ext & (CFBit | ECFBit | ZFBit | EZFBit)); - else - ccFlagBits = ccFlagBits | - (ext & (CFBit | ECFBit | ZFBit | EZFBit)); + if (!sign_bit) { + ccFlagBits = ccFlagBits & ~(ext & (ZFBit)); + cfofBits = cfofBits & ~(ext & (CFBit)); + ecfBit = ecfBit & ~(ext & ECFBit); + ezfBit = ezfBit & ~(ext & EZFBit); + } else { + ccFlagBits = ccFlagBits | (ext & (ZFBit)); + cfofBits = cfofBits | (ext & (CFBit)); + ecfBit = ecfBit | (ext & ECFBit); + ezfBit = ezfBit | (ext & EZFBit); + } ''' class Zext(RegOp): @@ -1403,9 +1517,13 @@ let {{ ''' flag_code = ''' // Check for a NULL selector and set ZF,EZF appropriately. - ccFlagBits = ccFlagBits & ~(ext & (ZFBit | EZFBit)); - if (!selector.si && !selector.ti) - ccFlagBits = ccFlagBits | (ext & (ZFBit | EZFBit)); + ccFlagBits = ccFlagBits & ~(ext & ZFBit); + ezfBit = ezfBit & ~(ext & EZFBit); + + if (!selector.si && !selector.ti) { + ccFlagBits = ccFlagBits | (ext & ZFBit); + ezfBit = ezfBit | (ext & EZFBit); + } ''' class Wrdh(RegOp): diff --git a/src/arch/x86/isa/microops/seqop.isa b/src/arch/x86/isa/microops/seqop.isa index 51d9776da..e3b251162 100644 --- a/src/arch/x86/isa/microops/seqop.isa +++ b/src/arch/x86/isa/microops/seqop.isa @@ -172,7 +172,8 @@ let {{ iop = InstObjParams("br", "MicroBranchFlags", "SeqOpBase", {"code": "nuIP = target;", "else_code": "nuIP = nuIP;", - "cond_test": "checkCondition(ccFlagBits, cc)", + "cond_test": "checkCondition(ccFlagBits | cfofBits | \ + ecfBit | ezfBit, cc)", "cond_control_flag_init": "flags[IsCondControl] = true"}) exec_output += SeqOpExecute.subst(iop) header_output += SeqOpDeclare.subst(iop) @@ -189,7 +190,8 @@ let {{ iop = InstObjParams("eret", "EretFlags", "SeqOpBase", {"code": "", "else_code": "", - "cond_test": "checkCondition(ccFlagBits, cc)", + "cond_test": "checkCondition(ccFlagBits | cfofBits | \ + ecfBit | ezfBit, cc)", "cond_control_flag_init": ""}) exec_output += SeqOpExecute.subst(iop) header_output += SeqOpDeclare.subst(iop) diff --git a/src/arch/x86/isa/microops/specop.isa b/src/arch/x86/isa/microops/specop.isa index 5c242e2c9..8092b28b9 100644 --- a/src/arch/x86/isa/microops/specop.isa +++ b/src/arch/x86/isa/microops/specop.isa @@ -181,7 +181,8 @@ let {{ iop = InstObjParams("fault", "MicroFaultFlags", "MicroFaultBase", {"code": "", - "cond_test": "checkCondition(ccFlagBits, cc)"}) + "cond_test": "checkCondition(ccFlagBits | cfofBits | \ + ecfBit | ezfBit, cc)"}) exec_output = MicroFaultExecute.subst(iop) header_output = MicroFaultDeclare.subst(iop) decoder_output = MicroFaultConstructor.subst(iop) diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa index e0ace11d0..8e2ae7fd4 100644 --- a/src/arch/x86/isa/operands.isa +++ b/src/arch/x86/isa/operands.isa @@ -119,10 +119,13 @@ def operands {{ # This holds 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), + 'ecfBit': intReg('INTREG_PSEUDO(2)', 62), + 'ezfBit': intReg('INTREG_PSEUDO(3)', 63), # 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', 61), - 'TOP': controlReg('MISCREG_X87_TOP', 62, ctype='ub'), + 'nccFlagBits': controlReg('MISCREG_RFLAGS', 64), + 'TOP': controlReg('MISCREG_X87_TOP', 65, ctype='ub'), # The segment base as used by memory instructions. 'SegBase': controlReg('MISCREG_SEG_EFF_BASE(segment)', 70), diff --git a/src/arch/x86/regs/misc.hh b/src/arch/x86/regs/misc.hh index 24420e8d5..bb69d8007 100644 --- a/src/arch/x86/regs/misc.hh +++ b/src/arch/x86/regs/misc.hh @@ -64,6 +64,9 @@ namespace X86ISA OFBit = 1 << 11 }; + const uint32_t cfofMask = CFBit | OFBit; + const uint32_t ccFlagMask = PFBit | AFBit | ZFBit | SFBit | DFBit; + enum RFLAGBit { TFBit = 1 << 8, IFBit = 1 << 9, diff --git a/src/arch/x86/x86_traits.hh b/src/arch/x86/x86_traits.hh index 004e3aeb9..6157cb30b 100644 --- a/src/arch/x86/x86_traits.hh +++ b/src/arch/x86/x86_traits.hh @@ -46,7 +46,7 @@ namespace X86ISA { const int NumMicroIntRegs = 16; - const int NumPseudoIntRegs = 1; + const int NumPseudoIntRegs = 4; //1. The condition code bits of the rflags register. const int NumImplicitIntRegs = 6; //1. The lower part of the result of multiplication. |