ARM: Implement ADR as separate from ADD.
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/formats/data.isa
src/arch/arm/isa/insts/data.isa

index 3643fa88fb95844177400673001c30635c1bf126..45dedff2cd0df3b21488844a94172844f9416196 100644 (file)
@@ -103,7 +103,6 @@ def format ArmDataProcReg() {{
 
 def format ArmDataProcImm() {{
     instDecode = '''
-          case %(opcode)#x:
             if (setCc) {
                 return new %(className)sImmCc(machInst, %(dest)s, %(op1)s,
                                                imm, rotC);
@@ -116,10 +115,30 @@ def format ArmDataProcImm() {{
 
     def instCode(opcode, mnem, dest="rd", op1="rn"):
         global instDecode
-        return instDecode % { "className": mnem.capitalize(),
-                              "opcode": opcode,
-                              "dest": dest,
-                              "op1": op1 }
+        code = '''
+          case %(opcode)#x:
+        ''' + instDecode
+        return code % { "className": mnem.capitalize(),
+                        "opcode": opcode,
+                        "dest": dest,
+                        "op1": op1 }
+
+    def adrCode(opcode, mnem, dest="rd", op1="rn", add="1"):
+        global instDecode
+        code = '''
+          case %(opcode)#x:
+            if (rn == 0xf) {
+                return new AdrImm(machInst, %(dest)s, %(add)s,
+                                             imm, false);
+            } else {
+        ''' + instDecode + '''
+            }
+        '''
+        return code % { "className": mnem.capitalize(),
+                        "opcode": opcode,
+                        "dest": dest,
+                        "add": add,
+                        "op1": op1 }
 
     decode_block = '''
     {
@@ -134,9 +153,9 @@ def format ArmDataProcImm() {{
     '''
     decode_block += instCode(0x0, "and")
     decode_block += instCode(0x1, "eor")
-    decode_block += instCode(0x2, "sub")
+    decode_block += adrCode(0x2, "sub", add="(IntRegIndex)0")
     decode_block += instCode(0x3, "rsb")
-    decode_block += instCode(0x4, "add")
+    decode_block += adrCode(0x4, "add", add="(IntRegIndex)1")
     decode_block += instCode(0x5, "adc")
     decode_block += instCode(0x6, "sbc")
     decode_block += instCode(0x7, "rsc")
@@ -274,7 +293,7 @@ def format Thumb16Adr() {{
     {
         const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
         const uint32_t imm8 = bits(machInst, 7, 0) << 2;
-        return new AddImm(machInst, rd, INTREG_PC, imm8, true);
+        return new AdrImm(machInst, rd, (IntRegIndex)1, imm8, false);
     }
     '''
 }};
@@ -491,7 +510,12 @@ def format Thumb32DataProcPlainBin() {{
                 const uint32_t imm = bits(machInst, 7, 0) |
                                      (bits(machInst, 14, 12) << 8) |
                                      (bits(machInst, 26) << 11);
-                return new AddImm(machInst, rd, rn, imm, true);
+                if (rn == 0xf) {
+                    return new AdrImm(machInst, rd, (IntRegIndex)1,
+                                      imm, false);
+                } else {
+                    return new AddImm(machInst, rd, rn, imm, true);
+                }
             }
           case 0x4:
             {
@@ -506,7 +530,12 @@ def format Thumb32DataProcPlainBin() {{
                 const uint32_t imm = bits(machInst, 7, 0) |
                                      (bits(machInst, 14, 12) << 8) |
                                      (bits(machInst, 26) << 11);
-                return new SubImm(machInst, rd, rn, imm, true);
+                if (rn == 0xf) {
+                    return new AdrImm(machInst, rd, (IntRegIndex)0,
+                                      imm, false);
+                } else {
+                    return new SubImm(machInst, rd, rn, imm, true);
+                }
             }
           case 0xc:
             {
index a3418edf07bed3bfdb8883ce8e9381c00afe31ca..02ecd6b4c4a62c6db9f716b0ae27c5993326930f 100644 (file)
@@ -200,6 +200,10 @@ let {{
     buildDataInst("sub", "AIWDest = resTemp = Op1 - secondOp;", "sub")
     buildDataInst("rsb", "AIWDest = resTemp = secondOp - Op1;", "rsb")
     buildDataInst("add", "AIWDest = resTemp = Op1 + secondOp;", "add")
+    buildImmDataInst("adr", '''
+                               AIWDest = resTemp = (readPC(xc) & ~0x3) +
+                               (op1 ? secondOp : -secondOp);
+                            ''')
     buildDataInst("adc", "AIWDest = resTemp = Op1 + secondOp + %s;" % oldC,
                   "add")
     buildDataInst("sbc", "AIWDest = resTemp = Op1 - secondOp - !%s;" % oldC,