changeset 7449084b1612 in /z/repo/m5
details: http://repo.m5sim.org/m5?cmd=changeset;node=7449084b1612
description:
        ARM: Fix RFE macrop.

        This changes the RFE macroop into 3 microops:

        URa = [sp]; URb = [sp+4]; // load CPSR,PC values from stack
        sp = sp + offset;         // optionally auto-increment
        PC = URa; CPSR = URb;     // write to the PC and CPSR.

        Importantly:
        - writing to PC is handled in the last micro-op.
        - loading occurs prior to state changes.

diffstat:

 src/arch/arm/insts/macromem.cc          |   9 ++++++++
 src/arch/arm/insts/macromem.hh          |  21 +++++++++++++++++++
 src/arch/arm/insts/mem.hh               |   8 +++++-
 src/arch/arm/intregs.hh                 |   2 +
 src/arch/arm/isa/insts/ldr.isa          |  25 ++++++++---------------
 src/arch/arm/isa/insts/macromem.isa     |  31 ++++++++++++++++++++++++++--
 src/arch/arm/isa/insts/mem.isa          |  25 +++++++++++++++++++---
 src/arch/arm/isa/templates/macromem.isa |  35 +++++++++++++++++++++++++++++++++
 src/arch/arm/isa/templates/mem.isa      |  24 ++++++++++++++--------
 9 files changed, 146 insertions(+), 34 deletions(-)

diffs (truncated from 339 to 300 lines):

diff -r 2b2efc67f6df -r 7449084b1612 src/arch/arm/insts/macromem.cc
--- a/src/arch/arm/insts/macromem.cc    Thu Mar 17 19:20:19 2011 -0500
+++ b/src/arch/arm/insts/macromem.cc    Thu Mar 17 19:20:19 2011 -0500
@@ -896,6 +896,15 @@
 }
 
 std::string
+MicroSetPCCPSR::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+{
+    std::stringstream ss;
+    printMnemonic(ss);
+    ss << "[PC,CPSR]";
+    return ss.str();
+}
+
+std::string
 MicroIntMov::generateDisassembly(Addr pc, const SymbolTable *symtab) const
 {
     std::stringstream ss;
diff -r 2b2efc67f6df -r 7449084b1612 src/arch/arm/insts/macromem.hh
--- a/src/arch/arm/insts/macromem.hh    Thu Mar 17 19:20:19 2011 -0500
+++ b/src/arch/arm/insts/macromem.hh    Thu Mar 17 19:20:19 2011 -0500
@@ -134,6 +134,27 @@
     {
     }
 };
+
+/**
+ * Microops of the form
+ * PC   = IntRegA
+ * CPSR = IntRegB
+ */
+class MicroSetPCCPSR : public MicroOp
+{
+    protected:
+    IntRegIndex ura, urb, urc;
+
+    MicroSetPCCPSR(const char *mnem, ExtMachInst machInst, OpClass __opClass,
+                   IntRegIndex _ura, IntRegIndex _urb, IntRegIndex _urc)
+        : MicroOp(mnem, machInst, __opClass),
+          ura(_ura), urb(_urb), urc(_urc)
+    {
+    }
+
+    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
 /**
  * Microops of the form IntRegA = IntRegB
  */
diff -r 2b2efc67f6df -r 7449084b1612 src/arch/arm/insts/mem.hh
--- a/src/arch/arm/insts/mem.hh Thu Mar 17 19:20:19 2011 -0500
+++ b/src/arch/arm/insts/mem.hh Thu Mar 17 19:20:19 2011 -0500
@@ -97,14 +97,18 @@
     IntRegIndex base;
     AddrMode mode;
     bool wb;
-    static const unsigned numMicroops = 2;
+    IntRegIndex ura, urb, urc;
+    static const unsigned numMicroops = 3;
 
     StaticInstPtr *uops;
 
     RfeOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
           IntRegIndex _base, AddrMode _mode, bool _wb)
         : MightBeMicro(mnem, _machInst, __opClass),
