sve_mem.isa revision 14106
114028Sgiacomo.gabrielli@arm.com// Copyright (c) 2017-2018 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;
56314028Sgiacomo.gabrielli@arm.com            %(op_wb)s;
56414091Sgabor.dozsa@arm.com        } else {
56514091Sgabor.dozsa@arm.com            %(fault_status_set_code)s;
56614091Sgabor.dozsa@arm.com            if (firstFault) {
56714091Sgabor.dozsa@arm.com               for (index = 0;
56814091Sgabor.dozsa@arm.com                    index < numElems && !(%(pred_check_code)s);
56914091Sgabor.dozsa@arm.com                    index++);
57014091Sgabor.dozsa@arm.com
57114091Sgabor.dozsa@arm.com               if (index < elemIndex) {
57214091Sgabor.dozsa@arm.com                  fault = NoFault;
57314091Sgabor.dozsa@arm.com                  memData = 0;
57414091Sgabor.dozsa@arm.com                  %(memacc_code)s;
57514091Sgabor.dozsa@arm.com                  %(op_wb)s;
57614091Sgabor.dozsa@arm.com               }
57714091Sgabor.dozsa@arm.com            }
57814028Sgiacomo.gabrielli@arm.com        }
57914028Sgiacomo.gabrielli@arm.com        return fault;
58014028Sgiacomo.gabrielli@arm.com    }
58114028Sgiacomo.gabrielli@arm.com}};
58214028Sgiacomo.gabrielli@arm.com
58314028Sgiacomo.gabrielli@arm.comdef template SveGatherLoadMicroopInitiateAcc {{
58414028Sgiacomo.gabrielli@arm.com    %(tpl_header)s
58514028Sgiacomo.gabrielli@arm.com    Fault %(class_name)s%(tpl_args)s::initiateAcc(ExecContext *xc,
58614028Sgiacomo.gabrielli@arm.com        Trace::InstRecord *traceData) const
58714028Sgiacomo.gabrielli@arm.com    {
58814028Sgiacomo.gabrielli@arm.com        Addr EA;
58914028Sgiacomo.gabrielli@arm.com        Fault fault = NoFault;
59014028Sgiacomo.gabrielli@arm.com        bool aarch64 M5_VAR_USED = true;
59114028Sgiacomo.gabrielli@arm.com
59214028Sgiacomo.gabrielli@arm.com        %(op_src_decl)s;
59314028Sgiacomo.gabrielli@arm.com        %(op_rd)s;
59414028Sgiacomo.gabrielli@arm.com        %(ea_code)s;
59514028Sgiacomo.gabrielli@arm.com
59614028Sgiacomo.gabrielli@arm.com        MemElemType memData;
59714028Sgiacomo.gabrielli@arm.com
59814091Sgabor.dozsa@arm.com        int index = elemIndex;
59914028Sgiacomo.gabrielli@arm.com        if (%(pred_check_code)s) {
60014028Sgiacomo.gabrielli@arm.com            fault = initiateMemRead(xc, traceData, EA, memData,
60114028Sgiacomo.gabrielli@arm.com                this->memAccessFlags);
60214091Sgabor.dozsa@arm.com            if (fault != NoFault) {
60314091Sgabor.dozsa@arm.com                %(fault_status_set_code)s;
60414091Sgabor.dozsa@arm.com                if (firstFault) {
60514091Sgabor.dozsa@arm.com                    for (index = 0;
60614091Sgabor.dozsa@arm.com                         index < numElems && !(%(pred_check_code)s);
60714091Sgabor.dozsa@arm.com                         index++);
60814091Sgabor.dozsa@arm.com                    if (index < elemIndex) {
60914091Sgabor.dozsa@arm.com                        fault = NoFault;
61014091Sgabor.dozsa@arm.com                        xc->setMemAccPredicate(false);
61114091Sgabor.dozsa@arm.com                    }
61214091Sgabor.dozsa@arm.com                }
61314091Sgabor.dozsa@arm.com            } else {
61414091Sgabor.dozsa@arm.com                %(fault_status_reset_code)s;
61514091Sgabor.dozsa@arm.com            }
61614028Sgiacomo.gabrielli@arm.com        } else {
61714028Sgiacomo.gabrielli@arm.com            xc->setMemAccPredicate(false);
61814091Sgabor.dozsa@arm.com            %(fault_status_reset_code)s;
61914028Sgiacomo.gabrielli@arm.com        }
62014028Sgiacomo.gabrielli@arm.com
62114028Sgiacomo.gabrielli@arm.com        return fault;
62214028Sgiacomo.gabrielli@arm.com    }
62314028Sgiacomo.gabrielli@arm.com}};
62414028Sgiacomo.gabrielli@arm.com
62514028Sgiacomo.gabrielli@arm.comdef template SveGatherLoadMicroopCompleteAcc {{
62614028Sgiacomo.gabrielli@arm.com    %(tpl_header)s
62714028Sgiacomo.gabrielli@arm.com    Fault %(class_name)s%(tpl_args)s::completeAcc(PacketPtr pkt,
62814028Sgiacomo.gabrielli@arm.com        ExecContext *xc, Trace::InstRecord *traceData) const
62914028Sgiacomo.gabrielli@arm.com    {
63014028Sgiacomo.gabrielli@arm.com        bool aarch64 M5_VAR_USED = true;
63114028Sgiacomo.gabrielli@arm.com
63214028Sgiacomo.gabrielli@arm.com        %(op_decl)s;
63314028Sgiacomo.gabrielli@arm.com        %(op_rd)s;
63414028Sgiacomo.gabrielli@arm.com
63514028Sgiacomo.gabrielli@arm.com        MemElemType memData = 0;
63614091Sgabor.dozsa@arm.com        if (xc->readMemAccPredicate()) {
63714028Sgiacomo.gabrielli@arm.com            getMem(pkt, memData, traceData);
63814028Sgiacomo.gabrielli@arm.com        }
63914028Sgiacomo.gabrielli@arm.com
64014091Sgabor.dozsa@arm.com        %(memacc_code)s;
64114091Sgabor.dozsa@arm.com        %(op_wb)s;
64214028Sgiacomo.gabrielli@arm.com
64314091Sgabor.dozsa@arm.com        return NoFault;
64414028Sgiacomo.gabrielli@arm.com    }
64514028Sgiacomo.gabrielli@arm.com}};
64614028Sgiacomo.gabrielli@arm.com
64714028Sgiacomo.gabrielli@arm.comdef template SveScatterStoreMicroopExecute {{
64814028Sgiacomo.gabrielli@arm.com    %(tpl_header)s
64914028Sgiacomo.gabrielli@arm.com    Fault %(class_name)s%(tpl_args)s::execute(ExecContext *xc,
65014028Sgiacomo.gabrielli@arm.com        Trace::InstRecord *traceData) const
65114028Sgiacomo.gabrielli@arm.com    {
65214028Sgiacomo.gabrielli@arm.com        Addr EA;
65314028Sgiacomo.gabrielli@arm.com        Fault fault = NoFault;
65414028Sgiacomo.gabrielli@arm.com        bool aarch64 M5_VAR_USED = true;
65514028Sgiacomo.gabrielli@arm.com
65614028Sgiacomo.gabrielli@arm.com        %(op_decl)s;
65714028Sgiacomo.gabrielli@arm.com        %(op_rd)s;
65814028Sgiacomo.gabrielli@arm.com        %(ea_code)s;
65914028Sgiacomo.gabrielli@arm.com
66014028Sgiacomo.gabrielli@arm.com        MemElemType memData;
66114028Sgiacomo.gabrielli@arm.com        %(memacc_code)s;
66214028Sgiacomo.gabrielli@arm.com
66314091Sgabor.dozsa@arm.com        int index = elemIndex;
66414028Sgiacomo.gabrielli@arm.com        if (%(pred_check_code)s) {
66514028Sgiacomo.gabrielli@arm.com            fault = writeMemAtomic(xc, traceData, memData, EA,
66614028Sgiacomo.gabrielli@arm.com                                   this->memAccessFlags, NULL);
66714028Sgiacomo.gabrielli@arm.com        }
66814028Sgiacomo.gabrielli@arm.com
66914028Sgiacomo.gabrielli@arm.com        if (fault == NoFault) {
67014028Sgiacomo.gabrielli@arm.com            %(op_wb)s;
67114028Sgiacomo.gabrielli@arm.com        }
67214028Sgiacomo.gabrielli@arm.com
67314028Sgiacomo.gabrielli@arm.com        return fault;
67414028Sgiacomo.gabrielli@arm.com    }
67514028Sgiacomo.gabrielli@arm.com}};
67614028Sgiacomo.gabrielli@arm.com
67714028Sgiacomo.gabrielli@arm.comdef template SveScatterStoreMicroopInitiateAcc {{
67814028Sgiacomo.gabrielli@arm.com    %(tpl_header)s
67914028Sgiacomo.gabrielli@arm.com    Fault %(class_name)s%(tpl_args)s::initiateAcc(ExecContext *xc,
68014028Sgiacomo.gabrielli@arm.com        Trace::InstRecord *traceData) const
68114028Sgiacomo.gabrielli@arm.com    {
68214028Sgiacomo.gabrielli@arm.com        Addr EA;
68314028Sgiacomo.gabrielli@arm.com        Fault fault = NoFault;
68414028Sgiacomo.gabrielli@arm.com        bool aarch64 M5_VAR_USED = true;
68514028Sgiacomo.gabrielli@arm.com
68614028Sgiacomo.gabrielli@arm.com        %(op_decl)s;
68714028Sgiacomo.gabrielli@arm.com        %(op_rd)s;
68814028Sgiacomo.gabrielli@arm.com        %(ea_code)s;
68914028Sgiacomo.gabrielli@arm.com
69014028Sgiacomo.gabrielli@arm.com        MemElemType memData;
69114028Sgiacomo.gabrielli@arm.com        %(memacc_code)s;
69214028Sgiacomo.gabrielli@arm.com
69314091Sgabor.dozsa@arm.com        int index = elemIndex;
69414028Sgiacomo.gabrielli@arm.com        if (%(pred_check_code)s) {
69514028Sgiacomo.gabrielli@arm.com            fault = writeMemTiming(xc, traceData, memData, EA,
69614028Sgiacomo.gabrielli@arm.com                                   this->memAccessFlags, NULL);
69714028Sgiacomo.gabrielli@arm.com        } else {
69814028Sgiacomo.gabrielli@arm.com            xc->setPredicate(false);
69914028Sgiacomo.gabrielli@arm.com        }
70014028Sgiacomo.gabrielli@arm.com
70114028Sgiacomo.gabrielli@arm.com        return fault;
70214028Sgiacomo.gabrielli@arm.com    }
70314028Sgiacomo.gabrielli@arm.com}};
70414028Sgiacomo.gabrielli@arm.com
70514028Sgiacomo.gabrielli@arm.comdef template SveScatterStoreMicroopCompleteAcc {{
70614028Sgiacomo.gabrielli@arm.com    %(tpl_header)s
70714028Sgiacomo.gabrielli@arm.com    Fault %(class_name)s%(tpl_args)s::completeAcc(PacketPtr pkt,
70814028Sgiacomo.gabrielli@arm.com        ExecContext *xc, Trace::InstRecord *traceData) const
70914028Sgiacomo.gabrielli@arm.com    {
71014028Sgiacomo.gabrielli@arm.com        return NoFault;
71114028Sgiacomo.gabrielli@arm.com    }
71214028Sgiacomo.gabrielli@arm.com}};
71314028Sgiacomo.gabrielli@arm.com
71414091Sgabor.dozsa@arm.comdef template SveFirstFaultWritebackMicroopDeclare {{
71514091Sgabor.dozsa@arm.com    %(tpl_header)s
71614091Sgabor.dozsa@arm.com    class SveFirstFaultWritebackMicroop : public MicroOp
71714091Sgabor.dozsa@arm.com    {
71814091Sgabor.dozsa@arm.com      protected:
71914091Sgabor.dozsa@arm.com        typedef RegElemType TPElem;
72014091Sgabor.dozsa@arm.com
72114091Sgabor.dozsa@arm.com        int numElems;
72214091Sgabor.dozsa@arm.com        StaticInst *macroOp;
72314091Sgabor.dozsa@arm.com
72414091Sgabor.dozsa@arm.com      public:
72514091Sgabor.dozsa@arm.com        SveFirstFaultWritebackMicroop(const char* mnem, ExtMachInst machInst,
72614091Sgabor.dozsa@arm.com            OpClass __opClass, int _numElems, StaticInst *_macroOp)
72714091Sgabor.dozsa@arm.com            : MicroOp(mnem, machInst, __opClass),
72814091Sgabor.dozsa@arm.com              numElems(_numElems), macroOp(_macroOp)
72914091Sgabor.dozsa@arm.com        {
73014091Sgabor.dozsa@arm.com            %(constructor)s;
73114091Sgabor.dozsa@arm.com        }
73214091Sgabor.dozsa@arm.com
73314091Sgabor.dozsa@arm.com        Fault execute(ExecContext *, Trace::InstRecord *) const;
73414091Sgabor.dozsa@arm.com
73514091Sgabor.dozsa@arm.com        std::string
73614091Sgabor.dozsa@arm.com        generateDisassembly(Addr pc, const SymbolTable *symtab) const
73714091Sgabor.dozsa@arm.com        {
73814091Sgabor.dozsa@arm.com            std::stringstream ss;
73914091Sgabor.dozsa@arm.com            ccprintf(ss, "%s", macroOp->disassemble(pc, symtab));
74014091Sgabor.dozsa@arm.com            ccprintf(ss, " (uop%d)", numElems);
74114091Sgabor.dozsa@arm.com            return ss.str();
74214091Sgabor.dozsa@arm.com        }
74314091Sgabor.dozsa@arm.com    };
74414091Sgabor.dozsa@arm.com}};
74514091Sgabor.dozsa@arm.com
74614091Sgabor.dozsa@arm.comdef template SveFirstFaultWritebackMicroopExecute {{
74714091Sgabor.dozsa@arm.com    %(tpl_header)s
74814091Sgabor.dozsa@arm.com    Fault %(class_name)s%(tpl_args)s::execute(ExecContext *xc,
74914091Sgabor.dozsa@arm.com        Trace::InstRecord *traceData) const
75014091Sgabor.dozsa@arm.com    {
75114091Sgabor.dozsa@arm.com        bool aarch64 M5_VAR_USED = true;
75214091Sgabor.dozsa@arm.com
75314091Sgabor.dozsa@arm.com        %(op_decl)s;
75414091Sgabor.dozsa@arm.com        %(op_rd)s;
75514091Sgabor.dozsa@arm.com
75614091Sgabor.dozsa@arm.com        int  index, firstFaultIndex;
75714091Sgabor.dozsa@arm.com        for (index = 0;
75814091Sgabor.dozsa@arm.com             index < numElems && !%(fault_status_check_code)s;
75914091Sgabor.dozsa@arm.com             index++);
76014091Sgabor.dozsa@arm.com        firstFaultIndex = index;
76114091Sgabor.dozsa@arm.com        for (index = 0; index < numElems; index++) {
76214091Sgabor.dozsa@arm.com            if (index < firstFaultIndex) {
76314091Sgabor.dozsa@arm.com                %(first_fault_forward_code)s;
76414091Sgabor.dozsa@arm.com            } else {
76514091Sgabor.dozsa@arm.com                %(first_fault_reset_code)s;
76614091Sgabor.dozsa@arm.com            }
76714091Sgabor.dozsa@arm.com        }
76814091Sgabor.dozsa@arm.com        return NoFault;
76914091Sgabor.dozsa@arm.com    }
77014091Sgabor.dozsa@arm.com}};
77114091Sgabor.dozsa@arm.com
77214028Sgiacomo.gabrielli@arm.comdef template SveGatherLoadCpySrcVecMicroopDeclare {{
77314028Sgiacomo.gabrielli@arm.com    class SveGatherLoadCpySrcVecMicroop : public MicroOp
77414028Sgiacomo.gabrielli@arm.com    {
77514028Sgiacomo.gabrielli@arm.com      protected:
77614028Sgiacomo.gabrielli@arm.com        IntRegIndex op1;
77714028Sgiacomo.gabrielli@arm.com
77814028Sgiacomo.gabrielli@arm.com        StaticInst *macroOp;
77914028Sgiacomo.gabrielli@arm.com
78014028Sgiacomo.gabrielli@arm.com      public:
78114028Sgiacomo.gabrielli@arm.com        SveGatherLoadCpySrcVecMicroop(const char* mnem, ExtMachInst machInst,
78214028Sgiacomo.gabrielli@arm.com            IntRegIndex _op1, StaticInst *_macroOp)
78314028Sgiacomo.gabrielli@arm.com            : MicroOp(mnem, machInst, SimdAluOp), op1(_op1), macroOp(_macroOp)
78414028Sgiacomo.gabrielli@arm.com        {
78514028Sgiacomo.gabrielli@arm.com            %(constructor)s;
78614028Sgiacomo.gabrielli@arm.com        }
78714028Sgiacomo.gabrielli@arm.com
78814028Sgiacomo.gabrielli@arm.com        Fault execute(ExecContext *, Trace::InstRecord *) const;
78914028Sgiacomo.gabrielli@arm.com
79014028Sgiacomo.gabrielli@arm.com        std::string
79114028Sgiacomo.gabrielli@arm.com        generateDisassembly(Addr pc, const SymbolTable *symtab) const
79214028Sgiacomo.gabrielli@arm.com        {
79314028Sgiacomo.gabrielli@arm.com            std::stringstream ss;
79414028Sgiacomo.gabrielli@arm.com            ccprintf(ss, "%s", macroOp->disassemble(pc, symtab));
79514028Sgiacomo.gabrielli@arm.com            ccprintf(ss, " (uop src vec cpy)");
79614028Sgiacomo.gabrielli@arm.com            return ss.str();
79714028Sgiacomo.gabrielli@arm.com        }
79814028Sgiacomo.gabrielli@arm.com    };
79914028Sgiacomo.gabrielli@arm.com}};
80014028Sgiacomo.gabrielli@arm.com
80114028Sgiacomo.gabrielli@arm.comdef template SveGatherLoadCpySrcVecMicroopExecute {{
80214028Sgiacomo.gabrielli@arm.com    Fault SveGatherLoadCpySrcVecMicroop::execute(ExecContext *xc,
80314028Sgiacomo.gabrielli@arm.com            Trace::InstRecord *traceData) const
80414028Sgiacomo.gabrielli@arm.com    {
80514028Sgiacomo.gabrielli@arm.com        Fault fault = NoFault;
80614028Sgiacomo.gabrielli@arm.com        %(op_decl)s;
80714028Sgiacomo.gabrielli@arm.com        %(op_rd)s;
80814028Sgiacomo.gabrielli@arm.com
80914028Sgiacomo.gabrielli@arm.com        %(code)s;
81014028Sgiacomo.gabrielli@arm.com        if (fault == NoFault)
81114028Sgiacomo.gabrielli@arm.com        {
81214028Sgiacomo.gabrielli@arm.com            %(op_wb)s;
81314028Sgiacomo.gabrielli@arm.com        }
81414028Sgiacomo.gabrielli@arm.com
81514028Sgiacomo.gabrielli@arm.com        return fault;
81614028Sgiacomo.gabrielli@arm.com    }
81714028Sgiacomo.gabrielli@arm.com}};
81814106Sjavier.setoain@arm.com
81914106Sjavier.setoain@arm.comdef template SveStructMemSIMicroopDeclare {{
82014106Sjavier.setoain@arm.com    template<class _Element>
82114106Sjavier.setoain@arm.com    class %(class_name)s : public %(base_class)s
82214106Sjavier.setoain@arm.com    {
82314106Sjavier.setoain@arm.com      protected:
82414106Sjavier.setoain@arm.com        typedef _Element Element;
82514106Sjavier.setoain@arm.com        typedef _Element TPElem;
82614106Sjavier.setoain@arm.com
82714106Sjavier.setoain@arm.com        IntRegIndex dest;
82814106Sjavier.setoain@arm.com        IntRegIndex gp;
82914106Sjavier.setoain@arm.com        IntRegIndex base;
83014106Sjavier.setoain@arm.com        int64_t imm;
83114106Sjavier.setoain@arm.com
83214106Sjavier.setoain@arm.com        uint8_t numRegs;
83314106Sjavier.setoain@arm.com        int regIndex;
83414106Sjavier.setoain@arm.com
83514106Sjavier.setoain@arm.com        unsigned memAccessFlags;
83614106Sjavier.setoain@arm.com
83714106Sjavier.setoain@arm.com        bool baseIsSP;
83814106Sjavier.setoain@arm.com
83914106Sjavier.setoain@arm.com      public:
84014106Sjavier.setoain@arm.com        %(class_name)s(const char* mnem, ExtMachInst machInst,
84114106Sjavier.setoain@arm.com            IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base,
84214106Sjavier.setoain@arm.com            int64_t _imm, uint8_t _numRegs, int _regIndex)
84314106Sjavier.setoain@arm.com            : %(base_class)s(mnem, machInst, %(op_class)s),
84414106Sjavier.setoain@arm.com              dest(_dest), gp(_gp), base(_base), imm(_imm),
84514106Sjavier.setoain@arm.com              numRegs(_numRegs), regIndex(_regIndex),
84614106Sjavier.setoain@arm.com              memAccessFlags(ArmISA::TLB::AllowUnaligned |
84714106Sjavier.setoain@arm.com                             ArmISA::TLB::MustBeOne)
84814106Sjavier.setoain@arm.com        {
84914106Sjavier.setoain@arm.com            %(constructor)s;
85014106Sjavier.setoain@arm.com            baseIsSP = isSP(_base);
85114106Sjavier.setoain@arm.com        }
85214106Sjavier.setoain@arm.com
85314106Sjavier.setoain@arm.com        Fault execute(ExecContext *, Trace::InstRecord *) const;
85414106Sjavier.setoain@arm.com        Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
85514106Sjavier.setoain@arm.com        Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const;
85614106Sjavier.setoain@arm.com
85714106Sjavier.setoain@arm.com        virtual void
85814106Sjavier.setoain@arm.com        annotateFault(ArmFault *fault)
85914106Sjavier.setoain@arm.com        {
86014106Sjavier.setoain@arm.com            %(fa_code)s
86114106Sjavier.setoain@arm.com        }
86214106Sjavier.setoain@arm.com
86314106Sjavier.setoain@arm.com        std::string
86414106Sjavier.setoain@arm.com        generateDisassembly(Addr pc, const SymbolTable *symtab) const
86514106Sjavier.setoain@arm.com        {
86614106Sjavier.setoain@arm.com            std::stringstream ss;
86714106Sjavier.setoain@arm.com            printMnemonic(ss, "", false);
86814106Sjavier.setoain@arm.com            ccprintf(ss, "{");
86914106Sjavier.setoain@arm.com            switch (dest) {
87014106Sjavier.setoain@arm.com                case INTRLVREG0:
87114106Sjavier.setoain@arm.com                    ccprintf(ss, "INTRLV0");
87214106Sjavier.setoain@arm.com                    break;
87314106Sjavier.setoain@arm.com                case INTRLVREG1:
87414106Sjavier.setoain@arm.com                    ccprintf(ss, "INTRLV1");
87514106Sjavier.setoain@arm.com                    break;
87614106Sjavier.setoain@arm.com                case INTRLVREG2:
87714106Sjavier.setoain@arm.com                    ccprintf(ss, "INTRLV2");
87814106Sjavier.setoain@arm.com                    break;
87914106Sjavier.setoain@arm.com                case INTRLVREG3:
88014106Sjavier.setoain@arm.com                    ccprintf(ss, "INTRLV3");
88114106Sjavier.setoain@arm.com                    break;
88214106Sjavier.setoain@arm.com                default:
88314106Sjavier.setoain@arm.com                    printVecReg(ss, dest, true);
88414106Sjavier.setoain@arm.com                    break;
88514106Sjavier.setoain@arm.com            }
88614106Sjavier.setoain@arm.com            ccprintf(ss, "}, ");
88714106Sjavier.setoain@arm.com            printVecPredReg(ss, gp);
88814106Sjavier.setoain@arm.com            if (_opClass == MemReadOp) {
88914106Sjavier.setoain@arm.com                ccprintf(ss, "/z");
89014106Sjavier.setoain@arm.com            }
89114106Sjavier.setoain@arm.com            ccprintf(ss, ", [");
89214106Sjavier.setoain@arm.com            printVecReg(ss, base, true);
89314106Sjavier.setoain@arm.com            if (imm != 0) {
89414106Sjavier.setoain@arm.com                ccprintf(ss, ", #%d", imm * sizeof(Element));
89514106Sjavier.setoain@arm.com            }
89614106Sjavier.setoain@arm.com            ccprintf(ss, "] (uop reg %d tfer)", regIndex);
89714106Sjavier.setoain@arm.com            return ss.str();
89814106Sjavier.setoain@arm.com        }
89914106Sjavier.setoain@arm.com    };
90014106Sjavier.setoain@arm.com}};
90114106Sjavier.setoain@arm.com
90214106Sjavier.setoain@arm.comdef template SveStructMemExecDeclare {{
90314106Sjavier.setoain@arm.com    template
90414106Sjavier.setoain@arm.com    Fault %(class_name)s<%(targs)s>::execute(ExecContext *,
90514106Sjavier.setoain@arm.com        Trace::InstRecord *) const;
90614106Sjavier.setoain@arm.com
90714106Sjavier.setoain@arm.com    template
90814106Sjavier.setoain@arm.com    Fault %(class_name)s<%(targs)s>::initiateAcc(ExecContext *,
90914106Sjavier.setoain@arm.com        Trace::InstRecord *) const;
91014106Sjavier.setoain@arm.com
91114106Sjavier.setoain@arm.com    template
91214106Sjavier.setoain@arm.com    Fault %(class_name)s<%(targs)s>::completeAcc(PacketPtr,
91314106Sjavier.setoain@arm.com        ExecContext *, Trace::InstRecord *) const;
91414106Sjavier.setoain@arm.com}};
91514106Sjavier.setoain@arm.com
91614106Sjavier.setoain@arm.comdef template SveStructLoadExecute {{
91714106Sjavier.setoain@arm.com    template <class Element>
91814106Sjavier.setoain@arm.com    Fault %(class_name)s<Element>::execute(ExecContext *xc,
91914106Sjavier.setoain@arm.com        Trace::InstRecord *traceData) const
92014106Sjavier.setoain@arm.com    {
92114106Sjavier.setoain@arm.com        Addr EA;
92214106Sjavier.setoain@arm.com        Fault fault = NoFault;
92314106Sjavier.setoain@arm.com        bool aarch64 M5_VAR_USED = true;
92414106Sjavier.setoain@arm.com        unsigned eCount = ArmStaticInst::getCurSveVecLen<Element>(
92514106Sjavier.setoain@arm.com            xc->tcBase());
92614106Sjavier.setoain@arm.com
92714106Sjavier.setoain@arm.com        %(op_decl)s;
92814106Sjavier.setoain@arm.com        %(op_rd)s;
92914106Sjavier.setoain@arm.com        %(ea_code)s;
93014106Sjavier.setoain@arm.com
93114106Sjavier.setoain@arm.com        TheISA::VecRegContainer memData;
93214106Sjavier.setoain@arm.com        auto memDataView = memData.as<Element>();
93314106Sjavier.setoain@arm.com
93414106Sjavier.setoain@arm.com        if (fault == NoFault) {
93514106Sjavier.setoain@arm.com            fault = xc->readMem(EA, memData.raw_ptr<uint8_t>(), memAccessSize,
93614106Sjavier.setoain@arm.com                this->memAccessFlags);
93714106Sjavier.setoain@arm.com            %(memacc_code)s;
93814106Sjavier.setoain@arm.com        }
93914106Sjavier.setoain@arm.com
94014106Sjavier.setoain@arm.com        if (fault == NoFault) {
94114106Sjavier.setoain@arm.com            %(op_wb)s;
94214106Sjavier.setoain@arm.com        }
94314106Sjavier.setoain@arm.com
94414106Sjavier.setoain@arm.com        return fault;
94514106Sjavier.setoain@arm.com    }
94614106Sjavier.setoain@arm.com}};
94714106Sjavier.setoain@arm.com
94814106Sjavier.setoain@arm.comdef template SveStructLoadInitiateAcc {{
94914106Sjavier.setoain@arm.com    template <class Element>
95014106Sjavier.setoain@arm.com    Fault %(class_name)s<Element>::initiateAcc(ExecContext *xc,
95114106Sjavier.setoain@arm.com        Trace::InstRecord *traceData) const
95214106Sjavier.setoain@arm.com    {
95314106Sjavier.setoain@arm.com        Addr EA;
95414106Sjavier.setoain@arm.com        Fault fault = NoFault;
95514106Sjavier.setoain@arm.com        bool aarch64 M5_VAR_USED = true;
95614106Sjavier.setoain@arm.com        unsigned eCount = ArmStaticInst::getCurSveVecLen<Element>(
95714106Sjavier.setoain@arm.com            xc->tcBase());
95814106Sjavier.setoain@arm.com
95914106Sjavier.setoain@arm.com        %(op_src_decl)s;
96014106Sjavier.setoain@arm.com        %(op_rd)s;
96114106Sjavier.setoain@arm.com
96214106Sjavier.setoain@arm.com        %(ea_code)s;
96314106Sjavier.setoain@arm.com
96414106Sjavier.setoain@arm.com        if (fault == NoFault) {
96514106Sjavier.setoain@arm.com            fault = xc->initiateMemRead(EA, memAccessSize,
96614106Sjavier.setoain@arm.com                this->memAccessFlags);
96714106Sjavier.setoain@arm.com        }
96814106Sjavier.setoain@arm.com
96914106Sjavier.setoain@arm.com        return fault;
97014106Sjavier.setoain@arm.com    }
97114106Sjavier.setoain@arm.com}};
97214106Sjavier.setoain@arm.com
97314106Sjavier.setoain@arm.comdef template SveStructLoadCompleteAcc {{
97414106Sjavier.setoain@arm.com    template <class Element>
97514106Sjavier.setoain@arm.com    Fault %(class_name)s<Element>::completeAcc(PacketPtr pkt,
97614106Sjavier.setoain@arm.com        ExecContext *xc, Trace::InstRecord *traceData) const
97714106Sjavier.setoain@arm.com    {
97814106Sjavier.setoain@arm.com        Fault fault = NoFault;
97914106Sjavier.setoain@arm.com        bool aarch64 M5_VAR_USED = true;
98014106Sjavier.setoain@arm.com        unsigned eCount = ArmStaticInst::getCurSveVecLen<Element>(
98114106Sjavier.setoain@arm.com            xc->tcBase());
98214106Sjavier.setoain@arm.com
98314106Sjavier.setoain@arm.com        %(op_decl)s;
98414106Sjavier.setoain@arm.com        %(op_rd)s;
98514106Sjavier.setoain@arm.com
98614106Sjavier.setoain@arm.com        TheISA::VecRegContainer memData;
98714106Sjavier.setoain@arm.com        auto memDataView = memData.as<Element>();
98814106Sjavier.setoain@arm.com
98914106Sjavier.setoain@arm.com        memcpy(memData.raw_ptr<uint8_t>(), pkt->getPtr<uint8_t>(),
99014106Sjavier.setoain@arm.com            pkt->getSize());
99114106Sjavier.setoain@arm.com
99214106Sjavier.setoain@arm.com        if (fault == NoFault) {
99314106Sjavier.setoain@arm.com            %(memacc_code)s;
99414106Sjavier.setoain@arm.com        }
99514106Sjavier.setoain@arm.com
99614106Sjavier.setoain@arm.com        if (fault == NoFault) {
99714106Sjavier.setoain@arm.com            %(op_wb)s;
99814106Sjavier.setoain@arm.com        }
99914106Sjavier.setoain@arm.com
100014106Sjavier.setoain@arm.com        return fault;
100114106Sjavier.setoain@arm.com    }
100214106Sjavier.setoain@arm.com}};
100314106Sjavier.setoain@arm.com
100414106Sjavier.setoain@arm.comdef template SveStructStoreExecute {{
100514106Sjavier.setoain@arm.com    template <class Element>
100614106Sjavier.setoain@arm.com    Fault %(class_name)s<Element>::execute(ExecContext *xc,
100714106Sjavier.setoain@arm.com        Trace::InstRecord *traceData) const
100814106Sjavier.setoain@arm.com    {
100914106Sjavier.setoain@arm.com        Addr EA;
101014106Sjavier.setoain@arm.com        Fault fault = NoFault;
101114106Sjavier.setoain@arm.com        bool aarch64 M5_VAR_USED = true;
101214106Sjavier.setoain@arm.com        unsigned eCount = ArmStaticInst::getCurSveVecLen<Element>(
101314106Sjavier.setoain@arm.com            xc->tcBase());
101414106Sjavier.setoain@arm.com
101514106Sjavier.setoain@arm.com        %(op_decl)s;
101614106Sjavier.setoain@arm.com        %(op_rd)s;
101714106Sjavier.setoain@arm.com        %(ea_code)s;
101814106Sjavier.setoain@arm.com
101914106Sjavier.setoain@arm.com        TheISA::VecRegContainer memData;
102014106Sjavier.setoain@arm.com        auto memDataView = memData.as<Element>();
102114106Sjavier.setoain@arm.com
102214106Sjavier.setoain@arm.com        %(wren_code)s;
102314106Sjavier.setoain@arm.com
102414106Sjavier.setoain@arm.com        if (fault == NoFault) {
102514106Sjavier.setoain@arm.com            %(memacc_code)s;
102614106Sjavier.setoain@arm.com        }
102714106Sjavier.setoain@arm.com
102814106Sjavier.setoain@arm.com        if (fault == NoFault) {
102914106Sjavier.setoain@arm.com            fault = xc->writeMem(memData.raw_ptr<uint8_t>(), memAccessSize, EA,
103014106Sjavier.setoain@arm.com                this->memAccessFlags, NULL, wrEn);
103114106Sjavier.setoain@arm.com        }
103214106Sjavier.setoain@arm.com
103314106Sjavier.setoain@arm.com        if (fault == NoFault) {
103414106Sjavier.setoain@arm.com            %(op_wb)s;
103514106Sjavier.setoain@arm.com        }
103614106Sjavier.setoain@arm.com
103714106Sjavier.setoain@arm.com        return fault;
103814106Sjavier.setoain@arm.com    }
103914106Sjavier.setoain@arm.com}};
104014106Sjavier.setoain@arm.com
104114106Sjavier.setoain@arm.comdef template SveStructStoreInitiateAcc {{
104214106Sjavier.setoain@arm.com    template <class Element>
104314106Sjavier.setoain@arm.com    Fault %(class_name)s<Element>::initiateAcc(ExecContext *xc,
104414106Sjavier.setoain@arm.com        Trace::InstRecord *traceData) const
104514106Sjavier.setoain@arm.com    {
104614106Sjavier.setoain@arm.com        Addr EA;
104714106Sjavier.setoain@arm.com        Fault fault = NoFault;
104814106Sjavier.setoain@arm.com        bool aarch64 M5_VAR_USED = true;
104914106Sjavier.setoain@arm.com        unsigned eCount = ArmStaticInst::getCurSveVecLen<Element>(
105014106Sjavier.setoain@arm.com            xc->tcBase());
105114106Sjavier.setoain@arm.com
105214106Sjavier.setoain@arm.com        %(op_decl)s;
105314106Sjavier.setoain@arm.com        %(op_rd)s;
105414106Sjavier.setoain@arm.com        %(ea_code)s;
105514106Sjavier.setoain@arm.com
105614106Sjavier.setoain@arm.com        TheISA::VecRegContainer memData;
105714106Sjavier.setoain@arm.com        auto memDataView = memData.as<Element>();
105814106Sjavier.setoain@arm.com
105914106Sjavier.setoain@arm.com        %(wren_code)s;
106014106Sjavier.setoain@arm.com
106114106Sjavier.setoain@arm.com        if (fault == NoFault) {
106214106Sjavier.setoain@arm.com            %(memacc_code)s;
106314106Sjavier.setoain@arm.com        }
106414106Sjavier.setoain@arm.com
106514106Sjavier.setoain@arm.com        if (fault == NoFault) {
106614106Sjavier.setoain@arm.com            fault = xc->writeMem(memData.raw_ptr<uint8_t>(), memAccessSize, EA,
106714106Sjavier.setoain@arm.com                this->memAccessFlags, NULL, wrEn);
106814106Sjavier.setoain@arm.com        }
106914106Sjavier.setoain@arm.com
107014106Sjavier.setoain@arm.com        return fault;
107114106Sjavier.setoain@arm.com    }
107214106Sjavier.setoain@arm.com}};
107314106Sjavier.setoain@arm.com
107414106Sjavier.setoain@arm.comdef template SveStructStoreCompleteAcc {{
107514106Sjavier.setoain@arm.com    template <class Element>
107614106Sjavier.setoain@arm.com    Fault %(class_name)s<Element>::completeAcc(PacketPtr pkt,
107714106Sjavier.setoain@arm.com        ExecContext *xc, Trace::InstRecord *traceData) const
107814106Sjavier.setoain@arm.com    {
107914106Sjavier.setoain@arm.com        return NoFault;
108014106Sjavier.setoain@arm.com    }
108114106Sjavier.setoain@arm.com}};
108214106Sjavier.setoain@arm.com
108314106Sjavier.setoain@arm.comdef template SveStructMemSSMicroopDeclare {{
108414106Sjavier.setoain@arm.com    template <class _Element>
108514106Sjavier.setoain@arm.com    class %(class_name)s : public %(base_class)s
108614106Sjavier.setoain@arm.com    {
108714106Sjavier.setoain@arm.com      protected:
108814106Sjavier.setoain@arm.com        typedef _Element Element;
108914106Sjavier.setoain@arm.com        typedef _Element TPElem;
109014106Sjavier.setoain@arm.com
109114106Sjavier.setoain@arm.com        IntRegIndex dest;
109214106Sjavier.setoain@arm.com        IntRegIndex gp;
109314106Sjavier.setoain@arm.com        IntRegIndex base;
109414106Sjavier.setoain@arm.com        IntRegIndex offset;
109514106Sjavier.setoain@arm.com
109614106Sjavier.setoain@arm.com        uint8_t numRegs;
109714106Sjavier.setoain@arm.com        int regIndex;
109814106Sjavier.setoain@arm.com
109914106Sjavier.setoain@arm.com        unsigned memAccessFlags;
110014106Sjavier.setoain@arm.com
110114106Sjavier.setoain@arm.com        bool baseIsSP;
110214106Sjavier.setoain@arm.com
110314106Sjavier.setoain@arm.com      public:
110414106Sjavier.setoain@arm.com        %(class_name)s(const char* mnem, ExtMachInst machInst,
110514106Sjavier.setoain@arm.com            IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base,
110614106Sjavier.setoain@arm.com            IntRegIndex _offset, uint8_t _numRegs, int _regIndex)
110714106Sjavier.setoain@arm.com            : %(base_class)s(mnem, machInst, %(op_class)s),
110814106Sjavier.setoain@arm.com              dest(_dest), gp(_gp), base(_base), offset(_offset),
110914106Sjavier.setoain@arm.com              numRegs(_numRegs), regIndex(_regIndex),
111014106Sjavier.setoain@arm.com              memAccessFlags(ArmISA::TLB::AllowUnaligned |
111114106Sjavier.setoain@arm.com                             ArmISA::TLB::MustBeOne)
111214106Sjavier.setoain@arm.com        {
111314106Sjavier.setoain@arm.com            %(constructor)s;
111414106Sjavier.setoain@arm.com            baseIsSP = isSP(_base);
111514106Sjavier.setoain@arm.com        }
111614106Sjavier.setoain@arm.com
111714106Sjavier.setoain@arm.com        Fault execute(ExecContext *, Trace::InstRecord *) const;
111814106Sjavier.setoain@arm.com        Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
111914106Sjavier.setoain@arm.com        Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const;
112014106Sjavier.setoain@arm.com
112114106Sjavier.setoain@arm.com        virtual void
112214106Sjavier.setoain@arm.com        annotateFault(ArmFault *fault)
112314106Sjavier.setoain@arm.com        {
112414106Sjavier.setoain@arm.com            %(fa_code)s
112514106Sjavier.setoain@arm.com        }
112614106Sjavier.setoain@arm.com
112714106Sjavier.setoain@arm.com        std::string
112814106Sjavier.setoain@arm.com        generateDisassembly(Addr pc, const SymbolTable *symtab) const
112914106Sjavier.setoain@arm.com        {
113014106Sjavier.setoain@arm.com            std::stringstream ss;
113114106Sjavier.setoain@arm.com            printMnemonic(ss, "", false);
113214106Sjavier.setoain@arm.com            ccprintf(ss, "{");
113314106Sjavier.setoain@arm.com            switch (dest) {
113414106Sjavier.setoain@arm.com                case INTRLVREG0:
113514106Sjavier.setoain@arm.com                    ccprintf(ss, "INTRLV0");
113614106Sjavier.setoain@arm.com                    break;
113714106Sjavier.setoain@arm.com                case INTRLVREG1:
113814106Sjavier.setoain@arm.com                    ccprintf(ss, "INTRLV1");
113914106Sjavier.setoain@arm.com                    break;
114014106Sjavier.setoain@arm.com                case INTRLVREG2:
114114106Sjavier.setoain@arm.com                    ccprintf(ss, "INTRLV2");
114214106Sjavier.setoain@arm.com                    break;
114314106Sjavier.setoain@arm.com                case INTRLVREG3:
114414106Sjavier.setoain@arm.com                    ccprintf(ss, "INTRLV3");
114514106Sjavier.setoain@arm.com                    break;
114614106Sjavier.setoain@arm.com                default:
114714106Sjavier.setoain@arm.com                    printVecReg(ss, dest, true);
114814106Sjavier.setoain@arm.com                    break;
114914106Sjavier.setoain@arm.com            }
115014106Sjavier.setoain@arm.com            ccprintf(ss, "}, ");
115114106Sjavier.setoain@arm.com            printVecPredReg(ss, gp);
115214106Sjavier.setoain@arm.com            if (_opClass == MemReadOp) {
115314106Sjavier.setoain@arm.com                ccprintf(ss, "/z");
115414106Sjavier.setoain@arm.com            }
115514106Sjavier.setoain@arm.com            ccprintf(ss, ", [");
115614106Sjavier.setoain@arm.com            printIntReg(ss, base);
115714106Sjavier.setoain@arm.com            ccprintf(ss, ", ");
115814106Sjavier.setoain@arm.com            printVecReg(ss, offset, true);
115914106Sjavier.setoain@arm.com            ccprintf(ss, "] (uop reg %d tfer)", regIndex);
116014106Sjavier.setoain@arm.com            return ss.str();
116114106Sjavier.setoain@arm.com        }
116214106Sjavier.setoain@arm.com    };
116314106Sjavier.setoain@arm.com}};
116414106Sjavier.setoain@arm.com
116514106Sjavier.setoain@arm.comdef template SveIntrlvMicroopDeclare {{
116614106Sjavier.setoain@arm.com    template <class _Element>
116714106Sjavier.setoain@arm.com    class %(class_name)s: public %(base_class)s
116814106Sjavier.setoain@arm.com    {
116914106Sjavier.setoain@arm.com      protected:
117014106Sjavier.setoain@arm.com        typedef _Element Element;
117114106Sjavier.setoain@arm.com        typedef _Element TPElem;
117214106Sjavier.setoain@arm.com        IntRegIndex dest;
117314106Sjavier.setoain@arm.com        IntRegIndex op1;
117414106Sjavier.setoain@arm.com        uint8_t numRegs;
117514106Sjavier.setoain@arm.com        int regIndex;
117614106Sjavier.setoain@arm.com
117714106Sjavier.setoain@arm.com        StaticInst *macroOp;
117814106Sjavier.setoain@arm.com
117914106Sjavier.setoain@arm.com      public:
118014106Sjavier.setoain@arm.com        %(class_name)s(const char* mnem, ExtMachInst machInst,
118114106Sjavier.setoain@arm.com            IntRegIndex _dest, IntRegIndex _op1,
118214106Sjavier.setoain@arm.com            uint8_t _numRegs, int _regIndex, StaticInst *_macroOp)
118314106Sjavier.setoain@arm.com            : MicroOp(mnem, machInst, SimdAluOp),
118414106Sjavier.setoain@arm.com            dest(_dest), op1(_op1), numRegs(_numRegs), regIndex(_regIndex),
118514106Sjavier.setoain@arm.com            macroOp(_macroOp)
118614106Sjavier.setoain@arm.com        {
118714106Sjavier.setoain@arm.com            %(constructor)s;
118814106Sjavier.setoain@arm.com        }
118914106Sjavier.setoain@arm.com
119014106Sjavier.setoain@arm.com        Fault execute(ExecContext *, Trace::InstRecord *) const;
119114106Sjavier.setoain@arm.com
119214106Sjavier.setoain@arm.com        std::string
119314106Sjavier.setoain@arm.com        generateDisassembly(Addr pc, const SymbolTable *symtab) const
119414106Sjavier.setoain@arm.com        {
119514106Sjavier.setoain@arm.com            std::stringstream ss;
119614106Sjavier.setoain@arm.com            ccprintf(ss, "%s", macroOp->disassemble(pc, symtab));
119714106Sjavier.setoain@arm.com            ccprintf(ss, " (uop interleave)");
119814106Sjavier.setoain@arm.com            return ss.str();
119914106Sjavier.setoain@arm.com        }
120014106Sjavier.setoain@arm.com    };
120114106Sjavier.setoain@arm.com}};
120214106Sjavier.setoain@arm.com
120314106Sjavier.setoain@arm.comdef template SveDeIntrlvMicroopDeclare {{
120414106Sjavier.setoain@arm.com    template <class _Element>
120514106Sjavier.setoain@arm.com    class %(class_name)s : public %(base_class)s
120614106Sjavier.setoain@arm.com    {
120714106Sjavier.setoain@arm.com      protected:
120814106Sjavier.setoain@arm.com        typedef _Element Element;
120914106Sjavier.setoain@arm.com        typedef _Element TPElem;
121014106Sjavier.setoain@arm.com        IntRegIndex dest;
121114106Sjavier.setoain@arm.com        uint8_t numRegs;
121214106Sjavier.setoain@arm.com        int regIndex;
121314106Sjavier.setoain@arm.com
121414106Sjavier.setoain@arm.com        StaticInst *macroOp;
121514106Sjavier.setoain@arm.com
121614106Sjavier.setoain@arm.com      public:
121714106Sjavier.setoain@arm.com        %(class_name)s(const char* mnem, ExtMachInst machInst,
121814106Sjavier.setoain@arm.com            IntRegIndex _dest, uint8_t _numRegs, int _regIndex,
121914106Sjavier.setoain@arm.com            StaticInst *_macroOp)
122014106Sjavier.setoain@arm.com            : MicroOp(mnem, machInst, SimdAluOp),
122114106Sjavier.setoain@arm.com            dest(_dest), numRegs(_numRegs), regIndex(_regIndex),
122214106Sjavier.setoain@arm.com            macroOp(_macroOp)
122314106Sjavier.setoain@arm.com        {
122414106Sjavier.setoain@arm.com            %(constructor)s;
122514106Sjavier.setoain@arm.com        }
122614106Sjavier.setoain@arm.com
122714106Sjavier.setoain@arm.com        Fault execute(ExecContext *, Trace::InstRecord *) const;
122814106Sjavier.setoain@arm.com
122914106Sjavier.setoain@arm.com        std::string
123014106Sjavier.setoain@arm.com        generateDisassembly(Addr pc, const SymbolTable *symtab) const
123114106Sjavier.setoain@arm.com        {
123214106Sjavier.setoain@arm.com            std::stringstream ss;
123314106Sjavier.setoain@arm.com            ccprintf(ss, "%s", macroOp->disassemble(pc, symtab));
123414106Sjavier.setoain@arm.com            ccprintf(ss, " (uop deinterleave)");
123514106Sjavier.setoain@arm.com            return ss.str();
123614106Sjavier.setoain@arm.com        }
123714106Sjavier.setoain@arm.com    };
123814106Sjavier.setoain@arm.com}};
123914106Sjavier.setoain@arm.com
124014106Sjavier.setoain@arm.comdef template SveIntrlvMicroopExecDeclare {{
124114106Sjavier.setoain@arm.com    template
124214106Sjavier.setoain@arm.com    Fault %(class_name)s<%(targs)s>::execute(
124314106Sjavier.setoain@arm.com            ExecContext *, Trace::InstRecord *) const;
124414106Sjavier.setoain@arm.com}};
124514106Sjavier.setoain@arm.com
124614106Sjavier.setoain@arm.comdef template SveIntrlvMicroopExecute {{
124714106Sjavier.setoain@arm.com    template <class Element>
124814106Sjavier.setoain@arm.com    Fault %(class_name)s<Element>::execute(ExecContext *xc,
124914106Sjavier.setoain@arm.com            Trace::InstRecord *traceData) const
125014106Sjavier.setoain@arm.com    {
125114106Sjavier.setoain@arm.com        Fault fault = NoFault;
125214106Sjavier.setoain@arm.com        %(op_decl)s;
125314106Sjavier.setoain@arm.com        %(op_rd)s;
125414106Sjavier.setoain@arm.com
125514106Sjavier.setoain@arm.com        %(code)s;
125614106Sjavier.setoain@arm.com        if (fault == NoFault)
125714106Sjavier.setoain@arm.com        {
125814106Sjavier.setoain@arm.com            %(op_wb)s;
125914106Sjavier.setoain@arm.com        }
126014106Sjavier.setoain@arm.com
126114106Sjavier.setoain@arm.com        return fault;
126214106Sjavier.setoain@arm.com    }
126314106Sjavier.setoain@arm.com}};
1264