ARM: Move some miscellaneous instructions out of the decoder to share with thumb.
authorGabe Black <gblack@eecs.umich.edu>
Wed, 2 Jun 2010 17:58:17 +0000 (12:58 -0500)
committerGabe Black <gblack@eecs.umich.edu>
Wed, 2 Jun 2010 17:58:17 +0000 (12:58 -0500)
src/arch/arm/isa/decoder/arm.isa
src/arch/arm/isa/formats/data.isa
src/arch/arm/isa/insts/misc.isa

index 49f70e5e412f3e2ece39c92bb5615ebd7fc81638..29ec46f9bd2f8bbb696162f7c8964dd7743e435f 100644 (file)
@@ -81,48 +81,7 @@ format DataOp {
     }
     0x1: decode IS_MISC {
         0: ArmDataProcImm::armDataProcImm();
-        1: decode OPCODE {
-            // The following two instructions aren't supposed to be defined
-            0x8: DataOp::movw({{ Rd = IMMED_11_0 | (RN << 12) ; }});
-            0x9: decode RN {
-                0: decode IMM {
-                    0: PredImmOp::nop({{ ; }});
-#if FULL_SYSTEM
-                    1: PredImmOp::yield({{ ; }});
-                    2: PredImmOp::wfe({{
-                        if (SevMailbox)
-                            SevMailbox = 0;
-                        else
-                            PseudoInst::quiesce(xc->tcBase());
-                    }}, IsNonSpeculative, IsQuiesce);
-                    3: PredImmOp::wfi({{
-                            PseudoInst::quiesce(xc->tcBase());
-                    }}, IsNonSpeculative, IsQuiesce);
-                    4: PredImmOp::sev({{
-                        // Need a way for O3 to not scoreboard these
-                        // accesses as pipeflushs
-                        System *sys = xc->tcBase()->getSystemPtr();
-                        for (int x = 0; x < sys->numContexts(); x++) {
-                            ThreadContext *oc = sys->getThreadContext(x);
-                            oc->setMiscReg(MISCREG_SEV_MAILBOX, 1);
-                        }
-                    }});
-#endif
-                }
-                default: PredImmOp::msr_i_cpsr({{
-                            SCTLR sctlr = Sctlr;
-                            uint32_t newCpsr =
-                                cpsrWriteByInstr(Cpsr | CondCodes,
-                                                 rotated_imm, RN, false, sctlr.nmfi);
-                            Cpsr = ~CondCodesMask & newCpsr;
-                            CondCodes = CondCodesMask & newCpsr;
-                }});
-            }
-            0xa: PredOp::movt({{ Rd = IMMED_11_0 << 16 | RN << 28 | Rd<15:0>; }});
-            0xb: PredImmOp::msr_i_spsr({{
-                       Spsr = spsrWriteByInstr(Spsr, rotated_imm, RN, false);
-            }});
-        }
+        1: ArmMisc::armMisc();
     }
     0x2: AddrMode2::addrMode2(True);
     0x3: decode OPCODE_4 {
index e97769835fbc247809d9b56ccbad9a54bf7694ff..a567a92b472ed17c1cce2039934ae69305a7217f 100644 (file)
@@ -1073,6 +1073,56 @@ def format Thumb16AddSp() {{
     '''
 }};
 
+def format ArmMisc() {{
+    decode_block = '''
+    {
+        const uint32_t unrotated = bits(machInst, 7, 0);
+        const uint32_t rotation = (bits(machInst, 11, 8) << 1);
+        const uint32_t imm = rotate_imm(unrotated, rotation);
+        const uint8_t byteMask = bits(machInst, 19, 16);
+        switch (OPCODE) {
+          case 0x8:
+            return new MovImm(machInst, (IntRegIndex)(uint32_t)RD,
+                    (IntRegIndex)INTREG_ZERO,
+                    bits(machInst, 11, 0) | (bits(machInst, 19, 16) << 12),
+                    false);
+          case 0x9:
+            if (RN == 0) {
+                switch (IMM) {
+                  case 0x0:
+                    return new NopInst(machInst);
+#if FULL_SYSTEM
+                  case 0x1:
+                    return new YieldInst(machInst);
+                  case 0x2:
+                    return new WfeInst(machInst);
+                  case 0x3:
+                    return new WfiInst(machInst);
+                  case 0x4:
+                    return new SevInst(machInst);
+#endif
+                  default:
+                    return new Unknown(machInst);
+                }
+            } else {
+                return new MsrCpsrImm(machInst, imm, byteMask);
+            }
+          case 0xa:
+            {
+                const uint32_t timm = (bits(machInst, 19, 16) << 12) |
+                                       bits(machInst, 11, 0);
+                return new MovtImm(machInst, (IntRegIndex)(uint32_t)RD,
+                                   (IntRegIndex)(uint32_t)RD, timm, true);
+            }
+          case 0xb:
+            return new MsrSpsrImm(machInst, imm, byteMask);
+          default:
+            return new Unknown(machInst);
+        }
+    }
+    '''
+}};
+
 def format Thumb16Misc() {{
     decode_block = '''
     {
index 64bff6cb108df470d99d49d9b83da94564a734c7..7f9a5c171b96e74d0ab093928ce5ca01d10fa9ae 100644 (file)
@@ -468,6 +468,54 @@ let {{
     decoder_output += BasicConstructor.subst(nopIop)
     exec_output += PredOpExecute.subst(nopIop)
 
+    yieldIop = InstObjParams("yield", "YieldInst", "PredOp", \
+            { "code" : "", "predicate_test" : predicateTest })
+    header_output += BasicDeclare.subst(yieldIop)
+    decoder_output += BasicConstructor.subst(yieldIop)
+    exec_output += PredOpExecute.subst(yieldIop)
+
+    wfeCode = '''
+#if FULL_SYSTEM
+    if (SevMailbox)
+        SevMailbox = 0;
+    else
+        PseudoInst::quiesce(xc->tcBase());
+#endif
+    '''
+    wfeIop = InstObjParams("wfe", "WfeInst", "PredOp", \
+            { "code" : wfeCode, "predicate_test" : predicateTest },
+            ["IsNonSpeculative", "IsQuiesce"])
+    header_output += BasicDeclare.subst(wfeIop)
+    decoder_output += BasicConstructor.subst(wfeIop)
+    exec_output += PredOpExecute.subst(wfeIop)
+
+    wfiCode = '''
+#if FULL_SYSTEM
+    PseudoInst::quiesce(xc->tcBase());
+#endif
+    '''
+    wfiIop = InstObjParams("wfi", "WfiInst", "PredOp", \
+            { "code" : wfiCode, "predicate_test" : predicateTest },
+            ["IsNonSpeculative", "IsQuiesce"])
+    header_output += BasicDeclare.subst(wfiIop)
+    decoder_output += BasicConstructor.subst(wfiIop)
+    exec_output += PredOpExecute.subst(wfiIop)
+
+    sevCode = '''
+    // Need a way for O3 to not scoreboard these accesses as pipe flushes.
+    System *sys = xc->tcBase()->getSystemPtr();
+    for (int x = 0; x < sys->numContexts(); x++) {
+        ThreadContext *oc = sys->getThreadContext(x);
+        oc->setMiscReg(MISCREG_SEV_MAILBOX, 1);
+    }
+    '''
+    sevIop = InstObjParams("sev", "SevInst", "PredOp", \
+            { "code" : sevCode, "predicate_test" : predicateTest },
+            ["IsNonSpeculative", "IsQuiesce"])
+    header_output += BasicDeclare.subst(sevIop)
+    decoder_output += BasicConstructor.subst(sevIop)
+    exec_output += PredOpExecute.subst(sevIop)
+
     itIop = InstObjParams("it", "ItInst", "PredOp", \
             { "code" : "Itstate = machInst.newItstate;",
               "predicate_test" : predicateTest })