macromem.cc revision 7175
17170Sgblack@eecs.umich.edu/*
27170Sgblack@eecs.umich.edu * Copyright (c) 2010 ARM Limited
37170Sgblack@eecs.umich.edu * All rights reserved
47170Sgblack@eecs.umich.edu *
57170Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall
67170Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual
77170Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating
87170Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software
97170Sgblack@eecs.umich.edu * licensed hereunder.  You may use the software subject to the license
107170Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated
117170Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software,
127170Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form.
137170Sgblack@eecs.umich.edu *
147170Sgblack@eecs.umich.edu * Copyright (c) 2007-2008 The Florida State University
157170Sgblack@eecs.umich.edu * All rights reserved.
167170Sgblack@eecs.umich.edu *
177170Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
187170Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
197170Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
207170Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
217170Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
227170Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
237170Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
247170Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
257170Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
267170Sgblack@eecs.umich.edu * this software without specific prior written permission.
277170Sgblack@eecs.umich.edu *
287170Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
297170Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
307170Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
317170Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
327170Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
337170Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
347170Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
357170Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
367170Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
377170Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
387170Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
397170Sgblack@eecs.umich.edu *
407170Sgblack@eecs.umich.edu * Authors: Stephen Hines
417170Sgblack@eecs.umich.edu */
427170Sgblack@eecs.umich.edu
437170Sgblack@eecs.umich.edu#include "arch/arm/insts/macromem.hh"
447170Sgblack@eecs.umich.edu#include "arch/arm/decoder.hh"
457170Sgblack@eecs.umich.edu
467170Sgblack@eecs.umich.eduusing namespace ArmISAInst;
477170Sgblack@eecs.umich.edu
487170Sgblack@eecs.umich.edunamespace ArmISA
497170Sgblack@eecs.umich.edu{
507170Sgblack@eecs.umich.edu
517170Sgblack@eecs.umich.eduMacroMemOp::MacroMemOp(const char *mnem, ExtMachInst machInst,
527170Sgblack@eecs.umich.edu                       OpClass __opClass, IntRegIndex rn,
537170Sgblack@eecs.umich.edu                       bool index, bool up, bool user, bool writeback,
547170Sgblack@eecs.umich.edu                       bool load, uint32_t reglist) :
557170Sgblack@eecs.umich.edu    PredMacroOp(mnem, machInst, __opClass)
567170Sgblack@eecs.umich.edu{
577170Sgblack@eecs.umich.edu    uint32_t regs = reglist;
587170Sgblack@eecs.umich.edu    uint32_t ones = number_of_ones(reglist);
597170Sgblack@eecs.umich.edu    // Remember that writeback adds a uop
607170Sgblack@eecs.umich.edu    numMicroops = ones + (writeback ? 1 : 0) + 1;
617170Sgblack@eecs.umich.edu    microOps = new StaticInstPtr[numMicroops];
627170Sgblack@eecs.umich.edu    uint32_t addr = 0;
637170Sgblack@eecs.umich.edu
647170Sgblack@eecs.umich.edu    if (!up)
657170Sgblack@eecs.umich.edu        addr = (ones << 2) - 4;
667170Sgblack@eecs.umich.edu
677170Sgblack@eecs.umich.edu    if (!index)
687170Sgblack@eecs.umich.edu        addr += 4;
697170Sgblack@eecs.umich.edu
707170Sgblack@eecs.umich.edu    // Add 0 to Rn and stick it in ureg0.
717170Sgblack@eecs.umich.edu    // This is equivalent to a move.
727170Sgblack@eecs.umich.edu    microOps[0] = new MicroAddiUop(machInst, INTREG_UREG0, rn, 0);
737170Sgblack@eecs.umich.edu
747170Sgblack@eecs.umich.edu    unsigned reg = 0;
757170Sgblack@eecs.umich.edu    bool force_user = user & !bits(reglist, 15);
767170Sgblack@eecs.umich.edu    bool exception_ret = user & bits(reglist, 15);
777170Sgblack@eecs.umich.edu
787170Sgblack@eecs.umich.edu    for (int i = 1; i < ones + 1; i++) {
797170Sgblack@eecs.umich.edu        // Find the next register.
807170Sgblack@eecs.umich.edu        while (!bits(regs, reg))
817170Sgblack@eecs.umich.edu            reg++;
827170Sgblack@eecs.umich.edu        replaceBits(regs, reg, 0);
837170Sgblack@eecs.umich.edu
847170Sgblack@eecs.umich.edu        unsigned regIdx = reg;
857170Sgblack@eecs.umich.edu        if (force_user) {
867170Sgblack@eecs.umich.edu            regIdx = intRegForceUser(regIdx);
877170Sgblack@eecs.umich.edu        }
887170Sgblack@eecs.umich.edu
897170Sgblack@eecs.umich.edu        if (load) {
907170Sgblack@eecs.umich.edu            if (reg == INTREG_PC && exception_ret) {
917170Sgblack@eecs.umich.edu                // This must be the exception return form of ldm.
927170Sgblack@eecs.umich.edu                microOps[i] =
937170Sgblack@eecs.umich.edu                    new MicroLdrRetUop(machInst, regIdx,
947170Sgblack@eecs.umich.edu                                       INTREG_UREG0, up, addr);
957170Sgblack@eecs.umich.edu            } else {
967170Sgblack@eecs.umich.edu                microOps[i] =
977170Sgblack@eecs.umich.edu                    new MicroLdrUop(machInst, regIdx, INTREG_UREG0, up, addr);
987170Sgblack@eecs.umich.edu            }
997170Sgblack@eecs.umich.edu        } else {
1007170Sgblack@eecs.umich.edu            microOps[i] =
1017170Sgblack@eecs.umich.edu                new MicroStrUop(machInst, regIdx, INTREG_UREG0, up, addr);
1027170Sgblack@eecs.umich.edu        }
1037170Sgblack@eecs.umich.edu
1047170Sgblack@eecs.umich.edu        if (up)
1057170Sgblack@eecs.umich.edu            addr += 4;
1067170Sgblack@eecs.umich.edu        else
1077170Sgblack@eecs.umich.edu            addr -= 4;
1087170Sgblack@eecs.umich.edu    }
1097170Sgblack@eecs.umich.edu
1107170Sgblack@eecs.umich.edu    StaticInstPtr &lastUop = microOps[numMicroops - 1];
1117170Sgblack@eecs.umich.edu    if (writeback) {
1127170Sgblack@eecs.umich.edu        if (up) {
1137170Sgblack@eecs.umich.edu            lastUop = new MicroAddiUop(machInst, rn, rn, ones * 4);
1147170Sgblack@eecs.umich.edu        } else {
1157170Sgblack@eecs.umich.edu            lastUop = new MicroSubiUop(machInst, rn, rn, ones * 4);
1167170Sgblack@eecs.umich.edu        }
1177170Sgblack@eecs.umich.edu    }
1187170Sgblack@eecs.umich.edu    lastUop->setLastMicroop();
1197170Sgblack@eecs.umich.edu}
1207170Sgblack@eecs.umich.edu
1217175Sgblack@eecs.umich.eduMacroVFPMemOp::MacroVFPMemOp(const char *mnem, ExtMachInst machInst,
1227175Sgblack@eecs.umich.edu                             OpClass __opClass, IntRegIndex rn,
1237175Sgblack@eecs.umich.edu                             RegIndex vd, bool single, bool up,
1247175Sgblack@eecs.umich.edu                             bool writeback, bool load, uint32_t offset) :
1257175Sgblack@eecs.umich.edu    PredMacroOp(mnem, machInst, __opClass)
1267175Sgblack@eecs.umich.edu{
1277175Sgblack@eecs.umich.edu    const int maxMicroops = 17;
1287175Sgblack@eecs.umich.edu    microOps = new StaticInstPtr[maxMicroops];
1297175Sgblack@eecs.umich.edu    int i = 0;
1307175Sgblack@eecs.umich.edu
1317175Sgblack@eecs.umich.edu    // The lowest order bit selects fldmx (set) or fldmd (clear). These seem
1327175Sgblack@eecs.umich.edu    // to be functionally identical except that fldmx is deprecated. For now
1337175Sgblack@eecs.umich.edu    // we'll assume they're otherwise interchangable.
1347175Sgblack@eecs.umich.edu    int count = (single ? offset : (offset / 2));
1357175Sgblack@eecs.umich.edu    if (count == 0 || count > NumFloatArchRegs)
1367175Sgblack@eecs.umich.edu        warn_once("Bad offset field for VFP load/store multiple.\n");
1377175Sgblack@eecs.umich.edu    if (count == 0) {
1387175Sgblack@eecs.umich.edu        // Force there to be at least one microop so the macroop makes sense.
1397175Sgblack@eecs.umich.edu        writeback = true;
1407175Sgblack@eecs.umich.edu    }
1417175Sgblack@eecs.umich.edu    if (count > NumFloatArchRegs)
1427175Sgblack@eecs.umich.edu        count = NumFloatArchRegs;
1437175Sgblack@eecs.umich.edu
1447175Sgblack@eecs.umich.edu    uint32_t addr = 0;
1457175Sgblack@eecs.umich.edu
1467175Sgblack@eecs.umich.edu    if (up)
1477175Sgblack@eecs.umich.edu        addr = -4 * offset;
1487175Sgblack@eecs.umich.edu
1497175Sgblack@eecs.umich.edu    for (int j = 0; j < count; j++) {
1507175Sgblack@eecs.umich.edu        if (load) {
1517175Sgblack@eecs.umich.edu            microOps[i++] = new MicroLdrFpUop(machInst, vd++, rn,
1527175Sgblack@eecs.umich.edu                                              true, addr);
1537175Sgblack@eecs.umich.edu            if (!single)
1547175Sgblack@eecs.umich.edu                microOps[i++] = new MicroLdrFpUop(machInst, vd++, rn,
1557175Sgblack@eecs.umich.edu                                                  true, addr + 4);
1567175Sgblack@eecs.umich.edu        } else {
1577175Sgblack@eecs.umich.edu            microOps[i++] = new MicroStrFpUop(machInst, vd++, rn,
1587175Sgblack@eecs.umich.edu                                              true, addr);
1597175Sgblack@eecs.umich.edu            if (!single)
1607175Sgblack@eecs.umich.edu                microOps[i++] = new MicroStrFpUop(machInst, vd++, rn,
1617175Sgblack@eecs.umich.edu                                                  true, addr + 4);
1627175Sgblack@eecs.umich.edu        }
1637175Sgblack@eecs.umich.edu        addr += (single ? 4 : 8);
1647175Sgblack@eecs.umich.edu    }
1657175Sgblack@eecs.umich.edu
1667175Sgblack@eecs.umich.edu    if (writeback) {
1677175Sgblack@eecs.umich.edu        if (up) {
1687175Sgblack@eecs.umich.edu            microOps[i++] =
1697175Sgblack@eecs.umich.edu                new MicroAddiUop(machInst, rn, rn, 4 * offset);
1707175Sgblack@eecs.umich.edu        } else {
1717175Sgblack@eecs.umich.edu            microOps[i++] =
1727175Sgblack@eecs.umich.edu                new MicroSubiUop(machInst, rn, rn, 4 * offset);
1737175Sgblack@eecs.umich.edu        }
1747175Sgblack@eecs.umich.edu    }
1757175Sgblack@eecs.umich.edu
1767175Sgblack@eecs.umich.edu    numMicroops = i;
1777175Sgblack@eecs.umich.edu    assert(numMicroops <= maxMicroops);
1787175Sgblack@eecs.umich.edu    microOps[numMicroops - 1]->setLastMicroop();
1797170Sgblack@eecs.umich.edu}
1807175Sgblack@eecs.umich.edu
1817175Sgblack@eecs.umich.edu}
182