ARM: Use fewer micro-ops for register update loads if possible.
authorGene WU <gene.wu@arm.com>
Thu, 26 Aug 2010 00:10:42 +0000 (19:10 -0500)
committerGene WU <gene.wu@arm.com>
Thu, 26 Aug 2010 00:10:42 +0000 (19:10 -0500)
Allow some loads that update the base register to use just two micro-ops. three
micro-ops are only used if the destination register matches the offset register
or the PC is the destination regsiter. If the PC is updated it needs to be
the last micro-op otherwise O3 will mispredict.

src/arch/arm/insts/macromem.cc
src/arch/arm/insts/macromem.hh
src/arch/arm/insts/mem.hh
src/arch/arm/isa/insts/ldr.isa
src/arch/arm/isa/insts/macromem.isa
src/arch/arm/isa/insts/mem.isa
src/arch/arm/isa/insts/str.isa
src/arch/arm/isa/templates/macromem.isa
src/arch/arm/isa/templates/mem.isa
src/arch/arm/isa/templates/pred.isa

index 5602231f9bc39baf5b2c393cb148b2a5e1ba4114..f64fbeff94fa76df4c2354b3f459c5fbf89dd8a8 100644 (file)
@@ -185,7 +185,7 @@ VldMultOp::VldMultOp(const char *mnem, ExtMachInst machInst, OpClass __opClass,
     if (wb) {
         if (rm != 15 && rm != 13) {
             microOps[uopIdx++] =
-                new MicroAddUop(machInst, rn, rn, rm);
+                new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL);
         } else {
             microOps[uopIdx++] =
                 new MicroAddiUop(machInst, rn, rn, regs * 8);
@@ -320,7 +320,7 @@ VldSingleOp::VldSingleOp(const char *mnem, ExtMachInst machInst,
     if (wb) {
         if (rm != 15 && rm != 13) {
             microOps[uopIdx++] =
-                new MicroAddUop(machInst, rn, rn, rm);
+                new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL);
         } else {
             microOps[uopIdx++] =
                 new MicroAddiUop(machInst, rn, rn, loadSize);
@@ -566,7 +566,7 @@ VstMultOp::VstMultOp(const char *mnem, ExtMachInst machInst, OpClass __opClass,
     if (wb) {
         if (rm != 15 && rm != 13) {
             microOps[uopIdx++] =
-                new MicroAddUop(machInst, rn, rn, rm);
+                new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL);
         } else {
             microOps[uopIdx++] =
                 new MicroAddiUop(machInst, rn, rn, regs * 8);
@@ -762,7 +762,7 @@ VstSingleOp::VstSingleOp(const char *mnem, ExtMachInst machInst,
     if (wb) {
         if (rm != 15 && rm != 13) {
             microOps[uopIdx++] =
-                new MicroAddUop(machInst, rn, rn, rm);
+                new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL);
         } else {
             microOps[uopIdx++] =
                 new MicroAddiUop(machInst, rn, rn, storeSize);
@@ -877,6 +877,17 @@ MicroIntImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
     return ss.str();
 }
 
+std::string
+MicroIntMov::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+{
+    std::stringstream ss;
+    printMnemonic(ss);
+    printReg(ss, ura);
+    ss << ", ";
+    printReg(ss, urb);
+    return ss.str();
+}
+
 std::string
 MicroIntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
 {
index 923e9c0a14a54826aef478d5436116b846337576..c1c8383dabc1c028c343d7e9806c53953d689642 100644 (file)
@@ -128,6 +128,23 @@ class MicroNeonMixLaneOp : public MicroNeonMixOp
     {
     }
 };
+/**
+ * Microops of the form IntRegA = IntRegB
+ */
+class MicroIntMov : public MicroOp
+{
+  protected:
+    RegIndex ura, urb;
+
+    MicroIntMov(const char *mnem, ExtMachInst machInst, OpClass __opClass,
+               RegIndex _ura, RegIndex _urb)
+            : MicroOp(mnem, machInst, __opClass),
+              ura(_ura), urb(_urb)
+    {
+    }
+
+    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
 
 /**
  * Microops of the form IntRegA = IntRegB op Imm
@@ -136,10 +153,10 @@ class MicroIntImmOp : public MicroOp
 {
   protected:
     RegIndex ura, urb;
-    uint8_t imm;
+    uint32_t imm;
 
     MicroIntImmOp(const char *mnem, ExtMachInst machInst, OpClass __opClass,
-                  RegIndex _ura, RegIndex _urb, uint8_t _imm)
+                  RegIndex _ura, RegIndex _urb, uint32_t _imm)
             : MicroOp(mnem, machInst, __opClass),
               ura(_ura), urb(_urb), imm(_imm)
     {
@@ -166,6 +183,26 @@ class MicroIntOp : public MicroOp
     std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
 };
 
+/**
+ * Microops of the form IntRegA = IntRegB op shifted IntRegC
+ */
+class MicroIntRegOp : public MicroOp
+{
+  protected:
+    RegIndex ura, urb, urc;
+    int32_t shiftAmt;
+    ArmShiftType shiftType;
+
+    MicroIntRegOp(const char *mnem, ExtMachInst machInst, OpClass __opClass,
+               RegIndex _ura, RegIndex _urb, RegIndex _urc,
+               int32_t _shiftAmt, ArmShiftType _shiftType)
+            : MicroOp(mnem, machInst, __opClass),
+              ura(_ura), urb(_urb), urc(_urc),
+              shiftAmt(_shiftAmt), shiftType(_shiftType)
+    {
+    }
+};
+
 /**
  * Memory microops which use IntReg + Imm addressing
  */
index 609afa9aa3832271e276a8057b1f9ddebbdaac07..1baba51128f36af080558164cbf62d38050e27a9 100644 (file)
@@ -77,13 +77,29 @@ class RfeOp : public PredOp
     IntRegIndex base;
     AddrMode mode;
     bool wb;
+    static const unsigned numMicroops = 2;
+
+    StaticInstPtr *uops;
 
     RfeOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
           IntRegIndex _base, AddrMode _mode, bool _wb)
         : PredOp(mnem, _machInst, __opClass),
-          base(_base), mode(_mode), wb(_wb)
+          base(_base), mode(_mode), wb(_wb), uops(NULL)
     {}
 
+    virtual
+    ~RfeOp()
+    {
+        delete uops;
+    }
+
+    StaticInstPtr
+    fetchMicroop(MicroPC microPC)
+    {
+        assert(uops != NULL && microPC < numMicroops);
+        return uops[microPC];
+    }
+
     std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
 };
 
@@ -101,13 +117,29 @@ class SrsOp : public PredOp
     uint32_t regMode;
     AddrMode mode;
     bool wb;
+    static const unsigned numMicroops = 2;
+
+    StaticInstPtr *uops;
 
     SrsOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
           uint32_t _regMode, AddrMode _mode, bool _wb)
         : PredOp(mnem, _machInst, __opClass),
-          regMode(_regMode), mode(_mode), wb(_wb)
+          regMode(_regMode), mode(_mode), wb(_wb), uops(NULL)
     {}
 
+    virtual
+    ~SrsOp()
+    {
+        delete uops;
+    }
+
+    StaticInstPtr
+    fetchMicroop(MicroPC microPC)
+    {
+        assert(uops != NULL && microPC < numMicroops);
+        return uops[microPC];
+    }
+
     std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
 };
 
@@ -125,13 +157,29 @@ class Memory : public PredOp
     IntRegIndex dest;
     IntRegIndex base;
     bool add;
+    static const unsigned numMicroops = 3;
+
+    StaticInstPtr *uops;
 
     Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
            IntRegIndex _dest, IntRegIndex _base, bool _add)
         : PredOp(mnem, _machInst, __opClass),
-          dest(_dest), base(_base), add(_add)
+          dest(_dest), base(_base), add(_add), uops(NULL)
     {}
 
+    virtual
+    ~Memory()
+    {
+        delete [] uops;
+    }
+
+    StaticInstPtr
+    fetchMicroop(MicroPC microPC)
+    {
+        assert(uops != NULL && microPC < numMicroops);
+        return uops[microPC];
+    }
+
     virtual void
     printOffset(std::ostream &os) const
     {}
index a936ffaaf08e04461d0cf1392ae01003bb7f42c8..38a458b2367584f54940a5da0081246abed29e0e 100644 (file)
@@ -67,7 +67,7 @@ let {{
             self.memFlags = ["ArmISA::TLB::MustBeOne"]
             self.codeBlobs = {"postacc_code" : ""}
 
-        def emitHelper(self, base = 'Memory'):
+        def emitHelper(self, base = 'Memory', wbDecl = None):
 
             global header_output, decoder_output, exec_output
 
@@ -76,7 +76,7 @@ let {{
             (newHeader,
              newDecoder,
              newExec) = self.fillTemplates(self.name, self.Name, codeBlobs,
-                                           self.memFlags, [], base)
+                                           self.memFlags, [], base, wbDecl)
 
             header_output += newHeader
             decoder_output += newDecoder
@@ -113,22 +113,36 @@ let {{
             Cpsr = ~CondCodesMask & newCpsr;
             CondCodes = CondCodesMask & newCpsr;
             '''
-            if self.writeback:
-                accCode += "Base = Base + %s;\n" % wbDiff
             self.codeBlobs["memacc_code"] = accCode
 
-            self.emitHelper('RfeOp')
+            wbDecl = None
+            if self.writeback:
+                wbDecl = "MicroAddiUop(machInst, base, base, %d);" % wbDiff
+            self.emitHelper('RfeOp', wbDecl)
 
     class LoadImmInst(LoadInst):
         def __init__(self, *args, **kargs):
             super(LoadImmInst, self).__init__(*args, **kargs)
             self.offset = self.op + " imm"
 
+            if self.add:
+                self.wbDecl = "MicroAddiUop(machInst, base, base, imm);"
+            else:
+                self.wbDecl = "MicroSubiUop(machInst, base, base, imm);"
+
     class LoadRegInst(LoadInst):
         def __init__(self, *args, **kargs):
             super(LoadRegInst, self).__init__(*args, **kargs)
             self.offset = self.op + " shift_rm_imm(Index, shiftAmt," + \
                                     " shiftType, CondCodes<29:>)"
+            if self.add:
+                 self.wbDecl = '''
+                     MicroAddUop(machInst, base, base, wbIndexReg, shiftAmt, shiftType);
+                 '''
+            else:
+                 self.wbDecl = '''
+                     MicroSubUop(machInst, base, base, wbIndexReg, shiftAmt, shiftType);
+                 '''
 
     class LoadSingle(LoadInst):
         def __init__(self, *args, **kargs):
@@ -175,20 +189,20 @@ let {{
                 accCode = "IWDest = cSwap(Mem%s, ((CPSR)Cpsr).e);"
             accCode = accCode % buildMemSuffix(self.sign, self.size)
 
-            if self.writeback:
-                accCode += "Base = Base %s;\n" % self.offset
-
             self.codeBlobs["memacc_code"] = accCode
 
             # Push it out to the output files
             base = buildMemBase(self.basePrefix, self.post, self.writeback)
-            self.emitHelper(base)
+            wbDecl = None
+            if self.writeback:
+                wbDecl = self.wbDecl
+            self.emitHelper(base, wbDecl)
 
     def loadImmClassName(post, add, writeback, size=4, sign=False, user=False):
         return memClassName("LOAD_IMM", post, add, writeback, size, sign, user)
 
     class LoadImm(LoadImmInst, LoadSingle):
-        decConstBase = 'LoadStoreImm'
+        decConstBase = 'LoadImm'
         basePrefix = 'MemoryImm'
         nameFunc = staticmethod(loadImmClassName)
 
@@ -196,7 +210,7 @@ let {{
         return memClassName("LOAD_REG", post, add, writeback, size, sign, user)
 
     class LoadReg(LoadRegInst, LoadSingle):
-        decConstBase = 'LoadStoreReg'
+        decConstBase = 'LoadReg'
         basePrefix = 'MemoryReg'
         nameFunc = staticmethod(loadRegClassName)
 
@@ -244,14 +258,14 @@ let {{
                 FpDest2.uw = (uint32_t)(swappedMem >> 32);
                 '''
 
-            if self.writeback:
-                accCode += "Base = Base %s;\n" % self.offset
-
             self.codeBlobs["memacc_code"] = accCode
 
             # Push it out to the output files
             base = buildMemBase(self.basePrefix, self.post, self.writeback)
-            self.emitHelper(base)
+            wbDecl = None
+            if self.writeback:
+                wbDecl = self.wbDecl
+            self.emitHelper(base, wbDecl)
 
     def loadDoubleImmClassName(post, add, writeback):
         return memClassName("LOAD_IMMD", post, add, writeback, 4, False, False)
@@ -265,7 +279,7 @@ let {{
         return memClassName("LOAD_REGD", post, add, writeback, 4, False, False)
 
     class LoadDoubleReg(LoadRegInst, LoadDouble):
-        decConstBase = 'LoadStoreDReg'
+        decConstBase = 'LoadDReg'
         basePrefix = 'MemoryDReg'
         nameFunc = staticmethod(loadDoubleRegClassName)
 
index bcb1e26b86192df08a724ec951f6fa568eb8fc2f..f595f4043423768d5b3ec84c8b938d8eee3c2bce 100644 (file)
@@ -575,8 +575,12 @@ let {{
                                     ['IsMicroop'])
 
     microAddUopIop = InstObjParams('add_uop', 'MicroAddUop',
-                                   'MicroIntOp',
-                                   {'code': 'Ra = Rb + Rc;',
+                                   'MicroIntRegOp',
+                                   {'code':
+                                    '''Ra = Rb + shift_rm_imm(Rc, shiftAmt,
+                                                              shiftType,
+                                                              CondCodes<29:>);
+                                    ''',
                                     'predicate_test': predicateTest},
                                    ['IsMicroop'])
 
@@ -586,15 +590,39 @@ let {{
                                      'predicate_test': predicateTest},
                                     ['IsMicroop'])
 
+    microSubUopIop = InstObjParams('sub_uop', 'MicroSubUop',
+                                   'MicroIntRegOp',
+                                   {'code':
+                                    '''Ra = Rb - shift_rm_imm(Rc, shiftAmt,
+                                                              shiftType,
+                                                              CondCodes<29:>);
+                                    ''',
+                                    'predicate_test': predicateTest},
+                                   ['IsMicroop'])
+
+    microUopRegMovIop = InstObjParams('uopReg_uop', 'MicroUopRegMov',
+                                   'MicroIntMov',
+                                   {'code': 'IWRa = Rb;',
+                                    'predicate_test': predicateTest},
+                                   ['IsMicroop'])
+
     header_output = MicroIntImmDeclare.subst(microAddiUopIop) + \
                     MicroIntImmDeclare.subst(microSubiUopIop) + \
-                    MicroIntDeclare.subst(microAddUopIop)
+                    MicroIntRegDeclare.subst(microAddUopIop) + \
+                    MicroIntRegDeclare.subst(microSubUopIop) + \
+                    MicroIntMovDeclare.subst(microUopRegMovIop)
+
     decoder_output = MicroIntImmConstructor.subst(microAddiUopIop) + \
                      MicroIntImmConstructor.subst(microSubiUopIop) + \
-                     MicroIntConstructor.subst(microAddUopIop)
+                     MicroIntRegConstructor.subst(microAddUopIop) + \
+                     MicroIntRegConstructor.subst(microSubUopIop) + \
+                     MicroIntMovConstructor.subst(microUopRegMovIop)
+
     exec_output = PredOpExecute.subst(microAddiUopIop) + \
                   PredOpExecute.subst(microSubiUopIop) + \
-                  PredOpExecute.subst(microAddUopIop)
+                  PredOpExecute.subst(microAddUopIop) + \
+                  PredOpExecute.subst(microSubUopIop) + \
+                  PredOpExecute.subst(microUopRegMovIop)
 }};
 
 let {{
index aa47d5b7f179643d98712867db7e28af187c9e36..507f8cd4bf07bf1f02b5d44f1f72cfeb0a1fac17 100644 (file)
@@ -48,7 +48,7 @@ let {{
             self.constructTemplate = eval(self.decConstBase + 'Constructor')
 
         def fillTemplates(self, name, Name, codeBlobs, memFlags, instFlags,
-                          base = 'Memory'):
+                          base = 'Memory', wbDecl = None):
             # Make sure flags are in lists (convert to lists if not).
             memFlags = makeList(memFlags)
             instFlags = makeList(instFlags)
@@ -62,14 +62,38 @@ let {{
 
             codeBlobs["ea_code"] = eaCode
 
-            iop = InstObjParams(name, Name, base, codeBlobs, instFlags)
-
-            # (header_output, decoder_output, decode_block, exec_output)
-            return (self.declareTemplate.subst(iop),
-                    self.constructTemplate.subst(iop),
-                    self.fullExecTemplate.subst(iop)
-                    + self.initiateAccTemplate.subst(iop)
-                    + self.completeAccTemplate.subst(iop))
+            macroName = Name
+            instFlagsCopy = list(instFlags)
+            codeBlobsCopy = dict(codeBlobs)
+            if wbDecl is not None:
+                instFlagsCopy.append('IsMicroop')
+                Name = Name + 'Acc'
+            codeBlobsCopy['acc_name'] = Name
+            codeBlobsCopy['wb_decl'] = wbDecl
+            codeBlobsCopy['use_uops'] = 0
+
+            iop = InstObjParams(name, Name, base,
+                                codeBlobsCopy, instFlagsCopy)
+
+            header_output = self.declareTemplate.subst(iop)
+            decoder_output = self.constructTemplate.subst(iop)
+            exec_output = self.fullExecTemplate.subst(iop) + \
+                          self.initiateAccTemplate.subst(iop) + \
+                          self.completeAccTemplate.subst(iop)
+
+            if wbDecl is not None:
+                iop = InstObjParams(name, macroName, base,
+                                    { "wb_decl" : wbDecl,
+                                      "acc_name" : Name,
+                                      "use_uops" : 1 },
+                                    ['IsMacroop'])
+                header_output += self.declareTemplate.subst(iop)
+                decoder_output += self.constructTemplate.subst(iop)
+                exec_output += PanicExecute.subst(iop) + \
+                               PanicInitiateAcc.subst(iop) + \
+                               PanicCompleteAcc.subst(iop)
+
+            return (header_output, decoder_output, exec_output)
 
     def pickPredicate(blobs):
         for val in blobs.values():
index 66a486ecf3b68c68f0443f07d67ac4bb72ccc4dd..ff98c58d219570372a37f536017278d71691cbe9 100644 (file)
@@ -67,7 +67,7 @@ let {{
             self.memFlags = ["ArmISA::TLB::MustBeOne"]
             self.codeBlobs = { "postacc_code" : "" }
 
-        def emitHelper(self, base = 'Memory'):
+        def emitHelper(self, base = 'Memory', wbDecl = None):
 
             global header_output, decoder_output, exec_output
 
@@ -76,7 +76,7 @@ let {{
             (newHeader,
              newDecoder,
              newExec) = self.fillTemplates(self.name, self.Name, codeBlobs,
-                                           self.memFlags, [], base)
+                                           self.memFlags, [], base, wbDecl)
 
             header_output += newHeader
             decoder_output += newDecoder
@@ -137,11 +137,24 @@ let {{
             super(StoreImmInst, self).__init__(*args, **kargs)
             self.offset = self.op + " imm"
 
+            if self.add:
+                self.wbDecl = "MicroAddiUop(machInst, base, base, imm);"
+            else:
+                self.wbDecl = "MicroSubiUop(machInst, base, base, imm);"
+
     class StoreRegInst(StoreInst):
         def __init__(self, *args, **kargs):
             super(StoreRegInst, self).__init__(*args, **kargs)
             self.offset = self.op + " shift_rm_imm(Index, shiftAmt," + \
                                     " shiftType, CondCodes<29:>)"
+            if self.add:
+                 self.wbDecl = '''
+                     MicroAddUop(machInst, base, base, index, shiftAmt, shiftType);
+                 '''
+            else:
+                 self.wbDecl = '''
+                     MicroSubUop(machInst, base, base, index, shiftAmt, shiftType);
+                 '''
 
     class StoreSingle(StoreInst):
         def __init__(self, *args, **kargs):
@@ -186,14 +199,14 @@ let {{
             accCode = accCode % \
                 { "suffix" : buildMemSuffix(self.sign, self.size) }
 
-            if self.writeback:
-                accCode += "Base = Base %s;\n" % self.offset
-
             self.codeBlobs["memacc_code"] = accCode
 
             # Push it out to the output files
             base = buildMemBase(self.basePrefix, self.post, self.writeback)
-            self.emitHelper(base)
+            wbDecl = None
+            if self.writeback:
+                wbDecl = self.wbDecl
+            self.emitHelper(base, wbDecl)
 
     def storeImmClassName(post, add, writeback, size=4, sign=False, user=False):
         return memClassName("STORE_IMM", post, add, writeback, size, sign, user)
@@ -217,7 +230,7 @@ let {{
         return memClassName("STORE_REG", post, add, writeback, size, sign, user)
 
     class StoreReg(StoreRegInst, StoreSingle):
-        decConstBase = 'LoadStoreReg'
+        decConstBase = 'StoreReg'
         basePrefix = 'MemoryReg'
         nameFunc = staticmethod(storeRegClassName)
 
@@ -265,14 +278,14 @@ let {{
                          ((uint64_t)cSwap(Dest2.uw, cpsr.e) << 32);
                 '''
 
-            if self.writeback:
-                accCode += "Base = Base %s;\n" % self.offset
-
             self.codeBlobs["memacc_code"] = accCode
 
             # Push it out to the output files
             base = buildMemBase(self.basePrefix, self.post, self.writeback)
-            self.emitHelper(base)
+            wbDecl = None
+            if self.writeback:
+                wbDecl = self.wbDecl
+            self.emitHelper(base, wbDecl)
 
     def storeDoubleImmClassName(post, add, writeback):
         return memClassName("STORE_IMMD", post, add, writeback, 4, False, False)
@@ -296,7 +309,7 @@ let {{
         return memClassName("STORE_REGD", post, add, writeback, 4, False, False)
 
     class StoreDoubleReg(StoreRegInst, StoreDouble):
-        decConstBase = 'LoadStoreDReg'
+        decConstBase = 'StoreDReg'
         basePrefix = 'MemoryDReg'
         nameFunc = staticmethod(storeDoubleRegClassName)
 
index 5397a2637a4589eb91869ef6f2b468655123fd45..c7ebfcd0696d5158f34b684d12fcebac236cd5e4 100644 (file)
@@ -214,6 +214,31 @@ def template MicroNeonMixLaneDeclare {{
     };
 }};
 
+////////////////////////////////////////////////////////////////////
+//
+// Integer = Integer
+//
+
+def template MicroIntMovDeclare {{
+    class %(class_name)s : public %(base_class)s
+    {
+      public:
+        %(class_name)s(ExtMachInst machInst,
+                       RegIndex _ura, RegIndex _urb);
+        %(BasicExecDeclare)s
+    };
+}};
+def template MicroIntMovConstructor {{
+    %(class_name)s::%(class_name)s(ExtMachInst machInst,
+                                   RegIndex _ura,
+                                   RegIndex _urb)
+        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
+                         _ura, _urb)
+    {
+        %(constructor)s;
+    }
+}};
+
 ////////////////////////////////////////////////////////////////////
 //
 // Integer = Integer op Immediate microops
@@ -225,7 +250,7 @@ def template MicroIntImmDeclare {{
       public:
         %(class_name)s(ExtMachInst machInst,
                        RegIndex _ura, RegIndex _urb,
-                       uint8_t _imm);
+                       int32_t _imm);
         %(BasicExecDeclare)s
     };
 }};
@@ -234,7 +259,7 @@ def template MicroIntImmConstructor {{
     %(class_name)s::%(class_name)s(ExtMachInst machInst,
                                    RegIndex _ura,
                                    RegIndex _urb,
-                                   uint8_t _imm)
+                                   int32_t _imm)
         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                          _ura, _urb, _imm)
     {
@@ -242,6 +267,28 @@ def template MicroIntImmConstructor {{
     }
 }};
 
+def template MicroIntRegDeclare {{
+    class %(class_name)s : public %(base_class)s
+    {
+      public:
+        %(class_name)s(ExtMachInst machInst,
+                       RegIndex _ura, RegIndex _urb, RegIndex _urc,
+                       int32_t _shiftAmt, ArmShiftType _shiftType);
+        %(BasicExecDeclare)s
+    };
+}};
+
+def template MicroIntRegConstructor {{
+    %(class_name)s::%(class_name)s(ExtMachInst machInst,
+                                   RegIndex _ura, RegIndex _urb, RegIndex _urc,
+                                   int32_t _shiftAmt, ArmShiftType _shiftType)
+        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
+                         _ura, _urb, _urc, _shiftAmt, _shiftType)
+    {
+        %(constructor)s;
+    }
+}};
+
 ////////////////////////////////////////////////////////////////////
 //
 // Macro Memory-format instructions
index 686a8b0aac849a2c4cd226563d910a948c0cdef9..1d0e1316c617e34f804fcacc7ed1b3c58ead6206 100644 (file)
 // Authors: Stephen Hines
 
 
+def template PanicExecute {{
+    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+                                  Trace::InstRecord *traceData) const
+    {
+        panic("Execute function executed when it shouldn't be!\n");
+        return NoFault;
+    }
+}};
+
+def template PanicInitiateAcc {{
+    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
+                                      Trace::InstRecord *traceData) const
+    {
+        panic("InitiateAcc function executed when it shouldn't be!\n");
+        return NoFault;
+    }
+}};
+
+def template PanicCompleteAcc {{
+    Fault %(class_name)s::completeAcc(PacketPtr pkt,
+                                      %(CPU_exec_context)s *xc,
+                                      Trace::InstRecord *traceData) const
+    {
+        panic("CompleteAcc function executed when it shouldn't be!\n");
+        return NoFault;
+    }
+}};
+
+
 def template SwapExecute {{
     Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
                                   Trace::InstRecord *traceData) const
@@ -73,7 +102,8 @@ def template SwapExecute {{
             xc->setPredicate(false);
         }
 
-        if (fault == NoFault && machInst.itstateMask != 0) {
+        if (fault == NoFault && machInst.itstateMask != 0 &&
+                (!isMicroop() || isLastMicroop())) {
             xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
         }
 
@@ -109,7 +139,8 @@ def template SwapInitiateAcc {{
             xc->setPredicate(false);
         }
 
-        if (fault == NoFault && machInst.itstateMask != 0) {
+        if (fault == NoFault && machInst.itstateMask != 0 &&
+                (!isMicroop() || isLastMicroop())) {
             xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
         }
 
@@ -172,7 +203,8 @@ def template LoadExecute {{
             xc->setPredicate(false);
         }
 
-        if (fault == NoFault && machInst.itstateMask != 0) {
+        if (fault == NoFault && machInst.itstateMask != 0 &&
+                (!isMicroop() || isLastMicroop())) {
             xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
         }
 
@@ -208,7 +240,8 @@ def template NeonLoadExecute {{
             }
         }
 
-        if (fault == NoFault && machInst.itstateMask != 0) {
+        if (fault == NoFault && machInst.itstateMask != 0 &&
+                (!isMicroop() || isLastMicroop())) {
             xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
         }
 
@@ -245,7 +278,8 @@ def template StoreExecute {{
             xc->setPredicate(false);
         }
 
-        if (fault == NoFault && machInst.itstateMask != 0) {
+        if (fault == NoFault && machInst.itstateMask != 0 &&
+                (!isMicroop() || isLastMicroop())) {
             xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
         }
 
@@ -285,7 +319,8 @@ def template NeonStoreExecute {{
             }
         }
 
-        if (fault == NoFault && machInst.itstateMask != 0) {
+        if (fault == NoFault && machInst.itstateMask != 0 &&
+                (!isMicroop() || isLastMicroop())) {
             xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
         }
 
@@ -328,7 +363,8 @@ def template StoreExExecute {{
             xc->setPredicate(false);
         }
 
-        if (fault == NoFault && machInst.itstateMask != 0) {
+        if (fault == NoFault && machInst.itstateMask != 0 &&
+                (!isMicroop() || isLastMicroop())) {
             xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
         }
 
@@ -365,8 +401,8 @@ def template StoreExInitiateAcc {{
         } else {
             xc->setPredicate(false);
         }
-
-        if (fault == NoFault && machInst.itstateMask != 0) {
+        if (fault == NoFault && machInst.itstateMask != 0 &&
+                (!isMicroop() || isLastMicroop())) {
             xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
         }
 
@@ -404,7 +440,8 @@ def template StoreInitiateAcc {{
             xc->setPredicate(false);
         }
 
-        if (fault == NoFault && machInst.itstateMask != 0) {
+        if (fault == NoFault && machInst.itstateMask != 0 &&
+                (!isMicroop() || isLastMicroop())) {
             xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
         }
 
@@ -443,7 +480,8 @@ def template NeonStoreInitiateAcc {{
             }
         }
 
-        if (fault == NoFault && machInst.itstateMask != 0) {
+        if (fault == NoFault && machInst.itstateMask != 0 &&
+                (!isMicroop() || isLastMicroop())) {
             xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
         }
 
@@ -469,7 +507,8 @@ def template LoadInitiateAcc {{
             }
         } else {
             xc->setPredicate(false);
-            if (fault == NoFault && machInst.itstateMask != 0) {
+            if (fault == NoFault && machInst.itstateMask != 0 &&
+                    (!isMicroop() || isLastMicroop())) {
                 xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
             }
         }
@@ -495,7 +534,8 @@ def template NeonLoadInitiateAcc {{
             if (fault == NoFault) {
                 fault = xc->readBytes(EA, NULL, %(size)d, memAccessFlags);
             }
-        } else if (fault == NoFault && machInst.itstateMask != 0) {
+        } else if (fault == NoFault && machInst.itstateMask != 0 &&
+                (!isMicroop() || isLastMicroop())) {
             xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
         }
 
@@ -791,7 +831,7 @@ def template StoreExImmDeclare {{
     };
 }};
 
-def template LoadStoreDRegDeclare {{
+def template StoreDRegDeclare {{
     /**
      * Static instruction class for "%(mnemonic)s".
      */
@@ -814,7 +854,7 @@ def template LoadStoreDRegDeclare {{
     };
 }};
 
-def template LoadStoreRegDeclare {{
+def template StoreRegDeclare {{
     /**
      * Static instruction class for "%(mnemonic)s".
      */
@@ -836,6 +876,71 @@ def template LoadStoreRegDeclare {{
     };
 }};
 
+def template LoadDRegDeclare {{
+    /**
+     * Static instruction class for "%(mnemonic)s".
+     */
+    class %(class_name)s : public %(base_class)s
+    {
+      public:
+
+        /// Constructor.
+        %(class_name)s(ExtMachInst machInst,
+                uint32_t _dest, uint32_t _dest2,
+                uint32_t _base, bool _add,
+                int32_t _shiftAmt, uint32_t _shiftType,
+                uint32_t _index);
+
+        %(BasicExecDeclare)s
+
+        %(InitiateAccDeclare)s
+
+        %(CompleteAccDeclare)s
+    };
+}};
+
+def template LoadRegDeclare {{
+    /**
+     * Static instruction class for "%(mnemonic)s".
+     */
+    class %(class_name)s : public %(base_class)s
+    {
+      public:
+
+        /// Constructor.
+        %(class_name)s(ExtMachInst machInst,
+                uint32_t _dest, uint32_t _base, bool _add,
+                int32_t _shiftAmt, uint32_t _shiftType,
+                uint32_t _index);
+
+        %(BasicExecDeclare)s
+
+        %(InitiateAccDeclare)s
+
+        %(CompleteAccDeclare)s
+    };
+}};
+
+def template LoadImmDeclare {{
+    /**
+     * Static instruction class for "%(mnemonic)s".
+     */
+    class %(class_name)s : public %(base_class)s
+    {
+      public:
+
+        /// Constructor.
+        %(class_name)s(ExtMachInst machInst,
+                uint32_t _dest, uint32_t _base, bool _add, int32_t _imm);
+
+        %(BasicExecDeclare)s
+
+        %(InitiateAccDeclare)s
+
+        %(CompleteAccDeclare)s
+    };
+}};
+
 def template InitiateAccDeclare {{
     Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
 }};
@@ -851,6 +956,13 @@ def template RfeConstructor {{
                  (IntRegIndex)_base, (AddrMode)_mode, _wb)
     {
         %(constructor)s;
+#if %(use_uops)d
+        assert(numMicroops >= 2);
+        uops = new StaticInstPtr[numMicroops];
+        uops[0] = new %(acc_name)s(machInst, _base, _mode, _wb);
+        uops[1] = new %(wb_decl)s;
+        uops[1]->setLastMicroop();
+#endif
     }
 }};
 
@@ -861,6 +973,13 @@ def template SrsConstructor {{
                  (OperatingMode)_regMode, (AddrMode)_mode, _wb)
     {
         %(constructor)s;
+#if %(use_uops)d
+        assert(numMicroops >= 2);
+        uops = new StaticInstPtr[numMicroops];
+        uops[0] = new %(acc_name)s(machInst, _regMode, _mode, _wb);
+        uops[1] = new %(wb_decl)s;
+        uops[1]->setLastMicroop();
+#endif
     }
 }};
 
@@ -883,6 +1002,13 @@ def template LoadStoreDImmConstructor {{
                  (IntRegIndex)_base, _add, _imm)
     {
         %(constructor)s;
+#if %(use_uops)d
+        assert(numMicroops >= 2);
+        uops = new StaticInstPtr[numMicroops];
+        uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add, _imm);
+        uops[1] = new %(wb_decl)s;
+        uops[1]->setLastMicroop();
+#endif
     }
 }};
 
@@ -896,6 +1022,14 @@ def template StoreExDImmConstructor {{
                  (IntRegIndex)_base, _add, _imm)
     {
         %(constructor)s;
+#if %(use_uops)d
+        assert(numMicroops >= 2);
+        uops = new StaticInstPtr[numMicroops];
+        uops[0] = new %(acc_name)s(machInst, _result, _dest, _dest2,
+                                   _base, _add, _imm);
+        uops[1] = new %(wb_decl)s;
+        uops[1]->setLastMicroop();
+#endif
     }
 }};
 
@@ -906,6 +1040,13 @@ def template LoadStoreImmConstructor {{
                  (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
     {
         %(constructor)s;
+#if %(use_uops)d
+        assert(numMicroops >= 2);
+        uops = new StaticInstPtr[numMicroops];
+        uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
+        uops[1] = new %(wb_decl)s;
+        uops[1]->setLastMicroop();
+#endif
     }
 }};
 
@@ -918,10 +1059,18 @@ def template StoreExImmConstructor {{
                  (IntRegIndex)_base, _add, _imm)
     {
         %(constructor)s;
+#if %(use_uops)d
+        assert(numMicroops >= 2);
+        uops = new StaticInstPtr[numMicroops];
+        uops[0] = new %(acc_name)s(machInst, _result, _dest,
+                                   _base, _add, _imm);
+        uops[1] = new %(wb_decl)s;
+        uops[1]->setLastMicroop();
+#endif
     }
 }};
 
-def template LoadStoreDRegConstructor {{
+def template StoreDRegConstructor {{
     inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
             uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
             int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
@@ -932,10 +1081,18 @@ def template LoadStoreDRegConstructor {{
                  (IntRegIndex)_index)
     {
         %(constructor)s;
+#if %(use_uops)d
+        assert(numMicroops >= 2);
+        uops = new StaticInstPtr[numMicroops];
+        uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
+                                   _shiftAmt, _shiftType, _index);
+        uops[1] = new %(wb_decl)s;
+        uops[1]->setLastMicroop();
+#endif
     }
 }};
 
-def template LoadStoreRegConstructor {{
+def template StoreRegConstructor {{
     inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
             uint32_t _dest, uint32_t _base, bool _add,
             int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
@@ -945,5 +1102,110 @@ def template LoadStoreRegConstructor {{
                  (IntRegIndex)_index)
     {
         %(constructor)s;
+#if %(use_uops)d
+        assert(numMicroops >= 2);
+        uops = new StaticInstPtr[numMicroops];
+        uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
+                                   _shiftAmt, _shiftType, _index);
+        uops[1] = new %(wb_decl)s;
+        uops[1]->setLastMicroop();
+#endif
     }
 }};
+
+def template LoadDRegConstructor {{
+    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
+            uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
+            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
+         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
+                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
+                 (IntRegIndex)_base, _add,
+                 _shiftAmt, (ArmShiftType)_shiftType,
+                 (IntRegIndex)_index)
+    {
+        %(constructor)s;
+#if %(use_uops)d
+        assert(numMicroops >= 2);
+        uops = new StaticInstPtr[numMicroops];
+        if ((_dest == _index) || (_dest2 == _index)) {
+            IntRegIndex wbIndexReg = INTREG_UREG0;
+            uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index);
+            uops[1] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
+                                       _shiftAmt, _shiftType, _index);
+            uops[2] = new %(wb_decl)s;
+            uops[2]->setLastMicroop();
+        } else {
+            IntRegIndex wbIndexReg = index;
+            uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
+                                       _shiftAmt, _shiftType, _index);
+            uops[1] = new %(wb_decl)s;
+            uops[1]->setLastMicroop();
+        }
+#endif
+    }
+}};
+
+def template LoadRegConstructor {{
+    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
+            uint32_t _dest, uint32_t _base, bool _add,
+            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
+         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
+                 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
+                 _shiftAmt, (ArmShiftType)_shiftType,
+                 (IntRegIndex)_index)
+    {
+        %(constructor)s;
+#if %(use_uops)d
+        assert(numMicroops >= 2);
+        uops = new StaticInstPtr[numMicroops];
+        if (_dest == INTREG_PC) {
+            IntRegIndex wbIndexReg = index;
+            uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
+                                       _shiftAmt, _shiftType, _index);
+            uops[1] = new %(wb_decl)s;
+            uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
+            uops[2]->setLastMicroop();
+        } else if(_dest == _index) {
+            IntRegIndex wbIndexReg = INTREG_UREG0;
+            uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index);
+            uops[1] = new %(acc_name)s(machInst, _dest, _base, _add,
+                                      _shiftAmt, _shiftType, _index);
+            uops[2] = new %(wb_decl)s;
+            uops[2]->setLastMicroop();
+        } else {
+            IntRegIndex wbIndexReg = index;
+            uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
+                                      _shiftAmt, _shiftType, _index);
+            uops[1] = new %(wb_decl)s;
+            uops[1]->setLastMicroop();
+
+        }
+#endif
+    }
+}};
+
+def template LoadImmConstructor {{
+    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
+            uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
+         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
+                 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
+    {
+        %(constructor)s;
+#if %(use_uops)d
+        assert(numMicroops >= 2);
+        uops = new StaticInstPtr[numMicroops];
+        if (_dest == INTREG_PC) {
+            uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
+                                   _imm);
+            uops[1] = new %(wb_decl)s;
+            uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
+            uops[2]->setLastMicroop();
+        } else {
+            uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
+            uops[1] = new %(wb_decl)s;
+            uops[1]->setLastMicroop();
+        }
+#endif
+    }
+}};
+
index 1029cfaeecbe116a76bd173b5d692735f51528a6..b5bdbc40e596693b39cd63b8873a19fe3a73c720 100644 (file)
@@ -146,7 +146,8 @@ def template PredOpExecute {{
             xc->setPredicate(false);
         }
 
-        if (fault == NoFault && machInst.itstateMask != 0) {
+        if (fault == NoFault && machInst.itstateMask != 0&&
+                (!isMicroop() || isLastMicroop())) {
             xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
         }