-          base(_base), mode(_mode), wb(_wb), uops(NULL)
+          base(_base), mode(_mode), wb(_wb),
+          ura(INTREG_UREG0), urb(INTREG_UREG1),
+          urc(INTREG_UREG2),
+          uops(NULL)
     {}
 
     virtual
diff -r 2b2efc67f6df -r 7449084b1612 src/arch/arm/intregs.hh
--- a/src/arch/arm/intregs.hh   Thu Mar 17 19:20:19 2011 -0500
+++ b/src/arch/arm/intregs.hh   Thu Mar 17 19:20:19 2011 -0500
@@ -110,6 +110,8 @@
 
     INTREG_ZERO, // Dummy zero reg since there has to be one.
     INTREG_UREG0,
+    INTREG_UREG1,
+    INTREG_UREG2,
     INTREG_CONDCODES,
     INTREG_FPCONDCODES,
 
diff -r 2b2efc67f6df -r 7449084b1612 src/arch/arm/isa/insts/ldr.isa
--- a/src/arch/arm/isa/insts/ldr.isa    Thu Mar 17 19:20:19 2011 -0500
+++ b/src/arch/arm/isa/insts/ldr.isa    Thu Mar 17 19:20:19 2011 -0500
@@ -67,7 +67,7 @@
             self.memFlags = ["ArmISA::TLB::MustBeOne"]
             self.codeBlobs = {"postacc_code" : ""}
 
-        def emitHelper(self, base = 'Memory', wbDecl = None, instFlags = []):
+        def emitHelper(self, base = 'Memory', wbDecl = None, instFlags = [], 
pcDecl = None):
 
             global header_output, decoder_output, exec_output
 
@@ -76,7 +76,8 @@
             (newHeader,
              newDecoder,
              newExec) = self.fillTemplates(self.name, self.Name, codeBlobs,
-                                           self.memFlags, instFlags, base, 
wbDecl)
+                                           self.memFlags, instFlags, base,
+                                           wbDecl, pcDecl)
 
             header_output += newHeader
             decoder_output += newDecoder
@@ -104,26 +105,18 @@
                 wbDiff = 8
             accCode = '''
             CPSR cpsr = Cpsr;
-            SCTLR sctlr = Sctlr;
-            // Use the version of NPC that gets set before NextThumb
-            pNPC = cSwap<uint32_t>(Mem.ud, cpsr.e);
-            uint32_t tempSpsr = cSwap<uint32_t>(Mem.ud >> 32, cpsr.e);
-            uint32_t newCpsr =
-                cpsrWriteByInstr(cpsr | CondCodes, tempSpsr,
-                                 0xF, true, sctlr.nmfi);
-            Cpsr = ~CondCodesMask & newCpsr;
-            NextThumb = ((CPSR)newCpsr).t;
-            NextJazelle = ((CPSR)newCpsr).j;
-            ForcedItState = ((((CPSR)tempSpsr).it2 << 2) & 0xFC)
-                | (((CPSR)tempSpsr).it1 & 0x3);
-            CondCodes = CondCodesMask & newCpsr;
+            URc = cpsr | CondCodes;
+            URa = cSwap<uint32_t>(Mem.ud, cpsr.e);
+            URb = cSwap<uint32_t>(Mem.ud >> 32, cpsr.e);
             '''
             self.codeBlobs["memacc_code"] = accCode
 
             wbDecl = None
+            pcDecl = "MicroUopSetPCCPSR(machInst, INTREG_UREG0, INTREG_UREG1, 
INTREG_UREG2);"
+
             if self.writeback:
                 wbDecl = "MicroAddiUop(machInst, base, base, %d);" % wbDiff
