114028Sgiacomo.gabrielli@arm.com/*
214028Sgiacomo.gabrielli@arm.com * Copyright (c) 2018 ARM Limited
314028Sgiacomo.gabrielli@arm.com * All rights reserved
414028Sgiacomo.gabrielli@arm.com *
514028Sgiacomo.gabrielli@arm.com * The license below extends only to copyright in the software and shall
614028Sgiacomo.gabrielli@arm.com * not be construed as granting a license to any other intellectual
714028Sgiacomo.gabrielli@arm.com * property including but not limited to intellectual property relating
814028Sgiacomo.gabrielli@arm.com * to a hardware implementation of the functionality of the software
914028Sgiacomo.gabrielli@arm.com * licensed hereunder.  You may use the software subject to the license
1014028Sgiacomo.gabrielli@arm.com * terms below provided that you ensure that this notice is replicated
1114028Sgiacomo.gabrielli@arm.com * unmodified and in its entirety in all distributions of the software,
1214028Sgiacomo.gabrielli@arm.com * modified or unmodified, in source code or in binary form.
1314028Sgiacomo.gabrielli@arm.com *
1414028Sgiacomo.gabrielli@arm.com * Redistribution and use in source and binary forms, with or without
1514028Sgiacomo.gabrielli@arm.com * modification, are permitted provided that the following conditions are
1614028Sgiacomo.gabrielli@arm.com * met: redistributions of source code must retain the above copyright
1714028Sgiacomo.gabrielli@arm.com * notice, this list of conditions and the following disclaimer;
1814028Sgiacomo.gabrielli@arm.com * redistributions in binary form must reproduce the above copyright
1914028Sgiacomo.gabrielli@arm.com * notice, this list of conditions and the following disclaimer in the
2014028Sgiacomo.gabrielli@arm.com * documentation and/or other materials provided with the distribution;
2114028Sgiacomo.gabrielli@arm.com * neither the name of the copyright holders nor the names of its
2214028Sgiacomo.gabrielli@arm.com * contributors may be used to endorse or promote products derived from
2314028Sgiacomo.gabrielli@arm.com * this software without specific prior written permission.
2414028Sgiacomo.gabrielli@arm.com *
2514028Sgiacomo.gabrielli@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2614028Sgiacomo.gabrielli@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2714028Sgiacomo.gabrielli@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2814028Sgiacomo.gabrielli@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2914028Sgiacomo.gabrielli@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3014028Sgiacomo.gabrielli@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3114028Sgiacomo.gabrielli@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3214028Sgiacomo.gabrielli@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3314028Sgiacomo.gabrielli@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3414028Sgiacomo.gabrielli@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3514028Sgiacomo.gabrielli@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3614028Sgiacomo.gabrielli@arm.com *
3714028Sgiacomo.gabrielli@arm.com * Authors: Giacomo Gabrielli
3814028Sgiacomo.gabrielli@arm.com */
3914028Sgiacomo.gabrielli@arm.com
4014028Sgiacomo.gabrielli@arm.com#ifndef __ARCH_ARM_SVE_MACROMEM_HH__
4114028Sgiacomo.gabrielli@arm.com#define __ARCH_ARM_SVE_MACROMEM_HH__
4214028Sgiacomo.gabrielli@arm.com
4314028Sgiacomo.gabrielli@arm.com#include "arch/arm/generated/decoder.hh"
4414028Sgiacomo.gabrielli@arm.com#include "arch/arm/insts/pred_inst.hh"
4514028Sgiacomo.gabrielli@arm.com
4614028Sgiacomo.gabrielli@arm.comnamespace ArmISA {
4714028Sgiacomo.gabrielli@arm.com
4814106Sjavier.setoain@arm.comtemplate <typename Element,
4914106Sjavier.setoain@arm.com         template <typename> class MicroopLdMemType,
5014106Sjavier.setoain@arm.com         template <typename> class MicroopDeIntrlvType>
5114106Sjavier.setoain@arm.comclass SveLdStructSS : public PredMacroOp
5214106Sjavier.setoain@arm.com{
5314106Sjavier.setoain@arm.com  protected:
5414106Sjavier.setoain@arm.com    IntRegIndex dest;
5514106Sjavier.setoain@arm.com    IntRegIndex gp;
5614106Sjavier.setoain@arm.com    IntRegIndex base;
5714106Sjavier.setoain@arm.com    IntRegIndex offset;
5814106Sjavier.setoain@arm.com    uint8_t numregs;
5914106Sjavier.setoain@arm.com
6014106Sjavier.setoain@arm.com  public:
6114106Sjavier.setoain@arm.com    SveLdStructSS(const char* mnem, ExtMachInst machInst, OpClass __opClass,
6214106Sjavier.setoain@arm.com            IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base,
6314106Sjavier.setoain@arm.com            IntRegIndex _offset, uint8_t _numregs)
6414106Sjavier.setoain@arm.com        : PredMacroOp(mnem, machInst, __opClass),
6514106Sjavier.setoain@arm.com          dest(_dest), gp(_gp), base(_base), offset(_offset), numregs(_numregs)
6614106Sjavier.setoain@arm.com    {
6714106Sjavier.setoain@arm.com        numMicroops = numregs * 2;
6814106Sjavier.setoain@arm.com
6914106Sjavier.setoain@arm.com        microOps = new StaticInstPtr[numMicroops];
7014106Sjavier.setoain@arm.com
7114106Sjavier.setoain@arm.com        for (int i = 0; i < numregs; ++i) {
7214106Sjavier.setoain@arm.com            microOps[i] = new MicroopLdMemType<Element>(
7314106Sjavier.setoain@arm.com                    mnem, machInst, static_cast<IntRegIndex>(INTRLVREG0 + i),
7414106Sjavier.setoain@arm.com                    _gp, _base, _offset, _numregs, i);
7514106Sjavier.setoain@arm.com        }
7614106Sjavier.setoain@arm.com        for (int i = 0; i < numregs; ++i) {
7714106Sjavier.setoain@arm.com            microOps[i + numregs] = new MicroopDeIntrlvType<Element>(
7814106Sjavier.setoain@arm.com                    mnem, machInst, static_cast<IntRegIndex>((_dest + i) % 32),
7914106Sjavier.setoain@arm.com                    _numregs, i, this);
8014106Sjavier.setoain@arm.com        }
8114106Sjavier.setoain@arm.com
8214106Sjavier.setoain@arm.com        microOps[0]->setFirstMicroop();
8314106Sjavier.setoain@arm.com        microOps[numMicroops - 1]->setLastMicroop();
8414106Sjavier.setoain@arm.com
8514106Sjavier.setoain@arm.com        for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) {
8614106Sjavier.setoain@arm.com            (*uop)->setDelayedCommit();
8714106Sjavier.setoain@arm.com        }
8814106Sjavier.setoain@arm.com    }
8914106Sjavier.setoain@arm.com
9014106Sjavier.setoain@arm.com    Fault
9114106Sjavier.setoain@arm.com    execute(ExecContext *, Trace::InstRecord *) const
9214106Sjavier.setoain@arm.com    {
9314106Sjavier.setoain@arm.com        panic("Execute method called when it shouldn't!");
9414106Sjavier.setoain@arm.com        return NoFault;
9514106Sjavier.setoain@arm.com    }
9614106Sjavier.setoain@arm.com
9714106Sjavier.setoain@arm.com    std::string
9814106Sjavier.setoain@arm.com    generateDisassembly(Addr pc, const SymbolTable *symtab) const
9914106Sjavier.setoain@arm.com    {
10014106Sjavier.setoain@arm.com        std::stringstream ss;
10114106Sjavier.setoain@arm.com        printMnemonic(ss, "", false);
10214106Sjavier.setoain@arm.com        ccprintf(ss, "{");
10314106Sjavier.setoain@arm.com        for (int i = 0; i < numregs; ++i) {
10414106Sjavier.setoain@arm.com            printVecReg(ss, (dest + i) % 32, true);
10514106Sjavier.setoain@arm.com            if (i < numregs - 1)
10614106Sjavier.setoain@arm.com                ccprintf(ss, ", ");
10714106Sjavier.setoain@arm.com        }
10814106Sjavier.setoain@arm.com        ccprintf(ss, "}, ");
10914106Sjavier.setoain@arm.com        printVecPredReg(ss, gp);
11014106Sjavier.setoain@arm.com        ccprintf(ss, "/z, [");
11114106Sjavier.setoain@arm.com        printIntReg(ss, base);
11214106Sjavier.setoain@arm.com        ccprintf(ss, ", ");
11314106Sjavier.setoain@arm.com        printIntReg(ss, offset);
11414106Sjavier.setoain@arm.com        ccprintf(ss, "]");
11514106Sjavier.setoain@arm.com        return ss.str();
11614106Sjavier.setoain@arm.com    }
11714106Sjavier.setoain@arm.com};
11814106Sjavier.setoain@arm.com
11914106Sjavier.setoain@arm.comtemplate <typename Element,
12014106Sjavier.setoain@arm.com         template <typename> class MicroopStMemType,
12114106Sjavier.setoain@arm.com         template <typename> class MicroopIntrlvType>
12214106Sjavier.setoain@arm.comclass SveStStructSS : public PredMacroOp
12314106Sjavier.setoain@arm.com{
12414106Sjavier.setoain@arm.com  protected:
12514106Sjavier.setoain@arm.com    IntRegIndex dest;
12614106Sjavier.setoain@arm.com    IntRegIndex gp;
12714106Sjavier.setoain@arm.com    IntRegIndex base;
12814106Sjavier.setoain@arm.com    IntRegIndex offset;
12914106Sjavier.setoain@arm.com    uint8_t numregs;
13014106Sjavier.setoain@arm.com
13114106Sjavier.setoain@arm.com  public:
13214106Sjavier.setoain@arm.com    SveStStructSS(const char* mnem, ExtMachInst machInst, OpClass __opClass,
13314106Sjavier.setoain@arm.com            IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base,
13414106Sjavier.setoain@arm.com            IntRegIndex _offset, uint8_t _numregs)
13514106Sjavier.setoain@arm.com        : PredMacroOp(mnem, machInst, __opClass),
13614106Sjavier.setoain@arm.com          dest(_dest), gp(_gp), base(_base), offset(_offset), numregs(_numregs)
13714106Sjavier.setoain@arm.com    {
13814106Sjavier.setoain@arm.com        numMicroops = numregs * 2;
13914106Sjavier.setoain@arm.com
14014106Sjavier.setoain@arm.com        microOps = new StaticInstPtr[numMicroops];
14114106Sjavier.setoain@arm.com
14214106Sjavier.setoain@arm.com        for (int i = 0; i < numregs; ++i) {
14314106Sjavier.setoain@arm.com            microOps[i] = new MicroopIntrlvType<Element>(
14414106Sjavier.setoain@arm.com                    mnem, machInst, static_cast<IntRegIndex>(INTRLVREG0 + i),
14514106Sjavier.setoain@arm.com                    _dest, _numregs, i, this);
14614106Sjavier.setoain@arm.com        }
14714106Sjavier.setoain@arm.com
14814106Sjavier.setoain@arm.com        for (int i = 0; i < numregs; ++i) {
14914106Sjavier.setoain@arm.com            microOps[i + numregs] = new MicroopStMemType<Element>(
15014106Sjavier.setoain@arm.com                    mnem, machInst, static_cast<IntRegIndex>(INTRLVREG0 + i),
15114106Sjavier.setoain@arm.com                    _gp, _base, _offset, _numregs, i);
15214106Sjavier.setoain@arm.com        }
15314106Sjavier.setoain@arm.com
15414106Sjavier.setoain@arm.com        microOps[0]->setFirstMicroop();
15514106Sjavier.setoain@arm.com        microOps[numMicroops - 1]->setLastMicroop();
15614106Sjavier.setoain@arm.com
15714106Sjavier.setoain@arm.com        for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) {
15814106Sjavier.setoain@arm.com            (*uop)->setDelayedCommit();
15914106Sjavier.setoain@arm.com        }
16014106Sjavier.setoain@arm.com    }
16114106Sjavier.setoain@arm.com
16214106Sjavier.setoain@arm.com    Fault
16314106Sjavier.setoain@arm.com    execute(ExecContext *, Trace::InstRecord *) const
16414106Sjavier.setoain@arm.com    {
16514106Sjavier.setoain@arm.com        panic("Execute method called when it shouldn't!");
16614106Sjavier.setoain@arm.com        return NoFault;
16714106Sjavier.setoain@arm.com    }
16814106Sjavier.setoain@arm.com
16914106Sjavier.setoain@arm.com    std::string
17014106Sjavier.setoain@arm.com    generateDisassembly(Addr pc, const SymbolTable *symtab) const
17114106Sjavier.setoain@arm.com    {
17214106Sjavier.setoain@arm.com        std::stringstream ss;
17314106Sjavier.setoain@arm.com        printMnemonic(ss, "", false);
17414106Sjavier.setoain@arm.com        ccprintf(ss, "{");
17514106Sjavier.setoain@arm.com        for (int i = 0; i < numregs; ++i) {
17614106Sjavier.setoain@arm.com            printVecReg(ss, (dest + i) % 32, true);
17714106Sjavier.setoain@arm.com            if (i < numregs - 1)
17814106Sjavier.setoain@arm.com                ccprintf(ss, ", ");
17914106Sjavier.setoain@arm.com        }
18014106Sjavier.setoain@arm.com        ccprintf(ss, "}, ");
18114106Sjavier.setoain@arm.com        printVecPredReg(ss, gp);
18214106Sjavier.setoain@arm.com        ccprintf(ss, ", [");
18314106Sjavier.setoain@arm.com        printIntReg(ss, base);
18414106Sjavier.setoain@arm.com        ccprintf(ss, ", ");
18514106Sjavier.setoain@arm.com        printIntReg(ss, offset);
18614106Sjavier.setoain@arm.com        ccprintf(ss, "]");
18714106Sjavier.setoain@arm.com        return ss.str();
18814106Sjavier.setoain@arm.com    }
18914106Sjavier.setoain@arm.com};
19014106Sjavier.setoain@arm.com
19114106Sjavier.setoain@arm.com
19214106Sjavier.setoain@arm.comtemplate <typename Element,
19314106Sjavier.setoain@arm.com         template <typename> class MicroopLdMemType,
19414106Sjavier.setoain@arm.com         template <typename> class MicroopDeIntrlvType>
19514106Sjavier.setoain@arm.comclass SveLdStructSI : public PredMacroOp
19614106Sjavier.setoain@arm.com{
19714106Sjavier.setoain@arm.com  protected:
19814106Sjavier.setoain@arm.com    IntRegIndex dest;
19914106Sjavier.setoain@arm.com    IntRegIndex gp;
20014106Sjavier.setoain@arm.com    IntRegIndex base;
20114106Sjavier.setoain@arm.com    int64_t imm;
20214106Sjavier.setoain@arm.com    uint8_t numregs;
20314106Sjavier.setoain@arm.com
20414106Sjavier.setoain@arm.com  public:
20514106Sjavier.setoain@arm.com    SveLdStructSI(const char* mnem, ExtMachInst machInst, OpClass __opClass,
20614106Sjavier.setoain@arm.com            IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base,
20714106Sjavier.setoain@arm.com            int64_t _imm, uint8_t _numregs)
20814106Sjavier.setoain@arm.com        : PredMacroOp(mnem, machInst, __opClass),
20914106Sjavier.setoain@arm.com          dest(_dest), gp(_gp), base(_base), imm(_imm), numregs(_numregs)
21014106Sjavier.setoain@arm.com    {
21114106Sjavier.setoain@arm.com        numMicroops = numregs * 2;
21214106Sjavier.setoain@arm.com
21314106Sjavier.setoain@arm.com        microOps = new StaticInstPtr[numMicroops];
21414106Sjavier.setoain@arm.com
21514106Sjavier.setoain@arm.com        for (int i = 0; i < numregs; ++i) {
21614106Sjavier.setoain@arm.com            microOps[i] = new MicroopLdMemType<Element>(
21714106Sjavier.setoain@arm.com                    mnem, machInst, static_cast<IntRegIndex>(INTRLVREG0 + i),
21814106Sjavier.setoain@arm.com                    _gp, _base, _imm, _numregs, i);
21914106Sjavier.setoain@arm.com        }
22014106Sjavier.setoain@arm.com        for (int i = 0; i < numregs; ++i) {
22114106Sjavier.setoain@arm.com            microOps[i + numregs] = new MicroopDeIntrlvType<Element>(
22214106Sjavier.setoain@arm.com                    mnem, machInst, static_cast<IntRegIndex>((_dest + i) % 32),
22314106Sjavier.setoain@arm.com                    _numregs, i, this);
22414106Sjavier.setoain@arm.com        }
22514106Sjavier.setoain@arm.com
22614106Sjavier.setoain@arm.com        microOps[0]->setFirstMicroop();
22714106Sjavier.setoain@arm.com        microOps[numMicroops - 1]->setLastMicroop();
22814106Sjavier.setoain@arm.com
22914106Sjavier.setoain@arm.com        for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) {
23014106Sjavier.setoain@arm.com            (*uop)->setDelayedCommit();
23114106Sjavier.setoain@arm.com        }
23214106Sjavier.setoain@arm.com    }
23314106Sjavier.setoain@arm.com
23414106Sjavier.setoain@arm.com    Fault
23514106Sjavier.setoain@arm.com    execute(ExecContext *, Trace::InstRecord *) const
23614106Sjavier.setoain@arm.com    {
23714106Sjavier.setoain@arm.com        panic("Execute method called when it shouldn't!");
23814106Sjavier.setoain@arm.com        return NoFault;
23914106Sjavier.setoain@arm.com    }
24014106Sjavier.setoain@arm.com
24114106Sjavier.setoain@arm.com    std::string
24214106Sjavier.setoain@arm.com    generateDisassembly(Addr pc, const SymbolTable *symtab) const
24314106Sjavier.setoain@arm.com    {
24414106Sjavier.setoain@arm.com        std::stringstream ss;
24514106Sjavier.setoain@arm.com        printMnemonic(ss, "", false);
24614106Sjavier.setoain@arm.com        ccprintf(ss, "{");
24714106Sjavier.setoain@arm.com        for (int i = 0; i < numregs; ++i) {
24814106Sjavier.setoain@arm.com            printVecReg(ss, (dest + i) % 32, true);
24914106Sjavier.setoain@arm.com            if (i < numregs - 1)
25014106Sjavier.setoain@arm.com                ccprintf(ss, ", ");
25114106Sjavier.setoain@arm.com        }
25214106Sjavier.setoain@arm.com        ccprintf(ss, "}, ");
25314106Sjavier.setoain@arm.com        printVecPredReg(ss, gp);
25414106Sjavier.setoain@arm.com        ccprintf(ss, "/z, [");
25514106Sjavier.setoain@arm.com        printIntReg(ss, base);
25614106Sjavier.setoain@arm.com        if (imm != 0) {
25714106Sjavier.setoain@arm.com            ccprintf(ss, ", #%d, MUL VL", imm);
25814106Sjavier.setoain@arm.com        }
25914106Sjavier.setoain@arm.com        ccprintf(ss, "]");
26014106Sjavier.setoain@arm.com        return ss.str();
26114106Sjavier.setoain@arm.com    }
26214106Sjavier.setoain@arm.com};
26314106Sjavier.setoain@arm.com
26414106Sjavier.setoain@arm.comtemplate <typename Element,
26514106Sjavier.setoain@arm.com         template <typename> class MicroopStMemType,
26614106Sjavier.setoain@arm.com         template <typename> class MicroopIntrlvType>
26714106Sjavier.setoain@arm.comclass SveStStructSI : public PredMacroOp
26814106Sjavier.setoain@arm.com{
26914106Sjavier.setoain@arm.com  protected:
27014106Sjavier.setoain@arm.com    IntRegIndex dest;
27114106Sjavier.setoain@arm.com    IntRegIndex gp;
27214106Sjavier.setoain@arm.com    IntRegIndex base;
27314106Sjavier.setoain@arm.com    int64_t imm;
27414106Sjavier.setoain@arm.com    uint8_t numregs;
27514106Sjavier.setoain@arm.com
27614106Sjavier.setoain@arm.com  public:
27714106Sjavier.setoain@arm.com    SveStStructSI(const char* mnem, ExtMachInst machInst, OpClass __opClass,
27814106Sjavier.setoain@arm.com            IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base,
27914106Sjavier.setoain@arm.com            int64_t _imm, uint8_t _numregs)
28014106Sjavier.setoain@arm.com        : PredMacroOp(mnem, machInst, __opClass),
28114106Sjavier.setoain@arm.com          dest(_dest), gp(_gp), base(_base), imm(_imm), numregs(_numregs)
28214106Sjavier.setoain@arm.com    {
28314106Sjavier.setoain@arm.com        numMicroops = numregs * 2;
28414106Sjavier.setoain@arm.com
28514106Sjavier.setoain@arm.com        microOps = new StaticInstPtr[numMicroops];
28614106Sjavier.setoain@arm.com
28714106Sjavier.setoain@arm.com        for (int i = 0; i < numregs; ++i) {
28814106Sjavier.setoain@arm.com            microOps[i] = new MicroopIntrlvType<Element>(
28914106Sjavier.setoain@arm.com                    mnem, machInst, static_cast<IntRegIndex>(INTRLVREG0 + i),
29014106Sjavier.setoain@arm.com                    _dest, _numregs, i, this);
29114106Sjavier.setoain@arm.com        }
29214106Sjavier.setoain@arm.com
29314106Sjavier.setoain@arm.com        for (int i = 0; i < numregs; ++i) {
29414106Sjavier.setoain@arm.com            microOps[i + numregs] = new MicroopStMemType<Element>(
29514106Sjavier.setoain@arm.com                    mnem, machInst, static_cast<IntRegIndex>(INTRLVREG0 + i),
29614106Sjavier.setoain@arm.com                    _gp, _base, _imm, _numregs, i);
29714106Sjavier.setoain@arm.com        }
29814106Sjavier.setoain@arm.com
29914106Sjavier.setoain@arm.com        microOps[0]->setFirstMicroop();
30014106Sjavier.setoain@arm.com        microOps[numMicroops - 1]->setLastMicroop();
30114106Sjavier.setoain@arm.com
30214106Sjavier.setoain@arm.com        for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) {
30314106Sjavier.setoain@arm.com            (*uop)->setDelayedCommit();
30414106Sjavier.setoain@arm.com        }
30514106Sjavier.setoain@arm.com    }
30614106Sjavier.setoain@arm.com
30714106Sjavier.setoain@arm.com    Fault
30814106Sjavier.setoain@arm.com    execute(ExecContext *, Trace::InstRecord *) const
30914106Sjavier.setoain@arm.com    {
31014106Sjavier.setoain@arm.com        panic("Execute method called when it shouldn't!");
31114106Sjavier.setoain@arm.com        return NoFault;
31214106Sjavier.setoain@arm.com    }
31314106Sjavier.setoain@arm.com
31414106Sjavier.setoain@arm.com    std::string
31514106Sjavier.setoain@arm.com    generateDisassembly(Addr pc, const SymbolTable *symtab) const
31614106Sjavier.setoain@arm.com    {
31714106Sjavier.setoain@arm.com        std::stringstream ss;
31814106Sjavier.setoain@arm.com        printMnemonic(ss, "", false);
31914106Sjavier.setoain@arm.com        ccprintf(ss, "{");
32014106Sjavier.setoain@arm.com        for (int i = 0; i < numregs; ++i) {
32114106Sjavier.setoain@arm.com            printVecReg(ss, (dest + i) % 32, true);
32214106Sjavier.setoain@arm.com            if (i < numregs - 1)
32314106Sjavier.setoain@arm.com                ccprintf(ss, ", ");
32414106Sjavier.setoain@arm.com        }
32514106Sjavier.setoain@arm.com        ccprintf(ss, "}, ");
32614106Sjavier.setoain@arm.com        printVecPredReg(ss, gp);
32714106Sjavier.setoain@arm.com        ccprintf(ss, ", [");
32814106Sjavier.setoain@arm.com        printIntReg(ss, base);
32914106Sjavier.setoain@arm.com        if (imm != 0) {
33014106Sjavier.setoain@arm.com            ccprintf(ss, ", #%d, MUL VL", imm);
33114106Sjavier.setoain@arm.com        }
33214106Sjavier.setoain@arm.com        ccprintf(ss, "]");
33314106Sjavier.setoain@arm.com        return ss.str();
33414106Sjavier.setoain@arm.com    }
33514106Sjavier.setoain@arm.com};
33614106Sjavier.setoain@arm.com
33714028Sgiacomo.gabrielli@arm.comtemplate <typename RegElemType, typename MemElemType,
33814091Sgabor.dozsa@arm.com          template <typename, typename> class MicroopType,
33914091Sgabor.dozsa@arm.com          template <typename> class FirstFaultWritebackMicroopType>
34014028Sgiacomo.gabrielli@arm.comclass SveIndexedMemVI : public PredMacroOp
34114028Sgiacomo.gabrielli@arm.com{
34214028Sgiacomo.gabrielli@arm.com  protected:
34314028Sgiacomo.gabrielli@arm.com    IntRegIndex dest;
34414028Sgiacomo.gabrielli@arm.com    IntRegIndex gp;
34514028Sgiacomo.gabrielli@arm.com    IntRegIndex base;
34614028Sgiacomo.gabrielli@arm.com    uint64_t imm;
34714028Sgiacomo.gabrielli@arm.com
34814028Sgiacomo.gabrielli@arm.com  public:
34914028Sgiacomo.gabrielli@arm.com    SveIndexedMemVI(const char *mnem, ExtMachInst machInst, OpClass __opClass,
35014028Sgiacomo.gabrielli@arm.com                    IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base,
35114091Sgabor.dozsa@arm.com                    uint64_t _imm, bool firstFault)
35214028Sgiacomo.gabrielli@arm.com        : PredMacroOp(mnem, machInst, __opClass),
35314028Sgiacomo.gabrielli@arm.com          dest(_dest), gp(_gp), base(_base), imm(_imm)
35414028Sgiacomo.gabrielli@arm.com    {
35514028Sgiacomo.gabrielli@arm.com        bool isLoad = (__opClass == MemReadOp);
35614091Sgabor.dozsa@arm.com        assert(!firstFault || isLoad);
35714028Sgiacomo.gabrielli@arm.com
35814028Sgiacomo.gabrielli@arm.com        int num_elems = ((machInst.sveLen + 1) * 16) / sizeof(RegElemType);
35914028Sgiacomo.gabrielli@arm.com
36014028Sgiacomo.gabrielli@arm.com        numMicroops = num_elems;
36114028Sgiacomo.gabrielli@arm.com        if (isLoad) {
36214091Sgabor.dozsa@arm.com            if (firstFault) {
36314091Sgabor.dozsa@arm.com                numMicroops += 2;
36414091Sgabor.dozsa@arm.com            } else {
36514091Sgabor.dozsa@arm.com                numMicroops++;
36614091Sgabor.dozsa@arm.com            }
36714028Sgiacomo.gabrielli@arm.com        }
36814028Sgiacomo.gabrielli@arm.com
36914028Sgiacomo.gabrielli@arm.com        microOps = new StaticInstPtr[numMicroops];
37014028Sgiacomo.gabrielli@arm.com
37114028Sgiacomo.gabrielli@arm.com        StaticInstPtr *uop = microOps;
37214028Sgiacomo.gabrielli@arm.com
37314028Sgiacomo.gabrielli@arm.com        if (isLoad) {
37414028Sgiacomo.gabrielli@arm.com            // The first microop of a gather load copies the source vector
37514028Sgiacomo.gabrielli@arm.com            // register used for address calculation to an auxiliary register,
37614028Sgiacomo.gabrielli@arm.com            // with all subsequent microops reading from the latter.  This is
37714028Sgiacomo.gabrielli@arm.com            // needed to properly handle cases where the source vector
37814028Sgiacomo.gabrielli@arm.com            // register is the same as the destination register
37914028Sgiacomo.gabrielli@arm.com            *uop = new ArmISAInst::SveGatherLoadCpySrcVecMicroop(
38014028Sgiacomo.gabrielli@arm.com                mnem, machInst, _base, this);
38114028Sgiacomo.gabrielli@arm.com            uop++;
38214028Sgiacomo.gabrielli@arm.com        }
38314028Sgiacomo.gabrielli@arm.com
38414028Sgiacomo.gabrielli@arm.com        for (int i = 0; i < num_elems; i++, uop++) {
38514028Sgiacomo.gabrielli@arm.com            *uop = new MicroopType<RegElemType, MemElemType>(
38614028Sgiacomo.gabrielli@arm.com                mnem, machInst, __opClass, _dest, _gp,
38714028Sgiacomo.gabrielli@arm.com                isLoad ? (IntRegIndex) VECREG_UREG0 : _base, _imm, i,
38814091Sgabor.dozsa@arm.com                num_elems, firstFault);
38914028Sgiacomo.gabrielli@arm.com        }
39014028Sgiacomo.gabrielli@arm.com
39114091Sgabor.dozsa@arm.com        if (firstFault) {
39214091Sgabor.dozsa@arm.com            *uop = new FirstFaultWritebackMicroopType<RegElemType>(
39314091Sgabor.dozsa@arm.com                mnem, machInst, __opClass, num_elems, this);
39414091Sgabor.dozsa@arm.com        } else {
39514091Sgabor.dozsa@arm.com            --uop;
39614091Sgabor.dozsa@arm.com        }
39714091Sgabor.dozsa@arm.com
39814028Sgiacomo.gabrielli@arm.com        (*uop)->setLastMicroop();
39914028Sgiacomo.gabrielli@arm.com        microOps[0]->setFirstMicroop();
40014028Sgiacomo.gabrielli@arm.com
40114028Sgiacomo.gabrielli@arm.com        for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) {
40214028Sgiacomo.gabrielli@arm.com            (*uop)->setDelayedCommit();
40314028Sgiacomo.gabrielli@arm.com        }
40414028Sgiacomo.gabrielli@arm.com    }
40514028Sgiacomo.gabrielli@arm.com
40614028Sgiacomo.gabrielli@arm.com    Fault
40714028Sgiacomo.gabrielli@arm.com    execute(ExecContext *, Trace::InstRecord *) const
40814028Sgiacomo.gabrielli@arm.com    {
40914028Sgiacomo.gabrielli@arm.com        panic("Execute method called when it shouldn't!");
41014028Sgiacomo.gabrielli@arm.com        return NoFault;
41114028Sgiacomo.gabrielli@arm.com    }
41214028Sgiacomo.gabrielli@arm.com
41314028Sgiacomo.gabrielli@arm.com    std::string
41414028Sgiacomo.gabrielli@arm.com    generateDisassembly(Addr pc, const SymbolTable *symtab) const
41514028Sgiacomo.gabrielli@arm.com    {
41614028Sgiacomo.gabrielli@arm.com        // TODO: add suffix to transfer and base registers
41714028Sgiacomo.gabrielli@arm.com        std::stringstream ss;
41814028Sgiacomo.gabrielli@arm.com        printMnemonic(ss, "", false);
41914028Sgiacomo.gabrielli@arm.com        ccprintf(ss, "{");
42014028Sgiacomo.gabrielli@arm.com        printVecReg(ss, dest, true);
42114028Sgiacomo.gabrielli@arm.com        ccprintf(ss, "}, ");
42214028Sgiacomo.gabrielli@arm.com        printVecPredReg(ss, gp);
42314028Sgiacomo.gabrielli@arm.com        ccprintf(ss, "/z, [");
42414028Sgiacomo.gabrielli@arm.com        printVecReg(ss, base, true);
42514028Sgiacomo.gabrielli@arm.com        if (imm != 0) {
42614028Sgiacomo.gabrielli@arm.com            ccprintf(ss, ", #%d", imm * sizeof(MemElemType));
42714028Sgiacomo.gabrielli@arm.com        }
42814028Sgiacomo.gabrielli@arm.com        ccprintf(ss, "]");
42914028Sgiacomo.gabrielli@arm.com        return ss.str();
43014028Sgiacomo.gabrielli@arm.com    }
43114028Sgiacomo.gabrielli@arm.com};
43214028Sgiacomo.gabrielli@arm.com
43314028Sgiacomo.gabrielli@arm.comtemplate <typename RegElemType, typename MemElemType,
43414091Sgabor.dozsa@arm.com          template <typename, typename> class MicroopType,
43514091Sgabor.dozsa@arm.com          template <typename> class FirstFaultWritebackMicroopType>
43614028Sgiacomo.gabrielli@arm.comclass SveIndexedMemSV : public PredMacroOp
43714028Sgiacomo.gabrielli@arm.com{
43814028Sgiacomo.gabrielli@arm.com  protected:
43914028Sgiacomo.gabrielli@arm.com    IntRegIndex dest;
44014028Sgiacomo.gabrielli@arm.com    IntRegIndex gp;
44114028Sgiacomo.gabrielli@arm.com    IntRegIndex base;
44214028Sgiacomo.gabrielli@arm.com    IntRegIndex offset;
44314028Sgiacomo.gabrielli@arm.com
44414028Sgiacomo.gabrielli@arm.com    bool offsetIs32;
44514028Sgiacomo.gabrielli@arm.com    bool offsetIsSigned;
44614028Sgiacomo.gabrielli@arm.com    bool offsetIsScaled;
44714028Sgiacomo.gabrielli@arm.com
44814028Sgiacomo.gabrielli@arm.com  public:
44914028Sgiacomo.gabrielli@arm.com    SveIndexedMemSV(const char *mnem, ExtMachInst machInst, OpClass __opClass,
45014028Sgiacomo.gabrielli@arm.com                    IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base,
45114028Sgiacomo.gabrielli@arm.com                    IntRegIndex _offset, bool _offsetIs32,
45214091Sgabor.dozsa@arm.com                    bool _offsetIsSigned, bool _offsetIsScaled,
45314091Sgabor.dozsa@arm.com                    bool firstFault)
45414028Sgiacomo.gabrielli@arm.com        : PredMacroOp(mnem, machInst, __opClass),
45514028Sgiacomo.gabrielli@arm.com          dest(_dest), gp(_gp), base(_base), offset(_offset),
45614028Sgiacomo.gabrielli@arm.com          offsetIs32(_offsetIs32), offsetIsSigned(_offsetIsSigned),
45714028Sgiacomo.gabrielli@arm.com          offsetIsScaled(_offsetIsScaled)
45814028Sgiacomo.gabrielli@arm.com    {
45914028Sgiacomo.gabrielli@arm.com        bool isLoad = (__opClass == MemReadOp);
46014091Sgabor.dozsa@arm.com        assert(!firstFault || isLoad);
46114028Sgiacomo.gabrielli@arm.com
46214028Sgiacomo.gabrielli@arm.com        int num_elems = ((machInst.sveLen + 1) * 16) / sizeof(RegElemType);
46314028Sgiacomo.gabrielli@arm.com
46414028Sgiacomo.gabrielli@arm.com        numMicroops = num_elems;
46514028Sgiacomo.gabrielli@arm.com        if (isLoad) {
46614091Sgabor.dozsa@arm.com            if (firstFault) {
46714091Sgabor.dozsa@arm.com                numMicroops += 2;
46814091Sgabor.dozsa@arm.com            } else {
46914091Sgabor.dozsa@arm.com                numMicroops++;
47014091Sgabor.dozsa@arm.com            }
47114028Sgiacomo.gabrielli@arm.com        }
47214028Sgiacomo.gabrielli@arm.com
47314028Sgiacomo.gabrielli@arm.com        microOps = new StaticInstPtr[numMicroops];
47414028Sgiacomo.gabrielli@arm.com
47514028Sgiacomo.gabrielli@arm.com        StaticInstPtr *uop = microOps;
47614028Sgiacomo.gabrielli@arm.com
47714028Sgiacomo.gabrielli@arm.com        if (isLoad) {
47814028Sgiacomo.gabrielli@arm.com            // The first microop of a gather load copies the source vector
47914028Sgiacomo.gabrielli@arm.com            // register used for address calculation to an auxiliary register,
48014028Sgiacomo.gabrielli@arm.com            // with all subsequent microops reading from the latter.  This is
48114028Sgiacomo.gabrielli@arm.com            // needed to properly handle cases where the source vector
48214028Sgiacomo.gabrielli@arm.com            // register is the same as the destination register
48314028Sgiacomo.gabrielli@arm.com            *uop = new ArmISAInst::SveGatherLoadCpySrcVecMicroop(
48414028Sgiacomo.gabrielli@arm.com                mnem, machInst, _offset, this);
48514028Sgiacomo.gabrielli@arm.com            uop++;
48614028Sgiacomo.gabrielli@arm.com        }
48714028Sgiacomo.gabrielli@arm.com
48814028Sgiacomo.gabrielli@arm.com        for (int i = 0; i < num_elems; i++, uop++) {
48914028Sgiacomo.gabrielli@arm.com            *uop = new MicroopType<RegElemType, MemElemType>(
49014028Sgiacomo.gabrielli@arm.com                mnem, machInst, __opClass, _dest, _gp, _base,
49114028Sgiacomo.gabrielli@arm.com                isLoad ? (IntRegIndex) VECREG_UREG0 : _offset, _offsetIs32,
49214091Sgabor.dozsa@arm.com                _offsetIsSigned, _offsetIsScaled, i, num_elems, firstFault);
49314028Sgiacomo.gabrielli@arm.com        }
49414028Sgiacomo.gabrielli@arm.com
49514091Sgabor.dozsa@arm.com        if (firstFault) {
49614091Sgabor.dozsa@arm.com            *uop = new FirstFaultWritebackMicroopType<RegElemType>(
49714091Sgabor.dozsa@arm.com                mnem, machInst, __opClass, num_elems, this);
49814091Sgabor.dozsa@arm.com        } else {
49914091Sgabor.dozsa@arm.com            --uop;
50014091Sgabor.dozsa@arm.com        }
50114091Sgabor.dozsa@arm.com
50214028Sgiacomo.gabrielli@arm.com        (*uop)->setLastMicroop();
50314028Sgiacomo.gabrielli@arm.com        microOps[0]->setFirstMicroop();
50414028Sgiacomo.gabrielli@arm.com
50514028Sgiacomo.gabrielli@arm.com        for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) {
50614028Sgiacomo.gabrielli@arm.com            (*uop)->setDelayedCommit();
50714028Sgiacomo.gabrielli@arm.com        }
50814028Sgiacomo.gabrielli@arm.com    }
50914028Sgiacomo.gabrielli@arm.com
51014028Sgiacomo.gabrielli@arm.com    Fault
51114028Sgiacomo.gabrielli@arm.com    execute(ExecContext *, Trace::InstRecord *) const
51214028Sgiacomo.gabrielli@arm.com    {
51314028Sgiacomo.gabrielli@arm.com        panic("Execute method called when it shouldn't!");
51414028Sgiacomo.gabrielli@arm.com        return NoFault;
51514028Sgiacomo.gabrielli@arm.com    }
51614028Sgiacomo.gabrielli@arm.com
51714028Sgiacomo.gabrielli@arm.com    std::string
51814028Sgiacomo.gabrielli@arm.com    generateDisassembly(Addr pc, const SymbolTable *symtab) const
51914028Sgiacomo.gabrielli@arm.com    {
52014028Sgiacomo.gabrielli@arm.com        // TODO: add suffix to transfer and base registers
52114028Sgiacomo.gabrielli@arm.com        std::stringstream ss;
52214028Sgiacomo.gabrielli@arm.com        printMnemonic(ss, "", false);
52314028Sgiacomo.gabrielli@arm.com        ccprintf(ss, "{");
52414028Sgiacomo.gabrielli@arm.com        printVecReg(ss, dest, true);
52514028Sgiacomo.gabrielli@arm.com        ccprintf(ss, "}, ");
52614028Sgiacomo.gabrielli@arm.com        printVecPredReg(ss, gp);
52714028Sgiacomo.gabrielli@arm.com        ccprintf(ss, "/z, [");
52814028Sgiacomo.gabrielli@arm.com        printIntReg(ss, base);
52914028Sgiacomo.gabrielli@arm.com        ccprintf(ss, ", ");
53014028Sgiacomo.gabrielli@arm.com        printVecReg(ss, offset, true);
53114028Sgiacomo.gabrielli@arm.com        ccprintf(ss, "]");
53214028Sgiacomo.gabrielli@arm.com        return ss.str();
53314028Sgiacomo.gabrielli@arm.com    }
53414028Sgiacomo.gabrielli@arm.com};
53514028Sgiacomo.gabrielli@arm.com
53614028Sgiacomo.gabrielli@arm.com}  // namespace ArmISA
53714028Sgiacomo.gabrielli@arm.com
53814028Sgiacomo.gabrielli@arm.com#endif  // __ARCH_ARM_SVE_MACROMEM_HH__
539