ARM: Reimplement load/store multiple external to the decoder.
authorGabe Black <gblack@eecs.umich.edu>
Wed, 2 Jun 2010 17:58:02 +0000 (12:58 -0500)
committerGabe Black <gblack@eecs.umich.edu>
Wed, 2 Jun 2010 17:58:02 +0000 (12:58 -0500)
--HG--
rename : src/arch/arm/isa/formats/macromem.isa => src/arch/arm/isa/insts/macromem.isa
rename : src/arch/arm/isa/formats/macromem.isa => src/arch/arm/isa/templates/macromem.isa

src/arch/arm/insts/macromem.hh
src/arch/arm/isa/decoder/arm.isa
src/arch/arm/isa/formats/macromem.isa
src/arch/arm/isa/insts/insts.isa
src/arch/arm/isa/insts/macromem.isa [new file with mode: 0644]
src/arch/arm/isa/templates/macromem.isa [new file with mode: 0644]
src/arch/arm/isa/templates/templates.isa

index 6c2db2026d8e98c8c5b30a3f54f52f1bade0bdac..e1ae1dae88ce512defa1acd8df6c335ed0d519c8 100644 (file)
@@ -82,39 +82,17 @@ class MicroIntOp : public PredOp
 class MicroMemOp : public MicroIntOp
 {
   protected:
+    bool up;
     unsigned memAccessFlags;
 
     MicroMemOp(const char *mnem, ExtMachInst machInst, OpClass __opClass,
-               RegIndex _ura, RegIndex _urb, uint8_t _imm)
+               RegIndex _ura, RegIndex _urb, bool _up, uint8_t _imm)
             : MicroIntOp(mnem, machInst, __opClass, _ura, _urb, _imm),
-              memAccessFlags(0)
+              up(_up), memAccessFlags(0)
     {
     }
 };
 
-/**
- * Arm Macro Memory operations like LDM/STM
- */
-class ArmMacroMemoryOp : public PredMacroOp
-{
-  protected:
-    /// Memory request flags.  See mem_req_base.hh.
-    unsigned memAccessFlags;
-
-    uint32_t reglist;
-    uint32_t ones;
-
-    ArmMacroMemoryOp(const char *mnem, ExtMachInst _machInst,
-                     OpClass __opClass)
-            : PredMacroOp(mnem, _machInst, __opClass), memAccessFlags(0),
-              reglist(machInst.regList), ones(0)
-    {
-        ones = number_of_ones(reglist);
-        numMicroops = ones + machInst.puswl.writeback + 1;
-        // Remember that writeback adds a uop
-        microOps = new StaticInstPtr[numMicroops];
-    }
-};
 }
 
 #endif //__ARCH_ARM_INSTS_MACROMEM_HH__
index dcdce6ca2268298a95251acc47e5a7cd4541e3ec..eeab247d799b7d90d034fb7d3453dce2e1668c40 100644 (file)
@@ -304,10 +304,7 @@ format DataOp {
             }
         }
     }