-            self.emitHelper('RfeOp', wbDecl, ["IsSerializeAfter", 
"IsNonSpeculative"])
+            self.emitHelper('RfeOp', wbDecl, ["IsSerializeAfter", 
"IsNonSpeculative"], pcDecl)
 
     class LoadImmInst(LoadInst):
         def __init__(self, *args, **kargs):
diff -r 2b2efc67f6df -r 7449084b1612 src/arch/arm/isa/insts/macromem.isa
--- a/src/arch/arm/isa/insts/macromem.isa       Thu Mar 17 19:20:19 2011 -0500
+++ b/src/arch/arm/isa/insts/macromem.isa       Thu Mar 17 19:20:19 2011 -0500
@@ -608,23 +608,48 @@
                                     'predicate_test': predicateTest},
                                    ['IsMicroop'])
 
+    setPCCPSRDecl = '''
+                    CPSR cpsrOrCondCodes = URc;
+                    SCTLR sctlr = Sctlr;
+                    pNPC = URa;
+                    uint32_t newCpsr =
+                    cpsrWriteByInstr(cpsrOrCondCodes, URb,
+                                     0xF, true, sctlr.nmfi);
+                    Cpsr = ~CondCodesMask & newCpsr;
+                    NextThumb = ((CPSR)newCpsr).t;
+                    NextJazelle = ((CPSR)newCpsr).j;
+                    ForcedItState = ((((CPSR)URb).it2 << 2) & 0xFC)
+                                    | (((CPSR)URb).it1 & 0x3);
+                    CondCodes = CondCodesMask & newCpsr;
+                    '''
+
+    microUopSetPCCPSRIop = InstObjParams('uopSet_uop', 'MicroUopSetPCCPSR',
+                                         'MicroSetPCCPSR',
+                                         {'code': setPCCPSRDecl,
+                                          'predicate_test': predicateTest},
+                                         ['IsMicroop'])
+
     header_output = MicroIntImmDeclare.subst(microAddiUopIop) + \
                     MicroIntImmDeclare.subst(microSubiUopIop) + \
                     MicroIntRegDeclare.subst(microAddUopIop) + \
                     MicroIntRegDeclare.subst(microSubUopIop) + \
-                    MicroIntMovDeclare.subst(microUopRegMovIop)
+                    MicroIntMovDeclare.subst(microUopRegMovIop) + \
+                    MicroSetPCCPSRDeclare.subst(microUopSetPCCPSRIop)
 
     decoder_output = MicroIntImmConstructor.subst(microAddiUopIop) + \
                      MicroIntImmConstructor.subst(microSubiUopIop) + \
                      MicroIntRegConstructor.subst(microAddUopIop) + \
                      MicroIntRegConstructor.subst(microSubUopIop) + \
-                     MicroIntMovConstructor.subst(microUopRegMovIop)
+                     MicroIntMovConstructor.subst(microUopRegMovIop) + \
+                     MicroSetPCCPSRConstructor.subst(microUopSetPCCPSRIop)
 
     exec_output = PredOpExecute.subst(microAddiUopIop) + \
                   PredOpExecute.subst(microSubiUopIop) + \
                   PredOpExecute.subst(microAddUopIop) + \
                   PredOpExecute.subst(microSubUopIop) + \
