ARM: Add support for interworking branch ALU instructions.
authorGabe Black <gblack@eecs.umich.edu>
Wed, 2 Jun 2010 17:58:04 +0000 (12:58 -0500)
committerGabe Black <gblack@eecs.umich.edu>
Wed, 2 Jun 2010 17:58:04 +0000 (12:58 -0500)
src/arch/arm/isa/insts/data.isa
src/arch/arm/isa/operands.isa

index daac4ed3cc3460f3f93af402580136f6adcdec5d..a3418edf07bed3bfdb8883ce8e9381c00afe31ca 100644 (file)
@@ -98,7 +98,7 @@ let {{
     regOp2 = "shift_rm_imm(Op2, shiftAmt, shiftType, CondCodes<29:>)"
     regRegOp2 = "shift_rm_rs(Op2, Shift<7:0>, shiftType, CondCodes<29:>)"
 
-    def buildDataInst(mnem, code, flagType = "logic"):
+    def buildImmDataInst(mnem, code, flagType = "logic"):
         global header_output, decoder_output, exec_output
         cCode = carryCode[flagType]
         vCode = overflowCode[flagType]
@@ -106,85 +106,117 @@ let {{
         if flagType == "llbit":
             negBit = 63
         if flagType == "overflow":
-            immCcCode = regCcCode = regRegCcCode = calcQCode
+            immCcCode = calcQCode
         else:
             immCcCode = calcCcCode % {
                 "icValue": secondOpRe.sub(immOp2, cCode[0]),
                 "ivValue": secondOpRe.sub(immOp2, vCode),
                 "negBit": negBit
             }
+        immCode = secondOpRe.sub(immOp2, code)
+        immIop = InstObjParams(mnem, mnem.capitalize() + "Imm", "DataImmOp",
+                               {"code" : immCode,
+                                "predicate_test": predicateTest})
+        immIopCc = InstObjParams(mnem + "s", mnem.capitalize() + "ImmCc",
+                                 "DataImmOp",
+                                 {"code" : immCode + immCcCode,
+                                  "predicate_test": predicateTest})
+        header_output += DataImmDeclare.subst(immIop) + \
+                         DataImmDeclare.subst(immIopCc)
+        decoder_output += DataImmConstructor.subst(immIop) + \
+                          DataImmConstructor.subst(immIopCc)
+        exec_output += PredOpExecute.subst(immIop) + \
+                       PredOpExecute.subst(immIopCc)
+
+    def buildRegDataInst(mnem, code, flagType = "logic"):
+        global header_output, decoder_output, exec_output
+        cCode = carryCode[flagType]
+        vCode = overflowCode[flagType]
+        negBit = 31
+        if flagType == "llbit":
+            negBit = 63
+        if flagType == "overflow":
+            regCcCode = calcQCode
+        else:
             regCcCode = calcCcCode % {
                 "icValue": secondOpRe.sub(regOp2, cCode[1]),
                 "ivValue": secondOpRe.sub(regOp2, vCode),
                 "negBit": negBit
             }
+        regCode = secondOpRe.sub(regOp2, code)
+        regIop = InstObjParams(mnem, mnem.capitalize() + "Reg", "DataRegOp",
+                               {"code" : regCode,
+                                "predicate_test": predicateTest})
+        regIopCc = InstObjParams(mnem + "s", mnem.capitalize() + "RegCc",
+                                 "DataRegOp",
+                                 {"code" : regCode + regCcCode,
+                                  "predicate_test": predicateTest})
+        header_output += DataRegDeclare.subst(regIop) + \
+                         DataRegDeclare.subst(regIopCc)
+        decoder_output += DataRegConstructor.subst(regIop) + \
+                          DataRegConstructor.subst(regIopCc)
+        exec_output += PredOpExecute.subst(regIop) + \
+                       PredOpExecute.subst(regIopCc)
+
+    def buildRegRegDataInst(mnem, code, flagType = "logic"):
+        global header_output, decoder_output, exec_output
+        cCode = carryCode[flagType]
+        vCode = overflowCode[flagType]
+        negBit = 31
+        if flagType == "llbit":
+            negBit = 63
+        if flagType == "overflow":
+            regRegCcCode = calcQCode
+        else:
             regRegCcCode = calcCcCode % {
                 "icValue": secondOpRe.sub(regRegOp2, cCode[2]),
                 "ivValue": secondOpRe.sub(regRegOp2, vCode),
                 "negBit": negBit
             }
-        immCode = secondOpRe.sub(immOp2, code)
-        regCode = secondOpRe.sub(regOp2, code)
         regRegCode = secondOpRe.sub(regRegOp2, code)
-        immIop = InstObjParams(mnem, mnem.capitalize() + "Imm", "DataImmOp",
-                               {"code" : immCode,
-                                "predicate_test": predicateTest})
-        regIop = InstObjParams(mnem, mnem.capitalize() + "Reg", "DataRegOp",
-                               {"code" : regCode,
-                                "predicate_test": predicateTest})
         regRegIop = InstObjParams(mnem, mnem.capitalize() + "RegReg",
                                   "DataRegRegOp",
                                   {"code" : regRegCode,
                                    "predicate_test": predicateTest})
-        immIopCc = InstObjParams(mnem + "s", mnem.capitalize() + "ImmCc",
-                                 "DataImmOp",
-                                 {"code" : immCode + immCcCode,
-                                  "predicate_test": predicateTest})
-        regIopCc = InstObjParams(mnem + "s", mnem.capitalize() + "RegCc",
-                                 "DataRegOp",
-                                 {"code" : regCode + regCcCode,
-                                  "predicate_test": predicateTest})
         regRegIopCc = InstObjParams(mnem + "s",
                                     mnem.capitalize() + "RegRegCc",
                                     "DataRegRegOp",
                                     {"code" : regRegCode + regRegCcCode,
                                      "predicate_test": predicateTest})
-        header_output += DataImmDeclare.subst(immIop) + \
-                         DataImmDeclare.subst(immIopCc) + \
-                         DataRegDeclare.subst(regIop) + \
-                         DataRegDeclare.subst(regIopCc) + \
-                         DataRegRegDeclare.subst(regRegIop) + \
+        header_output += DataRegRegDeclare.subst(regRegIop) + \
                          DataRegRegDeclare.subst(regRegIopCc)
-        decoder_output += DataImmConstructor.subst(immIop) + \
-                          DataImmConstructor.subst(immIopCc) + \
-                          DataRegConstructor.subst(regIop) + \
-                          DataRegConstructor.subst(regIopCc) + \
-                          DataRegRegConstructor.subst(regRegIop) + \
+        decoder_output += DataRegRegConstructor.subst(regRegIop) + \
                           DataRegRegConstructor.subst(regRegIopCc)
-        exec_output += PredOpExecute.subst(immIop) + \
-                       PredOpExecute.subst(immIopCc) + \
-                       PredOpExecute.subst(regIop) + \
-                       PredOpExecute.subst(regIopCc) + \
-                       PredOpExecute.subst(regRegIop) + \
+        exec_output += PredOpExecute.subst(regRegIop) + \
                        PredOpExecute.subst(regRegIopCc)
 
-    buildDataInst("and", "Dest = resTemp = Op1 & secondOp;")
-    buildDataInst("eor", "Dest = resTemp = Op1 ^ secondOp;")
-    buildDataInst("sub", "Dest = resTemp = Op1 - secondOp;", "sub")
-    buildDataInst("rsb", "Dest = resTemp = secondOp - Op1;", "rsb")
-    buildDataInst("add", "Dest = resTemp = Op1 + secondOp;", "add")
-    buildDataInst("adc", "Dest = resTemp = Op1 + secondOp + %s;" % oldC, "add")
-    buildDataInst("sbc", "Dest = resTemp = Op1 - secondOp - !%s;" % oldC, "sub")
-    buildDataInst("rsc", "Dest = resTemp = secondOp - Op1 - !%s;" % oldC, "rsb")
+    def buildDataInst(mnem, code, flagType = "logic"):
+        buildImmDataInst(mnem, code, flagType)
+        buildRegDataInst(mnem, code, flagType)
+        buildRegRegDataInst(mnem, code, flagType)
+
+    buildDataInst("and", "AIWDest = resTemp = Op1 & secondOp;")
+    buildDataInst("eor", "AIWDest = resTemp = Op1 ^ secondOp;")
+    buildDataInst("sub", "AIWDest = resTemp = Op1 - secondOp;", "sub")
+    buildDataInst("rsb", "AIWDest = resTemp = secondOp - Op1;", "rsb")
+    buildDataInst("add", "AIWDest = resTemp = Op1 + secondOp;", "add")
+    buildDataInst("adc", "AIWDest = resTemp = Op1 + secondOp + %s;" % oldC,
+                  "add")
+    buildDataInst("sbc", "AIWDest = resTemp = Op1 - secondOp - !%s;" % oldC,
+                  "sub")
+    buildDataInst("rsc", "AIWDest = resTemp = secondOp - Op1 - !%s;" % oldC,
+                  "rsb")
     buildDataInst("tst", "resTemp = Op1 & secondOp;")
     buildDataInst("teq", "resTemp = Op1 ^ secondOp;")
     buildDataInst("cmp", "resTemp = Op1 - secondOp;", "sub")
     buildDataInst("cmn", "resTemp = Op1 + secondOp;", "add")
-    buildDataInst("orr", "Dest = resTemp = Op1 | secondOp;")
+    buildDataInst("orr", "AIWDest = resTemp = Op1 | secondOp;")
     buildDataInst("orn", "Dest = resTemp = Op1 | ~secondOp;")
-    buildDataInst("mov", "Dest = resTemp = secondOp;")
-    buildDataInst("bic", "Dest = resTemp = Op1 & ~secondOp;")
-    buildDataInst("mvn", "Dest = resTemp = ~secondOp;")
+    buildImmDataInst("mov", "AIWDest = resTemp = secondOp;")
+    buildRegDataInst("mov", "AIWDest = resTemp = secondOp;")
+    buildRegRegDataInst("mov", "Dest = resTemp = secondOp;")
+    buildDataInst("bic", "AIWDest = resTemp = Op1 & ~secondOp;")
+    buildDataInst("mvn", "AIWDest = resTemp = ~secondOp;")
     buildDataInst("movt",
             "Dest = resTemp = insertBits(Op1, 31, 16, secondOp);")
 }};
index 84bd81ca0cfa898e183e554e2c29912c7af42524..6e792f725f771f8430fdd3c5aafcf826c89ebfb1 100644 (file)
@@ -64,6 +64,17 @@ let {{
         ((%(reg_idx)s == PCReg) ? setIWNextPC(xc, %(final_val)s) :
          xc->%(func)s(this, %(op_idx)s, %(final_val)s))
     '''
+    maybeAIWPCWrite = '''
+        if (%(reg_idx)s == PCReg) {
+            if (xc->readPC() & (ULL(1) << PcTBitShift)) {
+                setIWNextPC(xc, %(final_val)s);
+            } else {
+                setNextPC(xc, %(final_val)s);
+            }
+        } else {
+            xc->%(func)s(this, %(op_idx)s, %(final_val)s);
+        }
+    '''
 
     readNPC = 'xc->readNextPC() & ~PcModeMask'
     writeNPC = 'setNextPC(xc, %(final_val)s)'
@@ -78,7 +89,7 @@ def operands {{
     'IWDest': ('IntReg', 'uw', 'dest', 'IsInteger', 0,
                maybePCRead, maybeIWPCWrite),
     'AIWDest': ('IntReg', 'uw', 'dest', 'IsInteger', 0,
-                maybePCRead, maybeIWPCWrite),
+                maybePCRead, maybeAIWPCWrite),
     'Base': ('IntReg', 'uw', 'base', 'IsInteger', 1,
              maybePCRead, maybePCWrite),
     'Index': ('IntReg', 'uw', 'index', 'IsInteger', 2,