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"