-    0x4: decode PUSWL {
-        // Right now we only handle cases when S (PSRUSER) is not set
-        default: ArmMacroStore::ldmstm({{ }});
-    }
+    0x4: ArmMacroMem::armMacroMem();
     0x5: decode OPCODE_24 {
         // Branch (and Link) Instructions
         0: Branch::b({{ }});
index 704e4b71a3a6899ad110ddcd5e8c669bedbea12f..95b7ccd6a9b1d26d70c35a457771d2441566838e 100644 (file)
@@ -1,7 +1,16 @@
 // -*- mode:c++ -*-
 
-// Copyright (c) 2007-2008 The Florida State University
-// All rights reserved.
+// Copyright (c) 2010 ARM Limited
+// All rights reserved
+//
+// The license below extends only to copyright in the software and shall
+// not be construed as granting a license to any other intellectual
+// property including but not limited to intellectual property relating
+// to a hardware implementation of the functionality of the software
+// licensed hereunder.  You may use the software subject to the license
+// terms below provided that you ensure that this notice is replicated
+// unmodified and in its entirety in all distributions of the software,
+// modified or unmodified, in source code or in binary form.
 //
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 //
-// Authors: Stephen Hines
-//          Gabe Black
+// Authors: Gabe Black
 
-////////////////////////////////////////////////////////////////////
-//
-// Common microop templates
-//
-
-def template MicroConstructor {{
-    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
-                                          RegIndex _ura,
-                                          RegIndex _urb,
-                                          uint8_t _imm)
-        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
-                         _ura, _urb, _imm)
-    {
-        %(constructor)s;
-    }
-}};
-
-////////////////////////////////////////////////////////////////////
-//
-// Load/store microops
-//
-
-def template MicroMemDeclare {{
-    class %(class_name)s : public %(base_class)s
-    {
-      public:
-        %(class_name)s(ExtMachInst machInst,
-                       RegIndex _ura, RegIndex _urb,
-                       uint8_t _imm);
-        %(BasicExecDeclare)s
-        %(InitiateAccDeclare)s
-        %(CompleteAccDeclare)s
-    };
-}};
-
-let {{
-    microLdrUopIop = InstObjParams('ldr_uop', 'MicroLdrUop',
-                                   'MicroMemOp',
-                                   {'memacc_code': 'Ra = Mem;',
-                                    'ea_code': 'EA = Rb + (UP ? imm : -imm);',
-                                    'predicate_test': predicateTest},
-                                   ['IsMicroop'])
-
-    microLdrRetUopCode = '''
-        Ra = Mem;
-        Cpsr = cpsrWriteByInstr(Cpsr, Spsr, 0xF, true);
+def format ArmMacroMem() {{
+    decode_block = '''
+    return new LdmStm(machInst, (IntRegIndex)(uint32_t)RN, !PREPOST, UP,
+                      PSRUSER, WRITEBACK, LOADOP, machInst.regList);
     '''
-    microLdrRetUopIop = InstObjParams('ldr_ret_uop', 'MicroLdrRetUop',
-                                      'MicroMemOp',
-                                      {'memacc_code': microLdrRetUopCode,
-                                       'ea_code':
-                                          'EA = Rb + (UP ? imm : -imm);',
-                                       'predicate_test': predicateTest},
-                                      ['IsMicroop'])
-
-    microStrUopIop = InstObjParams('str_uop', 'MicroStrUop',
-                                   'MicroMemOp',
-                                   {'memacc_code': 'Mem = Ra;',
-                                    'ea_code': 'EA = Rb + (UP ? imm : -imm);',
-                                    'predicate_test': predicateTest},
-                                   ['IsMicroop'])
-
-    header_output = MicroMemDeclare.subst(microLdrUopIop) + \
-                    MicroMemDeclare.subst(microLdrRetUopIop) + \
-                    MicroMemDeclare.subst(microStrUopIop)
-    decoder_output = MicroConstructor.subst(microLdrUopIop) + \
-                     MicroConstructor.subst(microLdrRetUopIop) + \
-                     MicroConstructor.subst(microStrUopIop)
-    exec_output = LoadExecute.subst(microLdrUopIop) + \
-                  LoadExecute.subst(microLdrRetUopIop) + \
-                  StoreExecute.subst(microStrUopIop) + \
-                  LoadInitiateAcc.subst(microLdrUopIop) + \
-                  LoadInitiateAcc.subst(microLdrRetUopIop) + \
-                  StoreInitiateAcc.subst(microStrUopIop) + \
-                  LoadCompleteAcc.subst(microLdrUopIop) + \
-                  LoadCompleteAcc.subst(microLdrRetUopIop) + \
-                  StoreCompleteAcc.subst(microStrUopIop)
-}};
-
-////////////////////////////////////////////////////////////////////
-//
-// Integer = Integer op Immediate microops
-//
-
-def template MicroIntDeclare {{
-    class %(class_name)s : public %(base_class)s
-    {
-      public:
-        %(class_name)s(ExtMachInst machInst,
-                       RegIndex _ura, RegIndex _urb,
-                       uint8_t _imm);
-        %(BasicExecDeclare)s
-    };
-}};
-
-let {{
-    microAddiUopIop = InstObjParams('addi_uop', 'MicroAddiUop',
-                                    'MicroIntOp',
-                                    {'code': 'Ra = Rb + imm;',
-                                     'predicate_test': predicateTest},
-                                    ['IsMicroop'])
-
-    microSubiUopIop = InstObjParams('subi_uop', 'MicroSubiUop',
-                                    'MicroIntOp',
-                                    {'code': 'Ra = Rb - imm;',
-                                     'predicate_test': predicateTest},
-                                    ['IsMicroop'])
-
-    header_output = MicroIntDeclare.subst(microAddiUopIop) + \
-                    MicroIntDeclare.subst(microSubiUopIop)
-    decoder_output = MicroConstructor.subst(microAddiUopIop) + \
-                     MicroConstructor.subst(microSubiUopIop)
-    exec_output = PredOpExecute.subst(microAddiUopIop) + \
-                  PredOpExecute.subst(microSubiUopIop)
-}};
-
-////////////////////////////////////////////////////////////////////
-//
-// Macro Memory-format instructions
-//
-
-def template MacroStoreDeclare {{
-/**
- * Static instructions class for a store multiple instruction
- */
-class %(class_name)s : public %(base_class)s
-{
-    public:
-        // Constructor
-        %(class_name)s(ExtMachInst machInst);
-        %(BasicExecDeclare)s
-};
-}};
-
-def template MacroStoreConstructor {{
-inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
-    : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
-{
-    %(constructor)s;
-    uint32_t regs = reglist;
-    uint32_t addr = 0;
-    bool up = machInst.puswl.up;
-
-    if (!up)
-        addr = (ones << 2) - 4;
-
-    if (machInst.puswl.prepost)
-        addr += 4;
-
-    // Add 0 to Rn and stick it in ureg0.
-    // This is equivalent to a move.
-    microOps[0] = new MicroAddiUop(machInst, INTREG_UREG0, RN, 0);
-
-    unsigned reg = 0;
-    bool force_user = machInst.puswl.psruser & !OPCODE_15;
-    bool exception_ret = machInst.puswl.psruser & OPCODE_15;
-
-    for (int i = 1; i < ones + 1; i++) {
-        // Find the next register.
-        while (!bits(regs, reg))
-            reg++;
-        replaceBits(regs, reg, 0);
-
-        unsigned regIdx = reg;
-        if (force_user) {
-            regIdx = intRegForceUser(regIdx);
-        }
-
-        if (machInst.puswl.loadOp) {
-            if (reg == INTREG_PC && exception_ret) {
-                // This must be the exception return form of ldm.
-                microOps[i] =
-                    new MicroLdrRetUop(machInst, regIdx, INTREG_UREG0, addr);
-            } else {
-                microOps[i] =
-                    new MicroLdrUop(machInst, regIdx, INTREG_UREG0, addr);
-            }
-        } else {
-            microOps[i] =
-                new MicroStrUop(machInst, regIdx, INTREG_UREG0, addr);
-        }
-
-        if (up)
-            addr += 4;
-        else
-            addr -= 4;
-    }
-
-    StaticInstPtr &lastUop = microOps[numMicroops - 1];
-    if (machInst.puswl.writeback) {
-        if (up) {
-            lastUop = new MicroAddiUop(machInst, RN, RN, ones * 4);
-        } else {
-            lastUop = new MicroSubiUop(machInst, RN, RN, ones * 4);
-        }
-    }
-    lastUop->setLastMicroop();
-}
-
-}};
-
-def template MacroStoreExecute {{
-Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
-{
-    Fault fault = NoFault;
-
-    %(fp_enable_check)s;
-    %(op_decl)s;
-    %(op_rd)s;
-    %(code)s;
-    if (fault == NoFault)
-    {
-        %(op_wb)s;
-    }
-
-    return fault;
-}
-}};
-
-def format ArmMacroStore(code, mem_flags = [], inst_flag = [], *opt_flags) {{
-    iop = InstObjParams(name, Name, 'ArmMacroMemoryOp', code, opt_flags)
-    header_output = MacroStoreDeclare.subst(iop)
-    decoder_output = MacroStoreConstructor.subst(iop)
-    decode_block = BasicDecode.subst(iop)
-    exec_output = MacroStoreExecute.subst(iop)
 }};
index 404a63328d935d98eca92e0d2d8c74e620c6765c..9165b5df36d751b545afe26ba21867ef7ae53173 100644 (file)
@@ -48,3 +48,6 @@
 
 //Stores of a single item
 ##include "str.isa"
+
+//Load/store multiple
+##include "macromem.isa"
diff --git a/src/arch/arm/isa/insts/macromem.isa b/src/arch/arm/isa/insts/macromem.isa
new file mode 100644 (file)
index 0000000..b6d6b6b
--- /dev/null
@@ -0,0 +1,131 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2010 ARM Limited
+// All rights reserved
+//
+// The license below extends only to copyright in the software and shall
+// not be construed as granting a license to any other intellectual
+// property including but not limited to intellectual property relating
+// to a hardware implementation of the functionality of the software
+// licensed hereunder.  You may use the software subject to the license
+// terms below provided that you ensure that this notice is replicated
+// unmodified and in its entirety in all distributions of the software,
+// modified or unmodified, in source code or in binary form.
+//
+// Copyright (c) 2007-2008 The Florida State University
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met: redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer;
+// redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution;
+// neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: Stephen Hines
+//          Gabe Black
+
+////////////////////////////////////////////////////////////////////
+//
+// Load/store microops
+//
+
+let {{
+    predicateTest = 'testPredicate(CondCodes, condCode)'
+}};
+
+let {{
+    microLdrUopIop = InstObjParams('ldr_uop', 'MicroLdrUop',
+                                   'MicroMemOp',
+                                   {'memacc_code': 'Ra = Mem;',
+                                    'ea_code': 'EA = Rb + (up ? imm : -imm);',
+                                    'predicate_test': predicateTest},
+                                   ['IsMicroop'])
+
+    microLdrRetUopCode = '''
+        Ra = Mem;
+        uint32_t newCpsr =
+            cpsrWriteByInstr(Cpsr | CondCodes, Spsr, 0xF, true);
+        Cpsr = ~CondCodesMask & newCpsr;
+        CondCodes = CondCodesMask & newCpsr;
+    '''
+    microLdrRetUopIop = InstObjParams('ldr_ret_uop', 'MicroLdrRetUop',
+                                      'MicroMemOp',
+                                      {'memacc_code': microLdrRetUopCode,
+                                       'ea_code':
+                                          'EA = Rb + (up ? imm : -imm);',
+                                       'predicate_test': predicateTest},
+                                      ['IsMicroop'])
+
+    microStrUopIop = InstObjParams('str_uop', 'MicroStrUop',
+                                   'MicroMemOp',
+                                   {'memacc_code': 'Mem = Ra;',
+                                    'ea_code': 'EA = Rb + (up ? imm : -imm);',
+                                    'predicate_test': predicateTest},
+                                   ['IsMicroop'])
+
+    header_output = MicroMemDeclare.subst(microLdrUopIop) + \
+                    MicroMemDeclare.subst(microLdrRetUopIop) + \
+                    MicroMemDeclare.subst(microStrUopIop)
+    decoder_output = MicroMemConstructor.subst(microLdrUopIop) + \
+                     MicroMemConstructor.subst(microLdrRetUopIop) + \
+                     MicroMemConstructor.subst(microStrUopIop)
+    exec_output = LoadExecute.subst(microLdrUopIop) + \
+                  LoadExecute.subst(microLdrRetUopIop) + \
+                  StoreExecute.subst(microStrUopIop) + \
+                  LoadInitiateAcc.subst(microLdrUopIop) + \
+                  LoadInitiateAcc.subst(microLdrRetUopIop) + \
+                  StoreInitiateAcc.subst(microStrUopIop) + \
+                  LoadCompleteAcc.subst(microLdrUopIop) + \
+                  LoadCompleteAcc.subst(microLdrRetUopIop) + \
+                  StoreCompleteAcc.subst(microStrUopIop)
+}};
+
+////////////////////////////////////////////////////////////////////
+//
+// Integer = Integer op Immediate microops
+//
+
+let {{
+    microAddiUopIop = InstObjParams('addi_uop', 'MicroAddiUop',
+                                    'MicroIntOp',
+                                    {'code': 'Ra = Rb + imm;',
+                                     'predicate_test': predicateTest},
+                                    ['IsMicroop'])
+
+    microSubiUopIop = InstObjParams('subi_uop', 'MicroSubiUop',
+                                    'MicroIntOp',
+                                    {'code': 'Ra = Rb - imm;',
+                                     'predicate_test': predicateTest},
+                                    ['IsMicroop'])
+
+    header_output = MicroIntDeclare.subst(microAddiUopIop) + \
+                    MicroIntDeclare.subst(microSubiUopIop)
+    decoder_output = MicroIntConstructor.subst(microAddiUopIop) + \
+                     MicroIntConstructor.subst(microSubiUopIop)
+    exec_output = PredOpExecute.subst(microAddiUopIop) + \
+                  PredOpExecute.subst(microSubiUopIop)
+}};
+
+let {{
+    iop = InstObjParams("ldmstm", "LdmStm", 'PredMacroOp', "", [])
+    header_output = MacroMemDeclare.subst(iop)
+    decoder_output = MacroMemConstructor.subst(iop)
+    exec_output = MacroMemExecute.subst(iop)
+}};
diff --git a/src/arch/arm/isa/templates/macromem.isa b/src/arch/arm/isa/templates/macromem.isa
new file mode 100644 (file)
index 0000000..c474da0
--- /dev/null
@@ -0,0 +1,212 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2010 ARM Limited
+// All rights reserved
+//
+// The license below extends only to copyright in the software and shall
+// not be construed as granting a license to any other intellectual
+// property including but not limited to intellectual property relating
+// to a hardware implementation of the functionality of the software
+// licensed hereunder.  You may use the software subject to the license
+// terms below provided that you ensure that this notice is replicated
+// unmodified and in its entirety in all distributions of the software,
+// modified or unmodified, in source code or in binary form.
+//
+// Copyright (c) 2007-2008 The Florida State University
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met: redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer;
+// redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution;
+// neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: Stephen Hines
+//          Gabe Black
+
+////////////////////////////////////////////////////////////////////
+//
+// Load/store microops
+//
+
+def template MicroMemDeclare {{
+    class %(class_name)s : public %(base_class)s
+    {
+      public:
+        %(class_name)s(ExtMachInst machInst,
+                       RegIndex _ura, RegIndex _urb, bool _up,
+                       uint8_t _imm);
+        %(BasicExecDeclare)s
+        %(InitiateAccDeclare)s
+        %(CompleteAccDeclare)s
+    };
+}};
+
+def template MicroMemConstructor {{
+    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
+                                          RegIndex _ura,
+                                          RegIndex _urb,
+                                          bool _up,
+                                          uint8_t _imm)
+        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
+                         _ura, _urb, _up, _imm)
+    {
+        %(constructor)s;
+    }
+}};
+
+////////////////////////////////////////////////////////////////////
+//
+// Integer = Integer op Immediate microops
+//
+
+def template MicroIntDeclare {{
+    class %(class_name)s : public %(base_class)s
+    {
+      public:
+        %(class_name)s(ExtMachInst machInst,
+                       RegIndex _ura, RegIndex _urb,
+                       uint8_t _imm);
+        %(BasicExecDeclare)s
+    };
+}};
+
+def template MicroIntConstructor {{
+    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
+                                          RegIndex _ura,
+                                          RegIndex _urb,
+                                          uint8_t _imm)
+        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
+                         _ura, _urb, _imm)
+    {
+        %(constructor)s;
+    }
+}};
+
+////////////////////////////////////////////////////////////////////
+//
+// Macro Memory-format instructions
+//
+
+def template MacroMemDeclare {{
+/**
+ * Static instructions class for a store multiple instruction
+ */
+class %(class_name)s : public %(base_class)s
+{
+    public:
+        // Constructor
+        %(class_name)s(ExtMachInst machInst, IntRegIndex rn,
+                bool index, bool up, bool user, bool writeback, bool load,
+                uint32_t reglist);
+        %(BasicExecDeclare)s
+};
+}};
+
+def template MacroMemConstructor {{
+inline %(class_name)s::%(class_name)s(ExtMachInst machInst, IntRegIndex rn,
+        bool index, bool up, bool user, bool writeback, bool load,
+        uint32_t reglist)
+    : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
+{
+    %(constructor)s;
+    uint32_t regs = reglist;
+    uint32_t ones = number_of_ones(reglist);
+    // Remember that writeback adds a uop
+    numMicroops = ones + (writeback ? 1 : 0) + 1;
+    microOps = new StaticInstPtr[numMicroops];
+    uint32_t addr = 0;
+
+    if (!up)
+        addr = (ones << 2) - 4;
+
+    if (!index)
+        addr += 4;
+
+    // Add 0 to Rn and stick it in ureg0.
+    // This is equivalent to a move.
+    microOps[0] = new MicroAddiUop(machInst, INTREG_UREG0, rn, 0);
+
+    unsigned reg = 0;
+    bool force_user = user & !bits(reglist, 15);
+    bool exception_ret = user & bits(reglist, 15);
+
+    for (int i = 1; i < ones + 1; i++) {
+        // Find the next register.
+        while (!bits(regs, reg))
+            reg++;
+        replaceBits(regs, reg, 0);
+
+        unsigned regIdx = reg;
+        if (force_user) {
+            regIdx = intRegForceUser(regIdx);
+        }
+
+        if (load) {
+            if (reg == INTREG_PC && exception_ret) {
+                // This must be the exception return form of ldm.
+                microOps[i] =
+                    new MicroLdrRetUop(machInst, regIdx,
+                                       INTREG_UREG0, up, addr);
+            } else {
+                microOps[i] =
+                    new MicroLdrUop(machInst, regIdx, INTREG_UREG0, up, addr);
+            }
+        } else {
+            microOps[i] =
+                new MicroStrUop(machInst, regIdx, INTREG_UREG0, up, addr);
+        }
+
+        if (up)
+            addr += 4;
+        else
+            addr -= 4;
+    }
+
+    StaticInstPtr &lastUop = microOps[numMicroops - 1];
+    if (writeback) {
+        if (up) {
+            lastUop = new MicroAddiUop(machInst, rn, rn, ones * 4);
+        } else {
+            lastUop = new MicroSubiUop(machInst, rn, rn, ones * 4);
+        }
+    }
+    lastUop->setLastMicroop();
+}
+
+}};
+
+def template MacroMemExecute {{
+Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
+{
+    Fault fault = NoFault;
+
+    %(fp_enable_check)s;
+    %(op_decl)s;
+    %(op_rd)s;
+    %(code)s;
+    if (fault == NoFault)
+    {
+        %(op_wb)s;
+    }
+
+    return fault;
+}
+}};
index f10e8a07be6ada2d5f7f8ae3fcf2373ba9d92b70..821e0f82eb6cfab42aa47556f956db0eb52ec002 100644 (file)
@@ -42,3 +42,6 @@
 
 //Templates for memory instructions
 ##include "mem.isa"
+
+//Templates for microcoded memory instructions
+##include "macromem.isa"