summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2010-06-02 12:58:02 -0500
committerGabe Black <gblack@eecs.umich.edu>2010-06-02 12:58:02 -0500
commit51bde086d578e09e1058b17c40fae99404a325dc (patch)
tree52266766aba471241f4018b56bc69659e3547a6d
parent93a371481697f3f68f8189da6a7b14934fa93723 (diff)
downloadgem5-51bde086d578e09e1058b17c40fae99404a325dc.tar.xz
ARM: Reimplement load/store multiple external to the decoder.
--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
-rw-r--r--src/arch/arm/insts/macromem.hh28
-rw-r--r--src/arch/arm/isa/decoder/arm.isa5
-rw-r--r--src/arch/arm/isa/formats/macromem.isa244
-rw-r--r--src/arch/arm/isa/insts/insts.isa3
-rw-r--r--src/arch/arm/isa/insts/macromem.isa131
-rw-r--r--src/arch/arm/isa/templates/macromem.isa212
-rw-r--r--src/arch/arm/isa/templates/templates.isa3
7 files changed, 369 insertions, 257 deletions
diff --git a/src/arch/arm/insts/macromem.hh b/src/arch/arm/insts/macromem.hh
index 6c2db2026..e1ae1dae8 100644
--- a/src/arch/arm/insts/macromem.hh
+++ b/src/arch/arm/insts/macromem.hh
@@ -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__
diff --git a/src/arch/arm/isa/decoder/arm.isa b/src/arch/arm/isa/decoder/arm.isa
index dcdce6ca2..eeab247d7 100644
--- a/src/arch/arm/isa/decoder/arm.isa
+++ b/src/arch/arm/isa/decoder/arm.isa
@@ -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({{ }});
diff --git a/src/arch/arm/isa/formats/macromem.isa b/src/arch/arm/isa/formats/macromem.isa
index 704e4b71a..95b7ccd6a 100644
--- a/src/arch/arm/isa/formats/macromem.isa
+++ b/src/arch/arm/isa/formats/macromem.isa
@@ -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
@@ -26,232 +35,11 @@
// (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)
}};
diff --git a/src/arch/arm/isa/insts/insts.isa b/src/arch/arm/isa/insts/insts.isa
index 404a63328..9165b5df3 100644
--- a/src/arch/arm/isa/insts/insts.isa
+++ b/src/arch/arm/isa/insts/insts.isa
@@ -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
index 000000000..b6d6b6b5d
--- /dev/null
+++ b/src/arch/arm/isa/insts/macromem.isa
@@ -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
index 000000000..c474da0c8
--- /dev/null
+++ b/src/arch/arm/isa/templates/macromem.isa
@@ -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;
+}
+}};
diff --git a/src/arch/arm/isa/templates/templates.isa b/src/arch/arm/isa/templates/templates.isa
index f10e8a07b..821e0f82e 100644
--- a/src/arch/arm/isa/templates/templates.isa
+++ b/src/arch/arm/isa/templates/templates.isa
@@ -42,3 +42,6 @@
//Templates for memory instructions
##include "mem.isa"
+
+//Templates for microcoded memory instructions
+##include "macromem.isa"