ARM: Decode the SRS instruction.
authorGabe Black <gblack@eecs.umich.edu>
Wed, 2 Jun 2010 17:58:11 +0000 (12:58 -0500)
committerGabe Black <gblack@eecs.umich.edu>
Wed, 2 Jun 2010 17:58:11 +0000 (12:58 -0500)
src/arch/arm/isa/formats/mem.isa
src/arch/arm/isa/formats/uncond.isa

index 15a4a5c4f7f885558f933a6a78be1bcc548dc6f7..aa8bbf55ec1f0c8acff687ccfc400d51b866710f 100644 (file)
@@ -263,10 +263,10 @@ def format ArmSyncMem() {{
 def format Thumb32SrsRfe() {{
     decode_block = '''
     {
+        const bool wb = (bits(machInst, 21) == 1);
+        const bool add = (bits(machInst, 24, 23) == 0x3);
         if (bits(machInst, 20) == 1) {
-            const bool add = (bits(machInst, 24, 23) == 0x3);
             // post == add
-            const bool wb = (bits(machInst, 21) == 1);
             const IntRegIndex rn =
                 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
             if (!add && !wb) {
@@ -279,14 +279,31 @@ def format Thumb32SrsRfe() {{
                 return new %(rfe_uw)s(machInst, rn, RfeOp::IncrementAfter, wb);
             }
         } else {
-            return new WarnUnimplemented("srs", machInst);
+            const uint32_t mode = bits(machInst, 4, 0);
+            if (!add && !wb) {
+                return new %(srs)s(machInst, mode,
+                        SrsOp::DecrementBefore, wb);
+            } else if (add && !wb) {
+                return new %(srs_u)s(machInst, mode,
+                        SrsOp::IncrementAfter, wb);
+            } else if (!add && wb) {
+                return new %(srs_w)s(machInst, mode,
+                        SrsOp::DecrementBefore, wb);
+            } else {
+                return new %(srs_uw)s(machInst, mode,
+                        SrsOp::IncrementAfter, wb);
+            }
         }
     }
     ''' % {
         "rfe" : "RFE_" + loadImmClassName(False, False, False, 8),
         "rfe_u" : "RFE_" + loadImmClassName(True, True, False, 8),
         "rfe_w" : "RFE_" + loadImmClassName(False, False, True, 8),
-        "rfe_uw" : "RFE_" + loadImmClassName(True, True, True, 8)
+        "rfe_uw" : "RFE_" + loadImmClassName(True, True, True, 8),
+        "srs" : "SRS_" + storeImmClassName(False, False, False, 8),
+        "srs_u" : "SRS_" + storeImmClassName(True, True, False, 8),
+        "srs_w" : "SRS_" + storeImmClassName(False, False, True, 8),
+        "srs_uw" : "SRS_" + storeImmClassName(True, True, True, 8)
     }
 }};
 
index fd2f66e7523c192fa4b0f3ca4243b6a17609bc2f..45cdbd058d5b4069b17e74201135ecc2cb54862a 100644 (file)
@@ -163,7 +163,34 @@ def format ArmUnconditional() {{
                 {
                     const uint32_t val = ((machInst >> 20) & 0x5);
                     if (val == 0x4) {
-                        return new WarnUnimplemented("srs", machInst);
+                        const uint32_t mode = bits(machInst, 4, 0);
+                        switch (bits(machInst, 24, 21)) {
+                          case 0x2:
+                            return new %(srs)s(machInst, mode,
+                                    SrsOp::DecrementAfter, false);
+                          case 0x3:
+                            return new %(srs_w)s(machInst, mode,
+                                    SrsOp::DecrementAfter, true);
+                          case 0x6:
+                            return new %(srs_u)s(machInst, mode,
+                                    SrsOp::IncrementAfter, false);
+                          case 0x7:
+                            return new %(srs_uw)s(machInst, mode,
+                                    SrsOp::IncrementAfter, true);
+                          case 0xa:
+                            return new %(srs_p)s(machInst, mode,
+                                    SrsOp::DecrementBefore, false);
+                          case 0xb:
+                            return new %(srs_pw)s(machInst, mode,
+                                    SrsOp::DecrementBefore, true);
+                          case 0xe:
+                            return new %(srs_pu)s(machInst, mode,
+                                    SrsOp::IncrementBefore, false);
+                          case 0xf:
+                            return new %(srs_puw)s(machInst, mode,
+                                    SrsOp::IncrementBefore, true);
+                        }
+                        return new Unknown(machInst);
                     } else if (val == 0x1) {
                         switch (bits(machInst, 24, 21)) {
                           case 0x0:
@@ -266,6 +293,14 @@ def format ArmUnconditional() {{
         "rfe_p" : "RFE_" + loadImmClassName(False, False, False, 8),
         "rfe_pw" : "RFE_" + loadImmClassName(False, False, True, 8),
         "rfe_pu" : "RFE_" + loadImmClassName(False, True, False, 8),
-        "rfe_puw" : "RFE_" + loadImmClassName(False, True, True, 8)
+        "rfe_puw" : "RFE_" + loadImmClassName(False, True, True, 8),
+        "srs" : "SRS_" + storeImmClassName(True, False, False, 8),
+        "srs_w" : "SRS_" + storeImmClassName(True, False, True, 8),
+        "srs_u" : "SRS_" + storeImmClassName(True, True, False, 8),
+        "srs_uw" : "SRS_" + storeImmClassName(True, True, True, 8),
+        "srs_p" : "SRS_" + storeImmClassName(False, False, False, 8),
+        "srs_pw" : "SRS_" + storeImmClassName(False, False, True, 8),
+        "srs_pu" : "SRS_" + storeImmClassName(False, True, False, 8),
+        "srs_puw" : "SRS_" + storeImmClassName(False, True, True, 8)
     };
 }};