ARM: Construct the predicate test register for more instruction programatically.

If one of the condition codes isn't being used in the execution we should only
read it if the instruction might be dependent on it. With the preeceding changes
there are several more cases where we should dynamically pick instead of assuming
as we did before.
diff --git a/src/arch/arm/isa/insts/data.isa b/src/arch/arm/isa/insts/data.isa
index 94693c8..4172291 100644
--- a/src/arch/arm/isa/insts/data.isa
+++ b/src/arch/arm/isa/insts/data.isa
@@ -103,8 +103,8 @@
 
     secondOpRe = re.compile("secondOp")
     immOp2 = "imm"
-    regOp2 = "shift_rm_imm(Op2, shiftAmt, shiftType, CondCodesC)"
-    regRegOp2 = "shift_rm_rs(Op2, Shift<7:0>, shiftType, CondCodesC)"
+    regOp2 = "shift_rm_imm(Op2, shiftAmt, shiftType, OptShiftRmCondCodesC)"
+    regRegOp2 = "shift_rm_rs(Op2, Shift<7:0>, shiftType, 0)"
 
     def buildImmDataInst(mnem, code, flagType = "logic", suffix = "Imm", \
                          buildCc = True, buildNonCc = True, instFlags = []):
@@ -125,12 +125,12 @@
             }
         immCode = secondOpRe.sub(immOp2, code)
         immIop = InstObjParams(mnem, mnem.capitalize() + suffix, "DataImmOp",
-                               {"code" : immCode,
-                                "predicate_test": predicateTest}, instFlags)
+                       {"code" : immCode,
+                        "predicate_test": pickPredicate(immCode)}, instFlags)
         immIopCc = InstObjParams(mnem + "s", mnem.capitalize() + suffix + "Cc",
-                                 "DataImmOp",
-                                 {"code" : immCode + immCcCode,
-                                  "predicate_test": condPredicateTest}, instFlags)
+             "DataImmOp",
+             {"code" : immCode + immCcCode,
+              "predicate_test": pickPredicate(immCode + immCcCode)}, instFlags)
 
         def subst(iop):
             global header_output, decoder_output, exec_output
@@ -163,15 +163,15 @@
             }
         regCode = secondOpRe.sub(regOp2, code)
         regIop = InstObjParams(mnem, mnem.capitalize() + suffix, "DataRegOp",
-                               {"code" : regCode, "is_ras_pop" : isRasPop,
-                                "is_branch" : isBranch,
-                                "predicate_test": predicateTest}, instFlags)
+                       {"code" : regCode, "is_ras_pop" : isRasPop,
+                        "is_branch" : isBranch,
+                        "predicate_test": pickPredicate(regCode)}, instFlags)
         regIopCc = InstObjParams(mnem + "s", mnem.capitalize() + suffix + "Cc",
-                                 "DataRegOp",
-                                 {"code" : regCode + regCcCode,
-                                  "predicate_test": condPredicateTest,
-                                  "is_ras_pop" : isRasPop,
-                                  "is_branch" : isBranch}, instFlags)
+                         "DataRegOp",
+                         {"code" : regCode + regCcCode,
+                          "predicate_test": pickPredicate(regCode + regCcCode),
+                          "is_ras_pop" : isRasPop,
+                          "is_branch" : isBranch}, instFlags)
 
         def subst(iop):
             global header_output, decoder_output, exec_output
@@ -204,14 +204,14 @@
             }
         regRegCode = secondOpRe.sub(regRegOp2, code)
         regRegIop = InstObjParams(mnem, mnem.capitalize() + suffix,
-                                  "DataRegRegOp",
-                                  {"code" : regRegCode,
-                                   "predicate_test": predicateTest})
+                          "DataRegRegOp",
+                          {"code" : regRegCode,
+                           "predicate_test": pickPredicate(regRegCode)})
         regRegIopCc = InstObjParams(mnem + "s",
-                                    mnem.capitalize() + suffix + "Cc",
-                                    "DataRegRegOp",
-                                    {"code" : regRegCode + regRegCcCode,
-                                     "predicate_test": condPredicateTest})
+                mnem.capitalize() + suffix + "Cc",
+                "DataRegRegOp",
+                {"code" : regRegCode + regRegCcCode,
+                 "predicate_test": pickPredicate(regRegCode + regRegCcCode)})
 
         def subst(iop):
             global header_output, decoder_output, exec_output
