macromem.cc revision 9640
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
438229Snate@binkert.org#include <sstream>
448229Snate@binkert.org
457170Sgblack@eecs.umich.edu#include "arch/arm/insts/macromem.hh"
468961Sgblack@eecs.umich.edu#include "arch/arm/generated/decoder.hh"
477170Sgblack@eecs.umich.edu
487853SMatt.Horsnell@ARM.comusing namespace std;
497170Sgblack@eecs.umich.eduusing namespace ArmISAInst;
507170Sgblack@eecs.umich.edu
517170Sgblack@eecs.umich.edunamespace ArmISA
527170Sgblack@eecs.umich.edu{
537170Sgblack@eecs.umich.edu
547170Sgblack@eecs.umich.eduMacroMemOp::MacroMemOp(const char *mnem, ExtMachInst machInst,
557170Sgblack@eecs.umich.edu                       OpClass __opClass, IntRegIndex rn,
567170Sgblack@eecs.umich.edu                       bool index, bool up, bool user, bool writeback,
577170Sgblack@eecs.umich.edu                       bool load, uint32_t reglist) :
587170Sgblack@eecs.umich.edu    PredMacroOp(mnem, machInst, __opClass)
597170Sgblack@eecs.umich.edu{
607170Sgblack@eecs.umich.edu    uint32_t regs = reglist;
617170Sgblack@eecs.umich.edu    uint32_t ones = number_of_ones(reglist);
628148SAli.Saidi@ARM.com    // Remember that writeback adds a uop or two and the temp register adds one
638148SAli.Saidi@ARM.com    numMicroops = ones + (writeback ? (load ? 2 : 1) : 0) + 1;
648148SAli.Saidi@ARM.com
658148SAli.Saidi@ARM.com    // It's technically legal to do a lot of nothing
668148SAli.Saidi@ARM.com    if (!ones)
678148SAli.Saidi@ARM.com        numMicroops = 1;
688148SAli.Saidi@ARM.com
697170Sgblack@eecs.umich.edu    microOps = new StaticInstPtr[numMicroops];
707170Sgblack@eecs.umich.edu    uint32_t addr = 0;
717170Sgblack@eecs.umich.edu
727170Sgblack@eecs.umich.edu    if (!up)
737170Sgblack@eecs.umich.edu        addr = (ones << 2) - 4;
747170Sgblack@eecs.umich.edu
757170Sgblack@eecs.umich.edu    if (!index)
767170Sgblack@eecs.umich.edu        addr += 4;
777170Sgblack@eecs.umich.edu
787190Sgblack@eecs.umich.edu    StaticInstPtr *uop = microOps;
797190Sgblack@eecs.umich.edu
807170Sgblack@eecs.umich.edu    // Add 0 to Rn and stick it in ureg0.
817170Sgblack@eecs.umich.edu    // This is equivalent to a move.
827190Sgblack@eecs.umich.edu    *uop = new MicroAddiUop(machInst, INTREG_UREG0, rn, 0);
837190Sgblack@eecs.umich.edu
847170Sgblack@eecs.umich.edu    unsigned reg = 0;
858148SAli.Saidi@ARM.com    unsigned regIdx = 0;
867170Sgblack@eecs.umich.edu    bool force_user = user & !bits(reglist, 15);
877170Sgblack@eecs.umich.edu    bool exception_ret = user & bits(reglist, 15);
887170Sgblack@eecs.umich.edu
897190Sgblack@eecs.umich.edu    for (int i = 0; i < ones; i++) {
907170Sgblack@eecs.umich.edu        // Find the next register.
917170Sgblack@eecs.umich.edu        while (!bits(regs, reg))
927170Sgblack@eecs.umich.edu            reg++;
937170Sgblack@eecs.umich.edu        replaceBits(regs, reg, 0);
947170Sgblack@eecs.umich.edu
958148SAli.Saidi@ARM.com        regIdx = reg;
967170Sgblack@eecs.umich.edu        if (force_user) {
977310Sgblack@eecs.umich.edu            regIdx = intRegInMode(MODE_USER, regIdx);
987170Sgblack@eecs.umich.edu        }
997170Sgblack@eecs.umich.edu
1007170Sgblack@eecs.umich.edu        if (load) {
1018148SAli.Saidi@ARM.com            if (writeback && i == ones - 1) {
1028148SAli.Saidi@ARM.com                // If it's a writeback and this is the last register
1038148SAli.Saidi@ARM.com                // do the load into a temporary register which we'll move
1048148SAli.Saidi@ARM.com                // into the final one later
1058148SAli.Saidi@ARM.com                *++uop = new MicroLdrUop(machInst, INTREG_UREG1, INTREG_UREG0,
1068148SAli.Saidi@ARM.com                        up, addr);
1077170Sgblack@eecs.umich.edu            } else {
1088148SAli.Saidi@ARM.com                // Otherwise just do it normally
1098148SAli.Saidi@ARM.com                if (reg == INTREG_PC && exception_ret) {
1108148SAli.Saidi@ARM.com                    // This must be the exception return form of ldm.
1118148SAli.Saidi@ARM.com                    *++uop = new MicroLdrRetUop(machInst, regIdx,
1128148SAli.Saidi@ARM.com                                               INTREG_UREG0, up, addr);
1139640Snathanael.premillieu@irisa.fr                    if (!(condCode == COND_AL || condCode == COND_UC))
1149640Snathanael.premillieu@irisa.fr                        (*uop)->setFlag(StaticInst::IsCondControl);
1159640Snathanael.premillieu@irisa.fr                    else
1169640Snathanael.premillieu@irisa.fr                        (*uop)->setFlag(StaticInst::IsUncondControl);
1178148SAli.Saidi@ARM.com                } else {
1188148SAli.Saidi@ARM.com                    *++uop = new MicroLdrUop(machInst, regIdx,
1198148SAli.Saidi@ARM.com                                            INTREG_UREG0, up, addr);
1209250SAli.Saidi@ARM.com                    if (reg == INTREG_PC) {
1219250SAli.Saidi@ARM.com                        (*uop)->setFlag(StaticInst::IsControl);
1229250SAli.Saidi@ARM.com                        if (!(condCode == COND_AL || condCode == COND_UC))
1239250SAli.Saidi@ARM.com                            (*uop)->setFlag(StaticInst::IsCondControl);
1249250SAli.Saidi@ARM.com                        else
1259250SAli.Saidi@ARM.com                            (*uop)->setFlag(StaticInst::IsUncondControl);
1269250SAli.Saidi@ARM.com                        (*uop)->setFlag(StaticInst::IsIndirectControl);
1279250SAli.Saidi@ARM.com                    }
1288148SAli.Saidi@ARM.com                }
1297170Sgblack@eecs.umich.edu            }
1307170Sgblack@eecs.umich.edu        } else {
1317190Sgblack@eecs.umich.edu            *++uop = new MicroStrUop(machInst, regIdx, INTREG_UREG0, up, addr);
1327170Sgblack@eecs.umich.edu        }
1337170Sgblack@eecs.umich.edu
1347170Sgblack@eecs.umich.edu        if (up)
1357170Sgblack@eecs.umich.edu            addr += 4;
1367170Sgblack@eecs.umich.edu        else
1377170Sgblack@eecs.umich.edu            addr -= 4;
1387170Sgblack@eecs.umich.edu    }
1397170Sgblack@eecs.umich.edu
1408148SAli.Saidi@ARM.com    if (writeback && ones) {
1418148SAli.Saidi@ARM.com        // put the register update after we're done all loading
1428148SAli.Saidi@ARM.com        if (up)
1438148SAli.Saidi@ARM.com            *++uop = new MicroAddiUop(machInst, rn, rn, ones * 4);
1448148SAli.Saidi@ARM.com        else
1458148SAli.Saidi@ARM.com            *++uop = new MicroSubiUop(machInst, rn, rn, ones * 4);
1468148SAli.Saidi@ARM.com
1478148SAli.Saidi@ARM.com        // If this was a load move the last temporary value into place
1488148SAli.Saidi@ARM.com        // this way we can't take an exception after we update the base
1498148SAli.Saidi@ARM.com        // register.
1508148SAli.Saidi@ARM.com        if (load && reg == INTREG_PC && exception_ret) {
1518148SAli.Saidi@ARM.com            *++uop = new MicroUopRegMovRet(machInst, 0, INTREG_UREG1);
1529368Snathanael.premillieu@irisa.fr            if (!(condCode == COND_AL || condCode == COND_UC))
1539368Snathanael.premillieu@irisa.fr                (*uop)->setFlag(StaticInst::IsCondControl);
1549368Snathanael.premillieu@irisa.fr            else
1559368Snathanael.premillieu@irisa.fr                (*uop)->setFlag(StaticInst::IsUncondControl);
1568148SAli.Saidi@ARM.com        } else if (load) {
1578148SAli.Saidi@ARM.com            *++uop = new MicroUopRegMov(machInst, regIdx, INTREG_UREG1);
1588148SAli.Saidi@ARM.com            if (reg == INTREG_PC) {
1598542Sgblack@eecs.umich.edu                (*uop)->setFlag(StaticInst::IsControl);
1608542Sgblack@eecs.umich.edu                (*uop)->setFlag(StaticInst::IsCondControl);
1618542Sgblack@eecs.umich.edu                (*uop)->setFlag(StaticInst::IsIndirectControl);
1628148SAli.Saidi@ARM.com                // This is created as a RAS POP
1638148SAli.Saidi@ARM.com                if (rn == INTREG_SP)
1648542Sgblack@eecs.umich.edu                    (*uop)->setFlag(StaticInst::IsReturn);
1658148SAli.Saidi@ARM.com
1668148SAli.Saidi@ARM.com            }
1678148SAli.Saidi@ARM.com        }
1687170Sgblack@eecs.umich.edu    }
1697190Sgblack@eecs.umich.edu
1707190Sgblack@eecs.umich.edu    (*uop)->setLastMicroop();
1717343Sgblack@eecs.umich.edu
1727343Sgblack@eecs.umich.edu    for (StaticInstPtr *curUop = microOps;
1737343Sgblack@eecs.umich.edu            !(*curUop)->isLastMicroop(); curUop++) {
1747343Sgblack@eecs.umich.edu        MicroOp * uopPtr = dynamic_cast<MicroOp *>(curUop->get());
1757343Sgblack@eecs.umich.edu        assert(uopPtr);
1767343Sgblack@eecs.umich.edu        uopPtr->setDelayedCommit();
1777343Sgblack@eecs.umich.edu    }
1787170Sgblack@eecs.umich.edu}
1797170Sgblack@eecs.umich.edu
1807639Sgblack@eecs.umich.eduVldMultOp::VldMultOp(const char *mnem, ExtMachInst machInst, OpClass __opClass,
1817639Sgblack@eecs.umich.edu                     unsigned elems, RegIndex rn, RegIndex vd, unsigned regs,
1827639Sgblack@eecs.umich.edu                     unsigned inc, uint32_t size, uint32_t align, RegIndex rm) :
1837639Sgblack@eecs.umich.edu    PredMacroOp(mnem, machInst, __opClass)
1847639Sgblack@eecs.umich.edu{
1857639Sgblack@eecs.umich.edu    assert(regs > 0 && regs <= 4);
1867639Sgblack@eecs.umich.edu    assert(regs % elems == 0);
1877639Sgblack@eecs.umich.edu
1887639Sgblack@eecs.umich.edu    numMicroops = (regs > 2) ? 2 : 1;
1897639Sgblack@eecs.umich.edu    bool wb = (rm != 15);
1907639Sgblack@eecs.umich.edu    bool deinterleave = (elems > 1);
1917639Sgblack@eecs.umich.edu
1927639Sgblack@eecs.umich.edu    if (wb) numMicroops++;
1937639Sgblack@eecs.umich.edu    if (deinterleave) numMicroops += (regs / elems);
1947639Sgblack@eecs.umich.edu    microOps = new StaticInstPtr[numMicroops];
1957639Sgblack@eecs.umich.edu
1967639Sgblack@eecs.umich.edu    RegIndex rMid = deinterleave ? NumFloatArchRegs : vd * 2;
1977639Sgblack@eecs.umich.edu
1987639Sgblack@eecs.umich.edu    uint32_t noAlign = TLB::MustBeOne;
1997639Sgblack@eecs.umich.edu
2007639Sgblack@eecs.umich.edu    unsigned uopIdx = 0;
2017639Sgblack@eecs.umich.edu    switch (regs) {
2027639Sgblack@eecs.umich.edu      case 4:
2037639Sgblack@eecs.umich.edu        microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>(
2047639Sgblack@eecs.umich.edu                size, machInst, rMid, rn, 0, align);
2057639Sgblack@eecs.umich.edu        microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>(
2067639Sgblack@eecs.umich.edu                size, machInst, rMid + 4, rn, 16, noAlign);
2077639Sgblack@eecs.umich.edu        break;
2087639Sgblack@eecs.umich.edu      case 3:
2097639Sgblack@eecs.umich.edu        microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>(
2107639Sgblack@eecs.umich.edu                size, machInst, rMid, rn, 0, align);
2117639Sgblack@eecs.umich.edu        microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon8Uop>(
2127639Sgblack@eecs.umich.edu                size, machInst, rMid + 4, rn, 16, noAlign);
2137639Sgblack@eecs.umich.edu        break;
2147639Sgblack@eecs.umich.edu      case 2:
2157639Sgblack@eecs.umich.edu        microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>(
2167639Sgblack@eecs.umich.edu                size, machInst, rMid, rn, 0, align);
2177639Sgblack@eecs.umich.edu        break;
2187639Sgblack@eecs.umich.edu      case 1:
2197639Sgblack@eecs.umich.edu        microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon8Uop>(
2207639Sgblack@eecs.umich.edu                size, machInst, rMid, rn, 0, align);
2217639Sgblack@eecs.umich.edu        break;
2227639Sgblack@eecs.umich.edu      default:
2237853SMatt.Horsnell@ARM.com        // Unknown number of registers
2247853SMatt.Horsnell@ARM.com        microOps[uopIdx++] = new Unknown(machInst);
2257639Sgblack@eecs.umich.edu    }
2267639Sgblack@eecs.umich.edu    if (wb) {
2277639Sgblack@eecs.umich.edu        if (rm != 15 && rm != 13) {
2287639Sgblack@eecs.umich.edu            microOps[uopIdx++] =
2297646Sgene.wu@arm.com                new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL);
2307639Sgblack@eecs.umich.edu        } else {
2317639Sgblack@eecs.umich.edu            microOps[uopIdx++] =
2327639Sgblack@eecs.umich.edu                new MicroAddiUop(machInst, rn, rn, regs * 8);
2337639Sgblack@eecs.umich.edu        }
2347639Sgblack@eecs.umich.edu    }
2357639Sgblack@eecs.umich.edu    if (deinterleave) {
2367639Sgblack@eecs.umich.edu        switch (elems) {
2377639Sgblack@eecs.umich.edu          case 4:
2387639Sgblack@eecs.umich.edu            assert(regs == 4);
2397639Sgblack@eecs.umich.edu            microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon8Uop>(
2407639Sgblack@eecs.umich.edu                    size, machInst, vd * 2, rMid, inc * 2);
2417639Sgblack@eecs.umich.edu            break;
2427639Sgblack@eecs.umich.edu          case 3:
2437639Sgblack@eecs.umich.edu            assert(regs == 3);
2447639Sgblack@eecs.umich.edu            microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon6Uop>(
2457639Sgblack@eecs.umich.edu                    size, machInst, vd * 2, rMid, inc * 2);
2467639Sgblack@eecs.umich.edu            break;
2477639Sgblack@eecs.umich.edu          case 2:
2487639Sgblack@eecs.umich.edu            assert(regs == 4 || regs == 2);
2497639Sgblack@eecs.umich.edu            if (regs == 4) {
2507639Sgblack@eecs.umich.edu                microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>(
2517639Sgblack@eecs.umich.edu                        size, machInst, vd * 2, rMid, inc * 2);
2527639Sgblack@eecs.umich.edu                microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>(
2537639Sgblack@eecs.umich.edu                        size, machInst, vd * 2 + 2, rMid + 4, inc * 2);
2547639Sgblack@eecs.umich.edu            } else {
2557639Sgblack@eecs.umich.edu                microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>(
2567639Sgblack@eecs.umich.edu                        size, machInst, vd * 2, rMid, inc * 2);
2577639Sgblack@eecs.umich.edu            }
2587639Sgblack@eecs.umich.edu            break;
2597639Sgblack@eecs.umich.edu          default:
2607853SMatt.Horsnell@ARM.com            // Bad number of elements to deinterleave
2617853SMatt.Horsnell@ARM.com            microOps[uopIdx++] = new Unknown(machInst);
2627639Sgblack@eecs.umich.edu        }
2637639Sgblack@eecs.umich.edu    }
2647639Sgblack@eecs.umich.edu    assert(uopIdx == numMicroops);
2657639Sgblack@eecs.umich.edu
2667639Sgblack@eecs.umich.edu    for (unsigned i = 0; i < numMicroops - 1; i++) {
2677639Sgblack@eecs.umich.edu        MicroOp * uopPtr = dynamic_cast<MicroOp *>(microOps[i].get());
2687639Sgblack@eecs.umich.edu        assert(uopPtr);
2697639Sgblack@eecs.umich.edu        uopPtr->setDelayedCommit();
2707639Sgblack@eecs.umich.edu    }
2717639Sgblack@eecs.umich.edu    microOps[numMicroops - 1]->setLastMicroop();
2727639Sgblack@eecs.umich.edu}
2737639Sgblack@eecs.umich.edu
2747639Sgblack@eecs.umich.eduVldSingleOp::VldSingleOp(const char *mnem, ExtMachInst machInst,
2757639Sgblack@eecs.umich.edu                         OpClass __opClass, bool all, unsigned elems,
2767639Sgblack@eecs.umich.edu                         RegIndex rn, RegIndex vd, unsigned regs,
2777639Sgblack@eecs.umich.edu                         unsigned inc, uint32_t size, uint32_t align,
2787639Sgblack@eecs.umich.edu                         RegIndex rm, unsigned lane) :
2797639Sgblack@eecs.umich.edu    PredMacroOp(mnem, machInst, __opClass)
2807639Sgblack@eecs.umich.edu{
2817639Sgblack@eecs.umich.edu    assert(regs > 0 && regs <= 4);
2827639Sgblack@eecs.umich.edu    assert(regs % elems == 0);
2837639Sgblack@eecs.umich.edu
2847639Sgblack@eecs.umich.edu    unsigned eBytes = (1 << size);
2857639Sgblack@eecs.umich.edu    unsigned loadSize = eBytes * elems;
2867639Sgblack@eecs.umich.edu    unsigned loadRegs M5_VAR_USED = (loadSize + sizeof(FloatRegBits) - 1) /
2877639Sgblack@eecs.umich.edu                        sizeof(FloatRegBits);
2887639Sgblack@eecs.umich.edu
2897639Sgblack@eecs.umich.edu    assert(loadRegs > 0 && loadRegs <= 4);
2907639Sgblack@eecs.umich.edu
2917639Sgblack@eecs.umich.edu    numMicroops = 1;
2927639Sgblack@eecs.umich.edu    bool wb = (rm != 15);
2937639Sgblack@eecs.umich.edu
2947639Sgblack@eecs.umich.edu    if (wb) numMicroops++;
2957639Sgblack@eecs.umich.edu    numMicroops += (regs / elems);
2967639Sgblack@eecs.umich.edu    microOps = new StaticInstPtr[numMicroops];
2977639Sgblack@eecs.umich.edu
2987639Sgblack@eecs.umich.edu    RegIndex ufp0 = NumFloatArchRegs;
2997639Sgblack@eecs.umich.edu
3007639Sgblack@eecs.umich.edu    unsigned uopIdx = 0;
3017639Sgblack@eecs.umich.edu    switch (loadSize) {
3027639Sgblack@eecs.umich.edu      case 1:
3037639Sgblack@eecs.umich.edu        microOps[uopIdx++] = new MicroLdrNeon1Uop<uint8_t>(
3047639Sgblack@eecs.umich.edu                machInst, ufp0, rn, 0, align);
3057639Sgblack@eecs.umich.edu        break;
3067639Sgblack@eecs.umich.edu      case 2:
3077639Sgblack@eecs.umich.edu        if (eBytes == 2) {
3087639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroLdrNeon2Uop<uint16_t>(
3097639Sgblack@eecs.umich.edu                    machInst, ufp0, rn, 0, align);
3107639Sgblack@eecs.umich.edu        } else {
3117639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroLdrNeon2Uop<uint8_t>(
3127639Sgblack@eecs.umich.edu                    machInst, ufp0, rn, 0, align);
3137639Sgblack@eecs.umich.edu        }
3147639Sgblack@eecs.umich.edu        break;
3157639Sgblack@eecs.umich.edu      case 3:
3167639Sgblack@eecs.umich.edu        microOps[uopIdx++] = new MicroLdrNeon3Uop<uint8_t>(
3177639Sgblack@eecs.umich.edu                machInst, ufp0, rn, 0, align);
3187639Sgblack@eecs.umich.edu        break;
3197639Sgblack@eecs.umich.edu      case 4:
3207639Sgblack@eecs.umich.edu        switch (eBytes) {
3217639Sgblack@eecs.umich.edu          case 1:
3227639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroLdrNeon4Uop<uint8_t>(
3237639Sgblack@eecs.umich.edu                    machInst, ufp0, rn, 0, align);
3247639Sgblack@eecs.umich.edu            break;
3257639Sgblack@eecs.umich.edu          case 2:
3267639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroLdrNeon4Uop<uint16_t>(
3277639Sgblack@eecs.umich.edu                    machInst, ufp0, rn, 0, align);
3287639Sgblack@eecs.umich.edu            break;
3297639Sgblack@eecs.umich.edu          case 4:
3307639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroLdrNeon4Uop<uint32_t>(
3317639Sgblack@eecs.umich.edu                    machInst, ufp0, rn, 0, align);
3327639Sgblack@eecs.umich.edu            break;
3337639Sgblack@eecs.umich.edu        }
3347639Sgblack@eecs.umich.edu        break;
3357639Sgblack@eecs.umich.edu      case 6:
3367639Sgblack@eecs.umich.edu        microOps[uopIdx++] = new MicroLdrNeon6Uop<uint16_t>(
3377639Sgblack@eecs.umich.edu                machInst, ufp0, rn, 0, align);
3387639Sgblack@eecs.umich.edu        break;
3397639Sgblack@eecs.umich.edu      case 8:
3407639Sgblack@eecs.umich.edu        switch (eBytes) {
3417639Sgblack@eecs.umich.edu          case 2:
3427639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroLdrNeon8Uop<uint16_t>(
3437639Sgblack@eecs.umich.edu                    machInst, ufp0, rn, 0, align);
3447639Sgblack@eecs.umich.edu            break;
3457639Sgblack@eecs.umich.edu          case 4:
3467639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroLdrNeon8Uop<uint32_t>(
3477639Sgblack@eecs.umich.edu                    machInst, ufp0, rn, 0, align);
3487639Sgblack@eecs.umich.edu            break;
3497639Sgblack@eecs.umich.edu        }
3507639Sgblack@eecs.umich.edu        break;
3517639Sgblack@eecs.umich.edu      case 12:
3527639Sgblack@eecs.umich.edu        microOps[uopIdx++] = new MicroLdrNeon12Uop<uint32_t>(
3537639Sgblack@eecs.umich.edu                machInst, ufp0, rn, 0, align);
3547639Sgblack@eecs.umich.edu        break;
3557639Sgblack@eecs.umich.edu      case 16:
3567639Sgblack@eecs.umich.edu        microOps[uopIdx++] = new MicroLdrNeon16Uop<uint32_t>(
3577639Sgblack@eecs.umich.edu                machInst, ufp0, rn, 0, align);
3587639Sgblack@eecs.umich.edu        break;
3597639Sgblack@eecs.umich.edu      default:
3607853SMatt.Horsnell@ARM.com        // Unrecognized load size
3617853SMatt.Horsnell@ARM.com        microOps[uopIdx++] = new Unknown(machInst);
3627639Sgblack@eecs.umich.edu    }
3637639Sgblack@eecs.umich.edu    if (wb) {
3647639Sgblack@eecs.umich.edu        if (rm != 15 && rm != 13) {
3657639Sgblack@eecs.umich.edu            microOps[uopIdx++] =
3667646Sgene.wu@arm.com                new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL);
3677639Sgblack@eecs.umich.edu        } else {
3687639Sgblack@eecs.umich.edu            microOps[uopIdx++] =
3697639Sgblack@eecs.umich.edu                new MicroAddiUop(machInst, rn, rn, loadSize);
3707639Sgblack@eecs.umich.edu        }
3717639Sgblack@eecs.umich.edu    }
3727639Sgblack@eecs.umich.edu    switch (elems) {
3737639Sgblack@eecs.umich.edu      case 4:
3747639Sgblack@eecs.umich.edu        assert(regs == 4);
3757639Sgblack@eecs.umich.edu        switch (size) {
3767639Sgblack@eecs.umich.edu          case 0:
3777639Sgblack@eecs.umich.edu            if (all) {
3787639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroUnpackAllNeon2to8Uop<uint8_t>(
3797639Sgblack@eecs.umich.edu                        machInst, vd * 2, ufp0, inc * 2);
3807639Sgblack@eecs.umich.edu            } else {
3817639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroUnpackNeon2to8Uop<uint8_t>(
3827639Sgblack@eecs.umich.edu                        machInst, vd * 2, ufp0, inc * 2, lane);
3837639Sgblack@eecs.umich.edu            }
3847639Sgblack@eecs.umich.edu            break;
3857639Sgblack@eecs.umich.edu          case 1:
3867639Sgblack@eecs.umich.edu            if (all) {
3877639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroUnpackAllNeon2to8Uop<uint16_t>(
3887639Sgblack@eecs.umich.edu                        machInst, vd * 2, ufp0, inc * 2);
3897639Sgblack@eecs.umich.edu            } else {
3907639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroUnpackNeon2to8Uop<uint16_t>(
3917639Sgblack@eecs.umich.edu                        machInst, vd * 2, ufp0, inc * 2, lane);
3927639Sgblack@eecs.umich.edu            }
3937639Sgblack@eecs.umich.edu            break;
3947639Sgblack@eecs.umich.edu          case 2:
3957639Sgblack@eecs.umich.edu            if (all) {
3967639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroUnpackAllNeon4to8Uop<uint32_t>(
3977639Sgblack@eecs.umich.edu                        machInst, vd * 2, ufp0, inc * 2);
3987639Sgblack@eecs.umich.edu            } else {
3997639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroUnpackNeon4to8Uop<uint32_t>(
4007639Sgblack@eecs.umich.edu                        machInst, vd * 2, ufp0, inc * 2, lane);
4017639Sgblack@eecs.umich.edu            }
4027639Sgblack@eecs.umich.edu            break;
4037639Sgblack@eecs.umich.edu          default:
4047853SMatt.Horsnell@ARM.com            // Bad size
4057853SMatt.Horsnell@ARM.com            microOps[uopIdx++] = new Unknown(machInst);
4067639Sgblack@eecs.umich.edu            break;
4077639Sgblack@eecs.umich.edu        }
4087639Sgblack@eecs.umich.edu        break;
4097639Sgblack@eecs.umich.edu      case 3:
4107639Sgblack@eecs.umich.edu        assert(regs == 3);
4117639Sgblack@eecs.umich.edu        switch (size) {
4127639Sgblack@eecs.umich.edu          case 0:
4137639Sgblack@eecs.umich.edu            if (all) {
4147639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroUnpackAllNeon2to6Uop<uint8_t>(
4157639Sgblack@eecs.umich.edu                        machInst, vd * 2, ufp0, inc * 2);
4167639Sgblack@eecs.umich.edu            } else {
4177639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroUnpackNeon2to6Uop<uint8_t>(
4187639Sgblack@eecs.umich.edu                        machInst, vd * 2, ufp0, inc * 2, lane);
4197639Sgblack@eecs.umich.edu            }
4207639Sgblack@eecs.umich.edu            break;
4217639Sgblack@eecs.umich.edu          case 1:
4227639Sgblack@eecs.umich.edu            if (all) {
4237639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroUnpackAllNeon2to6Uop<uint16_t>(
4247639Sgblack@eecs.umich.edu                        machInst, vd * 2, ufp0, inc * 2);
4257639Sgblack@eecs.umich.edu            } else {
4267639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroUnpackNeon2to6Uop<uint16_t>(
4277639Sgblack@eecs.umich.edu                        machInst, vd * 2, ufp0, inc * 2, lane);
4287639Sgblack@eecs.umich.edu            }
4297639Sgblack@eecs.umich.edu            break;
4307639Sgblack@eecs.umich.edu          case 2:
4317639Sgblack@eecs.umich.edu            if (all) {
4327639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroUnpackAllNeon4to6Uop<uint32_t>(
4337639Sgblack@eecs.umich.edu                        machInst, vd * 2, ufp0, inc * 2);
4347639Sgblack@eecs.umich.edu            } else {
4357639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroUnpackNeon4to6Uop<uint32_t>(
4367639Sgblack@eecs.umich.edu                        machInst, vd * 2, ufp0, inc * 2, lane);
4377639Sgblack@eecs.umich.edu            }
4387639Sgblack@eecs.umich.edu            break;
4397639Sgblack@eecs.umich.edu          default:
4407853SMatt.Horsnell@ARM.com            // Bad size
4417853SMatt.Horsnell@ARM.com            microOps[uopIdx++] = new Unknown(machInst);
4427639Sgblack@eecs.umich.edu            break;
4437639Sgblack@eecs.umich.edu        }
4447639Sgblack@eecs.umich.edu        break;
4457639Sgblack@eecs.umich.edu      case 2:
4467639Sgblack@eecs.umich.edu        assert(regs == 2);
4477639Sgblack@eecs.umich.edu        assert(loadRegs <= 2);
4487639Sgblack@eecs.umich.edu        switch (size) {
4497639Sgblack@eecs.umich.edu          case 0:
4507639Sgblack@eecs.umich.edu            if (all) {
4517639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroUnpackAllNeon2to4Uop<uint8_t>(
4527639Sgblack@eecs.umich.edu                        machInst, vd * 2, ufp0, inc * 2);
4537639Sgblack@eecs.umich.edu            } else {
4547639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroUnpackNeon2to4Uop<uint8_t>(
4557639Sgblack@eecs.umich.edu                        machInst, vd * 2, ufp0, inc * 2, lane);
4567639Sgblack@eecs.umich.edu            }
4577639Sgblack@eecs.umich.edu            break;
4587639Sgblack@eecs.umich.edu          case 1:
4597639Sgblack@eecs.umich.edu            if (all) {
4607639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroUnpackAllNeon2to4Uop<uint16_t>(
4617639Sgblack@eecs.umich.edu                        machInst, vd * 2, ufp0, inc * 2);
4627639Sgblack@eecs.umich.edu            } else {
4637639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroUnpackNeon2to4Uop<uint16_t>(
4647639Sgblack@eecs.umich.edu                        machInst, vd * 2, ufp0, inc * 2, lane);
4657639Sgblack@eecs.umich.edu            }
4667639Sgblack@eecs.umich.edu            break;
4677639Sgblack@eecs.umich.edu          case 2:
4687639Sgblack@eecs.umich.edu            if (all) {
4697639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroUnpackAllNeon2to4Uop<uint32_t>(
4707639Sgblack@eecs.umich.edu                        machInst, vd * 2, ufp0, inc * 2);
4717639Sgblack@eecs.umich.edu            } else {
4727639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroUnpackNeon2to4Uop<uint32_t>(
4737639Sgblack@eecs.umich.edu                        machInst, vd * 2, ufp0, inc * 2, lane);
4747639Sgblack@eecs.umich.edu            }
4757639Sgblack@eecs.umich.edu            break;
4767639Sgblack@eecs.umich.edu          default:
4777853SMatt.Horsnell@ARM.com            // Bad size
4787853SMatt.Horsnell@ARM.com            microOps[uopIdx++] = new Unknown(machInst);
4797639Sgblack@eecs.umich.edu            break;
4807639Sgblack@eecs.umich.edu        }
4817639Sgblack@eecs.umich.edu        break;
4827639Sgblack@eecs.umich.edu      case 1:
4837639Sgblack@eecs.umich.edu        assert(regs == 1 || (all && regs == 2));
4847639Sgblack@eecs.umich.edu        assert(loadRegs <= 2);
4857639Sgblack@eecs.umich.edu        for (unsigned offset = 0; offset < regs; offset++) {
4867639Sgblack@eecs.umich.edu            switch (size) {
4877639Sgblack@eecs.umich.edu              case 0:
4887639Sgblack@eecs.umich.edu                if (all) {
4897639Sgblack@eecs.umich.edu                    microOps[uopIdx++] =
4907639Sgblack@eecs.umich.edu                        new MicroUnpackAllNeon2to2Uop<uint8_t>(
4917639Sgblack@eecs.umich.edu                            machInst, (vd + offset) * 2, ufp0, inc * 2);
4927639Sgblack@eecs.umich.edu                } else {
4937639Sgblack@eecs.umich.edu                    microOps[uopIdx++] =
4947639Sgblack@eecs.umich.edu                        new MicroUnpackNeon2to2Uop<uint8_t>(
4957639Sgblack@eecs.umich.edu                            machInst, (vd + offset) * 2, ufp0, inc * 2, lane);
4967639Sgblack@eecs.umich.edu                }
4977639Sgblack@eecs.umich.edu                break;
4987639Sgblack@eecs.umich.edu              case 1:
4997639Sgblack@eecs.umich.edu                if (all) {
5007639Sgblack@eecs.umich.edu                    microOps[uopIdx++] =
5017639Sgblack@eecs.umich.edu                        new MicroUnpackAllNeon2to2Uop<uint16_t>(
5027639Sgblack@eecs.umich.edu                            machInst, (vd + offset) * 2, ufp0, inc * 2);
5037639Sgblack@eecs.umich.edu                } else {
5047639Sgblack@eecs.umich.edu                    microOps[uopIdx++] =
5057639Sgblack@eecs.umich.edu                        new MicroUnpackNeon2to2Uop<uint16_t>(
5067639Sgblack@eecs.umich.edu                            machInst, (vd + offset) * 2, ufp0, inc * 2, lane);
5077639Sgblack@eecs.umich.edu                }
5087639Sgblack@eecs.umich.edu                break;
5097639Sgblack@eecs.umich.edu              case 2:
5107639Sgblack@eecs.umich.edu                if (all) {
5117639Sgblack@eecs.umich.edu                    microOps[uopIdx++] =
5127639Sgblack@eecs.umich.edu                        new MicroUnpackAllNeon2to2Uop<uint32_t>(
5137639Sgblack@eecs.umich.edu                            machInst, (vd + offset) * 2, ufp0, inc * 2);
5147639Sgblack@eecs.umich.edu                } else {
5157639Sgblack@eecs.umich.edu                    microOps[uopIdx++] =
5167639Sgblack@eecs.umich.edu                        new MicroUnpackNeon2to2Uop<uint32_t>(
5177639Sgblack@eecs.umich.edu                            machInst, (vd + offset) * 2, ufp0, inc * 2, lane);
5187639Sgblack@eecs.umich.edu                }
5197639Sgblack@eecs.umich.edu                break;
5207639Sgblack@eecs.umich.edu              default:
5217853SMatt.Horsnell@ARM.com                // Bad size
5227853SMatt.Horsnell@ARM.com                microOps[uopIdx++] = new Unknown(machInst);
5237639Sgblack@eecs.umich.edu                break;
5247639Sgblack@eecs.umich.edu            }
5257639Sgblack@eecs.umich.edu        }
5267639Sgblack@eecs.umich.edu        break;
5277639Sgblack@eecs.umich.edu      default:
5287853SMatt.Horsnell@ARM.com        // Bad number of elements to unpack
5297853SMatt.Horsnell@ARM.com        microOps[uopIdx++] = new Unknown(machInst);
5307639Sgblack@eecs.umich.edu    }
5317639Sgblack@eecs.umich.edu    assert(uopIdx == numMicroops);
5327639Sgblack@eecs.umich.edu
5337639Sgblack@eecs.umich.edu    for (unsigned i = 0; i < numMicroops - 1; i++) {
5347639Sgblack@eecs.umich.edu        MicroOp * uopPtr = dynamic_cast<MicroOp *>(microOps[i].get());
5357639Sgblack@eecs.umich.edu        assert(uopPtr);
5367639Sgblack@eecs.umich.edu        uopPtr->setDelayedCommit();
5377639Sgblack@eecs.umich.edu    }
5387639Sgblack@eecs.umich.edu    microOps[numMicroops - 1]->setLastMicroop();
5397639Sgblack@eecs.umich.edu}
5407639Sgblack@eecs.umich.edu
5417639Sgblack@eecs.umich.eduVstMultOp::VstMultOp(const char *mnem, ExtMachInst machInst, OpClass __opClass,
5427639Sgblack@eecs.umich.edu                     unsigned elems, RegIndex rn, RegIndex vd, unsigned regs,
5437639Sgblack@eecs.umich.edu                     unsigned inc, uint32_t size, uint32_t align, RegIndex rm) :
5447639Sgblack@eecs.umich.edu    PredMacroOp(mnem, machInst, __opClass)
5457639Sgblack@eecs.umich.edu{
5467639Sgblack@eecs.umich.edu    assert(regs > 0 && regs <= 4);
5477639Sgblack@eecs.umich.edu    assert(regs % elems == 0);
5487639Sgblack@eecs.umich.edu
5497639Sgblack@eecs.umich.edu    numMicroops = (regs > 2) ? 2 : 1;
5507639Sgblack@eecs.umich.edu    bool wb = (rm != 15);
5517639Sgblack@eecs.umich.edu    bool interleave = (elems > 1);
5527639Sgblack@eecs.umich.edu
5537639Sgblack@eecs.umich.edu    if (wb) numMicroops++;
5547639Sgblack@eecs.umich.edu    if (interleave) numMicroops += (regs / elems);
5557639Sgblack@eecs.umich.edu    microOps = new StaticInstPtr[numMicroops];
5567639Sgblack@eecs.umich.edu
5577639Sgblack@eecs.umich.edu    uint32_t noAlign = TLB::MustBeOne;
5587639Sgblack@eecs.umich.edu
5597639Sgblack@eecs.umich.edu    RegIndex rMid = interleave ? NumFloatArchRegs : vd * 2;
5607639Sgblack@eecs.umich.edu
5617639Sgblack@eecs.umich.edu    unsigned uopIdx = 0;
5627639Sgblack@eecs.umich.edu    if (interleave) {
5637639Sgblack@eecs.umich.edu        switch (elems) {
5647639Sgblack@eecs.umich.edu          case 4:
5657639Sgblack@eecs.umich.edu            assert(regs == 4);
5667639Sgblack@eecs.umich.edu            microOps[uopIdx++] = newNeonMixInst<MicroInterNeon8Uop>(
5677639Sgblack@eecs.umich.edu                    size, machInst, rMid, vd * 2, inc * 2);
5687639Sgblack@eecs.umich.edu            break;
5697639Sgblack@eecs.umich.edu          case 3:
5707639Sgblack@eecs.umich.edu            assert(regs == 3);
5717639Sgblack@eecs.umich.edu            microOps[uopIdx++] = newNeonMixInst<MicroInterNeon6Uop>(
5727639Sgblack@eecs.umich.edu                    size, machInst, rMid, vd * 2, inc * 2);
5737639Sgblack@eecs.umich.edu            break;
5747639Sgblack@eecs.umich.edu          case 2:
5757639Sgblack@eecs.umich.edu            assert(regs == 4 || regs == 2);
5767639Sgblack@eecs.umich.edu            if (regs == 4) {
5777639Sgblack@eecs.umich.edu                microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>(
5787639Sgblack@eecs.umich.edu                        size, machInst, rMid, vd * 2, inc * 2);
5797639Sgblack@eecs.umich.edu                microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>(
5807639Sgblack@eecs.umich.edu                        size, machInst, rMid + 4, vd * 2 + 2, inc * 2);
5817639Sgblack@eecs.umich.edu            } else {
5827639Sgblack@eecs.umich.edu                microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>(
5837639Sgblack@eecs.umich.edu                        size, machInst, rMid, vd * 2, inc * 2);
5847639Sgblack@eecs.umich.edu            }
5857639Sgblack@eecs.umich.edu            break;
5867639Sgblack@eecs.umich.edu          default:
5877853SMatt.Horsnell@ARM.com            // Bad number of elements to interleave
5887853SMatt.Horsnell@ARM.com            microOps[uopIdx++] = new Unknown(machInst);
5897639Sgblack@eecs.umich.edu        }
5907639Sgblack@eecs.umich.edu    }
5917639Sgblack@eecs.umich.edu    switch (regs) {
5927639Sgblack@eecs.umich.edu      case 4:
5937639Sgblack@eecs.umich.edu        microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>(
5947639Sgblack@eecs.umich.edu                size, machInst, rMid, rn, 0, align);
5957639Sgblack@eecs.umich.edu        microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>(
5967639Sgblack@eecs.umich.edu                size, machInst, rMid + 4, rn, 16, noAlign);
5977639Sgblack@eecs.umich.edu        break;
5987639Sgblack@eecs.umich.edu      case 3:
5997639Sgblack@eecs.umich.edu        microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>(
6007639Sgblack@eecs.umich.edu                size, machInst, rMid, rn, 0, align);
6017639Sgblack@eecs.umich.edu        microOps[uopIdx++] = newNeonMemInst<MicroStrNeon8Uop>(
6027639Sgblack@eecs.umich.edu                size, machInst, rMid + 4, rn, 16, noAlign);
6037639Sgblack@eecs.umich.edu        break;
6047639Sgblack@eecs.umich.edu      case 2:
6057639Sgblack@eecs.umich.edu        microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>(
6067639Sgblack@eecs.umich.edu                size, machInst, rMid, rn, 0, align);
6077639Sgblack@eecs.umich.edu        break;
6087639Sgblack@eecs.umich.edu      case 1:
6097639Sgblack@eecs.umich.edu        microOps[uopIdx++] = newNeonMemInst<MicroStrNeon8Uop>(
6107639Sgblack@eecs.umich.edu                size, machInst, rMid, rn, 0, align);
6117639Sgblack@eecs.umich.edu        break;
6127639Sgblack@eecs.umich.edu      default:
6137853SMatt.Horsnell@ARM.com        // Unknown number of registers
6147853SMatt.Horsnell@ARM.com        microOps[uopIdx++] = new Unknown(machInst);
6157639Sgblack@eecs.umich.edu    }
6167639Sgblack@eecs.umich.edu    if (wb) {
6177639Sgblack@eecs.umich.edu        if (rm != 15 && rm != 13) {
6187639Sgblack@eecs.umich.edu            microOps[uopIdx++] =
6197646Sgene.wu@arm.com                new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL);
6207639Sgblack@eecs.umich.edu        } else {
6217639Sgblack@eecs.umich.edu            microOps[uopIdx++] =
6227639Sgblack@eecs.umich.edu                new MicroAddiUop(machInst, rn, rn, regs * 8);
6237639Sgblack@eecs.umich.edu        }
6247639Sgblack@eecs.umich.edu    }
6257639Sgblack@eecs.umich.edu    assert(uopIdx == numMicroops);
6267639Sgblack@eecs.umich.edu
6277639Sgblack@eecs.umich.edu    for (unsigned i = 0; i < numMicroops - 1; i++) {
6287639Sgblack@eecs.umich.edu        MicroOp * uopPtr = dynamic_cast<MicroOp *>(microOps[i].get());
6297639Sgblack@eecs.umich.edu        assert(uopPtr);
6307639Sgblack@eecs.umich.edu        uopPtr->setDelayedCommit();
6317639Sgblack@eecs.umich.edu    }
6327639Sgblack@eecs.umich.edu    microOps[numMicroops - 1]->setLastMicroop();
6337639Sgblack@eecs.umich.edu}
6347639Sgblack@eecs.umich.edu
6357639Sgblack@eecs.umich.eduVstSingleOp::VstSingleOp(const char *mnem, ExtMachInst machInst,
6367639Sgblack@eecs.umich.edu                         OpClass __opClass, bool all, unsigned elems,
6377639Sgblack@eecs.umich.edu                         RegIndex rn, RegIndex vd, unsigned regs,
6387639Sgblack@eecs.umich.edu                         unsigned inc, uint32_t size, uint32_t align,
6397639Sgblack@eecs.umich.edu                         RegIndex rm, unsigned lane) :
6407639Sgblack@eecs.umich.edu    PredMacroOp(mnem, machInst, __opClass)
6417639Sgblack@eecs.umich.edu{
6427639Sgblack@eecs.umich.edu    assert(!all);
6437639Sgblack@eecs.umich.edu    assert(regs > 0 && regs <= 4);
6447639Sgblack@eecs.umich.edu    assert(regs % elems == 0);
6457639Sgblack@eecs.umich.edu
6467639Sgblack@eecs.umich.edu    unsigned eBytes = (1 << size);
6477639Sgblack@eecs.umich.edu    unsigned storeSize = eBytes * elems;
6487639Sgblack@eecs.umich.edu    unsigned storeRegs M5_VAR_USED = (storeSize + sizeof(FloatRegBits) - 1) /
6497639Sgblack@eecs.umich.edu                         sizeof(FloatRegBits);
6507639Sgblack@eecs.umich.edu
6517639Sgblack@eecs.umich.edu    assert(storeRegs > 0 && storeRegs <= 4);
6527639Sgblack@eecs.umich.edu
6537639Sgblack@eecs.umich.edu    numMicroops = 1;
6547639Sgblack@eecs.umich.edu    bool wb = (rm != 15);
6557639Sgblack@eecs.umich.edu
6567639Sgblack@eecs.umich.edu    if (wb) numMicroops++;
6577639Sgblack@eecs.umich.edu    numMicroops += (regs / elems);
6587639Sgblack@eecs.umich.edu    microOps = new StaticInstPtr[numMicroops];
6597639Sgblack@eecs.umich.edu
6607639Sgblack@eecs.umich.edu    RegIndex ufp0 = NumFloatArchRegs;
6617639Sgblack@eecs.umich.edu
6627639Sgblack@eecs.umich.edu    unsigned uopIdx = 0;
6637639Sgblack@eecs.umich.edu    switch (elems) {
6647639Sgblack@eecs.umich.edu      case 4:
6657639Sgblack@eecs.umich.edu        assert(regs == 4);
6667639Sgblack@eecs.umich.edu        switch (size) {
6677639Sgblack@eecs.umich.edu          case 0:
6687639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroPackNeon8to2Uop<uint8_t>(
6697639Sgblack@eecs.umich.edu                    machInst, ufp0, vd * 2, inc * 2, lane);
6707639Sgblack@eecs.umich.edu            break;
6717639Sgblack@eecs.umich.edu          case 1:
6727639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroPackNeon8to2Uop<uint16_t>(
6737639Sgblack@eecs.umich.edu                    machInst, ufp0, vd * 2, inc * 2, lane);
6747639Sgblack@eecs.umich.edu            break;
6757639Sgblack@eecs.umich.edu          case 2:
6767639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroPackNeon8to4Uop<uint32_t>(
6777639Sgblack@eecs.umich.edu                    machInst, ufp0, vd * 2, inc * 2, lane);
6787639Sgblack@eecs.umich.edu            break;
6797639Sgblack@eecs.umich.edu          default:
6807853SMatt.Horsnell@ARM.com            // Bad size
6817853SMatt.Horsnell@ARM.com            microOps[uopIdx++] = new Unknown(machInst);
6827639Sgblack@eecs.umich.edu            break;
6837639Sgblack@eecs.umich.edu        }
6847639Sgblack@eecs.umich.edu        break;
6857639Sgblack@eecs.umich.edu      case 3:
6867639Sgblack@eecs.umich.edu        assert(regs == 3);
6877639Sgblack@eecs.umich.edu        switch (size) {
6887639Sgblack@eecs.umich.edu          case 0:
6897639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroPackNeon6to2Uop<uint8_t>(
6907639Sgblack@eecs.umich.edu                    machInst, ufp0, vd * 2, inc * 2, lane);
6917639Sgblack@eecs.umich.edu            break;
6927639Sgblack@eecs.umich.edu          case 1:
6937639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroPackNeon6to2Uop<uint16_t>(
6947639Sgblack@eecs.umich.edu                    machInst, ufp0, vd * 2, inc * 2, lane);
6957639Sgblack@eecs.umich.edu            break;
6967639Sgblack@eecs.umich.edu          case 2:
6977639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroPackNeon6to4Uop<uint32_t>(
6987639Sgblack@eecs.umich.edu                    machInst, ufp0, vd * 2, inc * 2, lane);
6997639Sgblack@eecs.umich.edu            break;
7007639Sgblack@eecs.umich.edu          default:
7017853SMatt.Horsnell@ARM.com            // Bad size
7027853SMatt.Horsnell@ARM.com            microOps[uopIdx++] = new Unknown(machInst);
7037639Sgblack@eecs.umich.edu            break;
7047639Sgblack@eecs.umich.edu        }
7057639Sgblack@eecs.umich.edu        break;
7067639Sgblack@eecs.umich.edu      case 2:
7077639Sgblack@eecs.umich.edu        assert(regs == 2);
7087639Sgblack@eecs.umich.edu        assert(storeRegs <= 2);
7097639Sgblack@eecs.umich.edu        switch (size) {
7107639Sgblack@eecs.umich.edu          case 0:
7117639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroPackNeon4to2Uop<uint8_t>(
7127639Sgblack@eecs.umich.edu                    machInst, ufp0, vd * 2, inc * 2, lane);
7137639Sgblack@eecs.umich.edu            break;
7147639Sgblack@eecs.umich.edu          case 1:
7157639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroPackNeon4to2Uop<uint16_t>(
7167639Sgblack@eecs.umich.edu                    machInst, ufp0, vd * 2, inc * 2, lane);
7177639Sgblack@eecs.umich.edu            break;
7187639Sgblack@eecs.umich.edu          case 2:
7197639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroPackNeon4to2Uop<uint32_t>(
7207639Sgblack@eecs.umich.edu                    machInst, ufp0, vd * 2, inc * 2, lane);
7217639Sgblack@eecs.umich.edu            break;
7227639Sgblack@eecs.umich.edu          default:
7237853SMatt.Horsnell@ARM.com            // Bad size
7247853SMatt.Horsnell@ARM.com            microOps[uopIdx++] = new Unknown(machInst);
7257639Sgblack@eecs.umich.edu            break;
7267639Sgblack@eecs.umich.edu        }
7277639Sgblack@eecs.umich.edu        break;
7287639Sgblack@eecs.umich.edu      case 1:
7297639Sgblack@eecs.umich.edu        assert(regs == 1 || (all && regs == 2));
7307639Sgblack@eecs.umich.edu        assert(storeRegs <= 2);
7317639Sgblack@eecs.umich.edu        for (unsigned offset = 0; offset < regs; offset++) {
7327639Sgblack@eecs.umich.edu            switch (size) {
7337639Sgblack@eecs.umich.edu              case 0:
7347639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroPackNeon2to2Uop<uint8_t>(
7357639Sgblack@eecs.umich.edu                        machInst, ufp0, (vd + offset) * 2, inc * 2, lane);
7367639Sgblack@eecs.umich.edu                break;
7377639Sgblack@eecs.umich.edu              case 1:
7387639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroPackNeon2to2Uop<uint16_t>(
7397639Sgblack@eecs.umich.edu                        machInst, ufp0, (vd + offset) * 2, inc * 2, lane);
7407639Sgblack@eecs.umich.edu                break;
7417639Sgblack@eecs.umich.edu              case 2:
7427639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroPackNeon2to2Uop<uint32_t>(
7437639Sgblack@eecs.umich.edu                        machInst, ufp0, (vd + offset) * 2, inc * 2, lane);
7447639Sgblack@eecs.umich.edu                break;
7457639Sgblack@eecs.umich.edu              default:
7467853SMatt.Horsnell@ARM.com                // Bad size
7477853SMatt.Horsnell@ARM.com                microOps[uopIdx++] = new Unknown(machInst);
7487639Sgblack@eecs.umich.edu                break;
7497639Sgblack@eecs.umich.edu            }
7507639Sgblack@eecs.umich.edu        }
7517639Sgblack@eecs.umich.edu        break;
7527639Sgblack@eecs.umich.edu      default:
7537853SMatt.Horsnell@ARM.com        // Bad number of elements to unpack
7547853SMatt.Horsnell@ARM.com        microOps[uopIdx++] = new Unknown(machInst);
7557639Sgblack@eecs.umich.edu    }
7567639Sgblack@eecs.umich.edu    switch (storeSize) {
7577639Sgblack@eecs.umich.edu      case 1:
7587639Sgblack@eecs.umich.edu        microOps[uopIdx++] = new MicroStrNeon1Uop<uint8_t>(
7597639Sgblack@eecs.umich.edu                machInst, ufp0, rn, 0, align);
7607639Sgblack@eecs.umich.edu        break;
7617639Sgblack@eecs.umich.edu      case 2:
7627639Sgblack@eecs.umich.edu        if (eBytes == 2) {
7637639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroStrNeon2Uop<uint16_t>(
7647639Sgblack@eecs.umich.edu                    machInst, ufp0, rn, 0, align);
7657639Sgblack@eecs.umich.edu        } else {
7667639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroStrNeon2Uop<uint8_t>(
7677639Sgblack@eecs.umich.edu                    machInst, ufp0, rn, 0, align);
7687639Sgblack@eecs.umich.edu        }
7697639Sgblack@eecs.umich.edu        break;
7707639Sgblack@eecs.umich.edu      case 3:
7717639Sgblack@eecs.umich.edu        microOps[uopIdx++] = new MicroStrNeon3Uop<uint8_t>(
7727639Sgblack@eecs.umich.edu                machInst, ufp0, rn, 0, align);
7737639Sgblack@eecs.umich.edu        break;
7747639Sgblack@eecs.umich.edu      case 4:
7757639Sgblack@eecs.umich.edu        switch (eBytes) {
7767639Sgblack@eecs.umich.edu          case 1:
7777639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroStrNeon4Uop<uint8_t>(
7787639Sgblack@eecs.umich.edu                    machInst, ufp0, rn, 0, align);
7797639Sgblack@eecs.umich.edu            break;
7807639Sgblack@eecs.umich.edu          case 2:
7817639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroStrNeon4Uop<uint16_t>(
7827639Sgblack@eecs.umich.edu                    machInst, ufp0, rn, 0, align);
7837639Sgblack@eecs.umich.edu            break;
7847639Sgblack@eecs.umich.edu          case 4:
7857639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroStrNeon4Uop<uint32_t>(
7867639Sgblack@eecs.umich.edu                    machInst, ufp0, rn, 0, align);
7877639Sgblack@eecs.umich.edu            break;
7887639Sgblack@eecs.umich.edu        }
7897639Sgblack@eecs.umich.edu        break;
7907639Sgblack@eecs.umich.edu      case 6:
7917639Sgblack@eecs.umich.edu        microOps[uopIdx++] = new MicroStrNeon6Uop<uint16_t>(
7927639Sgblack@eecs.umich.edu                machInst, ufp0, rn, 0, align);
7937639Sgblack@eecs.umich.edu        break;
7947639Sgblack@eecs.umich.edu      case 8:
7957639Sgblack@eecs.umich.edu        switch (eBytes) {
7967639Sgblack@eecs.umich.edu          case 2:
7977639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroStrNeon8Uop<uint16_t>(
7987639Sgblack@eecs.umich.edu                    machInst, ufp0, rn, 0, align);
7997639Sgblack@eecs.umich.edu            break;
8007639Sgblack@eecs.umich.edu          case 4:
8017639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroStrNeon8Uop<uint32_t>(
8027639Sgblack@eecs.umich.edu                    machInst, ufp0, rn, 0, align);
8037639Sgblack@eecs.umich.edu            break;
8047639Sgblack@eecs.umich.edu        }
8057639Sgblack@eecs.umich.edu        break;
8067639Sgblack@eecs.umich.edu      case 12:
8077639Sgblack@eecs.umich.edu        microOps[uopIdx++] = new MicroStrNeon12Uop<uint32_t>(
8087639Sgblack@eecs.umich.edu                machInst, ufp0, rn, 0, align);
8097639Sgblack@eecs.umich.edu        break;
8107639Sgblack@eecs.umich.edu      case 16:
8117639Sgblack@eecs.umich.edu        microOps[uopIdx++] = new MicroStrNeon16Uop<uint32_t>(
8127639Sgblack@eecs.umich.edu                machInst, ufp0, rn, 0, align);
8137639Sgblack@eecs.umich.edu        break;
8147639Sgblack@eecs.umich.edu      default:
8157853SMatt.Horsnell@ARM.com        // Bad store size
8167853SMatt.Horsnell@ARM.com        microOps[uopIdx++] = new Unknown(machInst);
8177639Sgblack@eecs.umich.edu    }
8187639Sgblack@eecs.umich.edu    if (wb) {
8197639Sgblack@eecs.umich.edu        if (rm != 15 && rm != 13) {
8207639Sgblack@eecs.umich.edu            microOps[uopIdx++] =
8217646Sgene.wu@arm.com                new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL);
8227639Sgblack@eecs.umich.edu        } else {
8237639Sgblack@eecs.umich.edu            microOps[uopIdx++] =
8247639Sgblack@eecs.umich.edu                new MicroAddiUop(machInst, rn, rn, storeSize);
8257639Sgblack@eecs.umich.edu        }
8267639Sgblack@eecs.umich.edu    }
8277639Sgblack@eecs.umich.edu    assert(uopIdx == numMicroops);
8287639Sgblack@eecs.umich.edu
8297639Sgblack@eecs.umich.edu    for (unsigned i = 0; i < numMicroops - 1; i++) {
8307639Sgblack@eecs.umich.edu        MicroOp * uopPtr = dynamic_cast<MicroOp *>(microOps[i].get());
8317639Sgblack@eecs.umich.edu        assert(uopPtr);
8327639Sgblack@eecs.umich.edu        uopPtr->setDelayedCommit();
8337639Sgblack@eecs.umich.edu    }
8347639Sgblack@eecs.umich.edu    microOps[numMicroops - 1]->setLastMicroop();
8357639Sgblack@eecs.umich.edu}
8367639Sgblack@eecs.umich.edu
8377175Sgblack@eecs.umich.eduMacroVFPMemOp::MacroVFPMemOp(const char *mnem, ExtMachInst machInst,
8387175Sgblack@eecs.umich.edu                             OpClass __opClass, IntRegIndex rn,
8397175Sgblack@eecs.umich.edu                             RegIndex vd, bool single, bool up,
8407175Sgblack@eecs.umich.edu                             bool writeback, bool load, uint32_t offset) :
8417175Sgblack@eecs.umich.edu    PredMacroOp(mnem, machInst, __opClass)
8427175Sgblack@eecs.umich.edu{
8437175Sgblack@eecs.umich.edu    int i = 0;
8447175Sgblack@eecs.umich.edu
8457175Sgblack@eecs.umich.edu    // The lowest order bit selects fldmx (set) or fldmd (clear). These seem
8467175Sgblack@eecs.umich.edu    // to be functionally identical except that fldmx is deprecated. For now
8477175Sgblack@eecs.umich.edu    // we'll assume they're otherwise interchangable.
8487175Sgblack@eecs.umich.edu    int count = (single ? offset : (offset / 2));
8497175Sgblack@eecs.umich.edu    if (count == 0 || count > NumFloatArchRegs)
8507175Sgblack@eecs.umich.edu        warn_once("Bad offset field for VFP load/store multiple.\n");
8517175Sgblack@eecs.umich.edu    if (count == 0) {
8527175Sgblack@eecs.umich.edu        // Force there to be at least one microop so the macroop makes sense.
8537175Sgblack@eecs.umich.edu        writeback = true;
8547175Sgblack@eecs.umich.edu    }
8557175Sgblack@eecs.umich.edu    if (count > NumFloatArchRegs)
8567175Sgblack@eecs.umich.edu        count = NumFloatArchRegs;
8577175Sgblack@eecs.umich.edu
8587342Sgblack@eecs.umich.edu    numMicroops = count * (single ? 1 : 2) + (writeback ? 1 : 0);
8597342Sgblack@eecs.umich.edu    microOps = new StaticInstPtr[numMicroops];
8607342Sgblack@eecs.umich.edu
8617395Sgblack@eecs.umich.edu    int64_t addr = 0;
8627175Sgblack@eecs.umich.edu
8637342Sgblack@eecs.umich.edu    if (!up)
8647342Sgblack@eecs.umich.edu        addr = 4 * offset;
8657175Sgblack@eecs.umich.edu
8667342Sgblack@eecs.umich.edu    bool tempUp = up;
8677175Sgblack@eecs.umich.edu    for (int j = 0; j < count; j++) {
8687175Sgblack@eecs.umich.edu        if (load) {
8697639Sgblack@eecs.umich.edu            if (single) {
8707639Sgblack@eecs.umich.edu                microOps[i++] = new MicroLdrFpUop(machInst, vd++, rn,
8717639Sgblack@eecs.umich.edu                                                  tempUp, addr);
8727639Sgblack@eecs.umich.edu            } else {
8737639Sgblack@eecs.umich.edu                microOps[i++] = new MicroLdrDBFpUop(machInst, vd++, rn,
8747639Sgblack@eecs.umich.edu                                                    tempUp, addr);
8757639Sgblack@eecs.umich.edu                microOps[i++] = new MicroLdrDTFpUop(machInst, vd++, rn, tempUp,
8767639Sgblack@eecs.umich.edu                                                    addr + (up ? 4 : -4));
8777639Sgblack@eecs.umich.edu            }
8787175Sgblack@eecs.umich.edu        } else {
8797639Sgblack@eecs.umich.edu            if (single) {
8807639Sgblack@eecs.umich.edu                microOps[i++] = new MicroStrFpUop(machInst, vd++, rn,
8817639Sgblack@eecs.umich.edu                                                  tempUp, addr);
8827639Sgblack@eecs.umich.edu            } else {
8837639Sgblack@eecs.umich.edu                microOps[i++] = new MicroStrDBFpUop(machInst, vd++, rn,
8847639Sgblack@eecs.umich.edu                                                    tempUp, addr);
8857639Sgblack@eecs.umich.edu                microOps[i++] = new MicroStrDTFpUop(machInst, vd++, rn, tempUp,
8867639Sgblack@eecs.umich.edu                                                    addr + (up ? 4 : -4));
8877639Sgblack@eecs.umich.edu            }
8887175Sgblack@eecs.umich.edu        }
8897342Sgblack@eecs.umich.edu        if (!tempUp) {
8907342Sgblack@eecs.umich.edu            addr -= (single ? 4 : 8);
8917342Sgblack@eecs.umich.edu            // The microops don't handle negative displacement, so turn if we
8927342Sgblack@eecs.umich.edu            // hit zero, flip polarity and start adding.
8937395Sgblack@eecs.umich.edu            if (addr <= 0) {
8947342Sgblack@eecs.umich.edu                tempUp = true;
8957395Sgblack@eecs.umich.edu                addr = -addr;
8967342Sgblack@eecs.umich.edu            }
8977342Sgblack@eecs.umich.edu        } else {
8987342Sgblack@eecs.umich.edu            addr += (single ? 4 : 8);
8997342Sgblack@eecs.umich.edu        }
9007175Sgblack@eecs.umich.edu    }
9017175Sgblack@eecs.umich.edu
9027175Sgblack@eecs.umich.edu    if (writeback) {
9037175Sgblack@eecs.umich.edu        if (up) {
9047175Sgblack@eecs.umich.edu            microOps[i++] =
9057175Sgblack@eecs.umich.edu                new MicroAddiUop(machInst, rn, rn, 4 * offset);
9067175Sgblack@eecs.umich.edu        } else {
9077175Sgblack@eecs.umich.edu            microOps[i++] =
9087175Sgblack@eecs.umich.edu                new MicroSubiUop(machInst, rn, rn, 4 * offset);
9097175Sgblack@eecs.umich.edu        }
9107175Sgblack@eecs.umich.edu    }
9117175Sgblack@eecs.umich.edu
9127342Sgblack@eecs.umich.edu    assert(numMicroops == i);
9137175Sgblack@eecs.umich.edu    microOps[numMicroops - 1]->setLastMicroop();
9147343Sgblack@eecs.umich.edu
9157343Sgblack@eecs.umich.edu    for (StaticInstPtr *curUop = microOps;
9167343Sgblack@eecs.umich.edu            !(*curUop)->isLastMicroop(); curUop++) {
9177343Sgblack@eecs.umich.edu        MicroOp * uopPtr = dynamic_cast<MicroOp *>(curUop->get());
9187343Sgblack@eecs.umich.edu        assert(uopPtr);
9197343Sgblack@eecs.umich.edu        uopPtr->setDelayedCommit();
9207343Sgblack@eecs.umich.edu    }
9217170Sgblack@eecs.umich.edu}
9227175Sgblack@eecs.umich.edu
9237615Sminkyu.jeong@arm.comstd::string
9247639Sgblack@eecs.umich.eduMicroIntImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
9257639Sgblack@eecs.umich.edu{
9267639Sgblack@eecs.umich.edu    std::stringstream ss;
9277639Sgblack@eecs.umich.edu    printMnemonic(ss);
9287639Sgblack@eecs.umich.edu    printReg(ss, ura);
9297639Sgblack@eecs.umich.edu    ss << ", ";
9307639Sgblack@eecs.umich.edu    printReg(ss, urb);
9317639Sgblack@eecs.umich.edu    ss << ", ";
9327639Sgblack@eecs.umich.edu    ccprintf(ss, "#%d", imm);
9337639Sgblack@eecs.umich.edu    return ss.str();
9347639Sgblack@eecs.umich.edu}
9357639Sgblack@eecs.umich.edu
9367639Sgblack@eecs.umich.edustd::string
9378140SMatt.Horsnell@arm.comMicroSetPCCPSR::generateDisassembly(Addr pc, const SymbolTable *symtab) const
9388140SMatt.Horsnell@arm.com{
9398140SMatt.Horsnell@arm.com    std::stringstream ss;
9408140SMatt.Horsnell@arm.com    printMnemonic(ss);
9418140SMatt.Horsnell@arm.com    ss << "[PC,CPSR]";
9428140SMatt.Horsnell@arm.com    return ss.str();
9438140SMatt.Horsnell@arm.com}
9448140SMatt.Horsnell@arm.com
9458140SMatt.Horsnell@arm.comstd::string
9467646Sgene.wu@arm.comMicroIntMov::generateDisassembly(Addr pc, const SymbolTable *symtab) const
9477646Sgene.wu@arm.com{
9487646Sgene.wu@arm.com    std::stringstream ss;
9497646Sgene.wu@arm.com    printMnemonic(ss);
9507646Sgene.wu@arm.com    printReg(ss, ura);
9517646Sgene.wu@arm.com    ss << ", ";
9527646Sgene.wu@arm.com    printReg(ss, urb);
9537646Sgene.wu@arm.com    return ss.str();
9547646Sgene.wu@arm.com}
9557646Sgene.wu@arm.com
9567646Sgene.wu@arm.comstd::string
9577615Sminkyu.jeong@arm.comMicroIntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
9587615Sminkyu.jeong@arm.com{
9597615Sminkyu.jeong@arm.com    std::stringstream ss;
9607615Sminkyu.jeong@arm.com    printMnemonic(ss);
9617615Sminkyu.jeong@arm.com    printReg(ss, ura);
9627615Sminkyu.jeong@arm.com    ss << ", ";
9637615Sminkyu.jeong@arm.com    printReg(ss, urb);
9647615Sminkyu.jeong@arm.com    ss << ", ";
9657639Sgblack@eecs.umich.edu    printReg(ss, urc);
9667615Sminkyu.jeong@arm.com    return ss.str();
9677175Sgblack@eecs.umich.edu}
9687615Sminkyu.jeong@arm.com
9697615Sminkyu.jeong@arm.comstd::string
9707615Sminkyu.jeong@arm.comMicroMemOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
9717615Sminkyu.jeong@arm.com{
9727615Sminkyu.jeong@arm.com    std::stringstream ss;
9737615Sminkyu.jeong@arm.com    printMnemonic(ss);
9747615Sminkyu.jeong@arm.com    printReg(ss, ura);
9757615Sminkyu.jeong@arm.com    ss << ", [";
9767615Sminkyu.jeong@arm.com    printReg(ss, urb);
9777615Sminkyu.jeong@arm.com    ss << ", ";
9787615Sminkyu.jeong@arm.com    ccprintf(ss, "#%d", imm);
9797615Sminkyu.jeong@arm.com    ss << "]";
9807615Sminkyu.jeong@arm.com    return ss.str();
9817615Sminkyu.jeong@arm.com}
9827615Sminkyu.jeong@arm.com
9837615Sminkyu.jeong@arm.com}
984