diff options
Diffstat (limited to 'src/arch/arm/insts')
-rw-r--r-- | src/arch/arm/insts/macromem.cc | 121 | ||||
-rw-r--r-- | src/arch/arm/insts/macromem.hh | 8 |
2 files changed, 129 insertions, 0 deletions
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__ |