@@ -241,10 +241,6 @@
             code += '''
             SCTLR sctlr = Sctlr;
             CPSR old_cpsr = Cpsr;
-            old_cpsr.nz = CondCodesNZ;
-            old_cpsr.c = CondCodesC;
-            old_cpsr.v = CondCodesV;
-            old_cpsr.ge = CondCodesGE;
 
             CPSR new_cpsr =
                 cpsrWriteByInstr(old_cpsr, Spsr, 0xF, true, sctlr.nmfi);
diff --git a/src/arch/arm/isa/insts/ldr.isa b/src/arch/arm/isa/insts/ldr.isa
index a346c49..4c8bfd6 100644
--- a/src/arch/arm/isa/insts/ldr.isa
+++ b/src/arch/arm/isa/insts/ldr.isa
@@ -141,7 +141,7 @@
         def __init__(self, *args, **kargs):
             super(LoadRegInst, self).__init__(*args, **kargs)
             self.offset = self.op + " shift_rm_imm(Index, shiftAmt," + \
-                                    " shiftType, CondCodesC)"
+                                    " shiftType, OptShiftRmCondCodesC)"
             if self.add:
                  self.wbDecl = '''
                      MicroAddUop(machInst, base, base, wbIndexReg, shiftAmt, shiftType);
diff --git a/src/arch/arm/isa/insts/macromem.isa b/src/arch/arm/isa/insts/macromem.isa
index 31545d3..d580057 100644
--- a/src/arch/arm/isa/insts/macromem.isa
+++ b/src/arch/arm/isa/insts/macromem.isa
@@ -89,10 +89,6 @@
     microRetUopCode = '''
         CPSR old_cpsr = Cpsr;
         SCTLR sctlr = Sctlr;
-        old_cpsr.nz = CondCodesNZ;
-        old_cpsr.c = CondCodesC;
-        old_cpsr.v = CondCodesV;
-        old_cpsr.ge = CondCodesGE;
 
         CPSR new_cpsr =
             cpsrWriteByInstr(old_cpsr, Spsr, 0xF, true, sctlr.nmfi);
@@ -588,14 +584,14 @@
                                      'predicate_test': predicateTest},
                                     ['IsMicroop'])
 
+    microAddUopCode = '''
+        URa = URb + shift_rm_imm(URc, shiftAmt, shiftType, OptShiftRmCondCodesC);
+    '''
+
     microAddUopIop = InstObjParams('add_uop', 'MicroAddUop',
                                    'MicroIntRegOp',
-                                   {'code':
-                                    '''URa = URb + shift_rm_imm(URc, shiftAmt,
-                                                              shiftType,
-                                                              CondCodesC);
-                                    ''',
-                                    'predicate_test': predicateTest},
+                                   {'code': microAddUopCode,
+                                    'predicate_test': pickPredicate(microAddUopCode)},
                                    ['IsMicroop'])
 
     microSubiUopIop = InstObjParams('subi_uop', 'MicroSubiUop',
@@ -604,14 +600,13 @@
                                      'predicate_test': predicateTest},
                                     ['IsMicroop'])
 
+    microSubUopCode = '''
+        URa = URb - shift_rm_imm(URc, shiftAmt, shiftType, OptShiftRmCondCodesC);
+    '''
     microSubUopIop = InstObjParams('sub_uop', 'MicroSubUop',
                                    'MicroIntRegOp',
-                                   {'code':
-                                    '''URa = URb - shift_rm_imm(URc, shiftAmt,
-                                                              shiftType,
-                                                              CondCodesC);
-                                    ''',
-                                    'predicate_test': predicateTest},
+                                   {'code': microSubUopCode,
+                                    'predicate_test': pickPredicate(microSubUopCode)},
                                    ['IsMicroop'])
 
     microUopRegMovIop = InstObjParams('uopReg_uop', 'MicroUopRegMov',
diff --git a/src/arch/arm/isa/insts/mem.isa b/src/arch/arm/isa/insts/mem.isa
index cad0b15..fb09eac 100644
--- a/src/arch/arm/isa/insts/mem.isa
+++ b/src/arch/arm/isa/insts/mem.isa
@@ -120,14 +120,21 @@
 
     def pickPredicate(blobs):
         opt_nz = True
-        opt_c = True
+        opt_c = 'opt'
         opt_v = True
-        for val in blobs.values():
-            if re.search('(?<!Opt)CondCodesNZ', val):
+
+        if not isinstance(blobs, dict):
+            vals = [blobs]
+        else:
+            vals = blobs.values()
+        for val in vals:
+            if re.search('(?<!Opt)CondCodesNZ(?!.*=)', val):
                 opt_nz = False
-            if re.search('(?<!Opt)CondCodesC', val):
-                opt_c = False
-            if re.search('(?<!Opt)CondCodesV', val):
+            if re.search('OptShiftRmCondCodesC(?!.*=)', val):
+                opt_c = 'opt_shift_rm'
+            elif re.search('(?<!Opt)CondCodesC(?!.*=)', val):
+                opt_c = 'none'
+            if re.search('(?<!Opt)CondCodesV(?!.*=)', val):
                 opt_v = False
 
         # Build up the predicate piece by piece depending on which
@@ -137,8 +144,10 @@
             predicate += 'OptCondCodesNZ, '
         else:
             predicate += 'CondCodesNZ, '
-        if opt_c:
+        if opt_c == 'opt':
             predicate += 'OptCondCodesC, '
+        elif opt_c == 'opt_shift_rm':
+            predicate += 'OptShiftRmCondCodesC, '
         else:
             predicate += 'CondCodesC, '
         if opt_v:
@@ -146,7 +155,7 @@
         else:
             predicate += 'CondCodesV, '
         predicate += 'condCode)'
-
+        predicate += '/*auto*/'
         return predicate
 
     def memClassName(base, post, add, writeback, \
diff --git a/src/arch/arm/isa/insts/misc.isa b/src/arch/arm/isa/insts/misc.isa
index c270db4..4a4f1e3 100644
--- a/src/arch/arm/isa/insts/misc.isa
+++ b/src/arch/arm/isa/insts/misc.isa
@@ -226,7 +226,7 @@
     '''
     ssatIop = InstObjParams("ssat", "Ssat", "RegImmRegShiftOp",
                             { "code": ssatCode,
-                              "predicate_test": condPredicateTest }, [])
+                              "predicate_test": pickPredicate(ssatCode) }, [])
     header_output += RegImmRegShiftOpDeclare.subst(ssatIop)
     decoder_output += RegImmRegShiftOpConstructor.subst(ssatIop)
     exec_output += PredOpExecute.subst(ssatIop)
