X86: Split Condition Code register
authorNilay Vaish <nilay@cs.wisc.edu>
Tue, 22 May 2012 16:29:53 +0000 (11:29 -0500)
committerNilay Vaish <nilay@cs.wisc.edu>
Tue, 22 May 2012 16:29:53 +0000 (11:29 -0500)
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.

src/arch/x86/isa/microops/debug.isa
src/arch/x86/isa/microops/fpop.isa
src/arch/x86/isa/microops/mediaop.isa
src/arch/x86/isa/microops/regop.isa
src/arch/x86/isa/microops/seqop.isa
src/arch/x86/isa/microops/specop.isa
src/arch/x86/isa/operands.isa
src/arch/x86/regs/misc.hh
src/arch/x86/x86_traits.hh

index 220c1af972336ce4eb1611b4294eeaf544a326f7..2d6af83567a2c465fc6b2ba39f53ce04710d664e 100644 (file)
@@ -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)
index 01f26b0f51e3157d9c047a1f7aeb6736bb50614d..08a74173cc735cf9544e8c1ec27c93feff6f4460 100644 (file)
@@ -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;
         '''
index 0c48279902944f14bcb0dac99973100341c8eae0..7178f1f52528e3c9ae0277feff6c37f5fb06e527 100644 (file)
@@ -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;
         '''
index 79ec27f07833b900e1eabd487917f45e1a1a9cf3..cb1d577d7b963b856c0bb143be4c0fec5b49068a 100644 (file)
@@ -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):
index 51d9776da526859171614f744aaf797f1fe8377c..e3b2511624ed735744a6eec3d6bc442b99c22811 100644 (file)
@@ -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)
index 5c242e2c962e4f4a402959732255fa1302ec2840..8092b28b9aa7cc9ddb6fe21e7bcca255be50c73d 100644 (file)
@@ -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)
index e0ace11d042ef357f4b506ac49a79278d47669d7..8e2ae7fd440f0c2b3d3c7529c72ba6c2d1f710a0 100644 (file)
@@ -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),
 
index 24420e8d5f41474b8d39f2cbc1481f22beff88d9..bb69d8007a1941f829c40860ad8cc38dd3405a20 100644 (file)
@@ -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,
index 004e3aeb94689ca8052c94590581fc1d4309a7d9..6157cb30ba2bce00a6cedb662b317208c769103c 100644 (file)
@@ -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.