17170Sgblack@eecs.umich.edu/*
210339Smitch.hayenga@arm.com * Copyright (c) 2010-2014 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
4311793Sbrandon.potter@amd.com#include "arch/arm/insts/macromem.hh"
4411793Sbrandon.potter@amd.com
458229Snate@binkert.org#include <sstream>
468229Snate@binkert.org
478961Sgblack@eecs.umich.edu#include "arch/arm/generated/decoder.hh"
4810037SARM gem5 Developers#include "arch/arm/insts/neon64_mem.hh"
497170Sgblack@eecs.umich.edu
507853SMatt.Horsnell@ARM.comusing namespace std;
517170Sgblack@eecs.umich.eduusing namespace ArmISAInst;
527170Sgblack@eecs.umich.edu
537170Sgblack@eecs.umich.edunamespace ArmISA
547170Sgblack@eecs.umich.edu{
557170Sgblack@eecs.umich.edu
567170Sgblack@eecs.umich.eduMacroMemOp::MacroMemOp(const char *mnem, ExtMachInst machInst,
577170Sgblack@eecs.umich.edu                       OpClass __opClass, IntRegIndex rn,
587170Sgblack@eecs.umich.edu                       bool index, bool up, bool user, bool writeback,
597170Sgblack@eecs.umich.edu                       bool load, uint32_t reglist) :
607170Sgblack@eecs.umich.edu    PredMacroOp(mnem, machInst, __opClass)
617170Sgblack@eecs.umich.edu{
627170Sgblack@eecs.umich.edu    uint32_t regs = reglist;
637170Sgblack@eecs.umich.edu    uint32_t ones = number_of_ones(reglist);
6410346Smitch.hayenga@arm.com    uint32_t mem_ops = ones;
658148SAli.Saidi@ARM.com
6610346Smitch.hayenga@arm.com    // Copy the base address register if we overwrite it, or if this instruction
6710346Smitch.hayenga@arm.com    // is basically a no-op (we have to do something)
6810346Smitch.hayenga@arm.com    bool copy_base =  (bits(reglist, rn) && load) || !ones;
6910346Smitch.hayenga@arm.com    bool force_user = user & !bits(reglist, 15);
7010346Smitch.hayenga@arm.com    bool exception_ret = user & bits(reglist, 15);
7110346Smitch.hayenga@arm.com    bool pc_temp = load && writeback && bits(reglist, 15);
7210346Smitch.hayenga@arm.com
7310346Smitch.hayenga@arm.com    if (!ones) {
748148SAli.Saidi@ARM.com        numMicroops = 1;
7510346Smitch.hayenga@arm.com    } else if (load) {
7610346Smitch.hayenga@arm.com        numMicroops = ((ones + 1) / 2)
7710346Smitch.hayenga@arm.com                    + ((ones % 2 == 0 && exception_ret) ? 1 : 0)
7810346Smitch.hayenga@arm.com                    + (copy_base ? 1 : 0)
7910346Smitch.hayenga@arm.com                    + (writeback? 1 : 0)
8010346Smitch.hayenga@arm.com                    + (pc_temp ? 1 : 0);
8110346Smitch.hayenga@arm.com    } else {
8210346Smitch.hayenga@arm.com        numMicroops = ones + (writeback ? 1 : 0);
8310346Smitch.hayenga@arm.com    }
848148SAli.Saidi@ARM.com
857170Sgblack@eecs.umich.edu    microOps = new StaticInstPtr[numMicroops];
8610346Smitch.hayenga@arm.com
877170Sgblack@eecs.umich.edu    uint32_t addr = 0;
887170Sgblack@eecs.umich.edu
897170Sgblack@eecs.umich.edu    if (!up)
907170Sgblack@eecs.umich.edu        addr = (ones << 2) - 4;
917170Sgblack@eecs.umich.edu
927170Sgblack@eecs.umich.edu    if (!index)
937170Sgblack@eecs.umich.edu        addr += 4;
947170Sgblack@eecs.umich.edu
957190Sgblack@eecs.umich.edu    StaticInstPtr *uop = microOps;
967190Sgblack@eecs.umich.edu
977170Sgblack@eecs.umich.edu    // Add 0 to Rn and stick it in ureg0.
987170Sgblack@eecs.umich.edu    // This is equivalent to a move.
9910346Smitch.hayenga@arm.com    if (copy_base)
10010346Smitch.hayenga@arm.com        *uop++ = new MicroAddiUop(machInst, INTREG_UREG0, rn, 0);
1017190Sgblack@eecs.umich.edu
1027170Sgblack@eecs.umich.edu    unsigned reg = 0;
10310346Smitch.hayenga@arm.com    while (mem_ops != 0) {
10410346Smitch.hayenga@arm.com        // Do load operations in pairs if possible
10510346Smitch.hayenga@arm.com        if (load && mem_ops >= 2 &&
10610346Smitch.hayenga@arm.com            !(mem_ops == 2 && bits(regs,INTREG_PC) && exception_ret)) {
10710346Smitch.hayenga@arm.com            // 64-bit memory operation
10810346Smitch.hayenga@arm.com            // Find 2 set register bits (clear them after finding)
10910346Smitch.hayenga@arm.com            unsigned reg_idx1;
11010346Smitch.hayenga@arm.com            unsigned reg_idx2;
1117170Sgblack@eecs.umich.edu
11210346Smitch.hayenga@arm.com            // Find the first register
11310346Smitch.hayenga@arm.com            while (!bits(regs, reg)) reg++;
11410346Smitch.hayenga@arm.com            replaceBits(regs, reg, 0);
11510346Smitch.hayenga@arm.com            reg_idx1 = force_user ? intRegInMode(MODE_USER, reg) : reg;
1167170Sgblack@eecs.umich.edu
11710346Smitch.hayenga@arm.com            // Find the second register
11810346Smitch.hayenga@arm.com            while (!bits(regs, reg)) reg++;
11910346Smitch.hayenga@arm.com            replaceBits(regs, reg, 0);
12010346Smitch.hayenga@arm.com            reg_idx2 = force_user ? intRegInMode(MODE_USER, reg) : reg;
1217170Sgblack@eecs.umich.edu
12210346Smitch.hayenga@arm.com            // Load into temp reg if necessary
12310346Smitch.hayenga@arm.com            if (reg_idx2 == INTREG_PC && pc_temp)
12410346Smitch.hayenga@arm.com                reg_idx2 = INTREG_UREG1;
12510346Smitch.hayenga@arm.com
12610346Smitch.hayenga@arm.com            // Actually load both registers from memory
12710346Smitch.hayenga@arm.com            *uop = new MicroLdr2Uop(machInst, reg_idx1, reg_idx2,
12810346Smitch.hayenga@arm.com                    copy_base ? INTREG_UREG0 : rn, up, addr);
12910346Smitch.hayenga@arm.com
13010346Smitch.hayenga@arm.com            if (!writeback && reg_idx2 == INTREG_PC) {
13110346Smitch.hayenga@arm.com                // No writeback if idx==pc, set appropriate flags
13210346Smitch.hayenga@arm.com                (*uop)->setFlag(StaticInst::IsControl);
13310346Smitch.hayenga@arm.com                (*uop)->setFlag(StaticInst::IsIndirectControl);
13410346Smitch.hayenga@arm.com
13510346Smitch.hayenga@arm.com                if (!(condCode == COND_AL || condCode == COND_UC))
13610346Smitch.hayenga@arm.com                    (*uop)->setFlag(StaticInst::IsCondControl);
13710346Smitch.hayenga@arm.com                else
13810346Smitch.hayenga@arm.com                    (*uop)->setFlag(StaticInst::IsUncondControl);
13910346Smitch.hayenga@arm.com            }
14010346Smitch.hayenga@arm.com
14110346Smitch.hayenga@arm.com            if (up) addr += 8;
14210346Smitch.hayenga@arm.com            else addr -= 8;
14310346Smitch.hayenga@arm.com            mem_ops -= 2;
14410346Smitch.hayenga@arm.com        } else {
14510346Smitch.hayenga@arm.com            // 32-bit memory operation
14610346Smitch.hayenga@arm.com            // Find register for operation
14710346Smitch.hayenga@arm.com            unsigned reg_idx;
14811321Ssteve.reinhardt@amd.com            while (!bits(regs, reg)) reg++;
14910346Smitch.hayenga@arm.com            replaceBits(regs, reg, 0);
15010346Smitch.hayenga@arm.com            reg_idx = force_user ? intRegInMode(MODE_USER, reg) : reg;
15110346Smitch.hayenga@arm.com
15210346Smitch.hayenga@arm.com            if (load) {
15310346Smitch.hayenga@arm.com                if (writeback && reg_idx == INTREG_PC) {
15410346Smitch.hayenga@arm.com                    // If this instruction changes the PC and performs a
15510346Smitch.hayenga@arm.com                    // writeback, ensure the pc load/branch is the last uop.
15610346Smitch.hayenga@arm.com                    // Load into a temp reg here.
15710346Smitch.hayenga@arm.com                    *uop = new MicroLdrUop(machInst, INTREG_UREG1,
15810346Smitch.hayenga@arm.com                            copy_base ? INTREG_UREG0 : rn, up, addr);
15910346Smitch.hayenga@arm.com                } else if (reg_idx == INTREG_PC && exception_ret) {
16010346Smitch.hayenga@arm.com                    // Special handling for exception return
16110346Smitch.hayenga@arm.com                    *uop = new MicroLdrRetUop(machInst, reg_idx,
16210346Smitch.hayenga@arm.com                            copy_base ? INTREG_UREG0 : rn, up, addr);
16310346Smitch.hayenga@arm.com                } else {
16410346Smitch.hayenga@arm.com                    // standard single load uop
16510346Smitch.hayenga@arm.com                    *uop = new MicroLdrUop(machInst, reg_idx,
16610346Smitch.hayenga@arm.com                            copy_base ? INTREG_UREG0 : rn, up, addr);
16710346Smitch.hayenga@arm.com                }
16810346Smitch.hayenga@arm.com
16910346Smitch.hayenga@arm.com                // Loading pc as last operation?  Set appropriate flags.
17010346Smitch.hayenga@arm.com                if (!writeback && reg_idx == INTREG_PC) {
17110346Smitch.hayenga@arm.com                    (*uop)->setFlag(StaticInst::IsControl);
17210346Smitch.hayenga@arm.com                    (*uop)->setFlag(StaticInst::IsIndirectControl);
17310346Smitch.hayenga@arm.com
1749640Snathanael.premillieu@irisa.fr                    if (!(condCode == COND_AL || condCode == COND_UC))
1759640Snathanael.premillieu@irisa.fr                        (*uop)->setFlag(StaticInst::IsCondControl);
1769640Snathanael.premillieu@irisa.fr                    else
1779640Snathanael.premillieu@irisa.fr                        (*uop)->setFlag(StaticInst::IsUncondControl);
1788148SAli.Saidi@ARM.com                }
17910346Smitch.hayenga@arm.com            } else {
18010346Smitch.hayenga@arm.com                *uop = new MicroStrUop(machInst, reg_idx, rn, up, addr);
1817170Sgblack@eecs.umich.edu            }
18210346Smitch.hayenga@arm.com
18310346Smitch.hayenga@arm.com            if (up) addr += 4;
18410346Smitch.hayenga@arm.com            else addr -= 4;
18510346Smitch.hayenga@arm.com            --mem_ops;
1867170Sgblack@eecs.umich.edu        }
1877170Sgblack@eecs.umich.edu
18810346Smitch.hayenga@arm.com        // Load/store micro-op generated, go to next uop
18910346Smitch.hayenga@arm.com        ++uop;
1907170Sgblack@eecs.umich.edu    }
1917170Sgblack@eecs.umich.edu
1928148SAli.Saidi@ARM.com    if (writeback && ones) {
19310346Smitch.hayenga@arm.com        // Perform writeback uop operation
1948148SAli.Saidi@ARM.com        if (up)
19510346Smitch.hayenga@arm.com            *uop++ = new MicroAddiUop(machInst, rn, rn, ones * 4);
1968148SAli.Saidi@ARM.com        else
19710346Smitch.hayenga@arm.com            *uop++ = new MicroSubiUop(machInst, rn, rn, ones * 4);
1988148SAli.Saidi@ARM.com
19910346Smitch.hayenga@arm.com        // Write PC after address writeback?
20010346Smitch.hayenga@arm.com        if (pc_temp) {
20110346Smitch.hayenga@arm.com            if (exception_ret) {
20210346Smitch.hayenga@arm.com                *uop = new MicroUopRegMovRet(machInst, 0, INTREG_UREG1);
20310346Smitch.hayenga@arm.com            } else {
20410346Smitch.hayenga@arm.com                *uop = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG1);
20510346Smitch.hayenga@arm.com            }
20610346Smitch.hayenga@arm.com            (*uop)->setFlag(StaticInst::IsControl);
20710346Smitch.hayenga@arm.com            (*uop)->setFlag(StaticInst::IsIndirectControl);
20810346Smitch.hayenga@arm.com
2099368Snathanael.premillieu@irisa.fr            if (!(condCode == COND_AL || condCode == COND_UC))
2109368Snathanael.premillieu@irisa.fr                (*uop)->setFlag(StaticInst::IsCondControl);
2119368Snathanael.premillieu@irisa.fr            else
2129368Snathanael.premillieu@irisa.fr                (*uop)->setFlag(StaticInst::IsUncondControl);
2138148SAli.Saidi@ARM.com
21410346Smitch.hayenga@arm.com            if (rn == INTREG_SP)
21510346Smitch.hayenga@arm.com                (*uop)->setFlag(StaticInst::IsReturn);
21610346Smitch.hayenga@arm.com
21710346Smitch.hayenga@arm.com            ++uop;
2188148SAli.Saidi@ARM.com        }
2197170Sgblack@eecs.umich.edu    }
2207190Sgblack@eecs.umich.edu
22110346Smitch.hayenga@arm.com    --uop;
2227190Sgblack@eecs.umich.edu    (*uop)->setLastMicroop();
22310666SAli.Saidi@ARM.com    microOps[0]->setFirstMicroop();
2247343Sgblack@eecs.umich.edu
22510199SAndrew.Bardsley@arm.com    /* Take the control flags from the last microop for the macroop */
22610199SAndrew.Bardsley@arm.com    if ((*uop)->isControl())
22710199SAndrew.Bardsley@arm.com        setFlag(StaticInst::IsControl);
22810199SAndrew.Bardsley@arm.com    if ((*uop)->isCondCtrl())
22910199SAndrew.Bardsley@arm.com        setFlag(StaticInst::IsCondControl);
23010346Smitch.hayenga@arm.com    if ((*uop)->isUncondCtrl())
23110346Smitch.hayenga@arm.com        setFlag(StaticInst::IsUncondControl);
23210199SAndrew.Bardsley@arm.com    if ((*uop)->isIndirectCtrl())
23310199SAndrew.Bardsley@arm.com        setFlag(StaticInst::IsIndirectControl);
23410199SAndrew.Bardsley@arm.com    if ((*uop)->isReturn())
23510199SAndrew.Bardsley@arm.com        setFlag(StaticInst::IsReturn);
23610199SAndrew.Bardsley@arm.com
23710346Smitch.hayenga@arm.com    for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) {
23810346Smitch.hayenga@arm.com        (*uop)->setDelayedCommit();
2397343Sgblack@eecs.umich.edu    }
2407170Sgblack@eecs.umich.edu}
2417170Sgblack@eecs.umich.edu
24210037SARM gem5 DevelopersPairMemOp::PairMemOp(const char *mnem, ExtMachInst machInst, OpClass __opClass,
24310037SARM gem5 Developers                     uint32_t size, bool fp, bool load, bool noAlloc,
24410037SARM gem5 Developers                     bool signExt, bool exclusive, bool acrel,
24510037SARM gem5 Developers                     int64_t imm, AddrMode mode,
24610037SARM gem5 Developers                     IntRegIndex rn, IntRegIndex rt, IntRegIndex rt2) :
24710037SARM gem5 Developers    PredMacroOp(mnem, machInst, __opClass)
24810037SARM gem5 Developers{
24910346Smitch.hayenga@arm.com    bool post = (mode == AddrMd_PostIndex);
25010037SARM gem5 Developers    bool writeback = (mode != AddrMd_Offset);
25110346Smitch.hayenga@arm.com
25210346Smitch.hayenga@arm.com    if (load) {
25310346Smitch.hayenga@arm.com        // Use integer rounding to round up loads of size 4
25410346Smitch.hayenga@arm.com        numMicroops = (post ? 0 : 1) + ((size + 4) / 8) + (writeback ? 1 : 0);
25510346Smitch.hayenga@arm.com    } else {
25610346Smitch.hayenga@arm.com        numMicroops = (post ? 0 : 1) + (size / 4) + (writeback ? 1 : 0);
25710346Smitch.hayenga@arm.com    }
25810037SARM gem5 Developers    microOps = new StaticInstPtr[numMicroops];
25910037SARM gem5 Developers
26010037SARM gem5 Developers    StaticInstPtr *uop = microOps;
26110037SARM gem5 Developers
26210037SARM gem5 Developers    rn = makeSP(rn);
26310037SARM gem5 Developers
26410346Smitch.hayenga@arm.com    if (!post) {
26510346Smitch.hayenga@arm.com        *uop++ = new MicroAddXiSpAlignUop(machInst, INTREG_UREG0, rn,
26610346Smitch.hayenga@arm.com                post ? 0 : imm);
26710346Smitch.hayenga@arm.com    }
26810037SARM gem5 Developers
26910037SARM gem5 Developers    if (fp) {
27010037SARM gem5 Developers        if (size == 16) {
27110037SARM gem5 Developers            if (load) {
27210346Smitch.hayenga@arm.com                *uop++ = new MicroLdFp16Uop(machInst, rt,
27310346Smitch.hayenga@arm.com                        post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel);
27410346Smitch.hayenga@arm.com                *uop++ = new MicroLdFp16Uop(machInst, rt2,
27510346Smitch.hayenga@arm.com                        post ? rn : INTREG_UREG0, 16, noAlloc, exclusive, acrel);
27610037SARM gem5 Developers            } else {
27710346Smitch.hayenga@arm.com                *uop++ = new MicroStrQBFpXImmUop(machInst, rt,
27810346Smitch.hayenga@arm.com                        post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel);
27910346Smitch.hayenga@arm.com                *uop++ = new MicroStrQTFpXImmUop(machInst, rt,
28010346Smitch.hayenga@arm.com                        post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel);
28110346Smitch.hayenga@arm.com                *uop++ = new MicroStrQBFpXImmUop(machInst, rt2,
28210346Smitch.hayenga@arm.com                        post ? rn : INTREG_UREG0, 16, noAlloc, exclusive, acrel);
28310346Smitch.hayenga@arm.com                *uop++ = new MicroStrQTFpXImmUop(machInst, rt2,
28410346Smitch.hayenga@arm.com                        post ? rn : INTREG_UREG0, 16, noAlloc, exclusive, acrel);
28510037SARM gem5 Developers            }
28610037SARM gem5 Developers        } else if (size == 8) {
28710037SARM gem5 Developers            if (load) {
28810346Smitch.hayenga@arm.com                *uop++ = new MicroLdPairFp8Uop(machInst, rt, rt2,
28910346Smitch.hayenga@arm.com                        post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel);
29010037SARM gem5 Developers            } else {
29110346Smitch.hayenga@arm.com                *uop++ = new MicroStrFpXImmUop(machInst, rt,
29210346Smitch.hayenga@arm.com                        post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel);
29310346Smitch.hayenga@arm.com                *uop++ = new MicroStrFpXImmUop(machInst, rt2,
29410346Smitch.hayenga@arm.com                        post ? rn : INTREG_UREG0, 8, noAlloc, exclusive, acrel);
29510037SARM gem5 Developers            }
29610037SARM gem5 Developers        } else if (size == 4) {
29710037SARM gem5 Developers            if (load) {
29810346Smitch.hayenga@arm.com                *uop++ = new MicroLdrDFpXImmUop(machInst, rt, rt2,
29910346Smitch.hayenga@arm.com                        post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel);
30010037SARM gem5 Developers            } else {
30110346Smitch.hayenga@arm.com                *uop++ = new MicroStrDFpXImmUop(machInst, rt, rt2,
30210346Smitch.hayenga@arm.com                        post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel);
30310037SARM gem5 Developers            }
30410037SARM gem5 Developers        }
30510037SARM gem5 Developers    } else {
30610037SARM gem5 Developers        if (size == 8) {
30710037SARM gem5 Developers            if (load) {
30810346Smitch.hayenga@arm.com                *uop++ = new MicroLdPairUop(machInst, rt, rt2,
30910346Smitch.hayenga@arm.com                        post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel);
31010346Smitch.hayenga@arm.com            } else {
31110346Smitch.hayenga@arm.com                *uop++ = new MicroStrXImmUop(machInst, rt, post ? rn : INTREG_UREG0,
31210037SARM gem5 Developers                        0, noAlloc, exclusive, acrel);
31310346Smitch.hayenga@arm.com                *uop++ = new MicroStrXImmUop(machInst, rt2, post ? rn : INTREG_UREG0,
31410037SARM gem5 Developers                        size, noAlloc, exclusive, acrel);
31510037SARM gem5 Developers            }
31610037SARM gem5 Developers        } else if (size == 4) {
31710037SARM gem5 Developers            if (load) {
31810037SARM gem5 Developers                if (signExt) {
31910346Smitch.hayenga@arm.com                    *uop++ = new MicroLdrDSXImmUop(machInst, rt, rt2,
32010346Smitch.hayenga@arm.com                            post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel);
32110037SARM gem5 Developers                } else {
32210346Smitch.hayenga@arm.com                    *uop++ = new MicroLdrDUXImmUop(machInst, rt, rt2,
32310346Smitch.hayenga@arm.com                            post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel);
32410037SARM gem5 Developers                }
32510037SARM gem5 Developers            } else {
32610346Smitch.hayenga@arm.com                *uop++ = new MicroStrDXImmUop(machInst, rt, rt2,
32710346Smitch.hayenga@arm.com                        post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel);
32810037SARM gem5 Developers            }
32910037SARM gem5 Developers        }
33010037SARM gem5 Developers    }
33110037SARM gem5 Developers
33210037SARM gem5 Developers    if (writeback) {
33310346Smitch.hayenga@arm.com        *uop++ = new MicroAddXiUop(machInst, rn, post ? rn : INTREG_UREG0,
33410037SARM gem5 Developers                                   post ? imm : 0);
33510037SARM gem5 Developers    }
33610037SARM gem5 Developers
33710346Smitch.hayenga@arm.com    assert(uop == &microOps[numMicroops]);
33810346Smitch.hayenga@arm.com    (*--uop)->setLastMicroop();
33910666SAli.Saidi@ARM.com    microOps[0]->setFirstMicroop();
34010037SARM gem5 Developers
34110037SARM gem5 Developers    for (StaticInstPtr *curUop = microOps;
34210037SARM gem5 Developers            !(*curUop)->isLastMicroop(); curUop++) {
34310037SARM gem5 Developers        (*curUop)->setDelayedCommit();
34410037SARM gem5 Developers    }
34510037SARM gem5 Developers}
34610037SARM gem5 Developers
34710037SARM gem5 DevelopersBigFpMemImmOp::BigFpMemImmOp(const char *mnem, ExtMachInst machInst,
34810037SARM gem5 Developers                             OpClass __opClass, bool load, IntRegIndex dest,
34910037SARM gem5 Developers                             IntRegIndex base, int64_t imm) :
35010037SARM gem5 Developers    PredMacroOp(mnem, machInst, __opClass)
35110037SARM gem5 Developers{
35210346Smitch.hayenga@arm.com    numMicroops = load ? 1 : 2;
35310037SARM gem5 Developers    microOps = new StaticInstPtr[numMicroops];
35410037SARM gem5 Developers
35510346Smitch.hayenga@arm.com    StaticInstPtr *uop = microOps;
35610346Smitch.hayenga@arm.com
35710037SARM gem5 Developers    if (load) {
35810346Smitch.hayenga@arm.com        *uop = new MicroLdFp16Uop(machInst, dest, base, imm);
35910037SARM gem5 Developers    } else {
36010346Smitch.hayenga@arm.com        *uop = new MicroStrQBFpXImmUop(machInst, dest, base, imm);
36110346Smitch.hayenga@arm.com        (*uop)->setDelayedCommit();
36210346Smitch.hayenga@arm.com        *++uop = new MicroStrQTFpXImmUop(machInst, dest, base, imm);
36310037SARM gem5 Developers    }
36410346Smitch.hayenga@arm.com    (*uop)->setLastMicroop();
36510666SAli.Saidi@ARM.com    microOps[0]->setFirstMicroop();
36610037SARM gem5 Developers}
36710037SARM gem5 Developers
36810037SARM gem5 DevelopersBigFpMemPostOp::BigFpMemPostOp(const char *mnem, ExtMachInst machInst,
36910037SARM gem5 Developers                               OpClass __opClass, bool load, IntRegIndex dest,
37010037SARM gem5 Developers                               IntRegIndex base, int64_t imm) :
37110037SARM gem5 Developers    PredMacroOp(mnem, machInst, __opClass)
37210037SARM gem5 Developers{
37310346Smitch.hayenga@arm.com    numMicroops = load ? 2 : 3;
37410037SARM gem5 Developers    microOps = new StaticInstPtr[numMicroops];
37510037SARM gem5 Developers
37610346Smitch.hayenga@arm.com    StaticInstPtr *uop = microOps;
37710346Smitch.hayenga@arm.com
37810037SARM gem5 Developers    if (load) {
37910346Smitch.hayenga@arm.com        *uop++ = new MicroLdFp16Uop(machInst, dest, base, 0);
38010037SARM gem5 Developers    } else {
38110346Smitch.hayenga@arm.com        *uop++= new MicroStrQBFpXImmUop(machInst, dest, base, 0);
38210346Smitch.hayenga@arm.com        *uop++ = new MicroStrQTFpXImmUop(machInst, dest, base, 0);
38310037SARM gem5 Developers    }
38410346Smitch.hayenga@arm.com    *uop = new MicroAddXiUop(machInst, base, base, imm);
38510346Smitch.hayenga@arm.com    (*uop)->setLastMicroop();
38610666SAli.Saidi@ARM.com    microOps[0]->setFirstMicroop();
38710037SARM gem5 Developers
38810346Smitch.hayenga@arm.com    for (StaticInstPtr *curUop = microOps;
38910346Smitch.hayenga@arm.com            !(*curUop)->isLastMicroop(); curUop++) {
39010346Smitch.hayenga@arm.com        (*curUop)->setDelayedCommit();
39110346Smitch.hayenga@arm.com    }
39210037SARM gem5 Developers}
39310037SARM gem5 Developers
39410037SARM gem5 DevelopersBigFpMemPreOp::BigFpMemPreOp(const char *mnem, ExtMachInst machInst,
39510037SARM gem5 Developers                             OpClass __opClass, bool load, IntRegIndex dest,
39610037SARM gem5 Developers                             IntRegIndex base, int64_t imm) :
39710037SARM gem5 Developers    PredMacroOp(mnem, machInst, __opClass)
39810037SARM gem5 Developers{
39910346Smitch.hayenga@arm.com    numMicroops = load ? 2 : 3;
40010037SARM gem5 Developers    microOps = new StaticInstPtr[numMicroops];
40110037SARM gem5 Developers
40210346Smitch.hayenga@arm.com    StaticInstPtr *uop = microOps;
40310346Smitch.hayenga@arm.com
40410037SARM gem5 Developers    if (load) {
40510346Smitch.hayenga@arm.com        *uop++ = new MicroLdFp16Uop(machInst, dest, base, imm);
40610037SARM gem5 Developers    } else {
40710346Smitch.hayenga@arm.com        *uop++ = new MicroStrQBFpXImmUop(machInst, dest, base, imm);
40810346Smitch.hayenga@arm.com        *uop++ = new MicroStrQTFpXImmUop(machInst, dest, base, imm);
40910037SARM gem5 Developers    }
41010346Smitch.hayenga@arm.com    *uop = new MicroAddXiUop(machInst, base, base, imm);
41110346Smitch.hayenga@arm.com    (*uop)->setLastMicroop();
41210666SAli.Saidi@ARM.com    microOps[0]->setFirstMicroop();
41310037SARM gem5 Developers
41410346Smitch.hayenga@arm.com    for (StaticInstPtr *curUop = microOps;
41510346Smitch.hayenga@arm.com            !(*curUop)->isLastMicroop(); curUop++) {
41610346Smitch.hayenga@arm.com        (*curUop)->setDelayedCommit();
41710346Smitch.hayenga@arm.com    }
41810037SARM gem5 Developers}
41910037SARM gem5 Developers
42010037SARM gem5 DevelopersBigFpMemRegOp::BigFpMemRegOp(const char *mnem, ExtMachInst machInst,
42110037SARM gem5 Developers                             OpClass __opClass, bool load, IntRegIndex dest,
42210037SARM gem5 Developers                             IntRegIndex base, IntRegIndex offset,
42310037SARM gem5 Developers                             ArmExtendType type, int64_t imm) :
42410037SARM gem5 Developers    PredMacroOp(mnem, machInst, __opClass)
42510037SARM gem5 Developers{
42610346Smitch.hayenga@arm.com    numMicroops = load ? 1 : 2;
42710037SARM gem5 Developers    microOps = new StaticInstPtr[numMicroops];
42810037SARM gem5 Developers
42910346Smitch.hayenga@arm.com    StaticInstPtr *uop = microOps;
43010346Smitch.hayenga@arm.com
43110037SARM gem5 Developers    if (load) {
43210346Smitch.hayenga@arm.com        *uop = new MicroLdFp16RegUop(machInst, dest, base,
43310346Smitch.hayenga@arm.com                                  offset, type, imm);
43410037SARM gem5 Developers    } else {
43510346Smitch.hayenga@arm.com        *uop = new MicroStrQBFpXRegUop(machInst, dest, base,
43610346Smitch.hayenga@arm.com                                       offset, type, imm);
43710346Smitch.hayenga@arm.com        (*uop)->setDelayedCommit();
43810346Smitch.hayenga@arm.com        *++uop = new MicroStrQTFpXRegUop(machInst, dest, base,
43910346Smitch.hayenga@arm.com                                         offset, type, imm);
44010037SARM gem5 Developers    }
44110037SARM gem5 Developers
44210346Smitch.hayenga@arm.com    (*uop)->setLastMicroop();
44310666SAli.Saidi@ARM.com    microOps[0]->setFirstMicroop();
44410037SARM gem5 Developers}
44510037SARM gem5 Developers
44610037SARM gem5 DevelopersBigFpMemLitOp::BigFpMemLitOp(const char *mnem, ExtMachInst machInst,
44710037SARM gem5 Developers                             OpClass __opClass, IntRegIndex dest,
44810037SARM gem5 Developers                             int64_t imm) :
44910037SARM gem5 Developers    PredMacroOp(mnem, machInst, __opClass)
45010037SARM gem5 Developers{
45110346Smitch.hayenga@arm.com    numMicroops = 1;
45210037SARM gem5 Developers    microOps = new StaticInstPtr[numMicroops];
45310037SARM gem5 Developers
45410346Smitch.hayenga@arm.com    microOps[0] = new MicroLdFp16LitUop(machInst, dest, imm);
45510346Smitch.hayenga@arm.com    microOps[0]->setLastMicroop();
45610666SAli.Saidi@ARM.com    microOps[0]->setFirstMicroop();
45710037SARM gem5 Developers}
45810037SARM gem5 Developers
4597639Sgblack@eecs.umich.eduVldMultOp::VldMultOp(const char *mnem, ExtMachInst machInst, OpClass __opClass,
4607639Sgblack@eecs.umich.edu                     unsigned elems, RegIndex rn, RegIndex vd, unsigned regs,
4617639Sgblack@eecs.umich.edu                     unsigned inc, uint32_t size, uint32_t align, RegIndex rm) :
4627639Sgblack@eecs.umich.edu    PredMacroOp(mnem, machInst, __opClass)
4637639Sgblack@eecs.umich.edu{
4647639Sgblack@eecs.umich.edu    assert(regs > 0 && regs <= 4);
4657639Sgblack@eecs.umich.edu    assert(regs % elems == 0);
4667639Sgblack@eecs.umich.edu
4677639Sgblack@eecs.umich.edu    numMicroops = (regs > 2) ? 2 : 1;
4687639Sgblack@eecs.umich.edu    bool wb = (rm != 15);
4697639Sgblack@eecs.umich.edu    bool deinterleave = (elems > 1);
4707639Sgblack@eecs.umich.edu
4717639Sgblack@eecs.umich.edu    if (wb) numMicroops++;
4727639Sgblack@eecs.umich.edu    if (deinterleave) numMicroops += (regs / elems);
4737639Sgblack@eecs.umich.edu    microOps = new StaticInstPtr[numMicroops];
4747639Sgblack@eecs.umich.edu
47510037SARM gem5 Developers    RegIndex rMid = deinterleave ? NumFloatV7ArchRegs : vd * 2;
4767639Sgblack@eecs.umich.edu
4777639Sgblack@eecs.umich.edu    uint32_t noAlign = TLB::MustBeOne;
4787639Sgblack@eecs.umich.edu
4797639Sgblack@eecs.umich.edu    unsigned uopIdx = 0;
4807639Sgblack@eecs.umich.edu    switch (regs) {
4817639Sgblack@eecs.umich.edu      case 4:
4827639Sgblack@eecs.umich.edu        microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>(
4837639Sgblack@eecs.umich.edu                size, machInst, rMid, rn, 0, align);
4847639Sgblack@eecs.umich.edu        microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>(
4857639Sgblack@eecs.umich.edu                size, machInst, rMid + 4, rn, 16, noAlign);
4867639Sgblack@eecs.umich.edu        break;
4877639Sgblack@eecs.umich.edu      case 3:
4887639Sgblack@eecs.umich.edu        microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>(
4897639Sgblack@eecs.umich.edu                size, machInst, rMid, rn, 0, align);
4907639Sgblack@eecs.umich.edu        microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon8Uop>(
4917639Sgblack@eecs.umich.edu                size, machInst, rMid + 4, rn, 16, noAlign);
4927639Sgblack@eecs.umich.edu        break;
4937639Sgblack@eecs.umich.edu      case 2:
4947639Sgblack@eecs.umich.edu        microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>(
4957639Sgblack@eecs.umich.edu                size, machInst, rMid, rn, 0, align);
4967639Sgblack@eecs.umich.edu        break;
4977639Sgblack@eecs.umich.edu      case 1:
4987639Sgblack@eecs.umich.edu        microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon8Uop>(
4997639Sgblack@eecs.umich.edu                size, machInst, rMid, rn, 0, align);
5007639Sgblack@eecs.umich.edu        break;
5017639Sgblack@eecs.umich.edu      default:
5027853SMatt.Horsnell@ARM.com        // Unknown number of registers
5037853SMatt.Horsnell@ARM.com        microOps[uopIdx++] = new Unknown(machInst);
5047639Sgblack@eecs.umich.edu    }
5057639Sgblack@eecs.umich.edu    if (wb) {
5067639Sgblack@eecs.umich.edu        if (rm != 15 && rm != 13) {
5077639Sgblack@eecs.umich.edu            microOps[uopIdx++] =
5087646Sgene.wu@arm.com                new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL);
5097639Sgblack@eecs.umich.edu        } else {
5107639Sgblack@eecs.umich.edu            microOps[uopIdx++] =
5117639Sgblack@eecs.umich.edu                new MicroAddiUop(machInst, rn, rn, regs * 8);
5127639Sgblack@eecs.umich.edu        }
5137639Sgblack@eecs.umich.edu    }
5147639Sgblack@eecs.umich.edu    if (deinterleave) {
5157639Sgblack@eecs.umich.edu        switch (elems) {
5167639Sgblack@eecs.umich.edu          case 4:
5177639Sgblack@eecs.umich.edu            assert(regs == 4);
5187639Sgblack@eecs.umich.edu            microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon8Uop>(
5197639Sgblack@eecs.umich.edu                    size, machInst, vd * 2, rMid, inc * 2);
5207639Sgblack@eecs.umich.edu            break;
5217639Sgblack@eecs.umich.edu          case 3:
5227639Sgblack@eecs.umich.edu            assert(regs == 3);
5237639Sgblack@eecs.umich.edu            microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon6Uop>(
5247639Sgblack@eecs.umich.edu                    size, machInst, vd * 2, rMid, inc * 2);
5257639Sgblack@eecs.umich.edu            break;
5267639Sgblack@eecs.umich.edu          case 2:
5277639Sgblack@eecs.umich.edu            assert(regs == 4 || regs == 2);
5287639Sgblack@eecs.umich.edu            if (regs == 4) {
5297639Sgblack@eecs.umich.edu                microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>(
5307639Sgblack@eecs.umich.edu                        size, machInst, vd * 2, rMid, inc * 2);
5317639Sgblack@eecs.umich.edu                microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>(
5327639Sgblack@eecs.umich.edu                        size, machInst, vd * 2 + 2, rMid + 4, inc * 2);
5337639Sgblack@eecs.umich.edu            } else {
5347639Sgblack@eecs.umich.edu                microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>(
5357639Sgblack@eecs.umich.edu                        size, machInst, vd * 2, rMid, inc * 2);
5367639Sgblack@eecs.umich.edu            }
5377639Sgblack@eecs.umich.edu            break;
5387639Sgblack@eecs.umich.edu          default:
5397853SMatt.Horsnell@ARM.com            // Bad number of elements to deinterleave
5407853SMatt.Horsnell@ARM.com            microOps[uopIdx++] = new Unknown(machInst);
5417639Sgblack@eecs.umich.edu        }
5427639Sgblack@eecs.umich.edu    }
5437639Sgblack@eecs.umich.edu    assert(uopIdx == numMicroops);
5447639Sgblack@eecs.umich.edu
5457639Sgblack@eecs.umich.edu    for (unsigned i = 0; i < numMicroops - 1; i++) {
5467639Sgblack@eecs.umich.edu        MicroOp * uopPtr = dynamic_cast<MicroOp *>(microOps[i].get());
5477639Sgblack@eecs.umich.edu        assert(uopPtr);
5487639Sgblack@eecs.umich.edu        uopPtr->setDelayedCommit();
5497639Sgblack@eecs.umich.edu    }
55010666SAli.Saidi@ARM.com    microOps[0]->setFirstMicroop();
5517639Sgblack@eecs.umich.edu    microOps[numMicroops - 1]->setLastMicroop();
5527639Sgblack@eecs.umich.edu}
5537639Sgblack@eecs.umich.edu
5547639Sgblack@eecs.umich.eduVldSingleOp::VldSingleOp(const char *mnem, ExtMachInst machInst,
5557639Sgblack@eecs.umich.edu                         OpClass __opClass, bool all, unsigned elems,
5567639Sgblack@eecs.umich.edu                         RegIndex rn, RegIndex vd, unsigned regs,
5577639Sgblack@eecs.umich.edu                         unsigned inc, uint32_t size, uint32_t align,
5587639Sgblack@eecs.umich.edu                         RegIndex rm, unsigned lane) :
5597639Sgblack@eecs.umich.edu    PredMacroOp(mnem, machInst, __opClass)
5607639Sgblack@eecs.umich.edu{
5617639Sgblack@eecs.umich.edu    assert(regs > 0 && regs <= 4);
5627639Sgblack@eecs.umich.edu    assert(regs % elems == 0);
5637639Sgblack@eecs.umich.edu
5647639Sgblack@eecs.umich.edu    unsigned eBytes = (1 << size);
5657639Sgblack@eecs.umich.edu    unsigned loadSize = eBytes * elems;
56613544Sgabeblack@google.com    unsigned loadRegs M5_VAR_USED =
56713544Sgabeblack@google.com        (loadSize + sizeof(uint32_t) - 1) / sizeof(uint32_t);
5687639Sgblack@eecs.umich.edu
5697639Sgblack@eecs.umich.edu    assert(loadRegs > 0 && loadRegs <= 4);
5707639Sgblack@eecs.umich.edu
5717639Sgblack@eecs.umich.edu    numMicroops = 1;
5727639Sgblack@eecs.umich.edu    bool wb = (rm != 15);
5737639Sgblack@eecs.umich.edu
5747639Sgblack@eecs.umich.edu    if (wb) numMicroops++;
5757639Sgblack@eecs.umich.edu    numMicroops += (regs / elems);
5767639Sgblack@eecs.umich.edu    microOps = new StaticInstPtr[numMicroops];
5777639Sgblack@eecs.umich.edu
57810037SARM gem5 Developers    RegIndex ufp0 = NumFloatV7ArchRegs;
5797639Sgblack@eecs.umich.edu
5807639Sgblack@eecs.umich.edu    unsigned uopIdx = 0;
5817639Sgblack@eecs.umich.edu    switch (loadSize) {
5827639Sgblack@eecs.umich.edu      case 1:
5837639Sgblack@eecs.umich.edu        microOps[uopIdx++] = new MicroLdrNeon1Uop<uint8_t>(
5847639Sgblack@eecs.umich.edu                machInst, ufp0, rn, 0, align);
5857639Sgblack@eecs.umich.edu        break;
5867639Sgblack@eecs.umich.edu      case 2:
5877639Sgblack@eecs.umich.edu        if (eBytes == 2) {
5887639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroLdrNeon2Uop<uint16_t>(
5897639Sgblack@eecs.umich.edu                    machInst, ufp0, rn, 0, align);
5907639Sgblack@eecs.umich.edu        } else {
5917639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroLdrNeon2Uop<uint8_t>(
5927639Sgblack@eecs.umich.edu                    machInst, ufp0, rn, 0, align);
5937639Sgblack@eecs.umich.edu        }
5947639Sgblack@eecs.umich.edu        break;
5957639Sgblack@eecs.umich.edu      case 3:
5967639Sgblack@eecs.umich.edu        microOps[uopIdx++] = new MicroLdrNeon3Uop<uint8_t>(
5977639Sgblack@eecs.umich.edu                machInst, ufp0, rn, 0, align);
5987639Sgblack@eecs.umich.edu        break;
5997639Sgblack@eecs.umich.edu      case 4:
6007639Sgblack@eecs.umich.edu        switch (eBytes) {
6017639Sgblack@eecs.umich.edu          case 1:
6027639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroLdrNeon4Uop<uint8_t>(
6037639Sgblack@eecs.umich.edu                    machInst, ufp0, rn, 0, align);
6047639Sgblack@eecs.umich.edu            break;
6057639Sgblack@eecs.umich.edu          case 2:
6067639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroLdrNeon4Uop<uint16_t>(
6077639Sgblack@eecs.umich.edu                    machInst, ufp0, rn, 0, align);
6087639Sgblack@eecs.umich.edu            break;
6097639Sgblack@eecs.umich.edu          case 4:
6107639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroLdrNeon4Uop<uint32_t>(
6117639Sgblack@eecs.umich.edu                    machInst, ufp0, rn, 0, align);
6127639Sgblack@eecs.umich.edu            break;
6137639Sgblack@eecs.umich.edu        }
6147639Sgblack@eecs.umich.edu        break;
6157639Sgblack@eecs.umich.edu      case 6:
6167639Sgblack@eecs.umich.edu        microOps[uopIdx++] = new MicroLdrNeon6Uop<uint16_t>(
6177639Sgblack@eecs.umich.edu                machInst, ufp0, rn, 0, align);
6187639Sgblack@eecs.umich.edu        break;
6197639Sgblack@eecs.umich.edu      case 8:
6207639Sgblack@eecs.umich.edu        switch (eBytes) {
6217639Sgblack@eecs.umich.edu          case 2:
6227639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroLdrNeon8Uop<uint16_t>(
6237639Sgblack@eecs.umich.edu                    machInst, ufp0, rn, 0, align);
6247639Sgblack@eecs.umich.edu            break;
6257639Sgblack@eecs.umich.edu          case 4:
6267639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroLdrNeon8Uop<uint32_t>(
6277639Sgblack@eecs.umich.edu                    machInst, ufp0, rn, 0, align);
6287639Sgblack@eecs.umich.edu            break;
6297639Sgblack@eecs.umich.edu        }
6307639Sgblack@eecs.umich.edu        break;
6317639Sgblack@eecs.umich.edu      case 12:
6327639Sgblack@eecs.umich.edu        microOps[uopIdx++] = new MicroLdrNeon12Uop<uint32_t>(
6337639Sgblack@eecs.umich.edu                machInst, ufp0, rn, 0, align);
6347639Sgblack@eecs.umich.edu        break;
6357639Sgblack@eecs.umich.edu      case 16:
6367639Sgblack@eecs.umich.edu        microOps[uopIdx++] = new MicroLdrNeon16Uop<uint32_t>(
6377639Sgblack@eecs.umich.edu                machInst, ufp0, rn, 0, align);
6387639Sgblack@eecs.umich.edu        break;
6397639Sgblack@eecs.umich.edu      default:
6407853SMatt.Horsnell@ARM.com        // Unrecognized load size
6417853SMatt.Horsnell@ARM.com        microOps[uopIdx++] = new Unknown(machInst);
6427639Sgblack@eecs.umich.edu    }
6437639Sgblack@eecs.umich.edu    if (wb) {
6447639Sgblack@eecs.umich.edu        if (rm != 15 && rm != 13) {
6457639Sgblack@eecs.umich.edu            microOps[uopIdx++] =
6467646Sgene.wu@arm.com                new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL);
6477639Sgblack@eecs.umich.edu        } else {
6487639Sgblack@eecs.umich.edu            microOps[uopIdx++] =
6497639Sgblack@eecs.umich.edu                new MicroAddiUop(machInst, rn, rn, loadSize);
6507639Sgblack@eecs.umich.edu        }
6517639Sgblack@eecs.umich.edu    }
6527639Sgblack@eecs.umich.edu    switch (elems) {
6537639Sgblack@eecs.umich.edu      case 4:
6547639Sgblack@eecs.umich.edu        assert(regs == 4);
6557639Sgblack@eecs.umich.edu        switch (size) {
6567639Sgblack@eecs.umich.edu          case 0:
6577639Sgblack@eecs.umich.edu            if (all) {
6587639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroUnpackAllNeon2to8Uop<uint8_t>(
6597639Sgblack@eecs.umich.edu                        machInst, vd * 2, ufp0, inc * 2);
6607639Sgblack@eecs.umich.edu            } else {
6617639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroUnpackNeon2to8Uop<uint8_t>(
6627639Sgblack@eecs.umich.edu                        machInst, vd * 2, ufp0, inc * 2, lane);
6637639Sgblack@eecs.umich.edu            }
6647639Sgblack@eecs.umich.edu            break;
6657639Sgblack@eecs.umich.edu          case 1:
6667639Sgblack@eecs.umich.edu            if (all) {
6677639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroUnpackAllNeon2to8Uop<uint16_t>(
6687639Sgblack@eecs.umich.edu                        machInst, vd * 2, ufp0, inc * 2);
6697639Sgblack@eecs.umich.edu            } else {
6707639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroUnpackNeon2to8Uop<uint16_t>(
6717639Sgblack@eecs.umich.edu                        machInst, vd * 2, ufp0, inc * 2, lane);
6727639Sgblack@eecs.umich.edu            }
6737639Sgblack@eecs.umich.edu            break;
6747639Sgblack@eecs.umich.edu          case 2:
6757639Sgblack@eecs.umich.edu            if (all) {
6767639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroUnpackAllNeon4to8Uop<uint32_t>(
6777639Sgblack@eecs.umich.edu                        machInst, vd * 2, ufp0, inc * 2);
6787639Sgblack@eecs.umich.edu            } else {
6797639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroUnpackNeon4to8Uop<uint32_t>(
6807639Sgblack@eecs.umich.edu                        machInst, vd * 2, ufp0, inc * 2, lane);
6817639Sgblack@eecs.umich.edu            }
6827639Sgblack@eecs.umich.edu            break;
6837639Sgblack@eecs.umich.edu          default:
6847853SMatt.Horsnell@ARM.com            // Bad size
6857853SMatt.Horsnell@ARM.com            microOps[uopIdx++] = new Unknown(machInst);
6867639Sgblack@eecs.umich.edu            break;
6877639Sgblack@eecs.umich.edu        }
6887639Sgblack@eecs.umich.edu        break;
6897639Sgblack@eecs.umich.edu      case 3:
6907639Sgblack@eecs.umich.edu        assert(regs == 3);
6917639Sgblack@eecs.umich.edu        switch (size) {
6927639Sgblack@eecs.umich.edu          case 0:
6937639Sgblack@eecs.umich.edu            if (all) {
6947639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroUnpackAllNeon2to6Uop<uint8_t>(
6957639Sgblack@eecs.umich.edu                        machInst, vd * 2, ufp0, inc * 2);
6967639Sgblack@eecs.umich.edu            } else {
6977639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroUnpackNeon2to6Uop<uint8_t>(
6987639Sgblack@eecs.umich.edu                        machInst, vd * 2, ufp0, inc * 2, lane);
6997639Sgblack@eecs.umich.edu            }
7007639Sgblack@eecs.umich.edu            break;
7017639Sgblack@eecs.umich.edu          case 1:
7027639Sgblack@eecs.umich.edu            if (all) {
7037639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroUnpackAllNeon2to6Uop<uint16_t>(
7047639Sgblack@eecs.umich.edu                        machInst, vd * 2, ufp0, inc * 2);
7057639Sgblack@eecs.umich.edu            } else {
7067639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroUnpackNeon2to6Uop<uint16_t>(
7077639Sgblack@eecs.umich.edu                        machInst, vd * 2, ufp0, inc * 2, lane);
7087639Sgblack@eecs.umich.edu            }
7097639Sgblack@eecs.umich.edu            break;
7107639Sgblack@eecs.umich.edu          case 2:
7117639Sgblack@eecs.umich.edu            if (all) {
7127639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroUnpackAllNeon4to6Uop<uint32_t>(
7137639Sgblack@eecs.umich.edu                        machInst, vd * 2, ufp0, inc * 2);
7147639Sgblack@eecs.umich.edu            } else {
7157639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroUnpackNeon4to6Uop<uint32_t>(
7167639Sgblack@eecs.umich.edu                        machInst, vd * 2, ufp0, inc * 2, lane);
7177639Sgblack@eecs.umich.edu            }
7187639Sgblack@eecs.umich.edu            break;
7197639Sgblack@eecs.umich.edu          default:
7207853SMatt.Horsnell@ARM.com            // Bad size
7217853SMatt.Horsnell@ARM.com            microOps[uopIdx++] = new Unknown(machInst);
7227639Sgblack@eecs.umich.edu            break;
7237639Sgblack@eecs.umich.edu        }
7247639Sgblack@eecs.umich.edu        break;
7257639Sgblack@eecs.umich.edu      case 2:
7267639Sgblack@eecs.umich.edu        assert(regs == 2);
7277639Sgblack@eecs.umich.edu        assert(loadRegs <= 2);
7287639Sgblack@eecs.umich.edu        switch (size) {
7297639Sgblack@eecs.umich.edu          case 0:
7307639Sgblack@eecs.umich.edu            if (all) {
7317639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroUnpackAllNeon2to4Uop<uint8_t>(
7327639Sgblack@eecs.umich.edu                        machInst, vd * 2, ufp0, inc * 2);
7337639Sgblack@eecs.umich.edu            } else {
7347639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroUnpackNeon2to4Uop<uint8_t>(
7357639Sgblack@eecs.umich.edu                        machInst, vd * 2, ufp0, inc * 2, lane);
7367639Sgblack@eecs.umich.edu            }
7377639Sgblack@eecs.umich.edu            break;
7387639Sgblack@eecs.umich.edu          case 1:
7397639Sgblack@eecs.umich.edu            if (all) {
7407639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroUnpackAllNeon2to4Uop<uint16_t>(
7417639Sgblack@eecs.umich.edu                        machInst, vd * 2, ufp0, inc * 2);
7427639Sgblack@eecs.umich.edu            } else {
7437639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroUnpackNeon2to4Uop<uint16_t>(
7447639Sgblack@eecs.umich.edu                        machInst, vd * 2, ufp0, inc * 2, lane);
7457639Sgblack@eecs.umich.edu            }
7467639Sgblack@eecs.umich.edu            break;
7477639Sgblack@eecs.umich.edu          case 2:
7487639Sgblack@eecs.umich.edu            if (all) {
7497639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroUnpackAllNeon2to4Uop<uint32_t>(
7507639Sgblack@eecs.umich.edu                        machInst, vd * 2, ufp0, inc * 2);
7517639Sgblack@eecs.umich.edu            } else {
7527639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroUnpackNeon2to4Uop<uint32_t>(
7537639Sgblack@eecs.umich.edu                        machInst, vd * 2, ufp0, inc * 2, lane);
7547639Sgblack@eecs.umich.edu            }
7557639Sgblack@eecs.umich.edu            break;
7567639Sgblack@eecs.umich.edu          default:
7577853SMatt.Horsnell@ARM.com            // Bad size
7587853SMatt.Horsnell@ARM.com            microOps[uopIdx++] = new Unknown(machInst);
7597639Sgblack@eecs.umich.edu            break;
7607639Sgblack@eecs.umich.edu        }
7617639Sgblack@eecs.umich.edu        break;
7627639Sgblack@eecs.umich.edu      case 1:
7637639Sgblack@eecs.umich.edu        assert(regs == 1 || (all && regs == 2));
7647639Sgblack@eecs.umich.edu        assert(loadRegs <= 2);
7657639Sgblack@eecs.umich.edu        for (unsigned offset = 0; offset < regs; offset++) {
7667639Sgblack@eecs.umich.edu            switch (size) {
7677639Sgblack@eecs.umich.edu              case 0:
7687639Sgblack@eecs.umich.edu                if (all) {
7697639Sgblack@eecs.umich.edu                    microOps[uopIdx++] =
7707639Sgblack@eecs.umich.edu                        new MicroUnpackAllNeon2to2Uop<uint8_t>(
7717639Sgblack@eecs.umich.edu                            machInst, (vd + offset) * 2, ufp0, inc * 2);
7727639Sgblack@eecs.umich.edu                } else {
7737639Sgblack@eecs.umich.edu                    microOps[uopIdx++] =
7747639Sgblack@eecs.umich.edu                        new MicroUnpackNeon2to2Uop<uint8_t>(
7757639Sgblack@eecs.umich.edu                            machInst, (vd + offset) * 2, ufp0, inc * 2, lane);
7767639Sgblack@eecs.umich.edu                }
7777639Sgblack@eecs.umich.edu                break;
7787639Sgblack@eecs.umich.edu              case 1:
7797639Sgblack@eecs.umich.edu                if (all) {
7807639Sgblack@eecs.umich.edu                    microOps[uopIdx++] =
7817639Sgblack@eecs.umich.edu                        new MicroUnpackAllNeon2to2Uop<uint16_t>(
7827639Sgblack@eecs.umich.edu                            machInst, (vd + offset) * 2, ufp0, inc * 2);
7837639Sgblack@eecs.umich.edu                } else {
7847639Sgblack@eecs.umich.edu                    microOps[uopIdx++] =
7857639Sgblack@eecs.umich.edu                        new MicroUnpackNeon2to2Uop<uint16_t>(
7867639Sgblack@eecs.umich.edu                            machInst, (vd + offset) * 2, ufp0, inc * 2, lane);
7877639Sgblack@eecs.umich.edu                }
7887639Sgblack@eecs.umich.edu                break;
7897639Sgblack@eecs.umich.edu              case 2:
7907639Sgblack@eecs.umich.edu                if (all) {
7917639Sgblack@eecs.umich.edu                    microOps[uopIdx++] =
7927639Sgblack@eecs.umich.edu                        new MicroUnpackAllNeon2to2Uop<uint32_t>(
7937639Sgblack@eecs.umich.edu                            machInst, (vd + offset) * 2, ufp0, inc * 2);
7947639Sgblack@eecs.umich.edu                } else {
7957639Sgblack@eecs.umich.edu                    microOps[uopIdx++] =
7967639Sgblack@eecs.umich.edu                        new MicroUnpackNeon2to2Uop<uint32_t>(
7977639Sgblack@eecs.umich.edu                            machInst, (vd + offset) * 2, ufp0, inc * 2, lane);
7987639Sgblack@eecs.umich.edu                }
7997639Sgblack@eecs.umich.edu                break;
8007639Sgblack@eecs.umich.edu              default:
8017853SMatt.Horsnell@ARM.com                // Bad size
8027853SMatt.Horsnell@ARM.com                microOps[uopIdx++] = new Unknown(machInst);
8037639Sgblack@eecs.umich.edu                break;
8047639Sgblack@eecs.umich.edu            }
8057639Sgblack@eecs.umich.edu        }
8067639Sgblack@eecs.umich.edu        break;
8077639Sgblack@eecs.umich.edu      default:
8087853SMatt.Horsnell@ARM.com        // Bad number of elements to unpack
8097853SMatt.Horsnell@ARM.com        microOps[uopIdx++] = new Unknown(machInst);
8107639Sgblack@eecs.umich.edu    }
8117639Sgblack@eecs.umich.edu    assert(uopIdx == numMicroops);
8127639Sgblack@eecs.umich.edu
8137639Sgblack@eecs.umich.edu    for (unsigned i = 0; i < numMicroops - 1; i++) {
8147639Sgblack@eecs.umich.edu        MicroOp * uopPtr = dynamic_cast<MicroOp *>(microOps[i].get());
8157639Sgblack@eecs.umich.edu        assert(uopPtr);
8167639Sgblack@eecs.umich.edu        uopPtr->setDelayedCommit();
8177639Sgblack@eecs.umich.edu    }
81810666SAli.Saidi@ARM.com    microOps[0]->setFirstMicroop();
8197639Sgblack@eecs.umich.edu    microOps[numMicroops - 1]->setLastMicroop();
8207639Sgblack@eecs.umich.edu}
8217639Sgblack@eecs.umich.edu
8227639Sgblack@eecs.umich.eduVstMultOp::VstMultOp(const char *mnem, ExtMachInst machInst, OpClass __opClass,
8237639Sgblack@eecs.umich.edu                     unsigned elems, RegIndex rn, RegIndex vd, unsigned regs,
8247639Sgblack@eecs.umich.edu                     unsigned inc, uint32_t size, uint32_t align, RegIndex rm) :
8257639Sgblack@eecs.umich.edu    PredMacroOp(mnem, machInst, __opClass)
8267639Sgblack@eecs.umich.edu{
8277639Sgblack@eecs.umich.edu    assert(regs > 0 && regs <= 4);
8287639Sgblack@eecs.umich.edu    assert(regs % elems == 0);
8297639Sgblack@eecs.umich.edu
8307639Sgblack@eecs.umich.edu    numMicroops = (regs > 2) ? 2 : 1;
8317639Sgblack@eecs.umich.edu    bool wb = (rm != 15);
8327639Sgblack@eecs.umich.edu    bool interleave = (elems > 1);
8337639Sgblack@eecs.umich.edu
8347639Sgblack@eecs.umich.edu    if (wb) numMicroops++;
8357639Sgblack@eecs.umich.edu    if (interleave) numMicroops += (regs / elems);
8367639Sgblack@eecs.umich.edu    microOps = new StaticInstPtr[numMicroops];
8377639Sgblack@eecs.umich.edu
8387639Sgblack@eecs.umich.edu    uint32_t noAlign = TLB::MustBeOne;
8397639Sgblack@eecs.umich.edu
84010037SARM gem5 Developers    RegIndex rMid = interleave ? NumFloatV7ArchRegs : vd * 2;
8417639Sgblack@eecs.umich.edu
8427639Sgblack@eecs.umich.edu    unsigned uopIdx = 0;
8437639Sgblack@eecs.umich.edu    if (interleave) {
8447639Sgblack@eecs.umich.edu        switch (elems) {
8457639Sgblack@eecs.umich.edu          case 4:
8467639Sgblack@eecs.umich.edu            assert(regs == 4);
8477639Sgblack@eecs.umich.edu            microOps[uopIdx++] = newNeonMixInst<MicroInterNeon8Uop>(
8487639Sgblack@eecs.umich.edu                    size, machInst, rMid, vd * 2, inc * 2);
8497639Sgblack@eecs.umich.edu            break;
8507639Sgblack@eecs.umich.edu          case 3:
8517639Sgblack@eecs.umich.edu            assert(regs == 3);
8527639Sgblack@eecs.umich.edu            microOps[uopIdx++] = newNeonMixInst<MicroInterNeon6Uop>(
8537639Sgblack@eecs.umich.edu                    size, machInst, rMid, vd * 2, inc * 2);
8547639Sgblack@eecs.umich.edu            break;
8557639Sgblack@eecs.umich.edu          case 2:
8567639Sgblack@eecs.umich.edu            assert(regs == 4 || regs == 2);
8577639Sgblack@eecs.umich.edu            if (regs == 4) {
8587639Sgblack@eecs.umich.edu                microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>(
8597639Sgblack@eecs.umich.edu                        size, machInst, rMid, vd * 2, inc * 2);
8607639Sgblack@eecs.umich.edu                microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>(
8617639Sgblack@eecs.umich.edu                        size, machInst, rMid + 4, vd * 2 + 2, inc * 2);
8627639Sgblack@eecs.umich.edu            } else {
8637639Sgblack@eecs.umich.edu                microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>(
8647639Sgblack@eecs.umich.edu                        size, machInst, rMid, vd * 2, inc * 2);
8657639Sgblack@eecs.umich.edu            }
8667639Sgblack@eecs.umich.edu            break;
8677639Sgblack@eecs.umich.edu          default:
8687853SMatt.Horsnell@ARM.com            // Bad number of elements to interleave
8697853SMatt.Horsnell@ARM.com            microOps[uopIdx++] = new Unknown(machInst);
8707639Sgblack@eecs.umich.edu        }
8717639Sgblack@eecs.umich.edu    }
8727639Sgblack@eecs.umich.edu    switch (regs) {
8737639Sgblack@eecs.umich.edu      case 4:
8747639Sgblack@eecs.umich.edu        microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>(
8757639Sgblack@eecs.umich.edu                size, machInst, rMid, rn, 0, align);
8767639Sgblack@eecs.umich.edu        microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>(
8777639Sgblack@eecs.umich.edu                size, machInst, rMid + 4, rn, 16, noAlign);
8787639Sgblack@eecs.umich.edu        break;
8797639Sgblack@eecs.umich.edu      case 3:
8807639Sgblack@eecs.umich.edu        microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>(
8817639Sgblack@eecs.umich.edu                size, machInst, rMid, rn, 0, align);
8827639Sgblack@eecs.umich.edu        microOps[uopIdx++] = newNeonMemInst<MicroStrNeon8Uop>(
8837639Sgblack@eecs.umich.edu                size, machInst, rMid + 4, rn, 16, noAlign);
8847639Sgblack@eecs.umich.edu        break;
8857639Sgblack@eecs.umich.edu      case 2:
8867639Sgblack@eecs.umich.edu        microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>(
8877639Sgblack@eecs.umich.edu                size, machInst, rMid, rn, 0, align);
8887639Sgblack@eecs.umich.edu        break;
8897639Sgblack@eecs.umich.edu      case 1:
8907639Sgblack@eecs.umich.edu        microOps[uopIdx++] = newNeonMemInst<MicroStrNeon8Uop>(
8917639Sgblack@eecs.umich.edu                size, machInst, rMid, rn, 0, align);
8927639Sgblack@eecs.umich.edu        break;
8937639Sgblack@eecs.umich.edu      default:
8947853SMatt.Horsnell@ARM.com        // Unknown number of registers
8957853SMatt.Horsnell@ARM.com        microOps[uopIdx++] = new Unknown(machInst);
8967639Sgblack@eecs.umich.edu    }
8977639Sgblack@eecs.umich.edu    if (wb) {
8987639Sgblack@eecs.umich.edu        if (rm != 15 && rm != 13) {
8997639Sgblack@eecs.umich.edu            microOps[uopIdx++] =
9007646Sgene.wu@arm.com                new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL);
9017639Sgblack@eecs.umich.edu        } else {
9027639Sgblack@eecs.umich.edu            microOps[uopIdx++] =
9037639Sgblack@eecs.umich.edu                new MicroAddiUop(machInst, rn, rn, regs * 8);
9047639Sgblack@eecs.umich.edu        }
9057639Sgblack@eecs.umich.edu    }
9067639Sgblack@eecs.umich.edu    assert(uopIdx == numMicroops);
9077639Sgblack@eecs.umich.edu
9087639Sgblack@eecs.umich.edu    for (unsigned i = 0; i < numMicroops - 1; i++) {
9097639Sgblack@eecs.umich.edu        MicroOp * uopPtr = dynamic_cast<MicroOp *>(microOps[i].get());
9107639Sgblack@eecs.umich.edu        assert(uopPtr);
9117639Sgblack@eecs.umich.edu        uopPtr->setDelayedCommit();
9127639Sgblack@eecs.umich.edu    }
91310666SAli.Saidi@ARM.com    microOps[0]->setFirstMicroop();
9147639Sgblack@eecs.umich.edu    microOps[numMicroops - 1]->setLastMicroop();
9157639Sgblack@eecs.umich.edu}
9167639Sgblack@eecs.umich.edu
9177639Sgblack@eecs.umich.eduVstSingleOp::VstSingleOp(const char *mnem, ExtMachInst machInst,
9187639Sgblack@eecs.umich.edu                         OpClass __opClass, bool all, unsigned elems,
9197639Sgblack@eecs.umich.edu                         RegIndex rn, RegIndex vd, unsigned regs,
9207639Sgblack@eecs.umich.edu                         unsigned inc, uint32_t size, uint32_t align,
9217639Sgblack@eecs.umich.edu                         RegIndex rm, unsigned lane) :
9227639Sgblack@eecs.umich.edu    PredMacroOp(mnem, machInst, __opClass)
9237639Sgblack@eecs.umich.edu{
9247639Sgblack@eecs.umich.edu    assert(!all);
9257639Sgblack@eecs.umich.edu    assert(regs > 0 && regs <= 4);
9267639Sgblack@eecs.umich.edu    assert(regs % elems == 0);
9277639Sgblack@eecs.umich.edu
9287639Sgblack@eecs.umich.edu    unsigned eBytes = (1 << size);
9297639Sgblack@eecs.umich.edu    unsigned storeSize = eBytes * elems;
93013544Sgabeblack@google.com    unsigned storeRegs M5_VAR_USED =
93113544Sgabeblack@google.com        (storeSize + sizeof(uint32_t) - 1) / sizeof(uint32_t);
9327639Sgblack@eecs.umich.edu
9337639Sgblack@eecs.umich.edu    assert(storeRegs > 0 && storeRegs <= 4);
9347639Sgblack@eecs.umich.edu
9357639Sgblack@eecs.umich.edu    numMicroops = 1;
9367639Sgblack@eecs.umich.edu    bool wb = (rm != 15);
9377639Sgblack@eecs.umich.edu
9387639Sgblack@eecs.umich.edu    if (wb) numMicroops++;
9397639Sgblack@eecs.umich.edu    numMicroops += (regs / elems);
9407639Sgblack@eecs.umich.edu    microOps = new StaticInstPtr[numMicroops];
9417639Sgblack@eecs.umich.edu
94210037SARM gem5 Developers    RegIndex ufp0 = NumFloatV7ArchRegs;
9437639Sgblack@eecs.umich.edu
9447639Sgblack@eecs.umich.edu    unsigned uopIdx = 0;
9457639Sgblack@eecs.umich.edu    switch (elems) {
9467639Sgblack@eecs.umich.edu      case 4:
9477639Sgblack@eecs.umich.edu        assert(regs == 4);
9487639Sgblack@eecs.umich.edu        switch (size) {
9497639Sgblack@eecs.umich.edu          case 0:
9507639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroPackNeon8to2Uop<uint8_t>(
9517639Sgblack@eecs.umich.edu                    machInst, ufp0, vd * 2, inc * 2, lane);
9527639Sgblack@eecs.umich.edu            break;
9537639Sgblack@eecs.umich.edu          case 1:
9547639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroPackNeon8to2Uop<uint16_t>(
9557639Sgblack@eecs.umich.edu                    machInst, ufp0, vd * 2, inc * 2, lane);
9567639Sgblack@eecs.umich.edu            break;
9577639Sgblack@eecs.umich.edu          case 2:
9587639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroPackNeon8to4Uop<uint32_t>(
9597639Sgblack@eecs.umich.edu                    machInst, ufp0, vd * 2, inc * 2, lane);
9607639Sgblack@eecs.umich.edu            break;
9617639Sgblack@eecs.umich.edu          default:
9627853SMatt.Horsnell@ARM.com            // Bad size
9637853SMatt.Horsnell@ARM.com            microOps[uopIdx++] = new Unknown(machInst);
9647639Sgblack@eecs.umich.edu            break;
9657639Sgblack@eecs.umich.edu        }
9667639Sgblack@eecs.umich.edu        break;
9677639Sgblack@eecs.umich.edu      case 3:
9687639Sgblack@eecs.umich.edu        assert(regs == 3);
9697639Sgblack@eecs.umich.edu        switch (size) {
9707639Sgblack@eecs.umich.edu          case 0:
9717639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroPackNeon6to2Uop<uint8_t>(
9727639Sgblack@eecs.umich.edu                    machInst, ufp0, vd * 2, inc * 2, lane);
9737639Sgblack@eecs.umich.edu            break;
9747639Sgblack@eecs.umich.edu          case 1:
9757639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroPackNeon6to2Uop<uint16_t>(
9767639Sgblack@eecs.umich.edu                    machInst, ufp0, vd * 2, inc * 2, lane);
9777639Sgblack@eecs.umich.edu            break;
9787639Sgblack@eecs.umich.edu          case 2:
9797639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroPackNeon6to4Uop<uint32_t>(
9807639Sgblack@eecs.umich.edu                    machInst, ufp0, vd * 2, inc * 2, lane);
9817639Sgblack@eecs.umich.edu            break;
9827639Sgblack@eecs.umich.edu          default:
9837853SMatt.Horsnell@ARM.com            // Bad size
9847853SMatt.Horsnell@ARM.com            microOps[uopIdx++] = new Unknown(machInst);
9857639Sgblack@eecs.umich.edu            break;
9867639Sgblack@eecs.umich.edu        }
9877639Sgblack@eecs.umich.edu        break;
9887639Sgblack@eecs.umich.edu      case 2:
9897639Sgblack@eecs.umich.edu        assert(regs == 2);
9907639Sgblack@eecs.umich.edu        assert(storeRegs <= 2);
9917639Sgblack@eecs.umich.edu        switch (size) {
9927639Sgblack@eecs.umich.edu          case 0:
9937639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroPackNeon4to2Uop<uint8_t>(
9947639Sgblack@eecs.umich.edu                    machInst, ufp0, vd * 2, inc * 2, lane);
9957639Sgblack@eecs.umich.edu            break;
9967639Sgblack@eecs.umich.edu          case 1:
9977639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroPackNeon4to2Uop<uint16_t>(
9987639Sgblack@eecs.umich.edu                    machInst, ufp0, vd * 2, inc * 2, lane);
9997639Sgblack@eecs.umich.edu            break;
10007639Sgblack@eecs.umich.edu          case 2:
10017639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroPackNeon4to2Uop<uint32_t>(
10027639Sgblack@eecs.umich.edu                    machInst, ufp0, vd * 2, inc * 2, lane);
10037639Sgblack@eecs.umich.edu            break;
10047639Sgblack@eecs.umich.edu          default:
10057853SMatt.Horsnell@ARM.com            // Bad size
10067853SMatt.Horsnell@ARM.com            microOps[uopIdx++] = new Unknown(machInst);
10077639Sgblack@eecs.umich.edu            break;
10087639Sgblack@eecs.umich.edu        }
10097639Sgblack@eecs.umich.edu        break;
10107639Sgblack@eecs.umich.edu      case 1:
10117639Sgblack@eecs.umich.edu        assert(regs == 1 || (all && regs == 2));
10127639Sgblack@eecs.umich.edu        assert(storeRegs <= 2);
10137639Sgblack@eecs.umich.edu        for (unsigned offset = 0; offset < regs; offset++) {
10147639Sgblack@eecs.umich.edu            switch (size) {
10157639Sgblack@eecs.umich.edu              case 0:
10167639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroPackNeon2to2Uop<uint8_t>(
10177639Sgblack@eecs.umich.edu                        machInst, ufp0, (vd + offset) * 2, inc * 2, lane);
10187639Sgblack@eecs.umich.edu                break;
10197639Sgblack@eecs.umich.edu              case 1:
10207639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroPackNeon2to2Uop<uint16_t>(
10217639Sgblack@eecs.umich.edu                        machInst, ufp0, (vd + offset) * 2, inc * 2, lane);
10227639Sgblack@eecs.umich.edu                break;
10237639Sgblack@eecs.umich.edu              case 2:
10247639Sgblack@eecs.umich.edu                microOps[uopIdx++] = new MicroPackNeon2to2Uop<uint32_t>(
10257639Sgblack@eecs.umich.edu                        machInst, ufp0, (vd + offset) * 2, inc * 2, lane);
10267639Sgblack@eecs.umich.edu                break;
10277639Sgblack@eecs.umich.edu              default:
10287853SMatt.Horsnell@ARM.com                // Bad size
10297853SMatt.Horsnell@ARM.com                microOps[uopIdx++] = new Unknown(machInst);
10307639Sgblack@eecs.umich.edu                break;
10317639Sgblack@eecs.umich.edu            }
10327639Sgblack@eecs.umich.edu        }
10337639Sgblack@eecs.umich.edu        break;
10347639Sgblack@eecs.umich.edu      default:
10357853SMatt.Horsnell@ARM.com        // Bad number of elements to unpack
10367853SMatt.Horsnell@ARM.com        microOps[uopIdx++] = new Unknown(machInst);
10377639Sgblack@eecs.umich.edu    }
10387639Sgblack@eecs.umich.edu    switch (storeSize) {
10397639Sgblack@eecs.umich.edu      case 1:
10407639Sgblack@eecs.umich.edu        microOps[uopIdx++] = new MicroStrNeon1Uop<uint8_t>(
10417639Sgblack@eecs.umich.edu                machInst, ufp0, rn, 0, align);
10427639Sgblack@eecs.umich.edu        break;
10437639Sgblack@eecs.umich.edu      case 2:
10447639Sgblack@eecs.umich.edu        if (eBytes == 2) {
10457639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroStrNeon2Uop<uint16_t>(
10467639Sgblack@eecs.umich.edu                    machInst, ufp0, rn, 0, align);
10477639Sgblack@eecs.umich.edu        } else {
10487639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroStrNeon2Uop<uint8_t>(
10497639Sgblack@eecs.umich.edu                    machInst, ufp0, rn, 0, align);
10507639Sgblack@eecs.umich.edu        }
10517639Sgblack@eecs.umich.edu        break;
10527639Sgblack@eecs.umich.edu      case 3:
10537639Sgblack@eecs.umich.edu        microOps[uopIdx++] = new MicroStrNeon3Uop<uint8_t>(
10547639Sgblack@eecs.umich.edu                machInst, ufp0, rn, 0, align);
10557639Sgblack@eecs.umich.edu        break;
10567639Sgblack@eecs.umich.edu      case 4:
10577639Sgblack@eecs.umich.edu        switch (eBytes) {
10587639Sgblack@eecs.umich.edu          case 1:
10597639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroStrNeon4Uop<uint8_t>(
10607639Sgblack@eecs.umich.edu                    machInst, ufp0, rn, 0, align);
10617639Sgblack@eecs.umich.edu            break;
10627639Sgblack@eecs.umich.edu          case 2:
10637639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroStrNeon4Uop<uint16_t>(
10647639Sgblack@eecs.umich.edu                    machInst, ufp0, rn, 0, align);
10657639Sgblack@eecs.umich.edu            break;
10667639Sgblack@eecs.umich.edu          case 4:
10677639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroStrNeon4Uop<uint32_t>(
10687639Sgblack@eecs.umich.edu                    machInst, ufp0, rn, 0, align);
10697639Sgblack@eecs.umich.edu            break;
10707639Sgblack@eecs.umich.edu        }
10717639Sgblack@eecs.umich.edu        break;
10727639Sgblack@eecs.umich.edu      case 6:
10737639Sgblack@eecs.umich.edu        microOps[uopIdx++] = new MicroStrNeon6Uop<uint16_t>(
10747639Sgblack@eecs.umich.edu                machInst, ufp0, rn, 0, align);
10757639Sgblack@eecs.umich.edu        break;
10767639Sgblack@eecs.umich.edu      case 8:
10777639Sgblack@eecs.umich.edu        switch (eBytes) {
10787639Sgblack@eecs.umich.edu          case 2:
10797639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroStrNeon8Uop<uint16_t>(
10807639Sgblack@eecs.umich.edu                    machInst, ufp0, rn, 0, align);
10817639Sgblack@eecs.umich.edu            break;
10827639Sgblack@eecs.umich.edu          case 4:
10837639Sgblack@eecs.umich.edu            microOps[uopIdx++] = new MicroStrNeon8Uop<uint32_t>(
10847639Sgblack@eecs.umich.edu                    machInst, ufp0, rn, 0, align);
10857639Sgblack@eecs.umich.edu            break;
10867639Sgblack@eecs.umich.edu        }
10877639Sgblack@eecs.umich.edu        break;
10887639Sgblack@eecs.umich.edu      case 12:
10897639Sgblack@eecs.umich.edu        microOps[uopIdx++] = new MicroStrNeon12Uop<uint32_t>(
10907639Sgblack@eecs.umich.edu                machInst, ufp0, rn, 0, align);
10917639Sgblack@eecs.umich.edu        break;
10927639Sgblack@eecs.umich.edu      case 16:
10937639Sgblack@eecs.umich.edu        microOps[uopIdx++] = new MicroStrNeon16Uop<uint32_t>(
10947639Sgblack@eecs.umich.edu                machInst, ufp0, rn, 0, align);
10957639Sgblack@eecs.umich.edu        break;
10967639Sgblack@eecs.umich.edu      default:
10977853SMatt.Horsnell@ARM.com        // Bad store size
10987853SMatt.Horsnell@ARM.com        microOps[uopIdx++] = new Unknown(machInst);
10997639Sgblack@eecs.umich.edu    }
11007639Sgblack@eecs.umich.edu    if (wb) {
11017639Sgblack@eecs.umich.edu        if (rm != 15 && rm != 13) {
11027639Sgblack@eecs.umich.edu            microOps[uopIdx++] =
11037646Sgene.wu@arm.com                new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL);
11047639Sgblack@eecs.umich.edu        } else {
11057639Sgblack@eecs.umich.edu            microOps[uopIdx++] =
11067639Sgblack@eecs.umich.edu                new MicroAddiUop(machInst, rn, rn, storeSize);
11077639Sgblack@eecs.umich.edu        }
11087639Sgblack@eecs.umich.edu    }
11097639Sgblack@eecs.umich.edu    assert(uopIdx == numMicroops);
11107639Sgblack@eecs.umich.edu
11117639Sgblack@eecs.umich.edu    for (unsigned i = 0; i < numMicroops - 1; i++) {
11127639Sgblack@eecs.umich.edu        MicroOp * uopPtr = dynamic_cast<MicroOp *>(microOps[i].get());
11137639Sgblack@eecs.umich.edu        assert(uopPtr);
11147639Sgblack@eecs.umich.edu        uopPtr->setDelayedCommit();
11157639Sgblack@eecs.umich.edu    }
111610666SAli.Saidi@ARM.com    microOps[0]->setFirstMicroop();
11177639Sgblack@eecs.umich.edu    microOps[numMicroops - 1]->setLastMicroop();
11187639Sgblack@eecs.umich.edu}
11197639Sgblack@eecs.umich.edu
112010037SARM gem5 DevelopersVldMultOp64::VldMultOp64(const char *mnem, ExtMachInst machInst,
112110037SARM gem5 Developers                         OpClass __opClass, RegIndex rn, RegIndex vd,
112210037SARM gem5 Developers                         RegIndex rm, uint8_t eSize, uint8_t dataSize,
112310037SARM gem5 Developers                         uint8_t numStructElems, uint8_t numRegs, bool wb) :
112410037SARM gem5 Developers    PredMacroOp(mnem, machInst, __opClass)
112510037SARM gem5 Developers{
112610037SARM gem5 Developers    RegIndex vx = NumFloatV8ArchRegs / 4;
112710037SARM gem5 Developers    RegIndex rnsp = (RegIndex) makeSP((IntRegIndex) rn);
112810037SARM gem5 Developers    bool baseIsSP = isSP((IntRegIndex) rnsp);
112910037SARM gem5 Developers
113010037SARM gem5 Developers    numMicroops = wb ? 1 : 0;
113110037SARM gem5 Developers
113210037SARM gem5 Developers    int totNumBytes = numRegs * dataSize / 8;
113310037SARM gem5 Developers    assert(totNumBytes <= 64);
113410037SARM gem5 Developers
113510037SARM gem5 Developers    // The guiding principle here is that no more than 16 bytes can be
113610037SARM gem5 Developers    // transferred at a time
113710037SARM gem5 Developers    int numMemMicroops = totNumBytes / 16;
113810037SARM gem5 Developers    int residuum = totNumBytes % 16;
113910037SARM gem5 Developers    if (residuum)
114010037SARM gem5 Developers        ++numMemMicroops;
114110037SARM gem5 Developers    numMicroops += numMemMicroops;
114210037SARM gem5 Developers
114310037SARM gem5 Developers    int numMarshalMicroops = numRegs / 2 + (numRegs % 2 ? 1 : 0);
114410037SARM gem5 Developers    numMicroops += numMarshalMicroops;
114510037SARM gem5 Developers
114610037SARM gem5 Developers    microOps = new StaticInstPtr[numMicroops];
114710037SARM gem5 Developers    unsigned uopIdx = 0;
114810037SARM gem5 Developers    uint32_t memaccessFlags = TLB::MustBeOne | (TLB::ArmFlags) eSize |
114910037SARM gem5 Developers        TLB::AllowUnaligned;
115010037SARM gem5 Developers
115110037SARM gem5 Developers    int i = 0;
115211321Ssteve.reinhardt@amd.com    for (; i < numMemMicroops - 1; ++i) {
115310037SARM gem5 Developers        microOps[uopIdx++] = new MicroNeonLoad64(
115410037SARM gem5 Developers            machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags,
115510037SARM gem5 Developers            baseIsSP, 16 /* accSize */, eSize);
115610037SARM gem5 Developers    }
115710037SARM gem5 Developers    microOps[uopIdx++] =  new MicroNeonLoad64(
115810037SARM gem5 Developers        machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, baseIsSP,
115910037SARM gem5 Developers        residuum ? residuum : 16 /* accSize */, eSize);
116010037SARM gem5 Developers
116110037SARM gem5 Developers    // Writeback microop: the post-increment amount is encoded in "Rm": a
116210037SARM gem5 Developers    // 64-bit general register OR as '11111' for an immediate value equal to
116310037SARM gem5 Developers    // the total number of bytes transferred (i.e. 8, 16, 24, 32, 48 or 64)
116410037SARM gem5 Developers    if (wb) {
116510037SARM gem5 Developers        if (rm != ((RegIndex) INTREG_X31)) {
116610037SARM gem5 Developers            microOps[uopIdx++] = new MicroAddXERegUop(machInst, rnsp, rnsp, rm,
116710037SARM gem5 Developers                                                      UXTX, 0);
116810037SARM gem5 Developers        } else {
116910037SARM gem5 Developers            microOps[uopIdx++] = new MicroAddXiUop(machInst, rnsp, rnsp,
117010037SARM gem5 Developers                                                   totNumBytes);
117110037SARM gem5 Developers        }
117210037SARM gem5 Developers    }
117310037SARM gem5 Developers
117410037SARM gem5 Developers    for (int i = 0; i < numMarshalMicroops; ++i) {
117510339Smitch.hayenga@arm.com        switch(numRegs) {
117610339Smitch.hayenga@arm.com            case 1: microOps[uopIdx++] = new MicroDeintNeon64_1Reg(
117710339Smitch.hayenga@arm.com                        machInst, vd + (RegIndex) (2 * i), vx, eSize, dataSize,
117810339Smitch.hayenga@arm.com                        numStructElems, 1, i /* step */);
117910339Smitch.hayenga@arm.com                    break;
118010339Smitch.hayenga@arm.com            case 2: microOps[uopIdx++] = new MicroDeintNeon64_2Reg(
118110339Smitch.hayenga@arm.com                        machInst, vd + (RegIndex) (2 * i), vx, eSize, dataSize,
118210339Smitch.hayenga@arm.com                        numStructElems, 2, i /* step */);
118310339Smitch.hayenga@arm.com                    break;
118410339Smitch.hayenga@arm.com            case 3: microOps[uopIdx++] = new MicroDeintNeon64_3Reg(
118510339Smitch.hayenga@arm.com                        machInst, vd + (RegIndex) (2 * i), vx, eSize, dataSize,
118610339Smitch.hayenga@arm.com                        numStructElems, 3, i /* step */);
118710339Smitch.hayenga@arm.com                    break;
118810339Smitch.hayenga@arm.com            case 4: microOps[uopIdx++] = new MicroDeintNeon64_4Reg(
118910339Smitch.hayenga@arm.com                        machInst, vd + (RegIndex) (2 * i), vx, eSize, dataSize,
119010339Smitch.hayenga@arm.com                        numStructElems, 4, i /* step */);
119110339Smitch.hayenga@arm.com                    break;
119210339Smitch.hayenga@arm.com            default: panic("Invalid number of registers");
119310339Smitch.hayenga@arm.com        }
119410339Smitch.hayenga@arm.com
119510037SARM gem5 Developers    }
119610037SARM gem5 Developers
119710037SARM gem5 Developers    assert(uopIdx == numMicroops);
119810037SARM gem5 Developers
119910037SARM gem5 Developers    for (int i = 0; i < numMicroops - 1; ++i) {
120010037SARM gem5 Developers        microOps[i]->setDelayedCommit();
120110037SARM gem5 Developers    }
120210037SARM gem5 Developers    microOps[numMicroops - 1]->setLastMicroop();
120310037SARM gem5 Developers}
120410037SARM gem5 Developers
120510037SARM gem5 DevelopersVstMultOp64::VstMultOp64(const char *mnem, ExtMachInst machInst,
120610037SARM gem5 Developers                         OpClass __opClass, RegIndex rn, RegIndex vd,
120710037SARM gem5 Developers                         RegIndex rm, uint8_t eSize, uint8_t dataSize,
120810037SARM gem5 Developers                         uint8_t numStructElems, uint8_t numRegs, bool wb) :
120910037SARM gem5 Developers    PredMacroOp(mnem, machInst, __opClass)
121010037SARM gem5 Developers{
121110037SARM gem5 Developers    RegIndex vx = NumFloatV8ArchRegs / 4;
121210037SARM gem5 Developers    RegIndex rnsp = (RegIndex) makeSP((IntRegIndex) rn);
121310037SARM gem5 Developers    bool baseIsSP = isSP((IntRegIndex) rnsp);
121410037SARM gem5 Developers
121510037SARM gem5 Developers    numMicroops = wb ? 1 : 0;
121610037SARM gem5 Developers
121710037SARM gem5 Developers    int totNumBytes = numRegs * dataSize / 8;
121810037SARM gem5 Developers    assert(totNumBytes <= 64);
121910037SARM gem5 Developers
122010037SARM gem5 Developers    // The guiding principle here is that no more than 16 bytes can be
122110037SARM gem5 Developers    // transferred at a time
122210037SARM gem5 Developers    int numMemMicroops = totNumBytes / 16;
122310037SARM gem5 Developers    int residuum = totNumBytes % 16;
122410037SARM gem5 Developers    if (residuum)
122510037SARM gem5 Developers        ++numMemMicroops;
122610037SARM gem5 Developers    numMicroops += numMemMicroops;
122710037SARM gem5 Developers
122810037SARM gem5 Developers    int numMarshalMicroops = totNumBytes > 32 ? 2 : 1;
122910037SARM gem5 Developers    numMicroops += numMarshalMicroops;
123010037SARM gem5 Developers
123110037SARM gem5 Developers    microOps = new StaticInstPtr[numMicroops];
123210037SARM gem5 Developers    unsigned uopIdx = 0;
123310037SARM gem5 Developers
123411321Ssteve.reinhardt@amd.com    for (int i = 0; i < numMarshalMicroops; ++i) {
123510339Smitch.hayenga@arm.com        switch (numRegs) {
123610339Smitch.hayenga@arm.com            case 1: microOps[uopIdx++] = new MicroIntNeon64_1Reg(
123710339Smitch.hayenga@arm.com                        machInst, vx + (RegIndex) (2 * i), vd, eSize, dataSize,
123810339Smitch.hayenga@arm.com                        numStructElems, 1, i /* step */);
123910339Smitch.hayenga@arm.com                    break;
124010339Smitch.hayenga@arm.com            case 2: microOps[uopIdx++] = new MicroIntNeon64_2Reg(
124110339Smitch.hayenga@arm.com                        machInst, vx + (RegIndex) (2 * i), vd, eSize, dataSize,
124210339Smitch.hayenga@arm.com                        numStructElems, 2, i /* step */);
124310339Smitch.hayenga@arm.com                    break;
124410339Smitch.hayenga@arm.com            case 3: microOps[uopIdx++] = new MicroIntNeon64_3Reg(
124510339Smitch.hayenga@arm.com                        machInst, vx + (RegIndex) (2 * i), vd, eSize, dataSize,
124610339Smitch.hayenga@arm.com                        numStructElems, 3, i /* step */);
124710339Smitch.hayenga@arm.com                    break;
124810339Smitch.hayenga@arm.com            case 4: microOps[uopIdx++] = new MicroIntNeon64_4Reg(
124910339Smitch.hayenga@arm.com                        machInst, vx + (RegIndex) (2 * i), vd, eSize, dataSize,
125010339Smitch.hayenga@arm.com                        numStructElems, 4, i /* step */);
125110339Smitch.hayenga@arm.com                    break;
125210339Smitch.hayenga@arm.com            default: panic("Invalid number of registers");
125310339Smitch.hayenga@arm.com        }
125410037SARM gem5 Developers    }
125510037SARM gem5 Developers
125610037SARM gem5 Developers    uint32_t memaccessFlags = TLB::MustBeOne | (TLB::ArmFlags) eSize |
125710037SARM gem5 Developers        TLB::AllowUnaligned;
125810037SARM gem5 Developers
125910037SARM gem5 Developers    int i = 0;
126011321Ssteve.reinhardt@amd.com    for (; i < numMemMicroops - 1; ++i) {
126110037SARM gem5 Developers        microOps[uopIdx++] = new MicroNeonStore64(
126210037SARM gem5 Developers            machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags,
126310037SARM gem5 Developers            baseIsSP, 16 /* accSize */, eSize);
126410037SARM gem5 Developers    }
126510037SARM gem5 Developers    microOps[uopIdx++] = new MicroNeonStore64(
126610037SARM gem5 Developers        machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, baseIsSP,
126710037SARM gem5 Developers        residuum ? residuum : 16 /* accSize */, eSize);
126810037SARM gem5 Developers
126910037SARM gem5 Developers    // Writeback microop: the post-increment amount is encoded in "Rm": a
127010037SARM gem5 Developers    // 64-bit general register OR as '11111' for an immediate value equal to
127110037SARM gem5 Developers    // the total number of bytes transferred (i.e. 8, 16, 24, 32, 48 or 64)
127210037SARM gem5 Developers    if (wb) {
127310037SARM gem5 Developers        if (rm != ((RegIndex) INTREG_X31)) {
127410037SARM gem5 Developers            microOps[uopIdx++] = new MicroAddXERegUop(machInst, rnsp, rnsp, rm,
127510037SARM gem5 Developers                                                      UXTX, 0);
127610037SARM gem5 Developers        } else {
127710037SARM gem5 Developers            microOps[uopIdx++] = new MicroAddXiUop(machInst, rnsp, rnsp,
127810037SARM gem5 Developers                                                   totNumBytes);
127910037SARM gem5 Developers        }
128010037SARM gem5 Developers    }
128110037SARM gem5 Developers
128210037SARM gem5 Developers    assert(uopIdx == numMicroops);
128310037SARM gem5 Developers
128410037SARM gem5 Developers    for (int i = 0; i < numMicroops - 1; i++) {
128510037SARM gem5 Developers        microOps[i]->setDelayedCommit();
128610037SARM gem5 Developers    }
128710037SARM gem5 Developers    microOps[numMicroops - 1]->setLastMicroop();
128810037SARM gem5 Developers}
128910037SARM gem5 Developers
129010037SARM gem5 DevelopersVldSingleOp64::VldSingleOp64(const char *mnem, ExtMachInst machInst,
129110037SARM gem5 Developers                             OpClass __opClass, RegIndex rn, RegIndex vd,
129210037SARM gem5 Developers                             RegIndex rm, uint8_t eSize, uint8_t dataSize,
129310037SARM gem5 Developers                             uint8_t numStructElems, uint8_t index, bool wb,
129410037SARM gem5 Developers                             bool replicate) :
129510537Sandreas.hansson@arm.com    PredMacroOp(mnem, machInst, __opClass),
129610537Sandreas.hansson@arm.com    eSize(0), dataSize(0), numStructElems(0), index(0),
129710537Sandreas.hansson@arm.com    wb(false), replicate(false)
129810537Sandreas.hansson@arm.com
129910037SARM gem5 Developers{
130010037SARM gem5 Developers    RegIndex vx = NumFloatV8ArchRegs / 4;
130110037SARM gem5 Developers    RegIndex rnsp = (RegIndex) makeSP((IntRegIndex) rn);
130210037SARM gem5 Developers    bool baseIsSP = isSP((IntRegIndex) rnsp);
130310037SARM gem5 Developers
130410037SARM gem5 Developers    numMicroops = wb ? 1 : 0;
130510037SARM gem5 Developers
130610037SARM gem5 Developers    int eSizeBytes = 1 << eSize;
130710037SARM gem5 Developers    int totNumBytes = numStructElems * eSizeBytes;
130810037SARM gem5 Developers    assert(totNumBytes <= 64);
130910037SARM gem5 Developers
131010037SARM gem5 Developers    // The guiding principle here is that no more than 16 bytes can be
131110037SARM gem5 Developers    // transferred at a time
131210037SARM gem5 Developers    int numMemMicroops = totNumBytes / 16;
131310037SARM gem5 Developers    int residuum = totNumBytes % 16;
131410037SARM gem5 Developers    if (residuum)
131510037SARM gem5 Developers        ++numMemMicroops;
131610037SARM gem5 Developers    numMicroops += numMemMicroops;
131710037SARM gem5 Developers
131810037SARM gem5 Developers    int numMarshalMicroops = numStructElems / 2 + (numStructElems % 2 ? 1 : 0);
131910037SARM gem5 Developers    numMicroops += numMarshalMicroops;
132010037SARM gem5 Developers
132110037SARM gem5 Developers    microOps = new StaticInstPtr[numMicroops];
132210037SARM gem5 Developers    unsigned uopIdx = 0;
132310037SARM gem5 Developers
132410037SARM gem5 Developers    uint32_t memaccessFlags = TLB::MustBeOne | (TLB::ArmFlags) eSize |
132510037SARM gem5 Developers        TLB::AllowUnaligned;
132610037SARM gem5 Developers
132710037SARM gem5 Developers    int i = 0;
132810037SARM gem5 Developers    for (; i < numMemMicroops - 1; ++i) {
132910037SARM gem5 Developers        microOps[uopIdx++] = new MicroNeonLoad64(
133010037SARM gem5 Developers            machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags,
133110037SARM gem5 Developers            baseIsSP, 16 /* accSize */, eSize);
133210037SARM gem5 Developers    }
133310037SARM gem5 Developers    microOps[uopIdx++] = new MicroNeonLoad64(
133410037SARM gem5 Developers        machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, baseIsSP,
133510037SARM gem5 Developers        residuum ? residuum : 16 /* accSize */, eSize);
133610037SARM gem5 Developers
133710037SARM gem5 Developers    // Writeback microop: the post-increment amount is encoded in "Rm": a
133810037SARM gem5 Developers    // 64-bit general register OR as '11111' for an immediate value equal to
133910037SARM gem5 Developers    // the total number of bytes transferred (i.e. 8, 16, 24, 32, 48 or 64)
134010037SARM gem5 Developers    if (wb) {
134110037SARM gem5 Developers        if (rm != ((RegIndex) INTREG_X31)) {
134210037SARM gem5 Developers            microOps[uopIdx++] = new MicroAddXERegUop(machInst, rnsp, rnsp, rm,
134310037SARM gem5 Developers                                                      UXTX, 0);
134410037SARM gem5 Developers        } else {
134510037SARM gem5 Developers            microOps[uopIdx++] = new MicroAddXiUop(machInst, rnsp, rnsp,
134610037SARM gem5 Developers                                                   totNumBytes);
134710037SARM gem5 Developers        }
134810037SARM gem5 Developers    }
134910037SARM gem5 Developers
135011321Ssteve.reinhardt@amd.com    for (int i = 0; i < numMarshalMicroops; ++i) {
135110037SARM gem5 Developers        microOps[uopIdx++] = new MicroUnpackNeon64(
135210037SARM gem5 Developers            machInst, vd + (RegIndex) (2 * i), vx, eSize, dataSize,
135310037SARM gem5 Developers            numStructElems, index, i /* step */, replicate);
135410037SARM gem5 Developers    }
135510037SARM gem5 Developers
135610037SARM gem5 Developers    assert(uopIdx == numMicroops);
135710037SARM gem5 Developers
135810037SARM gem5 Developers    for (int i = 0; i < numMicroops - 1; i++) {
135910037SARM gem5 Developers        microOps[i]->setDelayedCommit();
136010037SARM gem5 Developers    }
136110037SARM gem5 Developers    microOps[numMicroops - 1]->setLastMicroop();
136210037SARM gem5 Developers}
136310037SARM gem5 Developers
136410037SARM gem5 DevelopersVstSingleOp64::VstSingleOp64(const char *mnem, ExtMachInst machInst,
136510037SARM gem5 Developers                             OpClass __opClass, RegIndex rn, RegIndex vd,
136610037SARM gem5 Developers                             RegIndex rm, uint8_t eSize, uint8_t dataSize,
136710037SARM gem5 Developers                             uint8_t numStructElems, uint8_t index, bool wb,
136810037SARM gem5 Developers                             bool replicate) :
136910537Sandreas.hansson@arm.com    PredMacroOp(mnem, machInst, __opClass),
137010537Sandreas.hansson@arm.com    eSize(0), dataSize(0), numStructElems(0), index(0),
137110537Sandreas.hansson@arm.com    wb(false), replicate(false)
137210037SARM gem5 Developers{
137310037SARM gem5 Developers    RegIndex vx = NumFloatV8ArchRegs / 4;
137410037SARM gem5 Developers    RegIndex rnsp = (RegIndex) makeSP((IntRegIndex) rn);
137510037SARM gem5 Developers    bool baseIsSP = isSP((IntRegIndex) rnsp);
137610037SARM gem5 Developers
137710037SARM gem5 Developers    numMicroops = wb ? 1 : 0;
137810037SARM gem5 Developers
137910037SARM gem5 Developers    int eSizeBytes = 1 << eSize;
138010037SARM gem5 Developers    int totNumBytes = numStructElems * eSizeBytes;
138110037SARM gem5 Developers    assert(totNumBytes <= 64);
138210037SARM gem5 Developers
138310037SARM gem5 Developers    // The guiding principle here is that no more than 16 bytes can be
138410037SARM gem5 Developers    // transferred at a time
138510037SARM gem5 Developers    int numMemMicroops = totNumBytes / 16;
138610037SARM gem5 Developers    int residuum = totNumBytes % 16;
138710037SARM gem5 Developers    if (residuum)
138810037SARM gem5 Developers        ++numMemMicroops;
138910037SARM gem5 Developers    numMicroops += numMemMicroops;
139010037SARM gem5 Developers
139110037SARM gem5 Developers    int numMarshalMicroops = totNumBytes > 32 ? 2 : 1;
139210037SARM gem5 Developers    numMicroops += numMarshalMicroops;
139310037SARM gem5 Developers
139410037SARM gem5 Developers    microOps = new StaticInstPtr[numMicroops];
139510037SARM gem5 Developers    unsigned uopIdx = 0;
139610037SARM gem5 Developers
139711321Ssteve.reinhardt@amd.com    for (int i = 0; i < numMarshalMicroops; ++i) {
139810037SARM gem5 Developers        microOps[uopIdx++] = new MicroPackNeon64(
139910037SARM gem5 Developers            machInst, vx + (RegIndex) (2 * i), vd, eSize, dataSize,
140010037SARM gem5 Developers            numStructElems, index, i /* step */, replicate);
140110037SARM gem5 Developers    }
140210037SARM gem5 Developers
140310037SARM gem5 Developers    uint32_t memaccessFlags = TLB::MustBeOne | (TLB::ArmFlags) eSize |
140410037SARM gem5 Developers        TLB::AllowUnaligned;
140510037SARM gem5 Developers
140610037SARM gem5 Developers    int i = 0;
140711321Ssteve.reinhardt@amd.com    for (; i < numMemMicroops - 1; ++i) {
140810037SARM gem5 Developers        microOps[uopIdx++] = new MicroNeonStore64(
140910037SARM gem5 Developers            machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags,
141010037SARM gem5 Developers            baseIsSP, 16 /* accsize */, eSize);
141110037SARM gem5 Developers    }
141210037SARM gem5 Developers    microOps[uopIdx++] = new MicroNeonStore64(
141310037SARM gem5 Developers        machInst, vx + (RegIndex) i, rnsp, 16 * i, memaccessFlags, baseIsSP,
141410037SARM gem5 Developers        residuum ? residuum : 16 /* accSize */, eSize);
141510037SARM gem5 Developers
141610037SARM gem5 Developers    // Writeback microop: the post-increment amount is encoded in "Rm": a
141710037SARM gem5 Developers    // 64-bit general register OR as '11111' for an immediate value equal to
141810037SARM gem5 Developers    // the total number of bytes transferred (i.e. 8, 16, 24, 32, 48 or 64)
141910037SARM gem5 Developers    if (wb) {
142010037SARM gem5 Developers        if (rm != ((RegIndex) INTREG_X31)) {
142110037SARM gem5 Developers            microOps[uopIdx++] = new MicroAddXERegUop(machInst, rnsp, rnsp, rm,
142210037SARM gem5 Developers                                                      UXTX, 0);
142310037SARM gem5 Developers        } else {
142410037SARM gem5 Developers            microOps[uopIdx++] = new MicroAddXiUop(machInst, rnsp, rnsp,
142510037SARM gem5 Developers                                                   totNumBytes);
142610037SARM gem5 Developers        }
142710037SARM gem5 Developers    }
142810037SARM gem5 Developers
142910037SARM gem5 Developers    assert(uopIdx == numMicroops);
143010037SARM gem5 Developers
143110037SARM gem5 Developers    for (int i = 0; i < numMicroops - 1; i++) {
143210037SARM gem5 Developers        microOps[i]->setDelayedCommit();
143310037SARM gem5 Developers    }
143410037SARM gem5 Developers    microOps[numMicroops - 1]->setLastMicroop();
143510037SARM gem5 Developers}
143610037SARM gem5 Developers
14377175Sgblack@eecs.umich.eduMacroVFPMemOp::MacroVFPMemOp(const char *mnem, ExtMachInst machInst,
14387175Sgblack@eecs.umich.edu                             OpClass __opClass, IntRegIndex rn,
14397175Sgblack@eecs.umich.edu                             RegIndex vd, bool single, bool up,
14407175Sgblack@eecs.umich.edu                             bool writeback, bool load, uint32_t offset) :
14417175Sgblack@eecs.umich.edu    PredMacroOp(mnem, machInst, __opClass)
14427175Sgblack@eecs.umich.edu{
14437175Sgblack@eecs.umich.edu    int i = 0;
14447175Sgblack@eecs.umich.edu
14457175Sgblack@eecs.umich.edu    // The lowest order bit selects fldmx (set) or fldmd (clear). These seem
14467175Sgblack@eecs.umich.edu    // to be functionally identical except that fldmx is deprecated. For now
14477175Sgblack@eecs.umich.edu    // we'll assume they're otherwise interchangable.
14487175Sgblack@eecs.umich.edu    int count = (single ? offset : (offset / 2));
144910037SARM gem5 Developers    if (count == 0 || count > NumFloatV7ArchRegs)
14507175Sgblack@eecs.umich.edu        warn_once("Bad offset field for VFP load/store multiple.\n");
14517175Sgblack@eecs.umich.edu    if (count == 0) {
14527175Sgblack@eecs.umich.edu        // Force there to be at least one microop so the macroop makes sense.
14537175Sgblack@eecs.umich.edu        writeback = true;
14547175Sgblack@eecs.umich.edu    }
145510037SARM gem5 Developers    if (count > NumFloatV7ArchRegs)
145610037SARM gem5 Developers        count = NumFloatV7ArchRegs;
14577175Sgblack@eecs.umich.edu
14587342Sgblack@eecs.umich.edu    numMicroops = count * (single ? 1 : 2) + (writeback ? 1 : 0);
14597342Sgblack@eecs.umich.edu    microOps = new StaticInstPtr[numMicroops];
14607342Sgblack@eecs.umich.edu
14617395Sgblack@eecs.umich.edu    int64_t addr = 0;
14627175Sgblack@eecs.umich.edu
14637342Sgblack@eecs.umich.edu    if (!up)
14647342Sgblack@eecs.umich.edu        addr = 4 * offset;
14657175Sgblack@eecs.umich.edu
14667342Sgblack@eecs.umich.edu    bool tempUp = up;
14677175Sgblack@eecs.umich.edu    for (int j = 0; j < count; j++) {
14687175Sgblack@eecs.umich.edu        if (load) {
14697639Sgblack@eecs.umich.edu            if (single) {
14707639Sgblack@eecs.umich.edu                microOps[i++] = new MicroLdrFpUop(machInst, vd++, rn,
14717639Sgblack@eecs.umich.edu                                                  tempUp, addr);
14727639Sgblack@eecs.umich.edu            } else {
14737639Sgblack@eecs.umich.edu                microOps[i++] = new MicroLdrDBFpUop(machInst, vd++, rn,
14747639Sgblack@eecs.umich.edu                                                    tempUp, addr);
14757639Sgblack@eecs.umich.edu                microOps[i++] = new MicroLdrDTFpUop(machInst, vd++, rn, tempUp,
14767639Sgblack@eecs.umich.edu                                                    addr + (up ? 4 : -4));
14777639Sgblack@eecs.umich.edu            }
14787175Sgblack@eecs.umich.edu        } else {
14797639Sgblack@eecs.umich.edu            if (single) {
14807639Sgblack@eecs.umich.edu                microOps[i++] = new MicroStrFpUop(machInst, vd++, rn,
14817639Sgblack@eecs.umich.edu                                                  tempUp, addr);
14827639Sgblack@eecs.umich.edu            } else {
14837639Sgblack@eecs.umich.edu                microOps[i++] = new MicroStrDBFpUop(machInst, vd++, rn,
14847639Sgblack@eecs.umich.edu                                                    tempUp, addr);
14857639Sgblack@eecs.umich.edu                microOps[i++] = new MicroStrDTFpUop(machInst, vd++, rn, tempUp,
14867639Sgblack@eecs.umich.edu                                                    addr + (up ? 4 : -4));
14877639Sgblack@eecs.umich.edu            }
14887175Sgblack@eecs.umich.edu        }
14897342Sgblack@eecs.umich.edu        if (!tempUp) {
14907342Sgblack@eecs.umich.edu            addr -= (single ? 4 : 8);
14917342Sgblack@eecs.umich.edu            // The microops don't handle negative displacement, so turn if we
14927342Sgblack@eecs.umich.edu            // hit zero, flip polarity and start adding.
14937395Sgblack@eecs.umich.edu            if (addr <= 0) {
14947342Sgblack@eecs.umich.edu                tempUp = true;
14957395Sgblack@eecs.umich.edu                addr = -addr;
14967342Sgblack@eecs.umich.edu            }
14977342Sgblack@eecs.umich.edu        } else {
14987342Sgblack@eecs.umich.edu            addr += (single ? 4 : 8);
14997342Sgblack@eecs.umich.edu        }
15007175Sgblack@eecs.umich.edu    }
15017175Sgblack@eecs.umich.edu
15027175Sgblack@eecs.umich.edu    if (writeback) {
15037175Sgblack@eecs.umich.edu        if (up) {
15047175Sgblack@eecs.umich.edu            microOps[i++] =
15057175Sgblack@eecs.umich.edu                new MicroAddiUop(machInst, rn, rn, 4 * offset);
15067175Sgblack@eecs.umich.edu        } else {
15077175Sgblack@eecs.umich.edu            microOps[i++] =
15087175Sgblack@eecs.umich.edu                new MicroSubiUop(machInst, rn, rn, 4 * offset);
15097175Sgblack@eecs.umich.edu        }
15107175Sgblack@eecs.umich.edu    }
15117175Sgblack@eecs.umich.edu
15127342Sgblack@eecs.umich.edu    assert(numMicroops == i);
15137175Sgblack@eecs.umich.edu    microOps[numMicroops - 1]->setLastMicroop();
15147343Sgblack@eecs.umich.edu
15157343Sgblack@eecs.umich.edu    for (StaticInstPtr *curUop = microOps;
15167343Sgblack@eecs.umich.edu            !(*curUop)->isLastMicroop(); curUop++) {
15177343Sgblack@eecs.umich.edu        MicroOp * uopPtr = dynamic_cast<MicroOp *>(curUop->get());
15187343Sgblack@eecs.umich.edu        assert(uopPtr);
15197343Sgblack@eecs.umich.edu        uopPtr->setDelayedCommit();
15207343Sgblack@eecs.umich.edu    }
15217170Sgblack@eecs.umich.edu}
15227175Sgblack@eecs.umich.edu
15237615Sminkyu.jeong@arm.comstd::string
15247639Sgblack@eecs.umich.eduMicroIntImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
15257639Sgblack@eecs.umich.edu{
15267639Sgblack@eecs.umich.edu    std::stringstream ss;
15277639Sgblack@eecs.umich.edu    printMnemonic(ss);
152812104Snathanael.premillieu@arm.com    printIntReg(ss, ura);
15297639Sgblack@eecs.umich.edu    ss << ", ";
153012104Snathanael.premillieu@arm.com    printIntReg(ss, urb);
15317639Sgblack@eecs.umich.edu    ss << ", ";
15327639Sgblack@eecs.umich.edu    ccprintf(ss, "#%d", imm);
15337639Sgblack@eecs.umich.edu    return ss.str();
15347639Sgblack@eecs.umich.edu}
15357639Sgblack@eecs.umich.edu
15367639Sgblack@eecs.umich.edustd::string
153710037SARM gem5 DevelopersMicroIntImmXOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
153810037SARM gem5 Developers{
153910037SARM gem5 Developers    std::stringstream ss;
154010037SARM gem5 Developers    printMnemonic(ss);
154112104Snathanael.premillieu@arm.com    printIntReg(ss, ura);
154210037SARM gem5 Developers    ss << ", ";
154312104Snathanael.premillieu@arm.com    printIntReg(ss, urb);
154410037SARM gem5 Developers    ss << ", ";
154510037SARM gem5 Developers    ccprintf(ss, "#%d", imm);
154610037SARM gem5 Developers    return ss.str();
154710037SARM gem5 Developers}
154810037SARM gem5 Developers
154910037SARM gem5 Developersstd::string
15508140SMatt.Horsnell@arm.comMicroSetPCCPSR::generateDisassembly(Addr pc, const SymbolTable *symtab) const
15518140SMatt.Horsnell@arm.com{
15528140SMatt.Horsnell@arm.com    std::stringstream ss;
15538140SMatt.Horsnell@arm.com    printMnemonic(ss);
15548140SMatt.Horsnell@arm.com    ss << "[PC,CPSR]";
15558140SMatt.Horsnell@arm.com    return ss.str();
15568140SMatt.Horsnell@arm.com}
15578140SMatt.Horsnell@arm.com
15588140SMatt.Horsnell@arm.comstd::string
155910037SARM gem5 DevelopersMicroIntRegXOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
156010037SARM gem5 Developers{
156110037SARM gem5 Developers    std::stringstream ss;
156210037SARM gem5 Developers    printMnemonic(ss);
156312104Snathanael.premillieu@arm.com    printIntReg(ss, ura);
156410037SARM gem5 Developers    ccprintf(ss, ", ");
156512104Snathanael.premillieu@arm.com    printIntReg(ss, urb);
156610037SARM gem5 Developers    printExtendOperand(false, ss, (IntRegIndex)urc, type, shiftAmt);
156710037SARM gem5 Developers    return ss.str();
156810037SARM gem5 Developers}
156910037SARM gem5 Developers
157010037SARM gem5 Developersstd::string
15717646Sgene.wu@arm.comMicroIntMov::generateDisassembly(Addr pc, const SymbolTable *symtab) const
15727646Sgene.wu@arm.com{
15737646Sgene.wu@arm.com    std::stringstream ss;
15747646Sgene.wu@arm.com    printMnemonic(ss);
157512104Snathanael.premillieu@arm.com    printIntReg(ss, ura);
15767646Sgene.wu@arm.com    ss << ", ";
157712104Snathanael.premillieu@arm.com    printIntReg(ss, urb);
15787646Sgene.wu@arm.com    return ss.str();
15797646Sgene.wu@arm.com}
15807646Sgene.wu@arm.com
15817646Sgene.wu@arm.comstd::string
15827615Sminkyu.jeong@arm.comMicroIntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
15837615Sminkyu.jeong@arm.com{
15847615Sminkyu.jeong@arm.com    std::stringstream ss;
15857615Sminkyu.jeong@arm.com    printMnemonic(ss);
158612104Snathanael.premillieu@arm.com    printIntReg(ss, ura);
15877615Sminkyu.jeong@arm.com    ss << ", ";
158812104Snathanael.premillieu@arm.com    printIntReg(ss, urb);
15897615Sminkyu.jeong@arm.com    ss << ", ";
159012104Snathanael.premillieu@arm.com    printIntReg(ss, urc);
15917615Sminkyu.jeong@arm.com    return ss.str();
15927175Sgblack@eecs.umich.edu}
15937615Sminkyu.jeong@arm.com
15947615Sminkyu.jeong@arm.comstd::string
15957615Sminkyu.jeong@arm.comMicroMemOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
15967615Sminkyu.jeong@arm.com{
15977615Sminkyu.jeong@arm.com    std::stringstream ss;
15987615Sminkyu.jeong@arm.com    printMnemonic(ss);
159910180SCurtis.Dunham@arm.com    if (isFloating())
160012104Snathanael.premillieu@arm.com        printFloatReg(ss, ura);
160110180SCurtis.Dunham@arm.com    else
160212104Snathanael.premillieu@arm.com        printIntReg(ss, ura);
16037615Sminkyu.jeong@arm.com    ss << ", [";
160412104Snathanael.premillieu@arm.com    printIntReg(ss, urb);
16057615Sminkyu.jeong@arm.com    ss << ", ";
16067615Sminkyu.jeong@arm.com    ccprintf(ss, "#%d", imm);
16077615Sminkyu.jeong@arm.com    ss << "]";
16087615Sminkyu.jeong@arm.com    return ss.str();
16097615Sminkyu.jeong@arm.com}
16107615Sminkyu.jeong@arm.com
161110346Smitch.hayenga@arm.comstd::string
161210346Smitch.hayenga@arm.comMicroMemPairOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
161310346Smitch.hayenga@arm.com{
161410346Smitch.hayenga@arm.com    std::stringstream ss;
161510346Smitch.hayenga@arm.com    printMnemonic(ss);
161612104Snathanael.premillieu@arm.com    printIntReg(ss, dest);
161710346Smitch.hayenga@arm.com    ss << ",";
161812104Snathanael.premillieu@arm.com    printIntReg(ss, dest2);
161910346Smitch.hayenga@arm.com    ss << ", [";
162012104Snathanael.premillieu@arm.com    printIntReg(ss, urb);
162110346Smitch.hayenga@arm.com    ss << ", ";
162210346Smitch.hayenga@arm.com    ccprintf(ss, "#%d", imm);
162310346Smitch.hayenga@arm.com    ss << "]";
162410346Smitch.hayenga@arm.com    return ss.str();
16257615Sminkyu.jeong@arm.com}
162610346Smitch.hayenga@arm.com
162710346Smitch.hayenga@arm.com}
1628