@@ -240,7 +240,7 @@
     '''
     usatIop = InstObjParams("usat", "Usat", "RegImmRegShiftOp",
                             { "code": usatCode,
-                              "predicate_test": condPredicateTest }, [])
+                              "predicate_test": pickPredicate(usatCode) }, [])
     header_output += RegImmRegShiftOpDeclare.subst(usatIop)
     decoder_output += RegImmRegShiftOpConstructor.subst(usatIop)
     exec_output += PredOpExecute.subst(usatIop)
@@ -260,7 +260,7 @@
     '''
     ssat16Iop = InstObjParams("ssat16", "Ssat16", "RegImmRegOp",
                               { "code": ssat16Code,
-                                "predicate_test": condPredicateTest }, [])
+                                "predicate_test": pickPredicate(ssat16Code) }, [])
     header_output += RegImmRegOpDeclare.subst(ssat16Iop)
     decoder_output += RegImmRegOpConstructor.subst(ssat16Iop)
     exec_output += PredOpExecute.subst(ssat16Iop)
@@ -280,7 +280,7 @@
     '''
     usat16Iop = InstObjParams("usat16", "Usat16", "RegImmRegOp",
                               { "code": usat16Code,
-                                "predicate_test": condPredicateTest }, [])
+                                "predicate_test": pickPredicate(usat16Code) }, [])
     header_output += RegImmRegOpDeclare.subst(usat16Iop)
     decoder_output += RegImmRegOpConstructor.subst(usat16Iop)
     exec_output += PredOpExecute.subst(usat16Iop)
diff --git a/src/arch/arm/isa/insts/mult.isa b/src/arch/arm/isa/insts/mult.isa
index f4f8b86..fe43909 100644
--- a/src/arch/arm/isa/insts/mult.isa
+++ b/src/arch/arm/isa/insts/mult.isa
@@ -87,14 +87,14 @@
 
         if unCc:
             iop = InstObjParams(mnem, Name, base,
-                                {"code" : code,
-                                 "predicate_test": predicateTest,
-                                 "op_class": "IntMultOp" })
+                            {"code" : code,
+                             "predicate_test": pickPredicate(code),
+                             "op_class": "IntMultOp" })
         if doCc:
             iopCc = InstObjParams(mnem + "s", Name + "Cc", base,
-                                  {"code" : code + ccCode,
-                                   "predicate_test": condPredicateTest,
-                                   "op_class": "IntMultOp" })
+                              {"code" : code + ccCode,
+                               "predicate_test": pickPredicate(code + ccCode),
+                               "op_class": "IntMultOp" })
 
         if regs == 3:
             declare = Mult3Declare
diff --git a/src/arch/arm/isa/insts/str.isa b/src/arch/arm/isa/insts/str.isa
index 95ba4ad..c01478c 100644
--- a/src/arch/arm/isa/insts/str.isa
+++ b/src/arch/arm/isa/insts/str.isa
@@ -152,7 +152,7 @@
         def __init__(self, *args, **kargs):
             super(StoreRegInst, self).__init__(*args, **kargs)
             self.offset = self.op + " shift_rm_imm(Index, shiftAmt," + \
-                                    " shiftType, CondCodesC)"
+                                    " shiftType, OptShiftRmCondCodesC)"
             if self.add:
                  self.wbDecl = '''
                      MicroAddUop(machInst, base, base, index, shiftAmt, shiftType);