-                  PredOpExecute.subst(microUopRegMovIop)
+                  PredOpExecute.subst(microUopRegMovIop) + \
+                  PredOpExecute.subst(microUopSetPCCPSRIop)
+
 }};
 
 let {{
diff -r 2b2efc67f6df -r 7449084b1612 src/arch/arm/isa/insts/mem.isa
--- a/src/arch/arm/isa/insts/mem.isa    Thu Mar 17 19:20:19 2011 -0500
+++ b/src/arch/arm/isa/insts/mem.isa    Thu Mar 17 19:20:19 2011 -0500
@@ -48,7 +48,7 @@
             self.constructTemplate = eval(self.decConstBase + 'Constructor')
 
         def fillTemplates(self, name, Name, codeBlobs, memFlags, instFlags,
-                          base = 'Memory', wbDecl = None):
+                          base = 'Memory', wbDecl = None, pcDecl = None):
             # Make sure flags are in lists (convert to lists if not).
             memFlags = makeList(memFlags)
             instFlags = makeList(instFlags)
@@ -65,12 +65,26 @@
             macroName = Name
             instFlagsCopy = list(instFlags)
             codeBlobsCopy = dict(codeBlobs)
-            if wbDecl is not None:
+
+            use_uops = 0
+            if wbDecl is not None or pcDecl is not None:
                 instFlagsCopy.append('IsMicroop')
                 Name = Name + 'Acc'
+                use_uops = 1
+
+            use_wb = 0
+            use_pc = 0
+            if wbDecl is not None:
+                use_wb = 1
+            if pcDecl is not None:
+                use_pc = 1
+
             codeBlobsCopy['acc_name'] = Name
             codeBlobsCopy['wb_decl'] = wbDecl
+            codeBlobsCopy['pc_decl'] = pcDecl
             codeBlobsCopy['use_uops'] = 0
+            codeBlobsCopy['use_wb'] = 0
+            codeBlobsCopy['use_pc'] = 0
 
             iop = InstObjParams(name, Name, base,
                                 codeBlobsCopy, instFlagsCopy)
@@ -81,11 +95,14 @@
                           self.initiateAccTemplate.subst(iop) + \
                           self.completeAccTemplate.subst(iop)
 
-            if wbDecl is not None:
+            if wbDecl is not None or pcDecl is not None:
                 iop = InstObjParams(name, macroName, base,
                                     { "wb_decl" : wbDecl,
+                                      "pc_decl" : pcDecl,
                                       "acc_name" : Name,
-                                      "use_uops" : 1 },
+                                      "use_uops" : use_uops,
+                                      "use_pc" : use_pc,
+                                      "use_wb" : use_wb },
                                     ['IsMacroop'])
                 header_output += self.declareTemplate.subst(iop)
                 decoder_output += self.constructTemplate.subst(iop)
diff -r 2b2efc67f6df -r 7449084b1612 src/arch/arm/isa/templates/macromem.isa
--- a/src/arch/arm/isa/templates/macromem.isa   Thu Mar 17 19:20:19 2011 -0500
+++ b/src/arch/arm/isa/templates/macromem.isa   Thu Mar 17 19:20:19 2011 -0500
@@ -109,6 +109,41 @@
 
 ////////////////////////////////////////////////////////////////////
 //
+// PC   = Integer(ura)
+// CPSR = Integer(urb)
+//
+
+def template MicroSetPCCPSRDeclare {{
+    class %(class_name)s : public %(base_class)s
+    {
+      public:
+        %(class_name)s(ExtMachInst machInst,
+                       IntRegIndex _ura,
+                       IntRegIndex _urb,
+                       IntRegIndex _urc);
+        %(BasicExecDeclare)s
+    };
+}};
+
+def template MicroSetPCCPSRConstructor {{
+    %(class_name)s::%(class_name)s(ExtMachInst machInst,
+                                   IntRegIndex _ura,
+                                   IntRegIndex _urb,
+                                   IntRegIndex _urc)
+          : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
+                           _ura, _urb, _urc)
+    {
+        %(constructor)s;
+        if (!(condCode == COND_AL || condCode == COND_UC)) {
+            for (int x = 0; x < _numDestRegs; x++) {
+                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
+            }
+        }
+    }
+}};
+
+////////////////////////////////////////////////////////////////////
+//
 // Integer = Integer op Integer microops
 //
 
diff -r 2b2efc67f6df -r 7449084b1612 src/arch/arm/isa/templates/mem.isa
--- a/src/arch/arm/isa/templates/mem.isa        Thu Mar 17 19:20:19 2011 -0500
_______________________________________________
m5-dev mailing list
m5-dev@m5sim.org
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to