diff options
-rw-r--r-- | src/arch/arm/SConscript | 1 | ||||
-rw-r--r-- | src/arch/arm/insts/macromem.cc | 121 | ||||
-rw-r--r-- | src/arch/arm/insts/macromem.hh | 8 | ||||
-rw-r--r-- | src/arch/arm/isa/insts/macromem.isa | 2 | ||||
-rw-r--r-- | src/arch/arm/isa/templates/macromem.isa | 85 |
5 files changed, 143 insertions, 74 deletions
diff --git a/src/arch/arm/SConscript b/src/arch/arm/SConscript index c1a08aa49..cb54612f0 100644 --- a/src/arch/arm/SConscript +++ b/src/arch/arm/SConscript @@ -49,6 +49,7 @@ if env['TARGET_ISA'] == 'arm': Dir('isa/formats') Source('faults.cc') Source('insts/branch.cc') + Source('insts/macromem.cc') Source('insts/mem.cc') Source('insts/pred_inst.cc') Source('insts/static_inst.cc') diff --git a/src/arch/arm/insts/macromem.cc b/src/arch/arm/insts/macromem.cc new file mode 100644 index 000000000..bb69f0991 --- /dev/null +++ b/src/arch/arm/insts/macromem.cc @@ -0,0 +1,121 @@ +/* + * 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 + */ + +#include "arch/arm/insts/macromem.hh" +#include "arch/arm/decoder.hh" + +using namespace ArmISAInst; + +namespace ArmISA +{ + +MacroMemOp::MacroMemOp(const char *mnem, ExtMachInst machInst, + OpClass __opClass, IntRegIndex rn, + bool index, bool up, bool user, bool writeback, + bool load, uint32_t reglist) : + PredMacroOp(mnem, machInst, __opClass) +{ + 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(); +} + +} diff --git a/src/arch/arm/insts/macromem.hh b/src/arch/arm/insts/macromem.hh index e1ae1dae8..8cad32710 100644 --- a/src/arch/arm/insts/macromem.hh +++ b/src/arch/arm/insts/macromem.hh @@ -93,6 +93,14 @@ class MicroMemOp : public MicroIntOp } }; +class MacroMemOp : public PredMacroOp +{ + protected: + MacroMemOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, + IntRegIndex rn, bool index, bool up, bool user, + bool writeback, bool load, uint32_t reglist); +}; + } #endif //__ARCH_ARM_INSTS_MACROMEM_HH__ diff --git a/src/arch/arm/isa/insts/macromem.isa b/src/arch/arm/isa/insts/macromem.isa index 3e466c70d..0f07a87c4 100644 --- a/src/arch/arm/isa/insts/macromem.isa +++ b/src/arch/arm/isa/insts/macromem.isa @@ -124,7 +124,7 @@ let {{ }}; let {{ - iop = InstObjParams("ldmstm", "LdmStm", 'PredMacroOp', "", []) + iop = InstObjParams("ldmstm", "LdmStm", 'MacroMemOp', "", []) header_output = MacroMemDeclare.subst(iop) decoder_output = MacroMemConstructor.subst(iop) }}; diff --git a/src/arch/arm/isa/templates/macromem.isa b/src/arch/arm/isa/templates/macromem.isa index c626bdec8..de5279392 100644 --- a/src/arch/arm/isa/templates/macromem.isa +++ b/src/arch/arm/isa/templates/macromem.isa @@ -60,11 +60,11 @@ def template MicroMemDeclare {{ }}; def template MicroMemConstructor {{ - inline %(class_name)s::%(class_name)s(ExtMachInst machInst, - RegIndex _ura, - RegIndex _urb, - bool _up, - uint8_t _imm) + %(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) { @@ -89,10 +89,10 @@ def template MicroIntDeclare {{ }}; def template MicroIntConstructor {{ - inline %(class_name)s::%(class_name)s(ExtMachInst machInst, - RegIndex _ura, - RegIndex _urb, - uint8_t _imm) + %(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) { @@ -121,74 +121,13 @@ class %(class_name)s : public %(base_class)s }}; def template MacroMemConstructor {{ -inline %(class_name)s::%(class_name)s(ExtMachInst machInst, IntRegIndex rn, +%(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) + : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, rn, + index, up, user, writeback, load, reglist) { %(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(); } }}; |