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

index 231796281292bc1c098eb33dc40adee687302bc2..23c33df4887ba83ed4ffff110f244342d186a2a1 100644 (file)
         0x1: decode HTOPCODE_10_9 {
             0x0: decode HTOPCODE_6 {
                 0x0: decode HTOPCODE_8_7 {
-                    0x0, 0x3: decode HTOPCODE_4 {
-                        0x0: WarnUnimpl::srs();
-                        0x1: WarnUnimpl::rfe();
-                    }
+                    0x0, 0x3: Thumb32SrsRfe::thumb32SrsRfe();
                     // This uses the same encoding as regular ARM.
                     default: ArmMacroMem::armMacroMem();
                 }
index 41706c48d25e33ece03c744a7b0ab8fd661b159e..5d389458cff61d1105d7baac710d1820976a5eb5 100644 (file)
@@ -255,6 +255,36 @@ def format ArmSyncMem() {{
     }
 }};
 
+def format Thumb32SrsRfe() {{
+    decode_block = '''
+    {
+        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) {
+                return new %(rfe)s(machInst, rn, RfeOp::DecrementBefore, wb);
+            } else if (add && !wb) {
+                return new %(rfe_u)s(machInst, rn, RfeOp::IncrementAfter, wb);
+            } else if (!add && wb) {
+                return new %(rfe_w)s(machInst, rn, RfeOp::DecrementBefore, wb);
+            } else {
+                return new %(rfe_uw)s(machInst, rn, RfeOp::IncrementAfter, wb);
+            }
+        } else {
+            return new WarnUnimplemented("srs", machInst);
+        }
+    }
+    ''' % {
+        "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)
+    }
+}};
+
 def format Thumb32LdrStrDExTbh() {{
     decode_block = '''
     {
index cd041f21b3eb290f28ae3b0a6594cbefb6853cca..d305ee996c7eba29c989f479390e12c09c2ce3a2 100644 (file)
@@ -165,7 +165,33 @@ def format ArmUnconditional() {{
                     if (val == 0x4) {
                         return new WarnUnimplemented("srs", machInst);
                     } else if (val == 0x1) {
-                        return new WarnUnimplemented("rfe", machInst);
+                        switch (bits(machInst, 24, 21)) {
+                          case 0x0:
+                            return new %(rfe)s(machInst, rn,
+                                    RfeOp::DecrementAfter, false);
+                          case 0x1:
+                            return new %(rfe_w)s(machInst, rn,
+                                    RfeOp::DecrementAfter, true);
+                          case 0x4:
+                            return new %(rfe_u)s(machInst, rn,
+                                    RfeOp::IncrementAfter, false);
+                          case 0x5:
+                            return new %(rfe_uw)s(machInst, rn,
+                                    RfeOp::IncrementAfter, true);
+                          case 0x8:
+                            return new %(rfe_p)s(machInst, rn,
+                                    RfeOp::DecrementBefore, false);
+                          case 0x9:
+                            return new %(rfe_pw)s(machInst, rn,
+                                    RfeOp::DecrementBefore, true);
+                          case 0xc:
+                            return new %(rfe_pu)s(machInst, rn,
+                                    RfeOp::IncrementBefore, false);
+                          case 0xd:
+                            return new %(rfe_puw)s(machInst, rn,
+                                    RfeOp::IncrementBefore, true);
+                        }
+                        return new Unknown(machInst);
                     }
                 }
                 break;
@@ -232,6 +258,14 @@ def format ArmUnconditional() {{
         "pld_radd" : "PLD_" + loadRegClassName(False, True, False, 1),
         "pld_rsub" : "PLD_" + loadRegClassName(False, False, False, 1),
         "pldw_radd" : "PLDW_" + loadRegClassName(False, True, False, 1),
-        "pldw_rsub" : "PLDW_" + loadRegClassName(False, False, False, 1)
+        "pldw_rsub" : "PLDW_" + loadRegClassName(False, False, False, 1),
+        "rfe" : "RFE_" + loadImmClassName(True, False, False, 8),
+        "rfe_w" : "RFE_" + loadImmClassName(True, False, True, 8),
+        "rfe_u" : "RFE_" + loadImmClassName(True, True, False, 8),
+        "rfe_uw" : "RFE_" + loadImmClassName(True, True, True, 8),
+        "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)
     };
 }};