114109Sgabor.dozsa@arm.com// Copyright (c) 2017-2019 ARM Limited
213955Sgiacomo.gabrielli@arm.com// All rights reserved
313955Sgiacomo.gabrielli@arm.com//
413955Sgiacomo.gabrielli@arm.com// The license below extends only to copyright in the software and shall
513955Sgiacomo.gabrielli@arm.com// not be construed as granting a license to any other intellectual
613955Sgiacomo.gabrielli@arm.com// property including but not limited to intellectual property relating
713955Sgiacomo.gabrielli@arm.com// to a hardware implementation of the functionality of the software
813955Sgiacomo.gabrielli@arm.com// licensed hereunder.  You may use the software subject to the license
913955Sgiacomo.gabrielli@arm.com// terms below provided that you ensure that this notice is replicated
1013955Sgiacomo.gabrielli@arm.com// unmodified and in its entirety in all distributions of the software,
1113955Sgiacomo.gabrielli@arm.com// modified or unmodified, in source code or in binary form.
1213955Sgiacomo.gabrielli@arm.com//
1313955Sgiacomo.gabrielli@arm.com// Redistribution and use in source and binary forms, with or without
1413955Sgiacomo.gabrielli@arm.com// modification, are permitted provided that the following conditions are
1513955Sgiacomo.gabrielli@arm.com// met: redistributions of source code must retain the above copyright
1613955Sgiacomo.gabrielli@arm.com// notice, this list of conditions and the following disclaimer;
1713955Sgiacomo.gabrielli@arm.com// redistributions in binary form must reproduce the above copyright
1813955Sgiacomo.gabrielli@arm.com// notice, this list of conditions and the following disclaimer in the
1913955Sgiacomo.gabrielli@arm.com// documentation and/or other materials provided with the distribution;
2013955Sgiacomo.gabrielli@arm.com// neither the name of the copyright holders nor the names of its
2113955Sgiacomo.gabrielli@arm.com// contributors may be used to endorse or promote products derived from
2213955Sgiacomo.gabrielli@arm.com// this software without specific prior written permission.
2313955Sgiacomo.gabrielli@arm.com//
2413955Sgiacomo.gabrielli@arm.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2513955Sgiacomo.gabrielli@arm.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2613955Sgiacomo.gabrielli@arm.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2713955Sgiacomo.gabrielli@arm.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2813955Sgiacomo.gabrielli@arm.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2913955Sgiacomo.gabrielli@arm.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3013955Sgiacomo.gabrielli@arm.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3113955Sgiacomo.gabrielli@arm.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3213955Sgiacomo.gabrielli@arm.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3313955Sgiacomo.gabrielli@arm.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3413955Sgiacomo.gabrielli@arm.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3513955Sgiacomo.gabrielli@arm.com//
3613955Sgiacomo.gabrielli@arm.com// Authors: Giacomo Gabrielli
3713955Sgiacomo.gabrielli@arm.com
3813955Sgiacomo.gabrielli@arm.comdef template SveMemFillSpillOpDeclare {{
3913955Sgiacomo.gabrielli@arm.com    class %(class_name)s : public %(base_class)s
4013955Sgiacomo.gabrielli@arm.com    {
4113955Sgiacomo.gabrielli@arm.com      protected:
4213955Sgiacomo.gabrielli@arm.com        typedef uint8_t TPElem;
4313955Sgiacomo.gabrielli@arm.com        typedef uint8_t RegElemType;
4413955Sgiacomo.gabrielli@arm.com        typedef uint8_t MemElemType;
4513955Sgiacomo.gabrielli@arm.com
4613955Sgiacomo.gabrielli@arm.com      public:
4713955Sgiacomo.gabrielli@arm.com        %(class_name)s(ExtMachInst machInst,
4813955Sgiacomo.gabrielli@arm.com            IntRegIndex _dest, IntRegIndex _base, uint64_t _imm)
4913955Sgiacomo.gabrielli@arm.com            : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
5013955Sgiacomo.gabrielli@arm.com                _dest, _base, _imm)
5113955Sgiacomo.gabrielli@arm.com        {
5213955Sgiacomo.gabrielli@arm.com            %(constructor)s;
5313955Sgiacomo.gabrielli@arm.com        }
5413955Sgiacomo.gabrielli@arm.com
5513955Sgiacomo.gabrielli@arm.com        Fault execute(ExecContext *, Trace::InstRecord *) const;
5613955Sgiacomo.gabrielli@arm.com        Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
5713955Sgiacomo.gabrielli@arm.com        Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const;
5813955Sgiacomo.gabrielli@arm.com
5913955Sgiacomo.gabrielli@arm.com        virtual void
6013955Sgiacomo.gabrielli@arm.com        annotateFault(ArmFault *fault) {
6113955Sgiacomo.gabrielli@arm.com            %(fa_code)s
6213955Sgiacomo.gabrielli@arm.com        }
6313955Sgiacomo.gabrielli@arm.com    };
6413955Sgiacomo.gabrielli@arm.com}};
6513955Sgiacomo.gabrielli@arm.com
6613955Sgiacomo.gabrielli@arm.comdef template SveContigMemSSOpDeclare {{
6713955Sgiacomo.gabrielli@arm.com    %(tpl_header)s
6813955Sgiacomo.gabrielli@arm.com    class %(class_name)s : public %(base_class)s
6913955Sgiacomo.gabrielli@arm.com    {
7013955Sgiacomo.gabrielli@arm.com      protected:
7113955Sgiacomo.gabrielli@arm.com        typedef RegElemType TPElem;
7213955Sgiacomo.gabrielli@arm.com
7313955Sgiacomo.gabrielli@arm.com      public:
7413955Sgiacomo.gabrielli@arm.com        %(class_name)s(const char* mnem, ExtMachInst machInst,
7513955Sgiacomo.gabrielli@arm.com            IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base,
7613955Sgiacomo.gabrielli@arm.com            IntRegIndex _offset)
7713955Sgiacomo.gabrielli@arm.com            : %(base_class)s(mnem, machInst, %(op_class)s,
7813955Sgiacomo.gabrielli@arm.com                _dest, _gp, _base, _offset)
7913955Sgiacomo.gabrielli@arm.com        {
8013955Sgiacomo.gabrielli@arm.com            %(constructor)s;
8113955Sgiacomo.gabrielli@arm.com        }
8213955Sgiacomo.gabrielli@arm.com
8313955Sgiacomo.gabrielli@arm.com        Fault execute(ExecContext *, Trace::InstRecord *) const;
8413955Sgiacomo.gabrielli@arm.com        Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
8513955Sgiacomo.gabrielli@arm.com        Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const;
8613955Sgiacomo.gabrielli@arm.com
8713955Sgiacomo.gabrielli@arm.com        virtual void
8813955Sgiacomo.gabrielli@arm.com        annotateFault(ArmFault *fault) {
8913955Sgiacomo.gabrielli@arm.com            %(fa_code)s
9013955Sgiacomo.gabrielli@arm.com        }
9113955Sgiacomo.gabrielli@arm.com    };
9213955Sgiacomo.gabrielli@arm.com}};
9313955Sgiacomo.gabrielli@arm.com
9413955Sgiacomo.gabrielli@arm.comdef template SveContigMemSIOpDeclare {{
9513955Sgiacomo.gabrielli@arm.com    %(tpl_header)s
9613955Sgiacomo.gabrielli@arm.com    class %(class_name)s : public %(base_class)s
9713955Sgiacomo.gabrielli@arm.com    {
9813955Sgiacomo.gabrielli@arm.com      protected:
9913955Sgiacomo.gabrielli@arm.com        typedef RegElemType TPElem;
10013955Sgiacomo.gabrielli@arm.com
10113955Sgiacomo.gabrielli@arm.com      public:
10213955Sgiacomo.gabrielli@arm.com        %(class_name)s(const char* mnem, ExtMachInst machInst,
10313955Sgiacomo.gabrielli@arm.com            IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base,
10413955Sgiacomo.gabrielli@arm.com            uint64_t _imm)
10513955Sgiacomo.gabrielli@arm.com            : %(base_class)s(mnem, machInst, %(op_class)s,
10613955Sgiacomo.gabrielli@arm.com                _dest, _gp, _base, _imm)
10713955Sgiacomo.gabrielli@arm.com        {
10813955Sgiacomo.gabrielli@arm.com            %(constructor)s;
10913955Sgiacomo.gabrielli@arm.com        }
11013955Sgiacomo.gabrielli@arm.com
11113955Sgiacomo.gabrielli@arm.com        Fault execute(ExecContext *, Trace::InstRecord *) const;
11213955Sgiacomo.gabrielli@arm.com        Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
11313955Sgiacomo.gabrielli@arm.com        Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const;
11413955Sgiacomo.gabrielli@arm.com
11513955Sgiacomo.gabrielli@arm.com        virtual void
11613955Sgiacomo.gabrielli@arm.com        annotateFault(ArmFault *fault) {
11713955Sgiacomo.gabrielli@arm.com            %(fa_code)s
11813955Sgiacomo.gabrielli@arm.com        }
11913955Sgiacomo.gabrielli@arm.com    };
12013955Sgiacomo.gabrielli@arm.com}};
12113955Sgiacomo.gabrielli@arm.com
12213955Sgiacomo.gabrielli@arm.comdef template SveContigMemExecDeclare {{
12313955Sgiacomo.gabrielli@arm.com    template
12413955Sgiacomo.gabrielli@arm.com    Fault %(class_name)s%(tpl_args)s::execute(ExecContext *,
12513955Sgiacomo.gabrielli@arm.com        Trace::InstRecord *) const;
12613955Sgiacomo.gabrielli@arm.com
12713955Sgiacomo.gabrielli@arm.com    template
12813955Sgiacomo.gabrielli@arm.com    Fault %(class_name)s%(tpl_args)s::initiateAcc(ExecContext *,
12913955Sgiacomo.gabrielli@arm.com        Trace::InstRecord *) const;
13013955Sgiacomo.gabrielli@arm.com
13113955Sgiacomo.gabrielli@arm.com    template
13213955Sgiacomo.gabrielli@arm.com    Fault %(class_name)s%(tpl_args)s::completeAcc(PacketPtr,
13313955Sgiacomo.gabrielli@arm.com        ExecContext *, Trace::InstRecord *) const;
13413955Sgiacomo.gabrielli@arm.com}};
13513955Sgiacomo.gabrielli@arm.com
13613955Sgiacomo.gabrielli@arm.comdef template SveContigLoadExecute {{
13713955Sgiacomo.gabrielli@arm.com    %(tpl_header)s
13813955Sgiacomo.gabrielli@arm.com    Fault %(class_name)s%(tpl_args)s::execute(ExecContext *xc,
13913955Sgiacomo.gabrielli@arm.com        Trace::InstRecord *traceData) const
14013955Sgiacomo.gabrielli@arm.com    {
14113955Sgiacomo.gabrielli@arm.com        Addr EA;
14213955Sgiacomo.gabrielli@arm.com        Fault fault = NoFault;
14313955Sgiacomo.gabrielli@arm.com        bool aarch64 M5_VAR_USED = true;
14413955Sgiacomo.gabrielli@arm.com        unsigned eCount = ArmStaticInst::getCurSveVecLen<RegElemType>(
14513955Sgiacomo.gabrielli@arm.com            xc->tcBase());
14613955Sgiacomo.gabrielli@arm.com
14713955Sgiacomo.gabrielli@arm.com        %(op_decl)s;
14813955Sgiacomo.gabrielli@arm.com        %(op_rd)s;
14913955Sgiacomo.gabrielli@arm.com        %(ea_code)s;
15013955Sgiacomo.gabrielli@arm.com
15113955Sgiacomo.gabrielli@arm.com        TheISA::VecRegContainer memData;
15213955Sgiacomo.gabrielli@arm.com        auto memDataView = memData.as<MemElemType>();
15313955Sgiacomo.gabrielli@arm.com
15414091Sgabor.dozsa@arm.com        %(rden_code)s;
15514091Sgabor.dozsa@arm.com
15614091Sgabor.dozsa@arm.com        fault = xc->readMem(EA, memData.raw_ptr<uint8_t>(), memAccessSize,
15714091Sgabor.dozsa@arm.com            this->memAccessFlags, rdEn);
15814091Sgabor.dozsa@arm.com
15914091Sgabor.dozsa@arm.com        %(fault_code)s;
16013955Sgiacomo.gabrielli@arm.com
16113955Sgiacomo.gabrielli@arm.com        if (fault == NoFault) {
16214091Sgabor.dozsa@arm.com            %(memacc_code)s;
16313955Sgiacomo.gabrielli@arm.com            %(op_wb)s;
16413955Sgiacomo.gabrielli@arm.com        }
16513955Sgiacomo.gabrielli@arm.com
16613955Sgiacomo.gabrielli@arm.com        return fault;
16713955Sgiacomo.gabrielli@arm.com    }
16813955Sgiacomo.gabrielli@arm.com}};
16913955Sgiacomo.gabrielli@arm.com
17013955Sgiacomo.gabrielli@arm.comdef template SveContigLoadInitiateAcc {{
17113955Sgiacomo.gabrielli@arm.com    %(tpl_header)s
17213955Sgiacomo.gabrielli@arm.com    Fault %(class_name)s%(tpl_args)s::initiateAcc(ExecContext *xc,
17313955Sgiacomo.gabrielli@arm.com        Trace::InstRecord *traceData) const
17413955Sgiacomo.gabrielli@arm.com    {
17513955Sgiacomo.gabrielli@arm.com        Addr EA;
17613955Sgiacomo.gabrielli@arm.com        Fault fault = NoFault;
17713955Sgiacomo.gabrielli@arm.com        bool aarch64 M5_VAR_USED = true;
17813955Sgiacomo.gabrielli@arm.com        unsigned eCount = ArmStaticInst::getCurSveVecLen<RegElemType>(
17913955Sgiacomo.gabrielli@arm.com            xc->tcBase());
18013955Sgiacomo.gabrielli@arm.com
18113955Sgiacomo.gabrielli@arm.com        %(op_src_decl)s;
18213955Sgiacomo.gabrielli@arm.com        %(op_rd)s;
18313955Sgiacomo.gabrielli@arm.com        %(ea_code)s;
18413955Sgiacomo.gabrielli@arm.com
18514091Sgabor.dozsa@arm.com        %(rden_code)s;
18614091Sgabor.dozsa@arm.com
18714091Sgabor.dozsa@arm.com        fault = xc->initiateMemRead(EA, memAccessSize, this->memAccessFlags,
18814091Sgabor.dozsa@arm.com            rdEn);
18914091Sgabor.dozsa@arm.com
19014091Sgabor.dozsa@arm.com        %(fault_code)s;
19113955Sgiacomo.gabrielli@arm.com
19213955Sgiacomo.gabrielli@arm.com        return fault;
19313955Sgiacomo.gabrielli@arm.com    }
19413955Sgiacomo.gabrielli@arm.com}};
19513955Sgiacomo.gabrielli@arm.com
19613955Sgiacomo.gabrielli@arm.comdef template SveContigLoadCompleteAcc {{
19713955Sgiacomo.gabrielli@arm.com    %(tpl_header)s
19813955Sgiacomo.gabrielli@arm.com    Fault %(class_name)s%(tpl_args)s::completeAcc(PacketPtr pkt,
19913955Sgiacomo.gabrielli@arm.com        ExecContext *xc, Trace::InstRecord *traceData) const
20013955Sgiacomo.gabrielli@arm.com    {
20113955Sgiacomo.gabrielli@arm.com        bool aarch64 M5_VAR_USED = true;
20213955Sgiacomo.gabrielli@arm.com        unsigned eCount = ArmStaticInst::getCurSveVecLen<RegElemType>(
20313955Sgiacomo.gabrielli@arm.com            xc->tcBase());
20413955Sgiacomo.gabrielli@arm.com
20513955Sgiacomo.gabrielli@arm.com        %(op_decl)s;
20613955Sgiacomo.gabrielli@arm.com        %(op_rd)s;
20713955Sgiacomo.gabrielli@arm.com
20813955Sgiacomo.gabrielli@arm.com        TheISA::VecRegContainer memData;
20913955Sgiacomo.gabrielli@arm.com        auto memDataView = memData.as<MemElemType>();
21013955Sgiacomo.gabrielli@arm.com
21114091Sgabor.dozsa@arm.com        if (xc->readMemAccPredicate()) {
21214091Sgabor.dozsa@arm.com            memcpy(memData.raw_ptr<uint8_t>(), pkt->getPtr<uint8_t>(),
21314091Sgabor.dozsa@arm.com                   pkt->getSize());
21413955Sgiacomo.gabrielli@arm.com        }
21513955Sgiacomo.gabrielli@arm.com
21614091Sgabor.dozsa@arm.com        %(memacc_code)s;
21714091Sgabor.dozsa@arm.com        %(op_wb)s;
21813955Sgiacomo.gabrielli@arm.com
21914091Sgabor.dozsa@arm.com        return NoFault;
22013955Sgiacomo.gabrielli@arm.com    }
22113955Sgiacomo.gabrielli@arm.com}};
22213955Sgiacomo.gabrielli@arm.com
22313955Sgiacomo.gabrielli@arm.comdef template SveContigStoreExecute {{
22413955Sgiacomo.gabrielli@arm.com    %(tpl_header)s
22513955Sgiacomo.gabrielli@arm.com    Fault %(class_name)s%(tpl_args)s::execute(ExecContext *xc,
22613955Sgiacomo.gabrielli@arm.com        Trace::InstRecord *traceData) const
22713955Sgiacomo.gabrielli@arm.com    {
22813955Sgiacomo.gabrielli@arm.com        Addr EA;
22913955Sgiacomo.gabrielli@arm.com        Fault fault = NoFault;
23013955Sgiacomo.gabrielli@arm.com        bool aarch64 M5_VAR_USED = true;
23113955Sgiacomo.gabrielli@arm.com        unsigned eCount = ArmStaticInst::getCurSveVecLen<RegElemType>(
23213955Sgiacomo.gabrielli@arm.com            xc->tcBase());
23313955Sgiacomo.gabrielli@arm.com
23413955Sgiacomo.gabrielli@arm.com        %(op_decl)s;
23513955Sgiacomo.gabrielli@arm.com        %(op_rd)s;
23613955Sgiacomo.gabrielli@arm.com        %(ea_code)s;
23713955Sgiacomo.gabrielli@arm.com
23813955Sgiacomo.gabrielli@arm.com        TheISA::VecRegContainer memData;
23913955Sgiacomo.gabrielli@arm.com        auto memDataView = memData.as<MemElemType>();
24013955Sgiacomo.gabrielli@arm.com
24113955Sgiacomo.gabrielli@arm.com        %(wren_code)s;
24213955Sgiacomo.gabrielli@arm.com
24313955Sgiacomo.gabrielli@arm.com        if (fault == NoFault) {
24413955Sgiacomo.gabrielli@arm.com            %(memacc_code)s;
24513955Sgiacomo.gabrielli@arm.com        }
24613955Sgiacomo.gabrielli@arm.com
24713955Sgiacomo.gabrielli@arm.com        if (fault == NoFault) {
24813955Sgiacomo.gabrielli@arm.com            fault = xc->writeMem(memData.raw_ptr<uint8_t>(), memAccessSize, EA,
24913955Sgiacomo.gabrielli@arm.com                this->memAccessFlags, NULL, wrEn);
25013955Sgiacomo.gabrielli@arm.com        }
25113955Sgiacomo.gabrielli@arm.com
25213955Sgiacomo.gabrielli@arm.com        if (fault == NoFault) {
25313955Sgiacomo.gabrielli@arm.com            %(op_wb)s;
25413955Sgiacomo.gabrielli@arm.com        }
25513955Sgiacomo.gabrielli@arm.com
25613955Sgiacomo.gabrielli@arm.com        return fault;
25713955Sgiacomo.gabrielli@arm.com    }
25813955Sgiacomo.gabrielli@arm.com}};
25913955Sgiacomo.gabrielli@arm.com
26013955Sgiacomo.gabrielli@arm.comdef template SveContigStoreInitiateAcc {{
26113955Sgiacomo.gabrielli@arm.com    %(tpl_header)s
26213955Sgiacomo.gabrielli@arm.com    Fault %(class_name)s%(tpl_args)s::initiateAcc(ExecContext *xc,
26313955Sgiacomo.gabrielli@arm.com        Trace::InstRecord *traceData) const
26413955Sgiacomo.gabrielli@arm.com    {
26513955Sgiacomo.gabrielli@arm.com        Addr EA;
26613955Sgiacomo.gabrielli@arm.com        Fault fault = NoFault;
26713955Sgiacomo.gabrielli@arm.com        bool aarch64 M5_VAR_USED = true;
26813955Sgiacomo.gabrielli@arm.com        unsigned eCount = ArmStaticInst::getCurSveVecLen<RegElemType>(
26913955Sgiacomo.gabrielli@arm.com            xc->tcBase());
27013955Sgiacomo.gabrielli@arm.com
27113955Sgiacomo.gabrielli@arm.com        %(op_decl)s;
27213955Sgiacomo.gabrielli@arm.com        %(op_rd)s;
27313955Sgiacomo.gabrielli@arm.com        %(ea_code)s;
27413955Sgiacomo.gabrielli@arm.com
27513955Sgiacomo.gabrielli@arm.com        TheISA::VecRegContainer memData;
27613955Sgiacomo.gabrielli@arm.com        auto memDataView = memData.as<MemElemType>();
27713955Sgiacomo.gabrielli@arm.com
27813955Sgiacomo.gabrielli@arm.com        %(wren_code)s;
27913955Sgiacomo.gabrielli@arm.com
28013955Sgiacomo.gabrielli@arm.com        if (fault == NoFault) {
28113955Sgiacomo.gabrielli@arm.com            %(memacc_code)s;
28213955Sgiacomo.gabrielli@arm.com        }
28313955Sgiacomo.gabrielli@arm.com
28413955Sgiacomo.gabrielli@arm.com        if (fault == NoFault) {
28513955Sgiacomo.gabrielli@arm.com            fault = xc->writeMem(memData.raw_ptr<uint8_t>(), memAccessSize, EA,
28613955Sgiacomo.gabrielli@arm.com                this->memAccessFlags, NULL, wrEn);
28713955Sgiacomo.gabrielli@arm.com        }
28813955Sgiacomo.gabrielli@arm.com
28913955Sgiacomo.gabrielli@arm.com        return fault;
29013955Sgiacomo.gabrielli@arm.com    }
29113955Sgiacomo.gabrielli@arm.com}};
29213955Sgiacomo.gabrielli@arm.com
29313955Sgiacomo.gabrielli@arm.comdef template SveContigStoreCompleteAcc {{
29413955Sgiacomo.gabrielli@arm.com    %(tpl_header)s
29513955Sgiacomo.gabrielli@arm.com    Fault %(class_name)s%(tpl_args)s::completeAcc(PacketPtr pkt,
29613955Sgiacomo.gabrielli@arm.com        ExecContext *xc, Trace::InstRecord *traceData) const
29713955Sgiacomo.gabrielli@arm.com    {
29813955Sgiacomo.gabrielli@arm.com        return NoFault;
29913955Sgiacomo.gabrielli@arm.com    }
30013955Sgiacomo.gabrielli@arm.com}};
30113955Sgiacomo.gabrielli@arm.com
30213955Sgiacomo.gabrielli@arm.comdef template SveLoadAndReplExecute {{
30313955Sgiacomo.gabrielli@arm.com    %(tpl_header)s
30413955Sgiacomo.gabrielli@arm.com    Fault %(class_name)s%(tpl_args)s::execute(ExecContext *xc,
30513955Sgiacomo.gabrielli@arm.com        Trace::InstRecord *traceData) const
30613955Sgiacomo.gabrielli@arm.com    {
30713955Sgiacomo.gabrielli@arm.com        Addr EA;
30813955Sgiacomo.gabrielli@arm.com        Fault fault = NoFault;
30913955Sgiacomo.gabrielli@arm.com        bool aarch64 M5_VAR_USED = true;
31013955Sgiacomo.gabrielli@arm.com        unsigned eCount = ArmStaticInst::getCurSveVecLen<RegElemType>(
31113955Sgiacomo.gabrielli@arm.com            xc->tcBase());
31213955Sgiacomo.gabrielli@arm.com
31313955Sgiacomo.gabrielli@arm.com        %(op_decl)s;
31413955Sgiacomo.gabrielli@arm.com        %(op_rd)s;
31513955Sgiacomo.gabrielli@arm.com        %(ea_code)s;
31613955Sgiacomo.gabrielli@arm.com
31713955Sgiacomo.gabrielli@arm.com        MemElemType memData;
31813955Sgiacomo.gabrielli@arm.com
31913955Sgiacomo.gabrielli@arm.com        if (fault == NoFault) {
32013955Sgiacomo.gabrielli@arm.com            fault = readMemAtomic(xc, traceData, EA, memData,
32113955Sgiacomo.gabrielli@arm.com                this->memAccessFlags);
32213955Sgiacomo.gabrielli@arm.com            %(memacc_code)s;
32313955Sgiacomo.gabrielli@arm.com        }
32413955Sgiacomo.gabrielli@arm.com
32513955Sgiacomo.gabrielli@arm.com        if (fault == NoFault) {
32613955Sgiacomo.gabrielli@arm.com            %(op_wb)s;
32713955Sgiacomo.gabrielli@arm.com        }
32813955Sgiacomo.gabrielli@arm.com
32913955Sgiacomo.gabrielli@arm.com        return fault;
33013955Sgiacomo.gabrielli@arm.com    }
33113955Sgiacomo.gabrielli@arm.com}};
33213955Sgiacomo.gabrielli@arm.com
33313955Sgiacomo.gabrielli@arm.comdef template SveLoadAndReplInitiateAcc {{
33413955Sgiacomo.gabrielli@arm.com    %(tpl_header)s
33513955Sgiacomo.gabrielli@arm.com    Fault %(class_name)s%(tpl_args)s::initiateAcc(ExecContext *xc,
33613955Sgiacomo.gabrielli@arm.com        Trace::InstRecord *traceData) const
33713955Sgiacomo.gabrielli@arm.com    {
33813955Sgiacomo.gabrielli@arm.com        Addr EA;
33913955Sgiacomo.gabrielli@arm.com        Fault fault = NoFault;
34013955Sgiacomo.gabrielli@arm.com        bool aarch64 M5_VAR_USED = true;
34113955Sgiacomo.gabrielli@arm.com
34213955Sgiacomo.gabrielli@arm.com        %(op_src_decl)s;
34313955Sgiacomo.gabrielli@arm.com        %(op_rd)s;
34413955Sgiacomo.gabrielli@arm.com
34513955Sgiacomo.gabrielli@arm.com        %(ea_code)s;
34613955Sgiacomo.gabrielli@arm.com
34713955Sgiacomo.gabrielli@arm.com        MemElemType memData;
34813955Sgiacomo.gabrielli@arm.com
34913955Sgiacomo.gabrielli@arm.com        if (fault == NoFault) {
35013955Sgiacomo.gabrielli@arm.com            fault = initiateMemRead(xc, traceData, EA, memData,
35113955Sgiacomo.gabrielli@arm.com                this->memAccessFlags);
35213955Sgiacomo.gabrielli@arm.com        }
35313955Sgiacomo.gabrielli@arm.com
35413955Sgiacomo.gabrielli@arm.com        return fault;
35513955Sgiacomo.gabrielli@arm.com    }
35613955Sgiacomo.gabrielli@arm.com}};
35713955Sgiacomo.gabrielli@arm.com
35813955Sgiacomo.gabrielli@arm.comdef template SveLoadAndReplCompleteAcc {{
35913955Sgiacomo.gabrielli@arm.com    %(tpl_header)s
36013955Sgiacomo.gabrielli@arm.com    Fault %(class_name)s%(tpl_args)s::completeAcc(PacketPtr pkt,
36113955Sgiacomo.gabrielli@arm.com        ExecContext *xc, Trace::InstRecord *traceData) const
36213955Sgiacomo.gabrielli@arm.com    {
36313955Sgiacomo.gabrielli@arm.com        Fault fault = NoFault;
36413955Sgiacomo.gabrielli@arm.com        bool aarch64 M5_VAR_USED = true;
36513955Sgiacomo.gabrielli@arm.com        unsigned eCount = ArmStaticInst::getCurSveVecLen<RegElemType>(
36613955Sgiacomo.gabrielli@arm.com            xc->tcBase());
36713955Sgiacomo.gabrielli@arm.com
36813955Sgiacomo.gabrielli@arm.com        %(op_decl)s;
36913955Sgiacomo.gabrielli@arm.com        %(op_rd)s;
37013955Sgiacomo.gabrielli@arm.com
37113955Sgiacomo.gabrielli@arm.com        MemElemType memData;
37213955Sgiacomo.gabrielli@arm.com        getMem(pkt, memData, traceData);
37313955Sgiacomo.gabrielli@arm.com
37413955Sgiacomo.gabrielli@arm.com        if (fault == NoFault) {
37513955Sgiacomo.gabrielli@arm.com            %(memacc_code)s;
37613955Sgiacomo.gabrielli@arm.com        }
37713955Sgiacomo.gabrielli@arm.com
37813955Sgiacomo.gabrielli@arm.com        if (fault == NoFault) {
37913955Sgiacomo.gabrielli@arm.com            %(op_wb)s;
38013955Sgiacomo.gabrielli@arm.com        }
38113955Sgiacomo.gabrielli@arm.com
38213955Sgiacomo.gabrielli@arm.com        return fault;
38313955Sgiacomo.gabrielli@arm.com    }
38413955Sgiacomo.gabrielli@arm.com}};
38513955Sgiacomo.gabrielli@arm.com
38614028Sgiacomo.gabrielli@arm.comdef template SveIndexedMemVIMicroopDeclare {{
38714028Sgiacomo.gabrielli@arm.com    %(tpl_header)s
38814028Sgiacomo.gabrielli@arm.com    class %(class_name)s : public %(base_class)s
38914028Sgiacomo.gabrielli@arm.com    {
39014028Sgiacomo.gabrielli@arm.com      protected:
39114028Sgiacomo.gabrielli@arm.com        typedef RegElemType TPElem;
39214028Sgiacomo.gabrielli@arm.com
39314028Sgiacomo.gabrielli@arm.com        IntRegIndex dest;
39414028Sgiacomo.gabrielli@arm.com        IntRegIndex gp;
39514028Sgiacomo.gabrielli@arm.com        IntRegIndex base;
39614028Sgiacomo.gabrielli@arm.com        uint64_t imm;
39714028Sgiacomo.gabrielli@arm.com
39814028Sgiacomo.gabrielli@arm.com        int elemIndex;
39914028Sgiacomo.gabrielli@arm.com        int numElems;
40014091Sgabor.dozsa@arm.com        bool firstFault;
40114028Sgiacomo.gabrielli@arm.com
40214028Sgiacomo.gabrielli@arm.com        unsigned memAccessFlags;
40314028Sgiacomo.gabrielli@arm.com
40414028Sgiacomo.gabrielli@arm.com      public:
40514028Sgiacomo.gabrielli@arm.com        %(class_name)s(const char* mnem, ExtMachInst machInst,
40614028Sgiacomo.gabrielli@arm.com            OpClass __opClass, IntRegIndex _dest, IntRegIndex _gp,
40714091Sgabor.dozsa@arm.com            IntRegIndex _base, uint64_t _imm, int _elemIndex, int _numElems,
40814091Sgabor.dozsa@arm.com            bool _firstFault)
40914028Sgiacomo.gabrielli@arm.com            : %(base_class)s(mnem, machInst, %(op_class)s),
41014028Sgiacomo.gabrielli@arm.com              dest(_dest), gp(_gp), base(_base), imm(_imm),
41114028Sgiacomo.gabrielli@arm.com              elemIndex(_elemIndex), numElems(_numElems),
41214091Sgabor.dozsa@arm.com              firstFault(_firstFault),
41314028Sgiacomo.gabrielli@arm.com              memAccessFlags(ArmISA::TLB::AllowUnaligned |
41414028Sgiacomo.gabrielli@arm.com                             ArmISA::TLB::MustBeOne)
41514028Sgiacomo.gabrielli@arm.com        {
41614028Sgiacomo.gabrielli@arm.com            %(constructor)s;
41714028Sgiacomo.gabrielli@arm.com            if (_opClass == MemReadOp && elemIndex == 0) {
41814028Sgiacomo.gabrielli@arm.com                // The first micro-op is responsible for pinning the
41914091Sgabor.dozsa@arm.com                // destination and the fault status registers
42014091Sgabor.dozsa@arm.com                assert(_numDestRegs == 2);
42114091Sgabor.dozsa@arm.com               _destRegIdx[0].setNumPinnedWrites(numElems - 1);
42214091Sgabor.dozsa@arm.com               _destRegIdx[1].setNumPinnedWrites(numElems - 1);
42314028Sgiacomo.gabrielli@arm.com            }
42414028Sgiacomo.gabrielli@arm.com        }
42514028Sgiacomo.gabrielli@arm.com
42614028Sgiacomo.gabrielli@arm.com        Fault execute(ExecContext *, Trace::InstRecord *) const;
42714028Sgiacomo.gabrielli@arm.com        Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
42814028Sgiacomo.gabrielli@arm.com        Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const;
42914028Sgiacomo.gabrielli@arm.com
43014028Sgiacomo.gabrielli@arm.com        virtual void
43114028Sgiacomo.gabrielli@arm.com        annotateFault(ArmFault *fault)
43214028Sgiacomo.gabrielli@arm.com        {
43314028Sgiacomo.gabrielli@arm.com            %(fa_code)s
43414028Sgiacomo.gabrielli@arm.com        }
43514028Sgiacomo.gabrielli@arm.com
43614028Sgiacomo.gabrielli@arm.com        std::string
43714028Sgiacomo.gabrielli@arm.com        generateDisassembly(Addr pc, const SymbolTable *symtab) const
43814028Sgiacomo.gabrielli@arm.com        {
43914028Sgiacomo.gabrielli@arm.com            // TODO: add suffix to transfer register
44014028Sgiacomo.gabrielli@arm.com            std::stringstream ss;
44114028Sgiacomo.gabrielli@arm.com            printMnemonic(ss, "", false);
44214028Sgiacomo.gabrielli@arm.com            ccprintf(ss, "{");
44314028Sgiacomo.gabrielli@arm.com            printVecReg(ss, dest, true);
44414028Sgiacomo.gabrielli@arm.com            ccprintf(ss, "}, ");
44514028Sgiacomo.gabrielli@arm.com            printVecPredReg(ss, gp);
44614028Sgiacomo.gabrielli@arm.com            if (_opClass == MemReadOp) {
44714028Sgiacomo.gabrielli@arm.com                ccprintf(ss, "/z");
44814028Sgiacomo.gabrielli@arm.com            }
44914028Sgiacomo.gabrielli@arm.com            ccprintf(ss, ", [");
45014028Sgiacomo.gabrielli@arm.com            printVecReg(ss, base, true);
45114028Sgiacomo.gabrielli@arm.com            if (imm != 0) {
45214028Sgiacomo.gabrielli@arm.com                ccprintf(ss, ", #%d", imm * sizeof(MemElemType));
45314028Sgiacomo.gabrielli@arm.com            }
45414028Sgiacomo.gabrielli@arm.com            ccprintf(ss, "] (uop elem %d tfer)", elemIndex);
45514028Sgiacomo.gabrielli@arm.com            return ss.str();
45614028Sgiacomo.gabrielli@arm.com        }
45714028Sgiacomo.gabrielli@arm.com    };
45814028Sgiacomo.gabrielli@arm.com}};
45914028Sgiacomo.gabrielli@arm.com
46014028Sgiacomo.gabrielli@arm.comdef template SveIndexedMemSVMicroopDeclare {{
46114028Sgiacomo.gabrielli@arm.com    %(tpl_header)s
46214028Sgiacomo.gabrielli@arm.com    class %(class_name)s : public %(base_class)s
46314028Sgiacomo.gabrielli@arm.com    {
46414028Sgiacomo.gabrielli@arm.com      protected:
46514028Sgiacomo.gabrielli@arm.com        typedef RegElemType TPElem;
46614028Sgiacomo.gabrielli@arm.com
46714028Sgiacomo.gabrielli@arm.com        IntRegIndex dest;
46814028Sgiacomo.gabrielli@arm.com        IntRegIndex gp;
46914028Sgiacomo.gabrielli@arm.com        IntRegIndex base;
47014028Sgiacomo.gabrielli@arm.com        IntRegIndex offset;
47114028Sgiacomo.gabrielli@arm.com
47214028Sgiacomo.gabrielli@arm.com        bool offsetIs32;
47314028Sgiacomo.gabrielli@arm.com        bool offsetIsSigned;
47414028Sgiacomo.gabrielli@arm.com        bool offsetIsScaled;
47514028Sgiacomo.gabrielli@arm.com
47614028Sgiacomo.gabrielli@arm.com        int elemIndex;
47714028Sgiacomo.gabrielli@arm.com        int numElems;
47814091Sgabor.dozsa@arm.com        bool firstFault;
47914028Sgiacomo.gabrielli@arm.com
48014028Sgiacomo.gabrielli@arm.com        unsigned memAccessFlags;
48114028Sgiacomo.gabrielli@arm.com
48214028Sgiacomo.gabrielli@arm.com      public:
48314028Sgiacomo.gabrielli@arm.com        %(class_name)s(const char* mnem, ExtMachInst machInst,
48414028Sgiacomo.gabrielli@arm.com            OpClass __opClass, IntRegIndex _dest, IntRegIndex _gp,
48514028Sgiacomo.gabrielli@arm.com            IntRegIndex _base, IntRegIndex _offset, bool _offsetIs32,
48614028Sgiacomo.gabrielli@arm.com            bool _offsetIsSigned, bool _offsetIsScaled, int _elemIndex,
48714091Sgabor.dozsa@arm.com            int _numElems, bool _firstFault)
48814028Sgiacomo.gabrielli@arm.com            : %(base_class)s(mnem, machInst, %(op_class)s),
48914028Sgiacomo.gabrielli@arm.com              dest(_dest), gp(_gp), base(_base), offset(_offset),
49014028Sgiacomo.gabrielli@arm.com              offsetIs32(_offsetIs32), offsetIsSigned(_offsetIsSigned),
49114028Sgiacomo.gabrielli@arm.com              offsetIsScaled(_offsetIsScaled), elemIndex(_elemIndex),
49214091Sgabor.dozsa@arm.com              numElems(_numElems), firstFault(_firstFault),
49314028Sgiacomo.gabrielli@arm.com              memAccessFlags(ArmISA::TLB::AllowUnaligned |
49414028Sgiacomo.gabrielli@arm.com                             ArmISA::TLB::MustBeOne)
49514028Sgiacomo.gabrielli@arm.com        {
49614028Sgiacomo.gabrielli@arm.com            %(constructor)s;
49714028Sgiacomo.gabrielli@arm.com            if (_opClass == MemReadOp && elemIndex == 0) {
49814028Sgiacomo.gabrielli@arm.com                // The first micro-op is responsible for pinning the
49914091Sgabor.dozsa@arm.com                // destination and the fault status registers
50014091Sgabor.dozsa@arm.com                assert(_numDestRegs == 2);
50114091Sgabor.dozsa@arm.com               _destRegIdx[0].setNumPinnedWrites(numElems - 1);
50214091Sgabor.dozsa@arm.com               _destRegIdx[1].setNumPinnedWrites(numElems - 1);
50314028Sgiacomo.gabrielli@arm.com            }
50414028Sgiacomo.gabrielli@arm.com        }
50514028Sgiacomo.gabrielli@arm.com
50614028Sgiacomo.gabrielli@arm.com        Fault execute(ExecContext *, Trace::InstRecord *) const;
50714028Sgiacomo.gabrielli@arm.com        Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
50814028Sgiacomo.gabrielli@arm.com        Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const;
50914028Sgiacomo.gabrielli@arm.com
51014028Sgiacomo.gabrielli@arm.com        virtual void
51114028Sgiacomo.gabrielli@arm.com        annotateFault(ArmFault *fault)
51214028Sgiacomo.gabrielli@arm.com        {
51314028Sgiacomo.gabrielli@arm.com            %(fa_code)s
51414028Sgiacomo.gabrielli@arm.com        }
51514028Sgiacomo.gabrielli@arm.com
51614028Sgiacomo.gabrielli@arm.com        std::string
51714028Sgiacomo.gabrielli@arm.com        generateDisassembly(Addr pc, const SymbolTable *symtab) const
51814028Sgiacomo.gabrielli@arm.com        {
51914028Sgiacomo.gabrielli@arm.com            // TODO: add suffix to transfer and base registers
52014028Sgiacomo.gabrielli@arm.com            std::stringstream ss;
52114028Sgiacomo.gabrielli@arm.com            printMnemonic(ss, "", false);
52214028Sgiacomo.gabrielli@arm.com            ccprintf(ss, "{");
52314028Sgiacomo.gabrielli@arm.com            printVecReg(ss, dest, true);
52414028Sgiacomo.gabrielli@arm.com            ccprintf(ss, "}, ");
52514028Sgiacomo.gabrielli@arm.com            printVecPredReg(ss, gp);
52614028Sgiacomo.gabrielli@arm.com            if (_opClass == MemReadOp) {
52714028Sgiacomo.gabrielli@arm.com                ccprintf(ss, "/z");
52814028Sgiacomo.gabrielli@arm.com            }
52914028Sgiacomo.gabrielli@arm.com            ccprintf(ss, ", [");
53014028Sgiacomo.gabrielli@arm.com            printIntReg(ss, base);
53114028Sgiacomo.gabrielli@arm.com            ccprintf(ss, ", ");
53214028Sgiacomo.gabrielli@arm.com            printVecReg(ss, offset, true);
53314028Sgiacomo.gabrielli@arm.com            ccprintf(ss, "] (uop elem %d tfer)", elemIndex);
53414028Sgiacomo.gabrielli@arm.com            return ss.str();
53514028Sgiacomo.gabrielli@arm.com        }
53614028Sgiacomo.gabrielli@arm.com    };
53714028Sgiacomo.gabrielli@arm.com}};
53814028Sgiacomo.gabrielli@arm.com
53914028Sgiacomo.gabrielli@arm.comdef template SveGatherLoadMicroopExecute {{
54014028Sgiacomo.gabrielli@arm.com    %(tpl_header)s
54114028Sgiacomo.gabrielli@arm.com    Fault %(class_name)s%(tpl_args)s::execute(ExecContext *xc,
54214028Sgiacomo.gabrielli@arm.com        Trace::InstRecord *traceData) const
54314028Sgiacomo.gabrielli@arm.com    {
54414028Sgiacomo.gabrielli@arm.com        Addr EA;
54514028Sgiacomo.gabrielli@arm.com        Fault fault = NoFault;
54614028Sgiacomo.gabrielli@arm.com        bool aarch64 M5_VAR_USED = true;
54714028Sgiacomo.gabrielli@arm.com
54814028Sgiacomo.gabrielli@arm.com        %(op_decl)s;
54914028Sgiacomo.gabrielli@arm.com        %(op_rd)s;
55014028Sgiacomo.gabrielli@arm.com        %(ea_code)s;
55114028Sgiacomo.gabrielli@arm.com
55214091Sgabor.dozsa@arm.com        MemElemType memData = 0;
55314028Sgiacomo.gabrielli@arm.com
55414091Sgabor.dozsa@arm.com        int index = elemIndex;
55514028Sgiacomo.gabrielli@arm.com        if (%(pred_check_code)s) {
55614028Sgiacomo.gabrielli@arm.com            fault = readMemAtomic(xc, traceData, EA, memData,
55714028Sgiacomo.gabrielli@arm.com                this->memAccessFlags);
55814028Sgiacomo.gabrielli@arm.com        }
55914028Sgiacomo.gabrielli@arm.com
56014028Sgiacomo.gabrielli@arm.com        if (fault == NoFault) {
56114091Sgabor.dozsa@arm.com            %(fault_status_reset_code)s;
56214028Sgiacomo.gabrielli@arm.com            %(memacc_code)s;
56314109Sgabor.dozsa@arm.com            if (traceData) {
56414109Sgabor.dozsa@arm.com                traceData->setData(memData);
56514109Sgabor.dozsa@arm.com            }
56614091Sgabor.dozsa@arm.com        } else {
56714091Sgabor.dozsa@arm.com            %(fault_status_set_code)s;
56814091Sgabor.dozsa@arm.com            if (firstFault) {
56914091Sgabor.dozsa@arm.com               for (index = 0;
57014091Sgabor.dozsa@arm.com                    index < numElems && !(%(pred_check_code)s);
57114091Sgabor.dozsa@arm.com                    index++);
57214091Sgabor.dozsa@arm.com
57314091Sgabor.dozsa@arm.com               if (index < elemIndex) {
57414091Sgabor.dozsa@arm.com                  fault = NoFault;
57514091Sgabor.dozsa@arm.com                  memData = 0;
57614091Sgabor.dozsa@arm.com                  %(memacc_code)s;
57714109Sgabor.dozsa@arm.com                  if (traceData) {
57814109Sgabor.dozsa@arm.com                      traceData->setData(memData);
57914109Sgabor.dozsa@arm.com                  }
58014091Sgabor.dozsa@arm.com               }
58114091Sgabor.dozsa@arm.com            }
58214028Sgiacomo.gabrielli@arm.com        }
58314028Sgiacomo.gabrielli@arm.com        return fault;
58414028Sgiacomo.gabrielli@arm.com    }
58514028Sgiacomo.gabrielli@arm.com}};
58614028Sgiacomo.gabrielli@arm.com
58714028Sgiacomo.gabrielli@arm.comdef template SveGatherLoadMicroopInitiateAcc {{
58814028Sgiacomo.gabrielli@arm.com    %(tpl_header)s
58914028Sgiacomo.gabrielli@arm.com    Fault %(class_name)s%(tpl_args)s::initiateAcc(ExecContext *xc,
59014028Sgiacomo.gabrielli@arm.com        Trace::InstRecord *traceData) const
59114028Sgiacomo.gabrielli@arm.com    {
59214028Sgiacomo.gabrielli@arm.com        Addr EA;
59314028Sgiacomo.gabrielli@arm.com        Fault fault = NoFault;
59414028Sgiacomo.gabrielli@arm.com        bool aarch64 M5_VAR_USED = true;
59514028Sgiacomo.gabrielli@arm.com
59614028Sgiacomo.gabrielli@arm.com        %(op_src_decl)s;
59714028Sgiacomo.gabrielli@arm.com        %(op_rd)s;
59814028Sgiacomo.gabrielli@arm.com        %(ea_code)s;
59914028Sgiacomo.gabrielli@arm.com
60014028Sgiacomo.gabrielli@arm.com        MemElemType memData;
60114028Sgiacomo.gabrielli@arm.com
60214091Sgabor.dozsa@arm.com        int index = elemIndex;
60314028Sgiacomo.gabrielli@arm.com        if (%(pred_check_code)s) {
60414028Sgiacomo.gabrielli@arm.com            fault = initiateMemRead(xc, traceData, EA, memData,
60514028Sgiacomo.gabrielli@arm.com                this->memAccessFlags);
60614091Sgabor.dozsa@arm.com            if (fault != NoFault) {
60714091Sgabor.dozsa@arm.com                %(fault_status_set_code)s;
60814091Sgabor.dozsa@arm.com                if (firstFault) {
60914091Sgabor.dozsa@arm.com                    for (index = 0;
61014091Sgabor.dozsa@arm.com                         index < numElems && !(%(pred_check_code)s);
61114091Sgabor.dozsa@arm.com                         index++);
61214091Sgabor.dozsa@arm.com                    if (index < elemIndex) {
61314091Sgabor.dozsa@arm.com                        fault = NoFault;
61414091Sgabor.dozsa@arm.com                        xc->setMemAccPredicate(false);
61514091Sgabor.dozsa@arm.com                    }
61614091Sgabor.dozsa@arm.com                }
61714091Sgabor.dozsa@arm.com            } else {
61814091Sgabor.dozsa@arm.com                %(fault_status_reset_code)s;
61914091Sgabor.dozsa@arm.com            }
62014028Sgiacomo.gabrielli@arm.com        } else {
62114028Sgiacomo.gabrielli@arm.com            xc->setMemAccPredicate(false);
62214091Sgabor.dozsa@arm.com            %(fault_status_reset_code)s;
62314028Sgiacomo.gabrielli@arm.com        }
62414028Sgiacomo.gabrielli@arm.com
62514028Sgiacomo.gabrielli@arm.com        return fault;
62614028Sgiacomo.gabrielli@arm.com    }
62714028Sgiacomo.gabrielli@arm.com}};
62814028Sgiacomo.gabrielli@arm.com
62914028Sgiacomo.gabrielli@arm.comdef template SveGatherLoadMicroopCompleteAcc {{
63014028Sgiacomo.gabrielli@arm.com    %(tpl_header)s
63114028Sgiacomo.gabrielli@arm.com    Fault %(class_name)s%(tpl_args)s::completeAcc(PacketPtr pkt,
63214028Sgiacomo.gabrielli@arm.com        ExecContext *xc, Trace::InstRecord *traceData) const
63314028Sgiacomo.gabrielli@arm.com    {
63414028Sgiacomo.gabrielli@arm.com        bool aarch64 M5_VAR_USED = true;
63514028Sgiacomo.gabrielli@arm.com
63614028Sgiacomo.gabrielli@arm.com        %(op_decl)s;
63714028Sgiacomo.gabrielli@arm.com        %(op_rd)s;
63814028Sgiacomo.gabrielli@arm.com
63914028Sgiacomo.gabrielli@arm.com        MemElemType memData = 0;
64014091Sgabor.dozsa@arm.com        if (xc->readMemAccPredicate()) {
64114028Sgiacomo.gabrielli@arm.com            getMem(pkt, memData, traceData);
64214028Sgiacomo.gabrielli@arm.com        }
64314028Sgiacomo.gabrielli@arm.com
64414091Sgabor.dozsa@arm.com        %(memacc_code)s;
64514109Sgabor.dozsa@arm.com        if (traceData) {
64614109Sgabor.dozsa@arm.com            traceData->setData(memData);
64714109Sgabor.dozsa@arm.com        }
64814028Sgiacomo.gabrielli@arm.com
64914091Sgabor.dozsa@arm.com        return NoFault;
65014028Sgiacomo.gabrielli@arm.com    }
65114028Sgiacomo.gabrielli@arm.com}};
65214028Sgiacomo.gabrielli@arm.com
65314028Sgiacomo.gabrielli@arm.comdef template SveScatterStoreMicroopExecute {{
65414028Sgiacomo.gabrielli@arm.com    %(tpl_header)s
65514028Sgiacomo.gabrielli@arm.com    Fault %(class_name)s%(tpl_args)s::execute(ExecContext *xc,
65614028Sgiacomo.gabrielli@arm.com        Trace::InstRecord *traceData) const
65714028Sgiacomo.gabrielli@arm.com    {
65814028Sgiacomo.gabrielli@arm.com        Addr EA;
65914028Sgiacomo.gabrielli@arm.com        Fault fault = NoFault;
66014028Sgiacomo.gabrielli@arm.com        bool aarch64 M5_VAR_USED = true;
66114028Sgiacomo.gabrielli@arm.com
66214028Sgiacomo.gabrielli@arm.com        %(op_decl)s;
66314028Sgiacomo.gabrielli@arm.com        %(op_rd)s;
66414028Sgiacomo.gabrielli@arm.com        %(ea_code)s;
66514028Sgiacomo.gabrielli@arm.com
66614028Sgiacomo.gabrielli@arm.com        MemElemType memData;
66714028Sgiacomo.gabrielli@arm.com        %(memacc_code)s;
66814028Sgiacomo.gabrielli@arm.com
66914091Sgabor.dozsa@arm.com        int index = elemIndex;
67014028Sgiacomo.gabrielli@arm.com        if (%(pred_check_code)s) {
67114028Sgiacomo.gabrielli@arm.com            fault = writeMemAtomic(xc, traceData, memData, EA,
67214028Sgiacomo.gabrielli@arm.com                                   this->memAccessFlags, NULL);
67314028Sgiacomo.gabrielli@arm.com        }
67414028Sgiacomo.gabrielli@arm.com
67514028Sgiacomo.gabrielli@arm.com        if (fault == NoFault) {
67614028Sgiacomo.gabrielli@arm.com            %(op_wb)s;
67714028Sgiacomo.gabrielli@arm.com        }
67814028Sgiacomo.gabrielli@arm.com
67914028Sgiacomo.gabrielli@arm.com        return fault;
68014028Sgiacomo.gabrielli@arm.com    }
68114028Sgiacomo.gabrielli@arm.com}};
68214028Sgiacomo.gabrielli@arm.com
68314028Sgiacomo.gabrielli@arm.comdef template SveScatterStoreMicroopInitiateAcc {{
68414028Sgiacomo.gabrielli@arm.com    %(tpl_header)s
68514028Sgiacomo.gabrielli@arm.com    Fault %(class_name)s%(tpl_args)s::initiateAcc(ExecContext *xc,
68614028Sgiacomo.gabrielli@arm.com        Trace::InstRecord *traceData) const
68714028Sgiacomo.gabrielli@arm.com    {
68814028Sgiacomo.gabrielli@arm.com        Addr EA;
68914028Sgiacomo.gabrielli@arm.com        Fault fault = NoFault;
69014028Sgiacomo.gabrielli@arm.com        bool aarch64 M5_VAR_USED = true;
69114028Sgiacomo.gabrielli@arm.com
69214028Sgiacomo.gabrielli@arm.com        %(op_decl)s;
69314028Sgiacomo.gabrielli@arm.com        %(op_rd)s;
69414028Sgiacomo.gabrielli@arm.com        %(ea_code)s;
69514028Sgiacomo.gabrielli@arm.com
69614028Sgiacomo.gabrielli@arm.com        MemElemType memData;
69714028Sgiacomo.gabrielli@arm.com        %(memacc_code)s;
69814028Sgiacomo.gabrielli@arm.com
69914091Sgabor.dozsa@arm.com        int index = elemIndex;
70014028Sgiacomo.gabrielli@arm.com        if (%(pred_check_code)s) {
70114028Sgiacomo.gabrielli@arm.com            fault = writeMemTiming(xc, traceData, memData, EA,
70214028Sgiacomo.gabrielli@arm.com                                   this->memAccessFlags, NULL);
70314028Sgiacomo.gabrielli@arm.com        } else {
70414028Sgiacomo.gabrielli@arm.com            xc->setPredicate(false);
70514028Sgiacomo.gabrielli@arm.com        }
70614028Sgiacomo.gabrielli@arm.com
70714028Sgiacomo.gabrielli@arm.com        return fault;
70814028Sgiacomo.gabrielli@arm.com    }
70914028Sgiacomo.gabrielli@arm.com}};
71014028Sgiacomo.gabrielli@arm.com
71114028Sgiacomo.gabrielli@arm.comdef template SveScatterStoreMicroopCompleteAcc {{
71214028Sgiacomo.gabrielli@arm.com    %(tpl_header)s
71314028Sgiacomo.gabrielli@arm.com    Fault %(class_name)s%(tpl_args)s::completeAcc(PacketPtr pkt,
71414028Sgiacomo.gabrielli@arm.com        ExecContext *xc, Trace::InstRecord *traceData) const
71514028Sgiacomo.gabrielli@arm.com    {
71614028Sgiacomo.gabrielli@arm.com        return NoFault;
71714028Sgiacomo.gabrielli@arm.com    }
71814028Sgiacomo.gabrielli@arm.com}};
71914028Sgiacomo.gabrielli@arm.com
72014091Sgabor.dozsa@arm.comdef template SveFirstFaultWritebackMicroopDeclare {{
72114091Sgabor.dozsa@arm.com    %(tpl_header)s
72214091Sgabor.dozsa@arm.com    class SveFirstFaultWritebackMicroop : public MicroOp
72314091Sgabor.dozsa@arm.com    {
72414091Sgabor.dozsa@arm.com      protected:
72514091Sgabor.dozsa@arm.com        typedef RegElemType TPElem;
72614091Sgabor.dozsa@arm.com
72714091Sgabor.dozsa@arm.com        int numElems;
72814091Sgabor.dozsa@arm.com        StaticInst *macroOp;
72914091Sgabor.dozsa@arm.com
73014091Sgabor.dozsa@arm.com      public:
73114091Sgabor.dozsa@arm.com        SveFirstFaultWritebackMicroop(const char* mnem, ExtMachInst machInst,
73214091Sgabor.dozsa@arm.com            OpClass __opClass, int _numElems, StaticInst *_macroOp)
73314091Sgabor.dozsa@arm.com            : MicroOp(mnem, machInst, __opClass),
73414091Sgabor.dozsa@arm.com              numElems(_numElems), macroOp(_macroOp)
73514091Sgabor.dozsa@arm.com        {
73614091Sgabor.dozsa@arm.com            %(constructor)s;
73714091Sgabor.dozsa@arm.com        }
73814091Sgabor.dozsa@arm.com
73914091Sgabor.dozsa@arm.com        Fault execute(ExecContext *, Trace::InstRecord *) const;
74014091Sgabor.dozsa@arm.com
74114091Sgabor.dozsa@arm.com        std::string
74214091Sgabor.dozsa@arm.com        generateDisassembly(Addr pc, const SymbolTable *symtab) const
74314091Sgabor.dozsa@arm.com        {
74414091Sgabor.dozsa@arm.com            std::stringstream ss;
74514091Sgabor.dozsa@arm.com            ccprintf(ss, "%s", macroOp->disassemble(pc, symtab));
74614091Sgabor.dozsa@arm.com            ccprintf(ss, " (uop%d)", numElems);
74714091Sgabor.dozsa@arm.com            return ss.str();
74814091Sgabor.dozsa@arm.com        }
74914091Sgabor.dozsa@arm.com    };
75014091Sgabor.dozsa@arm.com}};
75114091Sgabor.dozsa@arm.com
75214091Sgabor.dozsa@arm.comdef template SveFirstFaultWritebackMicroopExecute {{
75314091Sgabor.dozsa@arm.com    %(tpl_header)s
75414091Sgabor.dozsa@arm.com    Fault %(class_name)s%(tpl_args)s::execute(ExecContext *xc,
75514091Sgabor.dozsa@arm.com        Trace::InstRecord *traceData) const
75614091Sgabor.dozsa@arm.com    {
75714091Sgabor.dozsa@arm.com        bool aarch64 M5_VAR_USED = true;
75814091Sgabor.dozsa@arm.com
75914091Sgabor.dozsa@arm.com        %(op_decl)s;
76014091Sgabor.dozsa@arm.com        %(op_rd)s;
76114091Sgabor.dozsa@arm.com
76214091Sgabor.dozsa@arm.com        int  index, firstFaultIndex;
76314091Sgabor.dozsa@arm.com        for (index = 0;
76414091Sgabor.dozsa@arm.com             index < numElems && !%(fault_status_check_code)s;
76514091Sgabor.dozsa@arm.com             index++);
76614091Sgabor.dozsa@arm.com        firstFaultIndex = index;
76714091Sgabor.dozsa@arm.com        for (index = 0; index < numElems; index++) {
76814091Sgabor.dozsa@arm.com            if (index < firstFaultIndex) {
76914091Sgabor.dozsa@arm.com                %(first_fault_forward_code)s;
77014091Sgabor.dozsa@arm.com            } else {
77114091Sgabor.dozsa@arm.com                %(first_fault_reset_code)s;
77214091Sgabor.dozsa@arm.com            }
77314091Sgabor.dozsa@arm.com        }
77414091Sgabor.dozsa@arm.com        return NoFault;
77514091Sgabor.dozsa@arm.com    }
77614091Sgabor.dozsa@arm.com}};
77714091Sgabor.dozsa@arm.com
77814028Sgiacomo.gabrielli@arm.comdef template SveGatherLoadCpySrcVecMicroopDeclare {{
77914028Sgiacomo.gabrielli@arm.com    class SveGatherLoadCpySrcVecMicroop : public MicroOp
78014028Sgiacomo.gabrielli@arm.com    {
78114028Sgiacomo.gabrielli@arm.com      protected:
78214028Sgiacomo.gabrielli@arm.com        IntRegIndex op1;
78314028Sgiacomo.gabrielli@arm.com
78414028Sgiacomo.gabrielli@arm.com        StaticInst *macroOp;
78514028Sgiacomo.gabrielli@arm.com
78614028Sgiacomo.gabrielli@arm.com      public:
78714028Sgiacomo.gabrielli@arm.com        SveGatherLoadCpySrcVecMicroop(const char* mnem, ExtMachInst machInst,
78814028Sgiacomo.gabrielli@arm.com            IntRegIndex _op1, StaticInst *_macroOp)
78914028Sgiacomo.gabrielli@arm.com            : MicroOp(mnem, machInst, SimdAluOp), op1(_op1), macroOp(_macroOp)
79014028Sgiacomo.gabrielli@arm.com        {
79114028Sgiacomo.gabrielli@arm.com            %(constructor)s;
79214028Sgiacomo.gabrielli@arm.com        }
79314028Sgiacomo.gabrielli@arm.com
79414028Sgiacomo.gabrielli@arm.com        Fault execute(ExecContext *, Trace::InstRecord *) const;
79514028Sgiacomo.gabrielli@arm.com
79614028Sgiacomo.gabrielli@arm.com        std::string
79714028Sgiacomo.gabrielli@arm.com        generateDisassembly(Addr pc, const SymbolTable *symtab) const
79814028Sgiacomo.gabrielli@arm.com        {
79914028Sgiacomo.gabrielli@arm.com            std::stringstream ss;
80014028Sgiacomo.gabrielli@arm.com            ccprintf(ss, "%s", macroOp->disassemble(pc, symtab));
80114028Sgiacomo.gabrielli@arm.com            ccprintf(ss, " (uop src vec cpy)");
80214028Sgiacomo.gabrielli@arm.com            return ss.str();
80314028Sgiacomo.gabrielli@arm.com        }
80414028Sgiacomo.gabrielli@arm.com    };
80514028Sgiacomo.gabrielli@arm.com}};
80614028Sgiacomo.gabrielli@arm.com
80714028Sgiacomo.gabrielli@arm.comdef template SveGatherLoadCpySrcVecMicroopExecute {{
80814028Sgiacomo.gabrielli@arm.com    Fault SveGatherLoadCpySrcVecMicroop::execute(ExecContext *xc,
80914028Sgiacomo.gabrielli@arm.com            Trace::InstRecord *traceData) const
81014028Sgiacomo.gabrielli@arm.com    {
81114028Sgiacomo.gabrielli@arm.com        Fault fault = NoFault;
81214028Sgiacomo.gabrielli@arm.com        %(op_decl)s;
81314028Sgiacomo.gabrielli@arm.com        %(op_rd)s;
81414028Sgiacomo.gabrielli@arm.com
81514028Sgiacomo.gabrielli@arm.com        %(code)s;
81614028Sgiacomo.gabrielli@arm.com        if (fault == NoFault)
81714028Sgiacomo.gabrielli@arm.com        {
81814028Sgiacomo.gabrielli@arm.com            %(op_wb)s;
81914028Sgiacomo.gabrielli@arm.com        }
82014028Sgiacomo.gabrielli@arm.com
82114028Sgiacomo.gabrielli@arm.com        return fault;
82214028Sgiacomo.gabrielli@arm.com    }
82314028Sgiacomo.gabrielli@arm.com}};
82414106Sjavier.setoain@arm.com
82514106Sjavier.setoain@arm.comdef template SveStructMemSIMicroopDeclare {{
82614106Sjavier.setoain@arm.com    template<class _Element>
82714106Sjavier.setoain@arm.com    class %(class_name)s : public %(base_class)s
82814106Sjavier.setoain@arm.com    {
82914106Sjavier.setoain@arm.com      protected:
83014106Sjavier.setoain@arm.com        typedef _Element Element;
83114106Sjavier.setoain@arm.com        typedef _Element TPElem;
83214106Sjavier.setoain@arm.com
83314106Sjavier.setoain@arm.com        IntRegIndex dest;
83414106Sjavier.setoain@arm.com        IntRegIndex gp;
83514106Sjavier.setoain@arm.com        IntRegIndex base;
83614106Sjavier.setoain@arm.com        int64_t imm;
83714106Sjavier.setoain@arm.com
83814106Sjavier.setoain@arm.com        uint8_t numRegs;
83914106Sjavier.setoain@arm.com        int regIndex;
84014106Sjavier.setoain@arm.com
84114106Sjavier.setoain@arm.com        unsigned memAccessFlags;
84214106Sjavier.setoain@arm.com
84314106Sjavier.setoain@arm.com        bool baseIsSP;
84414106Sjavier.setoain@arm.com
84514106Sjavier.setoain@arm.com      public:
84614106Sjavier.setoain@arm.com        %(class_name)s(const char* mnem, ExtMachInst machInst,
84714106Sjavier.setoain@arm.com            IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base,
84814106Sjavier.setoain@arm.com            int64_t _imm, uint8_t _numRegs, int _regIndex)
84914106Sjavier.setoain@arm.com            : %(base_class)s(mnem, machInst, %(op_class)s),
85014106Sjavier.setoain@arm.com              dest(_dest), gp(_gp), base(_base), imm(_imm),
85114106Sjavier.setoain@arm.com              numRegs(_numRegs), regIndex(_regIndex),
85214106Sjavier.setoain@arm.com              memAccessFlags(ArmISA::TLB::AllowUnaligned |
85314106Sjavier.setoain@arm.com                             ArmISA::TLB::MustBeOne)
85414106Sjavier.setoain@arm.com        {
85514106Sjavier.setoain@arm.com            %(constructor)s;
85614106Sjavier.setoain@arm.com            baseIsSP = isSP(_base);
85714106Sjavier.setoain@arm.com        }
85814106Sjavier.setoain@arm.com
85914106Sjavier.setoain@arm.com        Fault execute(ExecContext *, Trace::InstRecord *) const;
86014106Sjavier.setoain@arm.com        Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
86114106Sjavier.setoain@arm.com        Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const;
86214106Sjavier.setoain@arm.com
86314106Sjavier.setoain@arm.com        virtual void
86414106Sjavier.setoain@arm.com        annotateFault(ArmFault *fault)
86514106Sjavier.setoain@arm.com        {
86614106Sjavier.setoain@arm.com            %(fa_code)s
86714106Sjavier.setoain@arm.com        }
86814106Sjavier.setoain@arm.com
86914106Sjavier.setoain@arm.com        std::string
87014106Sjavier.setoain@arm.com        generateDisassembly(Addr pc, const SymbolTable *symtab) const
87114106Sjavier.setoain@arm.com        {
87214106Sjavier.setoain@arm.com            std::stringstream ss;
87314106Sjavier.setoain@arm.com            printMnemonic(ss, "", false);
87414106Sjavier.setoain@arm.com            ccprintf(ss, "{");
87514106Sjavier.setoain@arm.com            switch (dest) {
87614106Sjavier.setoain@arm.com                case INTRLVREG0:
87714106Sjavier.setoain@arm.com                    ccprintf(ss, "INTRLV0");
87814106Sjavier.setoain@arm.com                    break;
87914106Sjavier.setoain@arm.com                case INTRLVREG1:
88014106Sjavier.setoain@arm.com                    ccprintf(ss, "INTRLV1");
88114106Sjavier.setoain@arm.com                    break;
88214106Sjavier.setoain@arm.com                case INTRLVREG2:
88314106Sjavier.setoain@arm.com                    ccprintf(ss, "INTRLV2");
88414106Sjavier.setoain@arm.com                    break;
88514106Sjavier.setoain@arm.com                case INTRLVREG3:
88614106Sjavier.setoain@arm.com                    ccprintf(ss, "INTRLV3");
88714106Sjavier.setoain@arm.com                    break;
88814106Sjavier.setoain@arm.com                default:
88914106Sjavier.setoain@arm.com                    printVecReg(ss, dest, true);
89014106Sjavier.setoain@arm.com                    break;
89114106Sjavier.setoain@arm.com            }
89214106Sjavier.setoain@arm.com            ccprintf(ss, "}, ");
89314106Sjavier.setoain@arm.com            printVecPredReg(ss, gp);
89414106Sjavier.setoain@arm.com            if (_opClass == MemReadOp) {
89514106Sjavier.setoain@arm.com                ccprintf(ss, "/z");
89614106Sjavier.setoain@arm.com            }
89714106Sjavier.setoain@arm.com            ccprintf(ss, ", [");
89814106Sjavier.setoain@arm.com            printVecReg(ss, base, true);
89914106Sjavier.setoain@arm.com            if (imm != 0) {
90014106Sjavier.setoain@arm.com                ccprintf(ss, ", #%d", imm * sizeof(Element));
90114106Sjavier.setoain@arm.com            }
90214106Sjavier.setoain@arm.com            ccprintf(ss, "] (uop reg %d tfer)", regIndex);
90314106Sjavier.setoain@arm.com            return ss.str();
90414106Sjavier.setoain@arm.com        }
90514106Sjavier.setoain@arm.com    };
90614106Sjavier.setoain@arm.com}};
90714106Sjavier.setoain@arm.com
90814106Sjavier.setoain@arm.comdef template SveStructMemExecDeclare {{
90914106Sjavier.setoain@arm.com    template
91014106Sjavier.setoain@arm.com    Fault %(class_name)s<%(targs)s>::execute(ExecContext *,
91114106Sjavier.setoain@arm.com        Trace::InstRecord *) const;
91214106Sjavier.setoain@arm.com
91314106Sjavier.setoain@arm.com    template
91414106Sjavier.setoain@arm.com    Fault %(class_name)s<%(targs)s>::initiateAcc(ExecContext *,
91514106Sjavier.setoain@arm.com        Trace::InstRecord *) const;
91614106Sjavier.setoain@arm.com
91714106Sjavier.setoain@arm.com    template
91814106Sjavier.setoain@arm.com    Fault %(class_name)s<%(targs)s>::completeAcc(PacketPtr,
91914106Sjavier.setoain@arm.com        ExecContext *, Trace::InstRecord *) const;
92014106Sjavier.setoain@arm.com}};
92114106Sjavier.setoain@arm.com
92214106Sjavier.setoain@arm.comdef template SveStructLoadExecute {{
92314106Sjavier.setoain@arm.com    template <class Element>
92414106Sjavier.setoain@arm.com    Fault %(class_name)s<Element>::execute(ExecContext *xc,
92514106Sjavier.setoain@arm.com        Trace::InstRecord *traceData) const
92614106Sjavier.setoain@arm.com    {
92714106Sjavier.setoain@arm.com        Addr EA;
92814106Sjavier.setoain@arm.com        Fault fault = NoFault;
92914106Sjavier.setoain@arm.com        bool aarch64 M5_VAR_USED = true;
93014106Sjavier.setoain@arm.com        unsigned eCount = ArmStaticInst::getCurSveVecLen<Element>(
93114106Sjavier.setoain@arm.com            xc->tcBase());
93214106Sjavier.setoain@arm.com
93314106Sjavier.setoain@arm.com        %(op_decl)s;
93414106Sjavier.setoain@arm.com        %(op_rd)s;
93514106Sjavier.setoain@arm.com        %(ea_code)s;
93614106Sjavier.setoain@arm.com
93714106Sjavier.setoain@arm.com        TheISA::VecRegContainer memData;
93814106Sjavier.setoain@arm.com        auto memDataView = memData.as<Element>();
93914106Sjavier.setoain@arm.com
94014106Sjavier.setoain@arm.com        if (fault == NoFault) {
94114106Sjavier.setoain@arm.com            fault = xc->readMem(EA, memData.raw_ptr<uint8_t>(), memAccessSize,
94214106Sjavier.setoain@arm.com                this->memAccessFlags);
94314106Sjavier.setoain@arm.com            %(memacc_code)s;
94414106Sjavier.setoain@arm.com        }
94514106Sjavier.setoain@arm.com
94614106Sjavier.setoain@arm.com        if (fault == NoFault) {
94714106Sjavier.setoain@arm.com            %(op_wb)s;
94814106Sjavier.setoain@arm.com        }
94914106Sjavier.setoain@arm.com
95014106Sjavier.setoain@arm.com        return fault;
95114106Sjavier.setoain@arm.com    }
95214106Sjavier.setoain@arm.com}};
95314106Sjavier.setoain@arm.com
95414106Sjavier.setoain@arm.comdef template SveStructLoadInitiateAcc {{
95514106Sjavier.setoain@arm.com    template <class Element>
95614106Sjavier.setoain@arm.com    Fault %(class_name)s<Element>::initiateAcc(ExecContext *xc,
95714106Sjavier.setoain@arm.com        Trace::InstRecord *traceData) const
95814106Sjavier.setoain@arm.com    {
95914106Sjavier.setoain@arm.com        Addr EA;
96014106Sjavier.setoain@arm.com        Fault fault = NoFault;
96114106Sjavier.setoain@arm.com        bool aarch64 M5_VAR_USED = true;
96214106Sjavier.setoain@arm.com        unsigned eCount = ArmStaticInst::getCurSveVecLen<Element>(
96314106Sjavier.setoain@arm.com            xc->tcBase());
96414106Sjavier.setoain@arm.com
96514106Sjavier.setoain@arm.com        %(op_src_decl)s;
96614106Sjavier.setoain@arm.com        %(op_rd)s;
96714106Sjavier.setoain@arm.com
96814106Sjavier.setoain@arm.com        %(ea_code)s;
96914106Sjavier.setoain@arm.com
97014106Sjavier.setoain@arm.com        if (fault == NoFault) {
97114106Sjavier.setoain@arm.com            fault = xc->initiateMemRead(EA, memAccessSize,
97214106Sjavier.setoain@arm.com                this->memAccessFlags);
97314106Sjavier.setoain@arm.com        }
97414106Sjavier.setoain@arm.com
97514106Sjavier.setoain@arm.com        return fault;
97614106Sjavier.setoain@arm.com    }
97714106Sjavier.setoain@arm.com}};
97814106Sjavier.setoain@arm.com
97914106Sjavier.setoain@arm.comdef template SveStructLoadCompleteAcc {{
98014106Sjavier.setoain@arm.com    template <class Element>
98114106Sjavier.setoain@arm.com    Fault %(class_name)s<Element>::completeAcc(PacketPtr pkt,
98214106Sjavier.setoain@arm.com        ExecContext *xc, Trace::InstRecord *traceData) const
98314106Sjavier.setoain@arm.com    {
98414106Sjavier.setoain@arm.com        Fault fault = NoFault;
98514106Sjavier.setoain@arm.com        bool aarch64 M5_VAR_USED = true;
98614106Sjavier.setoain@arm.com        unsigned eCount = ArmStaticInst::getCurSveVecLen<Element>(
98714106Sjavier.setoain@arm.com            xc->tcBase());
98814106Sjavier.setoain@arm.com
98914106Sjavier.setoain@arm.com        %(op_decl)s;
99014106Sjavier.setoain@arm.com        %(op_rd)s;
99114106Sjavier.setoain@arm.com
99214106Sjavier.setoain@arm.com        TheISA::VecRegContainer memData;
99314106Sjavier.setoain@arm.com        auto memDataView = memData.as<Element>();
99414106Sjavier.setoain@arm.com
99514106Sjavier.setoain@arm.com        memcpy(memData.raw_ptr<uint8_t>(), pkt->getPtr<uint8_t>(),
99614106Sjavier.setoain@arm.com            pkt->getSize());
99714106Sjavier.setoain@arm.com
99814106Sjavier.setoain@arm.com        if (fault == NoFault) {
99914106Sjavier.setoain@arm.com            %(memacc_code)s;
100014106Sjavier.setoain@arm.com        }
100114106Sjavier.setoain@arm.com
100214106Sjavier.setoain@arm.com        if (fault == NoFault) {
100314106Sjavier.setoain@arm.com            %(op_wb)s;
100414106Sjavier.setoain@arm.com        }
100514106Sjavier.setoain@arm.com
100614106Sjavier.setoain@arm.com        return fault;
100714106Sjavier.setoain@arm.com    }
100814106Sjavier.setoain@arm.com}};
100914106Sjavier.setoain@arm.com
101014106Sjavier.setoain@arm.comdef template SveStructStoreExecute {{
101114106Sjavier.setoain@arm.com    template <class Element>
101214106Sjavier.setoain@arm.com    Fault %(class_name)s<Element>::execute(ExecContext *xc,
101314106Sjavier.setoain@arm.com        Trace::InstRecord *traceData) const
101414106Sjavier.setoain@arm.com    {
101514106Sjavier.setoain@arm.com        Addr EA;
101614106Sjavier.setoain@arm.com        Fault fault = NoFault;
101714106Sjavier.setoain@arm.com        bool aarch64 M5_VAR_USED = true;
101814106Sjavier.setoain@arm.com        unsigned eCount = ArmStaticInst::getCurSveVecLen<Element>(
101914106Sjavier.setoain@arm.com            xc->tcBase());
102014106Sjavier.setoain@arm.com
102114106Sjavier.setoain@arm.com        %(op_decl)s;
102214106Sjavier.setoain@arm.com        %(op_rd)s;
102314106Sjavier.setoain@arm.com        %(ea_code)s;
102414106Sjavier.setoain@arm.com
102514106Sjavier.setoain@arm.com        TheISA::VecRegContainer memData;
102614106Sjavier.setoain@arm.com        auto memDataView = memData.as<Element>();
102714106Sjavier.setoain@arm.com
102814106Sjavier.setoain@arm.com        %(wren_code)s;
102914106Sjavier.setoain@arm.com
103014106Sjavier.setoain@arm.com        if (fault == NoFault) {
103114106Sjavier.setoain@arm.com            %(memacc_code)s;
103214106Sjavier.setoain@arm.com        }
103314106Sjavier.setoain@arm.com
103414106Sjavier.setoain@arm.com        if (fault == NoFault) {
103514106Sjavier.setoain@arm.com            fault = xc->writeMem(memData.raw_ptr<uint8_t>(), memAccessSize, EA,
103614106Sjavier.setoain@arm.com                this->memAccessFlags, NULL, wrEn);
103714106Sjavier.setoain@arm.com        }
103814106Sjavier.setoain@arm.com
103914106Sjavier.setoain@arm.com        if (fault == NoFault) {
104014106Sjavier.setoain@arm.com            %(op_wb)s;
104114106Sjavier.setoain@arm.com        }
104214106Sjavier.setoain@arm.com
104314106Sjavier.setoain@arm.com        return fault;
104414106Sjavier.setoain@arm.com    }
104514106Sjavier.setoain@arm.com}};
104614106Sjavier.setoain@arm.com
104714106Sjavier.setoain@arm.comdef template SveStructStoreInitiateAcc {{
104814106Sjavier.setoain@arm.com    template <class Element>
104914106Sjavier.setoain@arm.com    Fault %(class_name)s<Element>::initiateAcc(ExecContext *xc,
105014106Sjavier.setoain@arm.com        Trace::InstRecord *traceData) const
105114106Sjavier.setoain@arm.com    {
105214106Sjavier.setoain@arm.com        Addr EA;
105314106Sjavier.setoain@arm.com        Fault fault = NoFault;
105414106Sjavier.setoain@arm.com        bool aarch64 M5_VAR_USED = true;
105514106Sjavier.setoain@arm.com        unsigned eCount = ArmStaticInst::getCurSveVecLen<Element>(
105614106Sjavier.setoain@arm.com            xc->tcBase());
105714106Sjavier.setoain@arm.com
105814106Sjavier.setoain@arm.com        %(op_decl)s;
105914106Sjavier.setoain@arm.com        %(op_rd)s;
106014106Sjavier.setoain@arm.com        %(ea_code)s;
106114106Sjavier.setoain@arm.com
106214106Sjavier.setoain@arm.com        TheISA::VecRegContainer memData;
106314106Sjavier.setoain@arm.com        auto memDataView = memData.as<Element>();
106414106Sjavier.setoain@arm.com
106514106Sjavier.setoain@arm.com        %(wren_code)s;
106614106Sjavier.setoain@arm.com
106714106Sjavier.setoain@arm.com        if (fault == NoFault) {
106814106Sjavier.setoain@arm.com            %(memacc_code)s;
106914106Sjavier.setoain@arm.com        }
107014106Sjavier.setoain@arm.com
107114106Sjavier.setoain@arm.com        if (fault == NoFault) {
107214106Sjavier.setoain@arm.com            fault = xc->writeMem(memData.raw_ptr<uint8_t>(), memAccessSize, EA,
107314106Sjavier.setoain@arm.com                this->memAccessFlags, NULL, wrEn);
107414106Sjavier.setoain@arm.com        }
107514106Sjavier.setoain@arm.com
107614106Sjavier.setoain@arm.com        return fault;
107714106Sjavier.setoain@arm.com    }
107814106Sjavier.setoain@arm.com}};
107914106Sjavier.setoain@arm.com
108014106Sjavier.setoain@arm.comdef template SveStructStoreCompleteAcc {{
108114106Sjavier.setoain@arm.com    template <class Element>
108214106Sjavier.setoain@arm.com    Fault %(class_name)s<Element>::completeAcc(PacketPtr pkt,
108314106Sjavier.setoain@arm.com        ExecContext *xc, Trace::InstRecord *traceData) const
108414106Sjavier.setoain@arm.com    {
108514106Sjavier.setoain@arm.com        return NoFault;
108614106Sjavier.setoain@arm.com    }
108714106Sjavier.setoain@arm.com}};
108814106Sjavier.setoain@arm.com
108914106Sjavier.setoain@arm.comdef template SveStructMemSSMicroopDeclare {{
109014106Sjavier.setoain@arm.com    template <class _Element>
109114106Sjavier.setoain@arm.com    class %(class_name)s : public %(base_class)s
109214106Sjavier.setoain@arm.com    {
109314106Sjavier.setoain@arm.com      protected:
109414106Sjavier.setoain@arm.com        typedef _Element Element;
109514106Sjavier.setoain@arm.com        typedef _Element TPElem;
109614106Sjavier.setoain@arm.com
109714106Sjavier.setoain@arm.com        IntRegIndex dest;
109814106Sjavier.setoain@arm.com        IntRegIndex gp;
109914106Sjavier.setoain@arm.com        IntRegIndex base;
110014106Sjavier.setoain@arm.com        IntRegIndex offset;
110114106Sjavier.setoain@arm.com
110214106Sjavier.setoain@arm.com        uint8_t numRegs;
110314106Sjavier.setoain@arm.com        int regIndex;
110414106Sjavier.setoain@arm.com
110514106Sjavier.setoain@arm.com        unsigned memAccessFlags;
110614106Sjavier.setoain@arm.com
110714106Sjavier.setoain@arm.com        bool baseIsSP;
110814106Sjavier.setoain@arm.com
110914106Sjavier.setoain@arm.com      public:
111014106Sjavier.setoain@arm.com        %(class_name)s(const char* mnem, ExtMachInst machInst,
111114106Sjavier.setoain@arm.com            IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base,
111214106Sjavier.setoain@arm.com            IntRegIndex _offset, uint8_t _numRegs, int _regIndex)
111314106Sjavier.setoain@arm.com            : %(base_class)s(mnem, machInst, %(op_class)s),
111414106Sjavier.setoain@arm.com              dest(_dest), gp(_gp), base(_base), offset(_offset),
111514106Sjavier.setoain@arm.com              numRegs(_numRegs), regIndex(_regIndex),
111614106Sjavier.setoain@arm.com              memAccessFlags(ArmISA::TLB::AllowUnaligned |
111714106Sjavier.setoain@arm.com                             ArmISA::TLB::MustBeOne)
111814106Sjavier.setoain@arm.com        {
111914106Sjavier.setoain@arm.com            %(constructor)s;
112014106Sjavier.setoain@arm.com            baseIsSP = isSP(_base);
112114106Sjavier.setoain@arm.com        }
112214106Sjavier.setoain@arm.com
112314106Sjavier.setoain@arm.com        Fault execute(ExecContext *, Trace::InstRecord *) const;
112414106Sjavier.setoain@arm.com        Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
112514106Sjavier.setoain@arm.com        Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const;
112614106Sjavier.setoain@arm.com
112714106Sjavier.setoain@arm.com        virtual void
112814106Sjavier.setoain@arm.com        annotateFault(ArmFault *fault)
112914106Sjavier.setoain@arm.com        {
113014106Sjavier.setoain@arm.com            %(fa_code)s
113114106Sjavier.setoain@arm.com        }
113214106Sjavier.setoain@arm.com
113314106Sjavier.setoain@arm.com        std::string
113414106Sjavier.setoain@arm.com        generateDisassembly(Addr pc, const SymbolTable *symtab) const
113514106Sjavier.setoain@arm.com        {
113614106Sjavier.setoain@arm.com            std::stringstream ss;
113714106Sjavier.setoain@arm.com            printMnemonic(ss, "", false);
113814106Sjavier.setoain@arm.com            ccprintf(ss, "{");
113914106Sjavier.setoain@arm.com            switch (dest) {
114014106Sjavier.setoain@arm.com                case INTRLVREG0:
114114106Sjavier.setoain@arm.com                    ccprintf(ss, "INTRLV0");
114214106Sjavier.setoain@arm.com                    break;
114314106Sjavier.setoain@arm.com                case INTRLVREG1:
114414106Sjavier.setoain@arm.com                    ccprintf(ss, "INTRLV1");
114514106Sjavier.setoain@arm.com                    break;
114614106Sjavier.setoain@arm.com                case INTRLVREG2:
114714106Sjavier.setoain@arm.com                    ccprintf(ss, "INTRLV2");
114814106Sjavier.setoain@arm.com                    break;
114914106Sjavier.setoain@arm.com                case INTRLVREG3:
115014106Sjavier.setoain@arm.com                    ccprintf(ss, "INTRLV3");
115114106Sjavier.setoain@arm.com                    break;
115214106Sjavier.setoain@arm.com                default:
115314106Sjavier.setoain@arm.com                    printVecReg(ss, dest, true);
115414106Sjavier.setoain@arm.com                    break;
115514106Sjavier.setoain@arm.com            }
115614106Sjavier.setoain@arm.com            ccprintf(ss, "}, ");
115714106Sjavier.setoain@arm.com            printVecPredReg(ss, gp);
115814106Sjavier.setoain@arm.com            if (_opClass == MemReadOp) {
115914106Sjavier.setoain@arm.com                ccprintf(ss, "/z");
116014106Sjavier.setoain@arm.com            }
116114106Sjavier.setoain@arm.com            ccprintf(ss, ", [");
116214106Sjavier.setoain@arm.com            printIntReg(ss, base);
116314106Sjavier.setoain@arm.com            ccprintf(ss, ", ");
116414106Sjavier.setoain@arm.com            printVecReg(ss, offset, true);
116514106Sjavier.setoain@arm.com            ccprintf(ss, "] (uop reg %d tfer)", regIndex);
116614106Sjavier.setoain@arm.com            return ss.str();
116714106Sjavier.setoain@arm.com        }
116814106Sjavier.setoain@arm.com    };
116914106Sjavier.setoain@arm.com}};
117014106Sjavier.setoain@arm.com
117114106Sjavier.setoain@arm.comdef template SveIntrlvMicroopDeclare {{
117214106Sjavier.setoain@arm.com    template <class _Element>
117314106Sjavier.setoain@arm.com    class %(class_name)s: public %(base_class)s
117414106Sjavier.setoain@arm.com    {
117514106Sjavier.setoain@arm.com      protected:
117614106Sjavier.setoain@arm.com        typedef _Element Element;
117714106Sjavier.setoain@arm.com        typedef _Element TPElem;
117814106Sjavier.setoain@arm.com        IntRegIndex dest;
117914106Sjavier.setoain@arm.com        IntRegIndex op1;
118014106Sjavier.setoain@arm.com        uint8_t numRegs;
118114106Sjavier.setoain@arm.com        int regIndex;
118214106Sjavier.setoain@arm.com
118314106Sjavier.setoain@arm.com        StaticInst *macroOp;
118414106Sjavier.setoain@arm.com
118514106Sjavier.setoain@arm.com      public:
118614106Sjavier.setoain@arm.com        %(class_name)s(const char* mnem, ExtMachInst machInst,
118714106Sjavier.setoain@arm.com            IntRegIndex _dest, IntRegIndex _op1,
118814106Sjavier.setoain@arm.com            uint8_t _numRegs, int _regIndex, StaticInst *_macroOp)
118914106Sjavier.setoain@arm.com            : MicroOp(mnem, machInst, SimdAluOp),
119014106Sjavier.setoain@arm.com            dest(_dest), op1(_op1), numRegs(_numRegs), regIndex(_regIndex),
119114106Sjavier.setoain@arm.com            macroOp(_macroOp)
119214106Sjavier.setoain@arm.com        {
119314106Sjavier.setoain@arm.com            %(constructor)s;
119414106Sjavier.setoain@arm.com        }
119514106Sjavier.setoain@arm.com
119614106Sjavier.setoain@arm.com        Fault execute(ExecContext *, Trace::InstRecord *) const;
119714106Sjavier.setoain@arm.com
119814106Sjavier.setoain@arm.com        std::string
119914106Sjavier.setoain@arm.com        generateDisassembly(Addr pc, const SymbolTable *symtab) const
120014106Sjavier.setoain@arm.com        {
120114106Sjavier.setoain@arm.com            std::stringstream ss;
120214106Sjavier.setoain@arm.com            ccprintf(ss, "%s", macroOp->disassemble(pc, symtab));
120314106Sjavier.setoain@arm.com            ccprintf(ss, " (uop interleave)");
120414106Sjavier.setoain@arm.com            return ss.str();
120514106Sjavier.setoain@arm.com        }
120614106Sjavier.setoain@arm.com    };
120714106Sjavier.setoain@arm.com}};
120814106Sjavier.setoain@arm.com
120914106Sjavier.setoain@arm.comdef template SveDeIntrlvMicroopDeclare {{
121014106Sjavier.setoain@arm.com    template <class _Element>
121114106Sjavier.setoain@arm.com    class %(class_name)s : public %(base_class)s
121214106Sjavier.setoain@arm.com    {
121314106Sjavier.setoain@arm.com      protected:
121414106Sjavier.setoain@arm.com        typedef _Element Element;
121514106Sjavier.setoain@arm.com        typedef _Element TPElem;
121614106Sjavier.setoain@arm.com        IntRegIndex dest;
121714106Sjavier.setoain@arm.com        uint8_t numRegs;
121814106Sjavier.setoain@arm.com        int regIndex;
121914106Sjavier.setoain@arm.com
122014106Sjavier.setoain@arm.com        StaticInst *macroOp;
122114106Sjavier.setoain@arm.com
122214106Sjavier.setoain@arm.com      public:
122314106Sjavier.setoain@arm.com        %(class_name)s(const char* mnem, ExtMachInst machInst,
122414106Sjavier.setoain@arm.com            IntRegIndex _dest, uint8_t _numRegs, int _regIndex,
122514106Sjavier.setoain@arm.com            StaticInst *_macroOp)
122614106Sjavier.setoain@arm.com            : MicroOp(mnem, machInst, SimdAluOp),
122714106Sjavier.setoain@arm.com            dest(_dest), numRegs(_numRegs), regIndex(_regIndex),
122814106Sjavier.setoain@arm.com            macroOp(_macroOp)
122914106Sjavier.setoain@arm.com        {
123014106Sjavier.setoain@arm.com            %(constructor)s;
123114106Sjavier.setoain@arm.com        }
123214106Sjavier.setoain@arm.com
123314106Sjavier.setoain@arm.com        Fault execute(ExecContext *, Trace::InstRecord *) const;
123414106Sjavier.setoain@arm.com
123514106Sjavier.setoain@arm.com        std::string
123614106Sjavier.setoain@arm.com        generateDisassembly(Addr pc, const SymbolTable *symtab) const
123714106Sjavier.setoain@arm.com        {
123814106Sjavier.setoain@arm.com            std::stringstream ss;
123914106Sjavier.setoain@arm.com            ccprintf(ss, "%s", macroOp->disassemble(pc, symtab));
124014106Sjavier.setoain@arm.com            ccprintf(ss, " (uop deinterleave)");
124114106Sjavier.setoain@arm.com            return ss.str();
124214106Sjavier.setoain@arm.com        }
124314106Sjavier.setoain@arm.com    };
124414106Sjavier.setoain@arm.com}};
124514106Sjavier.setoain@arm.com
124614106Sjavier.setoain@arm.comdef template SveIntrlvMicroopExecDeclare {{
124714106Sjavier.setoain@arm.com    template
124814106Sjavier.setoain@arm.com    Fault %(class_name)s<%(targs)s>::execute(
124914106Sjavier.setoain@arm.com            ExecContext *, Trace::InstRecord *) const;
125014106Sjavier.setoain@arm.com}};
125114106Sjavier.setoain@arm.com
125214106Sjavier.setoain@arm.comdef template SveIntrlvMicroopExecute {{
125314106Sjavier.setoain@arm.com    template <class Element>
125414106Sjavier.setoain@arm.com    Fault %(class_name)s<Element>::execute(ExecContext *xc,
125514106Sjavier.setoain@arm.com            Trace::InstRecord *traceData) const
125614106Sjavier.setoain@arm.com    {
125714106Sjavier.setoain@arm.com        Fault fault = NoFault;
125814106Sjavier.setoain@arm.com        %(op_decl)s;
125914106Sjavier.setoain@arm.com        %(op_rd)s;
126014106Sjavier.setoain@arm.com
126114106Sjavier.setoain@arm.com        %(code)s;
126214106Sjavier.setoain@arm.com        if (fault == NoFault)
126314106Sjavier.setoain@arm.com        {
126414106Sjavier.setoain@arm.com            %(op_wb)s;
126514106Sjavier.setoain@arm.com        }
126614106Sjavier.setoain@arm.com
126714106Sjavier.setoain@arm.com        return fault;
126814106Sjavier.setoain@arm.com    }
126914106Sjavier.setoain@arm.com}};
1270