X86: make use of register predication
authorNilay Vaish <nilay@cs.wisc.edu>
Tue, 11 Sep 2012 14:33:42 +0000 (09:33 -0500)
committerNilay Vaish <nilay@cs.wisc.edu>
Tue, 11 Sep 2012 14:33:42 +0000 (09:33 -0500)
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.

src/arch/x86/isa/microops/regop.isa
src/arch/x86/isa/operands.isa

index a96a552a36d9d2f0f050ce31f09cdb45b99586ad..d14ec8aadc9519998d5d710b052b0d85f1f7c94f 100644 (file)
@@ -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);
             }
         '''
 
index e0cd2d628c160ae1d1fbfee38f31b859b38180bb..05b127e374e074cc190a6e2d7e4656cba03ac105 100644 (file)
@@ -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),