114110Sgabor.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.com// @file Definition of SVE memory access instructions.
3913955Sgiacomo.gabrielli@arm.com
4013955Sgiacomo.gabrielli@arm.comoutput header {{
4113955Sgiacomo.gabrielli@arm.com
4213955Sgiacomo.gabrielli@arm.com    // Decodes SVE contiguous load instructions, scalar plus scalar form.
4313955Sgiacomo.gabrielli@arm.com    template <template <typename T1, typename T2> class Base>
4413955Sgiacomo.gabrielli@arm.com    StaticInstPtr
4513955Sgiacomo.gabrielli@arm.com    decodeSveContigLoadSSInsts(uint8_t dtype, ExtMachInst machInst,
4613955Sgiacomo.gabrielli@arm.com                               IntRegIndex zt, IntRegIndex pg, IntRegIndex rn,
4713955Sgiacomo.gabrielli@arm.com                               IntRegIndex rm, bool firstFaulting)
4813955Sgiacomo.gabrielli@arm.com    {
4913955Sgiacomo.gabrielli@arm.com        const char* mn = firstFaulting ? "ldff1" : "ld1";
5013955Sgiacomo.gabrielli@arm.com        switch (dtype) {
5113955Sgiacomo.gabrielli@arm.com          case 0x0:
5213955Sgiacomo.gabrielli@arm.com            return new Base<uint8_t, uint8_t>(mn, machInst, zt, pg, rn, rm);
5313955Sgiacomo.gabrielli@arm.com          case 0x1:
5413955Sgiacomo.gabrielli@arm.com            return new Base<uint16_t, uint8_t>(mn, machInst, zt, pg, rn, rm);
5513955Sgiacomo.gabrielli@arm.com          case 0x2:
5613955Sgiacomo.gabrielli@arm.com            return new Base<uint32_t, uint8_t>(mn, machInst, zt, pg, rn, rm);
5713955Sgiacomo.gabrielli@arm.com          case 0x3:
5813955Sgiacomo.gabrielli@arm.com            return new Base<uint64_t, uint8_t>(mn, machInst, zt, pg, rn, rm);
5913955Sgiacomo.gabrielli@arm.com          case 0x4:
6013955Sgiacomo.gabrielli@arm.com            return new Base<int64_t, int32_t>(mn, machInst, zt, pg, rn, rm);
6113955Sgiacomo.gabrielli@arm.com          case 0x5:
6213955Sgiacomo.gabrielli@arm.com            return new Base<uint16_t, uint16_t>(mn, machInst, zt, pg, rn, rm);
6313955Sgiacomo.gabrielli@arm.com          case 0x6:
6413955Sgiacomo.gabrielli@arm.com            return new Base<uint32_t, uint16_t>(mn, machInst, zt, pg, rn, rm);
6513955Sgiacomo.gabrielli@arm.com          case 0x7:
6613955Sgiacomo.gabrielli@arm.com            return new Base<uint64_t, uint16_t>(mn, machInst, zt, pg, rn, rm);
6713955Sgiacomo.gabrielli@arm.com          case 0x8:
6813955Sgiacomo.gabrielli@arm.com            return new Base<int64_t, int16_t>(mn, machInst, zt, pg, rn, rm);
6913955Sgiacomo.gabrielli@arm.com          case 0x9:
7013955Sgiacomo.gabrielli@arm.com            return new Base<int32_t, int16_t>(mn, machInst, zt, pg, rn, rm);
7113955Sgiacomo.gabrielli@arm.com          case 0xa:
7213955Sgiacomo.gabrielli@arm.com            return new Base<uint32_t, uint32_t>(mn, machInst, zt, pg, rn, rm);
7313955Sgiacomo.gabrielli@arm.com          case 0xb:
7413955Sgiacomo.gabrielli@arm.com            return new Base<uint64_t, uint32_t>(mn, machInst, zt, pg, rn, rm);
7513955Sgiacomo.gabrielli@arm.com          case 0xc:
7613955Sgiacomo.gabrielli@arm.com            return new Base<int64_t, int8_t>(mn, machInst, zt, pg, rn, rm);
7713955Sgiacomo.gabrielli@arm.com          case 0xd:
7813955Sgiacomo.gabrielli@arm.com            return new Base<int32_t, int8_t>(mn, machInst, zt, pg, rn, rm);
7913955Sgiacomo.gabrielli@arm.com          case 0xe:
8013955Sgiacomo.gabrielli@arm.com            return new Base<int16_t, int8_t>(mn, machInst, zt, pg, rn, rm);
8113955Sgiacomo.gabrielli@arm.com          case 0xf:
8213955Sgiacomo.gabrielli@arm.com            return new Base<uint64_t, uint64_t>(mn, machInst, zt, pg, rn, rm);
8313955Sgiacomo.gabrielli@arm.com        }
8413955Sgiacomo.gabrielli@arm.com        return new Unknown64(machInst);
8513955Sgiacomo.gabrielli@arm.com    }
8613955Sgiacomo.gabrielli@arm.com
8713955Sgiacomo.gabrielli@arm.com    // Decodes SVE contiguous load instructions, scalar plus immediate form.
8813955Sgiacomo.gabrielli@arm.com    template <template <typename T1, typename T2> class Base>
8913955Sgiacomo.gabrielli@arm.com    StaticInstPtr
9013955Sgiacomo.gabrielli@arm.com    decodeSveContigLoadSIInsts(uint8_t dtype, ExtMachInst machInst,
9113955Sgiacomo.gabrielli@arm.com                               IntRegIndex zt, IntRegIndex pg, IntRegIndex rn,
9214091Sgabor.dozsa@arm.com                               uint64_t imm, bool nonFaulting,
9313955Sgiacomo.gabrielli@arm.com                               bool replicate = false)
9413955Sgiacomo.gabrielli@arm.com    {
9514091Sgabor.dozsa@arm.com        assert(!(nonFaulting && replicate));
9614091Sgabor.dozsa@arm.com        const char* mn = replicate ? "ld1r" : (nonFaulting ? "ldnf1" : "ld1");
9713955Sgiacomo.gabrielli@arm.com        switch (dtype) {
9813955Sgiacomo.gabrielli@arm.com          case 0x0:
9913955Sgiacomo.gabrielli@arm.com            return new Base<uint8_t, uint8_t>(mn, machInst, zt, pg, rn, imm);
10013955Sgiacomo.gabrielli@arm.com          case 0x1:
10113955Sgiacomo.gabrielli@arm.com            return new Base<uint16_t, uint8_t>(mn, machInst, zt, pg, rn, imm);
10213955Sgiacomo.gabrielli@arm.com          case 0x2:
10313955Sgiacomo.gabrielli@arm.com            return new Base<uint32_t, uint8_t>(mn, machInst, zt, pg, rn, imm);
10413955Sgiacomo.gabrielli@arm.com          case 0x3:
10513955Sgiacomo.gabrielli@arm.com            return new Base<uint64_t, uint8_t>(mn, machInst, zt, pg, rn, imm);
10613955Sgiacomo.gabrielli@arm.com          case 0x4:
10713955Sgiacomo.gabrielli@arm.com            return new Base<int64_t, int32_t>(mn, machInst, zt, pg, rn, imm);
10813955Sgiacomo.gabrielli@arm.com          case 0x5:
10913955Sgiacomo.gabrielli@arm.com            return new Base<uint16_t, uint16_t>(mn, machInst, zt, pg, rn, imm);
11013955Sgiacomo.gabrielli@arm.com          case 0x6:
11113955Sgiacomo.gabrielli@arm.com            return new Base<uint32_t, uint16_t>(mn, machInst, zt, pg, rn, imm);
11213955Sgiacomo.gabrielli@arm.com          case 0x7:
11313955Sgiacomo.gabrielli@arm.com            return new Base<uint64_t, uint16_t>(mn, machInst, zt, pg, rn, imm);
11413955Sgiacomo.gabrielli@arm.com          case 0x8:
11513955Sgiacomo.gabrielli@arm.com            return new Base<int64_t, int16_t>(mn, machInst, zt, pg, rn, imm);
11613955Sgiacomo.gabrielli@arm.com          case 0x9:
11713955Sgiacomo.gabrielli@arm.com            return new Base<int32_t, int16_t>(mn, machInst, zt, pg, rn, imm);
11813955Sgiacomo.gabrielli@arm.com          case 0xa:
11913955Sgiacomo.gabrielli@arm.com            return new Base<uint32_t, uint32_t>(mn, machInst, zt, pg, rn, imm);
12013955Sgiacomo.gabrielli@arm.com          case 0xb:
12113955Sgiacomo.gabrielli@arm.com            return new Base<uint64_t, uint32_t>(mn, machInst, zt, pg, rn, imm);
12213955Sgiacomo.gabrielli@arm.com          case 0xc:
12313955Sgiacomo.gabrielli@arm.com            return new Base<int64_t, int8_t>(mn, machInst, zt, pg, rn, imm);
12413955Sgiacomo.gabrielli@arm.com          case 0xd:
12513955Sgiacomo.gabrielli@arm.com            return new Base<int32_t, int8_t>(mn, machInst, zt, pg, rn, imm);
12613955Sgiacomo.gabrielli@arm.com          case 0xe:
12713955Sgiacomo.gabrielli@arm.com            return new Base<int16_t, int8_t>(mn, machInst, zt, pg, rn, imm);
12813955Sgiacomo.gabrielli@arm.com          case 0xf:
12913955Sgiacomo.gabrielli@arm.com            return new Base<uint64_t, uint64_t>(mn, machInst, zt, pg, rn, imm);
13013955Sgiacomo.gabrielli@arm.com        }
13113955Sgiacomo.gabrielli@arm.com        return new Unknown64(machInst);
13213955Sgiacomo.gabrielli@arm.com    }
13313955Sgiacomo.gabrielli@arm.com
13413955Sgiacomo.gabrielli@arm.com    // Decodes SVE contiguous store instructions, scalar plus scalar form.
13513955Sgiacomo.gabrielli@arm.com    template <template <typename T1, typename T2> class Base>
13613955Sgiacomo.gabrielli@arm.com    StaticInstPtr
13713955Sgiacomo.gabrielli@arm.com    decodeSveContigStoreSSInsts(uint8_t dtype, ExtMachInst machInst,
13813955Sgiacomo.gabrielli@arm.com                                IntRegIndex zt, IntRegIndex pg, IntRegIndex rn,
13913955Sgiacomo.gabrielli@arm.com                                IntRegIndex rm)
14013955Sgiacomo.gabrielli@arm.com    {
14113955Sgiacomo.gabrielli@arm.com        const char* mn = "st1";
14213955Sgiacomo.gabrielli@arm.com        switch (dtype) {
14313955Sgiacomo.gabrielli@arm.com          case 0x0:
14413955Sgiacomo.gabrielli@arm.com            return new Base<uint8_t, uint8_t>(mn, machInst, zt, pg, rn, rm);
14513955Sgiacomo.gabrielli@arm.com          case 0x1:
14613955Sgiacomo.gabrielli@arm.com            return new Base<uint16_t, uint8_t>(mn, machInst, zt, pg, rn, rm);
14713955Sgiacomo.gabrielli@arm.com          case 0x2:
14813955Sgiacomo.gabrielli@arm.com            return new Base<uint32_t, uint8_t>(mn, machInst, zt, pg, rn, rm);
14913955Sgiacomo.gabrielli@arm.com          case 0x3:
15013955Sgiacomo.gabrielli@arm.com            return new Base<uint64_t, uint8_t>(mn, machInst, zt, pg, rn, rm);
15113955Sgiacomo.gabrielli@arm.com          case 0x5:
15213955Sgiacomo.gabrielli@arm.com            return new Base<uint16_t, uint16_t>(mn, machInst, zt, pg, rn, rm);
15313955Sgiacomo.gabrielli@arm.com          case 0x6:
15413955Sgiacomo.gabrielli@arm.com            return new Base<uint32_t, uint16_t>(mn, machInst, zt, pg, rn, rm);
15513955Sgiacomo.gabrielli@arm.com          case 0x7:
15613955Sgiacomo.gabrielli@arm.com            return new Base<uint64_t, uint16_t>(mn, machInst, zt, pg, rn, rm);
15713955Sgiacomo.gabrielli@arm.com          case 0xa:
15813955Sgiacomo.gabrielli@arm.com            return new Base<uint32_t, uint32_t>(mn, machInst, zt, pg, rn, rm);
15913955Sgiacomo.gabrielli@arm.com          case 0xb:
16013955Sgiacomo.gabrielli@arm.com            return new Base<uint64_t, uint32_t>(mn, machInst, zt, pg, rn, rm);
16113955Sgiacomo.gabrielli@arm.com          case 0xf:
16213955Sgiacomo.gabrielli@arm.com            return new Base<uint64_t, uint64_t>(mn, machInst, zt, pg, rn, rm);
16313955Sgiacomo.gabrielli@arm.com        }
16413955Sgiacomo.gabrielli@arm.com        return new Unknown64(machInst);
16513955Sgiacomo.gabrielli@arm.com    }
16613955Sgiacomo.gabrielli@arm.com
16713955Sgiacomo.gabrielli@arm.com    // Decodes SVE contiguous store instructions, scalar plus immediate form.
16813955Sgiacomo.gabrielli@arm.com    template <template <typename T1, typename T2> class Base>
16913955Sgiacomo.gabrielli@arm.com    StaticInstPtr
17013955Sgiacomo.gabrielli@arm.com    decodeSveContigStoreSIInsts(uint8_t dtype, ExtMachInst machInst,
17113955Sgiacomo.gabrielli@arm.com                                IntRegIndex zt, IntRegIndex pg, IntRegIndex rn,
17213955Sgiacomo.gabrielli@arm.com                                int8_t imm)
17313955Sgiacomo.gabrielli@arm.com    {
17413955Sgiacomo.gabrielli@arm.com        const char* mn = "st1";
17513955Sgiacomo.gabrielli@arm.com        switch (dtype) {
17613955Sgiacomo.gabrielli@arm.com          case 0x0:
17713955Sgiacomo.gabrielli@arm.com            return new Base<uint8_t, uint8_t>(mn, machInst, zt, pg, rn, imm);
17813955Sgiacomo.gabrielli@arm.com          case 0x1:
17913955Sgiacomo.gabrielli@arm.com            return new Base<uint16_t, uint8_t>(mn, machInst, zt, pg, rn, imm);
18013955Sgiacomo.gabrielli@arm.com          case 0x2:
18113955Sgiacomo.gabrielli@arm.com            return new Base<uint32_t, uint8_t>(mn, machInst, zt, pg, rn, imm);
18213955Sgiacomo.gabrielli@arm.com          case 0x3:
18313955Sgiacomo.gabrielli@arm.com            return new Base<uint64_t, uint8_t>(mn, machInst, zt, pg, rn, imm);
18413955Sgiacomo.gabrielli@arm.com          case 0x5:
18513955Sgiacomo.gabrielli@arm.com            return new Base<uint16_t, uint16_t>(mn, machInst, zt, pg, rn, imm);
18613955Sgiacomo.gabrielli@arm.com          case 0x6:
18713955Sgiacomo.gabrielli@arm.com            return new Base<uint32_t, uint16_t>(mn, machInst, zt, pg, rn, imm);
18813955Sgiacomo.gabrielli@arm.com          case 0x7:
18913955Sgiacomo.gabrielli@arm.com            return new Base<uint64_t, uint16_t>(mn, machInst, zt, pg, rn, imm);
19013955Sgiacomo.gabrielli@arm.com          case 0xa:
19113955Sgiacomo.gabrielli@arm.com            return new Base<uint32_t, uint32_t>(mn, machInst, zt, pg, rn, imm);
19213955Sgiacomo.gabrielli@arm.com          case 0xb:
19313955Sgiacomo.gabrielli@arm.com            return new Base<uint64_t, uint32_t>(mn, machInst, zt, pg, rn, imm);
19413955Sgiacomo.gabrielli@arm.com          case 0xf:
19513955Sgiacomo.gabrielli@arm.com            return new Base<uint64_t, uint64_t>(mn, machInst, zt, pg, rn, imm);
19613955Sgiacomo.gabrielli@arm.com        }
19713955Sgiacomo.gabrielli@arm.com        return new Unknown64(machInst);
19813955Sgiacomo.gabrielli@arm.com    }
19913955Sgiacomo.gabrielli@arm.com
20013955Sgiacomo.gabrielli@arm.com    // NOTE: SVE load-and-replicate instructions are decoded with
20113955Sgiacomo.gabrielli@arm.com    // decodeSveContigLoadSIInsts(...).
20213955Sgiacomo.gabrielli@arm.com
20313955Sgiacomo.gabrielli@arm.com}};
20413955Sgiacomo.gabrielli@arm.com
20514028Sgiacomo.gabrielli@arm.comoutput decoder {{
20614028Sgiacomo.gabrielli@arm.com
20714106Sjavier.setoain@arm.com    template <class etype>
20814106Sjavier.setoain@arm.com    StaticInstPtr
20914106Sjavier.setoain@arm.com    decodeSveStructLoadSIInstsByNReg(uint8_t esize, ExtMachInst machInst,
21014106Sjavier.setoain@arm.com            IntRegIndex zt, IntRegIndex pg, IntRegIndex xn,
21114106Sjavier.setoain@arm.com            int64_t imm, int numregs)
21214106Sjavier.setoain@arm.com    {
21314106Sjavier.setoain@arm.com        static const char* nm[5][4] = {
21414106Sjavier.setoain@arm.com            { nullptr, nullptr, nullptr, nullptr},
21514106Sjavier.setoain@arm.com            { nullptr, nullptr, nullptr, nullptr},
21614106Sjavier.setoain@arm.com            { "ld2b", "ld2h", "ld2w", "ld2d" },
21714106Sjavier.setoain@arm.com            { "ld3b", "ld3h", "ld3w", "ld3d" },
21814106Sjavier.setoain@arm.com            { "ld4b", "ld4h", "ld4w", "ld4d" } };
21914106Sjavier.setoain@arm.com
22014106Sjavier.setoain@arm.com        switch (numregs) {
22114106Sjavier.setoain@arm.com            case 2:
22214106Sjavier.setoain@arm.com                return new SveLdStructSI<etype,
22314106Sjavier.setoain@arm.com                        SveLoadRegImmMicroop,
22414106Sjavier.setoain@arm.com                        SveDeIntrlv2Microop>(
22514106Sjavier.setoain@arm.com                               nm[numregs][esize], machInst, MemReadOp,
22614106Sjavier.setoain@arm.com                               zt, pg, xn, imm, numregs);
22714106Sjavier.setoain@arm.com            case 3:
22814106Sjavier.setoain@arm.com                return new SveLdStructSI<etype,
22914106Sjavier.setoain@arm.com                        SveLoadRegImmMicroop,
23014106Sjavier.setoain@arm.com                        SveDeIntrlv3Microop>(
23114106Sjavier.setoain@arm.com                               nm[numregs][esize], machInst, MemReadOp,
23214106Sjavier.setoain@arm.com                               zt, pg, xn, imm, numregs);
23314106Sjavier.setoain@arm.com            case 4:
23414106Sjavier.setoain@arm.com                return new SveLdStructSI<etype,
23514106Sjavier.setoain@arm.com                        SveLoadRegImmMicroop,
23614106Sjavier.setoain@arm.com                        SveDeIntrlv4Microop>(
23714106Sjavier.setoain@arm.com                               nm[numregs][esize], machInst, MemReadOp,
23814106Sjavier.setoain@arm.com                               zt, pg, xn, imm, numregs);
23914106Sjavier.setoain@arm.com        }
24014106Sjavier.setoain@arm.com        return new Unknown64(machInst);
24114106Sjavier.setoain@arm.com    }
24214106Sjavier.setoain@arm.com
24314106Sjavier.setoain@arm.com    StaticInstPtr
24414106Sjavier.setoain@arm.com    decodeSveStructLoadSIInsts(uint8_t esize, ExtMachInst machInst,
24514106Sjavier.setoain@arm.com            IntRegIndex zt, IntRegIndex pg, IntRegIndex xn,
24614106Sjavier.setoain@arm.com            int64_t imm, int numregs)
24714106Sjavier.setoain@arm.com    {
24814106Sjavier.setoain@arm.com        switch (esize) {
24914106Sjavier.setoain@arm.com            case 0:
25014106Sjavier.setoain@arm.com                return decodeSveStructLoadSIInstsByNReg<uint8_t>(esize,
25114106Sjavier.setoain@arm.com                        machInst, zt, pg, xn, imm, numregs);
25214106Sjavier.setoain@arm.com            case 1:
25314106Sjavier.setoain@arm.com                return decodeSveStructLoadSIInstsByNReg<uint16_t>(esize,
25414106Sjavier.setoain@arm.com                        machInst, zt, pg, xn, imm, numregs);
25514106Sjavier.setoain@arm.com            case 2:
25614106Sjavier.setoain@arm.com                return decodeSveStructLoadSIInstsByNReg<uint32_t>(esize,
25714106Sjavier.setoain@arm.com                        machInst, zt, pg, xn, imm, numregs);
25814106Sjavier.setoain@arm.com            case 3:
25914106Sjavier.setoain@arm.com                return decodeSveStructLoadSIInstsByNReg<uint64_t>(esize,
26014106Sjavier.setoain@arm.com                        machInst, zt, pg, xn, imm, numregs);
26114106Sjavier.setoain@arm.com        }
26214106Sjavier.setoain@arm.com        return new Unknown64(machInst);
26314106Sjavier.setoain@arm.com    }
26414106Sjavier.setoain@arm.com
26514106Sjavier.setoain@arm.com    template <class etype>
26614106Sjavier.setoain@arm.com    StaticInstPtr
26714106Sjavier.setoain@arm.com    decodeSveStructStoreSIInstsByNReg(uint8_t esize, ExtMachInst machInst,
26814106Sjavier.setoain@arm.com            IntRegIndex zt, IntRegIndex pg, IntRegIndex xn,
26914106Sjavier.setoain@arm.com            int64_t imm, int numregs)
27014106Sjavier.setoain@arm.com    {
27114106Sjavier.setoain@arm.com        static const char* nm[5][4] = {
27214106Sjavier.setoain@arm.com            { nullptr, nullptr, nullptr, nullptr},
27314106Sjavier.setoain@arm.com            { nullptr, nullptr, nullptr, nullptr},
27414106Sjavier.setoain@arm.com            { "st2b", "st2h", "st2w", "st2d" },
27514106Sjavier.setoain@arm.com            { "st3b", "st3h", "st3w", "st3d" },
27614106Sjavier.setoain@arm.com            { "st4b", "st4h", "st4w", "st4d" } };
27714106Sjavier.setoain@arm.com
27814106Sjavier.setoain@arm.com        switch (numregs) {
27914106Sjavier.setoain@arm.com            case 2:
28014106Sjavier.setoain@arm.com                return new SveStStructSI<etype,
28114106Sjavier.setoain@arm.com                        SveStoreRegImmMicroop,
28214106Sjavier.setoain@arm.com                        SveIntrlv2Microop>(
28314106Sjavier.setoain@arm.com                            nm[numregs][esize], machInst, MemWriteOp,
28414106Sjavier.setoain@arm.com                            zt, pg, xn, imm, numregs);
28514106Sjavier.setoain@arm.com            case 3:
28614106Sjavier.setoain@arm.com                return new SveStStructSI<etype,
28714106Sjavier.setoain@arm.com                        SveStoreRegImmMicroop,
28814106Sjavier.setoain@arm.com                        SveIntrlv3Microop>(
28914106Sjavier.setoain@arm.com                            nm[numregs][esize], machInst, MemWriteOp,
29014106Sjavier.setoain@arm.com                            zt, pg, xn, imm, numregs);
29114106Sjavier.setoain@arm.com           case 4:
29214106Sjavier.setoain@arm.com                return new SveStStructSI<etype,
29314106Sjavier.setoain@arm.com                        SveStoreRegImmMicroop,
29414106Sjavier.setoain@arm.com                        SveIntrlv4Microop>(
29514106Sjavier.setoain@arm.com                            nm[numregs][esize], machInst, MemWriteOp,
29614106Sjavier.setoain@arm.com                            zt, pg, xn, imm, numregs);
29714106Sjavier.setoain@arm.com        }
29814106Sjavier.setoain@arm.com        return new Unknown64(machInst);
29914106Sjavier.setoain@arm.com    }
30014106Sjavier.setoain@arm.com
30114106Sjavier.setoain@arm.com    StaticInstPtr
30214106Sjavier.setoain@arm.com    decodeSveStructStoreSIInsts(uint8_t esize, ExtMachInst machInst,
30314106Sjavier.setoain@arm.com            IntRegIndex zt, IntRegIndex pg, IntRegIndex xn,
30414106Sjavier.setoain@arm.com            int64_t imm, int numregs)
30514106Sjavier.setoain@arm.com    {
30614106Sjavier.setoain@arm.com        switch (esize) {
30714106Sjavier.setoain@arm.com            case 0:
30814106Sjavier.setoain@arm.com                return decodeSveStructStoreSIInstsByNReg<uint8_t>(esize,
30914106Sjavier.setoain@arm.com                    machInst, zt, pg, xn, imm, numregs);
31014106Sjavier.setoain@arm.com            case 1:
31114106Sjavier.setoain@arm.com                return decodeSveStructStoreSIInstsByNReg<uint16_t>(esize,
31214106Sjavier.setoain@arm.com                    machInst, zt, pg, xn, imm, numregs);
31314106Sjavier.setoain@arm.com            case 2:
31414106Sjavier.setoain@arm.com                return decodeSveStructStoreSIInstsByNReg<uint32_t>(esize,
31514106Sjavier.setoain@arm.com                    machInst, zt, pg, xn, imm, numregs);
31614106Sjavier.setoain@arm.com            case 3:
31714106Sjavier.setoain@arm.com                return decodeSveStructStoreSIInstsByNReg<uint64_t>(esize,
31814106Sjavier.setoain@arm.com                    machInst, zt, pg, xn, imm, numregs);
31914106Sjavier.setoain@arm.com        }
32014106Sjavier.setoain@arm.com        return new Unknown64(machInst);
32114106Sjavier.setoain@arm.com    }
32214106Sjavier.setoain@arm.com
32314106Sjavier.setoain@arm.com    template <class etype>
32414106Sjavier.setoain@arm.com    StaticInstPtr
32514106Sjavier.setoain@arm.com    decodeSveStructLoadSSInstsByNReg(uint8_t esize, ExtMachInst machInst,
32614106Sjavier.setoain@arm.com            IntRegIndex zt, IntRegIndex pg, IntRegIndex xn,
32714106Sjavier.setoain@arm.com            IntRegIndex xm, int numregs)
32814106Sjavier.setoain@arm.com    {
32914106Sjavier.setoain@arm.com        static const char* nm[5][4] = {
33014106Sjavier.setoain@arm.com            { nullptr, nullptr, nullptr, nullptr},
33114106Sjavier.setoain@arm.com            { nullptr, nullptr, nullptr, nullptr},
33214106Sjavier.setoain@arm.com            { "ld2b", "ld2h", "ld2w", "ld2d" },
33314106Sjavier.setoain@arm.com            { "ld3b", "ld3h", "ld3w", "ld3d" },
33414106Sjavier.setoain@arm.com            { "ld4b", "ld4h", "ld4w", "ld4d" } };
33514106Sjavier.setoain@arm.com
33614106Sjavier.setoain@arm.com        switch (numregs) {
33714106Sjavier.setoain@arm.com            case 2:
33814106Sjavier.setoain@arm.com                return new SveLdStructSS<etype,
33914106Sjavier.setoain@arm.com                        SveLoadRegRegMicroop,
34014106Sjavier.setoain@arm.com                        SveDeIntrlv2Microop>(
34114106Sjavier.setoain@arm.com                               nm[numregs][esize], machInst, MemReadOp,
34214106Sjavier.setoain@arm.com                               zt, pg, xn, xm, numregs);
34314106Sjavier.setoain@arm.com            case 3:
34414106Sjavier.setoain@arm.com                return new SveLdStructSS<etype,
34514106Sjavier.setoain@arm.com                        SveLoadRegRegMicroop,
34614106Sjavier.setoain@arm.com                        SveDeIntrlv3Microop>(
34714106Sjavier.setoain@arm.com                               nm[numregs][esize], machInst, MemReadOp,
34814106Sjavier.setoain@arm.com                               zt, pg, xn, xm, numregs);
34914106Sjavier.setoain@arm.com            case 4:
35014106Sjavier.setoain@arm.com                return new SveLdStructSS<etype,
35114106Sjavier.setoain@arm.com                        SveLoadRegRegMicroop,
35214106Sjavier.setoain@arm.com                        SveDeIntrlv4Microop>(
35314106Sjavier.setoain@arm.com                               nm[numregs][esize], machInst, MemReadOp,
35414106Sjavier.setoain@arm.com                               zt, pg, xn, xm, numregs);
35514106Sjavier.setoain@arm.com        }
35614106Sjavier.setoain@arm.com        return new Unknown64(machInst);
35714106Sjavier.setoain@arm.com    }
35814106Sjavier.setoain@arm.com
35914106Sjavier.setoain@arm.com    StaticInstPtr
36014106Sjavier.setoain@arm.com    decodeSveStructLoadSSInsts(uint8_t esize, ExtMachInst machInst,
36114106Sjavier.setoain@arm.com            IntRegIndex zt, IntRegIndex pg, IntRegIndex xn,
36214106Sjavier.setoain@arm.com            IntRegIndex xm, int numregs)
36314106Sjavier.setoain@arm.com    {
36414106Sjavier.setoain@arm.com        switch (esize) {
36514106Sjavier.setoain@arm.com            case 0:
36614106Sjavier.setoain@arm.com                return decodeSveStructLoadSSInstsByNReg<uint8_t>(esize,
36714106Sjavier.setoain@arm.com                            machInst, zt, pg, xn, xm, numregs);
36814106Sjavier.setoain@arm.com            case 1:
36914106Sjavier.setoain@arm.com                return decodeSveStructLoadSSInstsByNReg<uint16_t>(esize,
37014106Sjavier.setoain@arm.com                            machInst, zt, pg, xn, xm, numregs);
37114106Sjavier.setoain@arm.com            case 2:
37214106Sjavier.setoain@arm.com                return decodeSveStructLoadSSInstsByNReg<uint32_t>(esize,
37314106Sjavier.setoain@arm.com                            machInst, zt, pg, xn, xm, numregs);
37414106Sjavier.setoain@arm.com            case 3:
37514106Sjavier.setoain@arm.com                return decodeSveStructLoadSSInstsByNReg<uint64_t>(esize,
37614106Sjavier.setoain@arm.com                            machInst, zt, pg, xn, xm, numregs);
37714106Sjavier.setoain@arm.com        }
37814106Sjavier.setoain@arm.com        return new Unknown64(machInst);
37914106Sjavier.setoain@arm.com    }
38014106Sjavier.setoain@arm.com
38114106Sjavier.setoain@arm.com    template <class etype>
38214106Sjavier.setoain@arm.com    StaticInstPtr
38314106Sjavier.setoain@arm.com    decodeSveStructStoreSSInstsByNReg(uint8_t esize, ExtMachInst machInst,
38414106Sjavier.setoain@arm.com            IntRegIndex zt, IntRegIndex pg, IntRegIndex xn,
38514106Sjavier.setoain@arm.com            IntRegIndex xm, int numregs)
38614106Sjavier.setoain@arm.com    {
38714106Sjavier.setoain@arm.com        static const char* nm[5][4] = {
38814106Sjavier.setoain@arm.com            { nullptr, nullptr, nullptr, nullptr},
38914106Sjavier.setoain@arm.com            { nullptr, nullptr, nullptr, nullptr},
39014106Sjavier.setoain@arm.com            { "st2b", "st2h", "st2w", "st2d" },
39114106Sjavier.setoain@arm.com            { "st3b", "st3h", "st3w", "st3d" },
39214106Sjavier.setoain@arm.com            { "st4b", "st4h", "st4w", "st4d" } };
39314106Sjavier.setoain@arm.com
39414106Sjavier.setoain@arm.com        switch (numregs) {
39514106Sjavier.setoain@arm.com            case 2:
39614106Sjavier.setoain@arm.com                return new SveStStructSS<etype,
39714106Sjavier.setoain@arm.com                        SveStoreRegRegMicroop,
39814106Sjavier.setoain@arm.com                        SveIntrlv2Microop>(
39914106Sjavier.setoain@arm.com                               nm[numregs][esize], machInst, MemWriteOp,
40014106Sjavier.setoain@arm.com                               zt, pg, xn, xm, numregs);
40114106Sjavier.setoain@arm.com            case 3:
40214106Sjavier.setoain@arm.com                return new SveStStructSS<etype,
40314106Sjavier.setoain@arm.com                        SveStoreRegRegMicroop,
40414106Sjavier.setoain@arm.com                        SveIntrlv3Microop>(
40514106Sjavier.setoain@arm.com                               nm[numregs][esize], machInst, MemWriteOp,
40614106Sjavier.setoain@arm.com                               zt, pg, xn, xm, numregs);
40714106Sjavier.setoain@arm.com            case 4:
40814106Sjavier.setoain@arm.com                return new SveStStructSS<etype,
40914106Sjavier.setoain@arm.com                        SveStoreRegRegMicroop,
41014106Sjavier.setoain@arm.com                        SveIntrlv4Microop>(
41114106Sjavier.setoain@arm.com                               nm[numregs][esize], machInst, MemWriteOp,
41214106Sjavier.setoain@arm.com                               zt, pg, xn, xm, numregs);
41314106Sjavier.setoain@arm.com        }
41414106Sjavier.setoain@arm.com        return new Unknown64(machInst);
41514106Sjavier.setoain@arm.com    }
41614106Sjavier.setoain@arm.com
41714106Sjavier.setoain@arm.com    StaticInstPtr
41814106Sjavier.setoain@arm.com    decodeSveStructStoreSSInsts(uint8_t esize, ExtMachInst machInst,
41914106Sjavier.setoain@arm.com            IntRegIndex zt, IntRegIndex pg, IntRegIndex xn,
42014106Sjavier.setoain@arm.com            IntRegIndex xm, int numregs)
42114106Sjavier.setoain@arm.com    {
42214106Sjavier.setoain@arm.com        switch (esize) {
42314106Sjavier.setoain@arm.com            case 0:
42414106Sjavier.setoain@arm.com                return decodeSveStructStoreSSInstsByNReg<uint8_t>(esize,
42514106Sjavier.setoain@arm.com                            machInst, zt, pg, xn, xm, numregs);
42614106Sjavier.setoain@arm.com            case 1:
42714106Sjavier.setoain@arm.com                return decodeSveStructStoreSSInstsByNReg<uint16_t>(esize,
42814106Sjavier.setoain@arm.com                            machInst, zt, pg, xn, xm, numregs);
42914106Sjavier.setoain@arm.com            case 2:
43014106Sjavier.setoain@arm.com                return decodeSveStructStoreSSInstsByNReg<uint32_t>(esize,
43114106Sjavier.setoain@arm.com                            machInst, zt, pg, xn, xm, numregs);
43214106Sjavier.setoain@arm.com            case 3:
43314106Sjavier.setoain@arm.com                return decodeSveStructStoreSSInstsByNReg<uint64_t>(esize,
43414106Sjavier.setoain@arm.com                            machInst, zt, pg, xn, xm, numregs);
43514106Sjavier.setoain@arm.com        }
43614106Sjavier.setoain@arm.com        return new Unknown64(machInst);
43714106Sjavier.setoain@arm.com    }
43814106Sjavier.setoain@arm.com
43914028Sgiacomo.gabrielli@arm.com    StaticInstPtr
44014028Sgiacomo.gabrielli@arm.com    decodeSveGatherLoadVIInsts(uint8_t dtype, ExtMachInst machInst,
44114028Sgiacomo.gabrielli@arm.com                               IntRegIndex zt, IntRegIndex pg, IntRegIndex zn,
44214028Sgiacomo.gabrielli@arm.com                               uint64_t imm, bool esizeIs32,
44314091Sgabor.dozsa@arm.com                               bool firstFault)
44414028Sgiacomo.gabrielli@arm.com    {
44514091Sgabor.dozsa@arm.com        const char* mn = firstFault ? "ldff1" : "ld1";
44614028Sgiacomo.gabrielli@arm.com        switch (dtype) {
44714028Sgiacomo.gabrielli@arm.com          case 0x0:
44814028Sgiacomo.gabrielli@arm.com            if (esizeIs32) {
44914028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemVI<int32_t, int8_t,
45014091Sgabor.dozsa@arm.com                                           SveGatherLoadVIMicroop,
45114091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
45214091Sgabor.dozsa@arm.com                    mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
45314028Sgiacomo.gabrielli@arm.com            } else {
45414028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemVI<int64_t, int8_t,
45514091Sgabor.dozsa@arm.com                                           SveGatherLoadVIMicroop,
45614091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
45714091Sgabor.dozsa@arm.com                    mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
45814028Sgiacomo.gabrielli@arm.com            }
45914028Sgiacomo.gabrielli@arm.com          case 0x1:
46014028Sgiacomo.gabrielli@arm.com            if (esizeIs32) {
46114028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemVI<uint32_t, uint8_t,
46214091Sgabor.dozsa@arm.com                                           SveGatherLoadVIMicroop,
46314091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
46414091Sgabor.dozsa@arm.com                    mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
46514028Sgiacomo.gabrielli@arm.com            } else {
46614028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemVI<uint64_t, uint8_t,
46714091Sgabor.dozsa@arm.com                                           SveGatherLoadVIMicroop,
46814091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
46914091Sgabor.dozsa@arm.com                    mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
47014028Sgiacomo.gabrielli@arm.com            }
47114028Sgiacomo.gabrielli@arm.com          case 0x2:
47214028Sgiacomo.gabrielli@arm.com            if (esizeIs32) {
47314028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemVI<int32_t, int16_t,
47414091Sgabor.dozsa@arm.com                                           SveGatherLoadVIMicroop,
47514091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
47614091Sgabor.dozsa@arm.com                    mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
47714028Sgiacomo.gabrielli@arm.com            } else {
47814028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemVI<int64_t, int16_t,
47914091Sgabor.dozsa@arm.com                                           SveGatherLoadVIMicroop,
48014091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
48114091Sgabor.dozsa@arm.com                    mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
48214028Sgiacomo.gabrielli@arm.com            }
48314028Sgiacomo.gabrielli@arm.com          case 0x3:
48414028Sgiacomo.gabrielli@arm.com            if (esizeIs32) {
48514028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemVI<uint32_t, uint16_t,
48614091Sgabor.dozsa@arm.com                                           SveGatherLoadVIMicroop,
48714091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
48814091Sgabor.dozsa@arm.com                    mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
48914028Sgiacomo.gabrielli@arm.com            } else {
49014028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemVI<uint64_t, uint16_t,
49114091Sgabor.dozsa@arm.com                                           SveGatherLoadVIMicroop,
49214091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
49314091Sgabor.dozsa@arm.com                    mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
49414028Sgiacomo.gabrielli@arm.com            }
49514028Sgiacomo.gabrielli@arm.com          case 0x4:
49614028Sgiacomo.gabrielli@arm.com            if (esizeIs32) {
49714028Sgiacomo.gabrielli@arm.com                break;
49814028Sgiacomo.gabrielli@arm.com            } else {
49914028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemVI<int64_t, int32_t,
50014091Sgabor.dozsa@arm.com                                           SveGatherLoadVIMicroop,
50114091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
50214091Sgabor.dozsa@arm.com                    mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
50314028Sgiacomo.gabrielli@arm.com            }
50414028Sgiacomo.gabrielli@arm.com          case 0x5:
50514028Sgiacomo.gabrielli@arm.com            if (esizeIs32) {
50614028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemVI<uint32_t, uint32_t,
50714091Sgabor.dozsa@arm.com                                           SveGatherLoadVIMicroop,
50814091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
50914091Sgabor.dozsa@arm.com                    mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
51014028Sgiacomo.gabrielli@arm.com            } else {
51114028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemVI<uint64_t, uint32_t,
51214091Sgabor.dozsa@arm.com                                           SveGatherLoadVIMicroop,
51314091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
51414091Sgabor.dozsa@arm.com                    mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
51514028Sgiacomo.gabrielli@arm.com            }
51614028Sgiacomo.gabrielli@arm.com          case 0x7:
51714028Sgiacomo.gabrielli@arm.com            if (esizeIs32) {
51814028Sgiacomo.gabrielli@arm.com                break;
51914028Sgiacomo.gabrielli@arm.com            } else {
52014028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemVI<uint64_t, uint64_t,
52114091Sgabor.dozsa@arm.com                                           SveGatherLoadVIMicroop,
52214091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
52314091Sgabor.dozsa@arm.com                    mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
52414028Sgiacomo.gabrielli@arm.com            }
52514028Sgiacomo.gabrielli@arm.com        }
52614028Sgiacomo.gabrielli@arm.com        return new Unknown64(machInst);
52714028Sgiacomo.gabrielli@arm.com    }
52814028Sgiacomo.gabrielli@arm.com
52914028Sgiacomo.gabrielli@arm.com    StaticInstPtr
53014028Sgiacomo.gabrielli@arm.com    decodeSveGatherLoadSVInsts(uint8_t dtype, ExtMachInst machInst,
53114028Sgiacomo.gabrielli@arm.com                               IntRegIndex zt, IntRegIndex pg, IntRegIndex rn,
53214028Sgiacomo.gabrielli@arm.com                               IntRegIndex zm, bool esizeIs32, bool offsetIs32,
53314028Sgiacomo.gabrielli@arm.com                               bool offsetIsSigned, bool offsetIsScaled,
53414091Sgabor.dozsa@arm.com                               bool firstFault)
53514028Sgiacomo.gabrielli@arm.com    {
53614091Sgabor.dozsa@arm.com        const char* mn = firstFault ? "ldff1" : "ld1";
53714028Sgiacomo.gabrielli@arm.com        switch (dtype) {
53814028Sgiacomo.gabrielli@arm.com          case 0x0:
53914028Sgiacomo.gabrielli@arm.com            if (esizeIs32) {
54014028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemSV<int32_t, int8_t,
54114091Sgabor.dozsa@arm.com                                           SveGatherLoadSVMicroop,
54214091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
54314028Sgiacomo.gabrielli@arm.com                    mn, machInst, MemReadOp, zt, pg, rn, zm,
54414091Sgabor.dozsa@arm.com                    offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
54514028Sgiacomo.gabrielli@arm.com            } else {
54614028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemSV<int64_t, int8_t,
54714091Sgabor.dozsa@arm.com                                           SveGatherLoadSVMicroop,
54814091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
54914028Sgiacomo.gabrielli@arm.com                    mn, machInst, MemReadOp, zt, pg, rn, zm,
55014091Sgabor.dozsa@arm.com                    offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
55114028Sgiacomo.gabrielli@arm.com            }
55214028Sgiacomo.gabrielli@arm.com          case 0x1:
55314028Sgiacomo.gabrielli@arm.com            if (esizeIs32) {
55414028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemSV<uint32_t, uint8_t,
55514091Sgabor.dozsa@arm.com                                           SveGatherLoadSVMicroop,
55614091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
55714028Sgiacomo.gabrielli@arm.com                    mn, machInst, MemReadOp, zt, pg, rn, zm,
55814091Sgabor.dozsa@arm.com                    offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
55914028Sgiacomo.gabrielli@arm.com            } else {
56014028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemSV<uint64_t, uint8_t,
56114091Sgabor.dozsa@arm.com                                           SveGatherLoadSVMicroop,
56214091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
56314028Sgiacomo.gabrielli@arm.com                    mn, machInst, MemReadOp, zt, pg, rn, zm,
56414091Sgabor.dozsa@arm.com                    offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
56514028Sgiacomo.gabrielli@arm.com            }
56614028Sgiacomo.gabrielli@arm.com          case 0x2:
56714028Sgiacomo.gabrielli@arm.com            if (esizeIs32) {
56814028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemSV<int32_t, int16_t,
56914091Sgabor.dozsa@arm.com                                           SveGatherLoadSVMicroop,
57014091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
57114028Sgiacomo.gabrielli@arm.com                    mn, machInst, MemReadOp, zt, pg, rn, zm,
57214091Sgabor.dozsa@arm.com                    offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
57314028Sgiacomo.gabrielli@arm.com            } else {
57414028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemSV<int64_t, int16_t,
57514091Sgabor.dozsa@arm.com                                           SveGatherLoadSVMicroop,
57614091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
57714028Sgiacomo.gabrielli@arm.com                    mn, machInst, MemReadOp, zt, pg, rn, zm,
57814091Sgabor.dozsa@arm.com                    offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
57914028Sgiacomo.gabrielli@arm.com            }
58014028Sgiacomo.gabrielli@arm.com          case 0x3:
58114028Sgiacomo.gabrielli@arm.com            if (esizeIs32) {
58214028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemSV<uint32_t, uint16_t,
58314091Sgabor.dozsa@arm.com                                           SveGatherLoadSVMicroop,
58414091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
58514028Sgiacomo.gabrielli@arm.com                    mn, machInst, MemReadOp, zt, pg, rn, zm,
58614091Sgabor.dozsa@arm.com                    offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
58714028Sgiacomo.gabrielli@arm.com            } else {
58814028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemSV<uint64_t, uint16_t,
58914091Sgabor.dozsa@arm.com                                           SveGatherLoadSVMicroop,
59014091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
59114028Sgiacomo.gabrielli@arm.com                    mn, machInst, MemReadOp, zt, pg, rn, zm,
59214091Sgabor.dozsa@arm.com                    offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
59314028Sgiacomo.gabrielli@arm.com            }
59414028Sgiacomo.gabrielli@arm.com          case 0x4:
59514028Sgiacomo.gabrielli@arm.com            if (esizeIs32) {
59614028Sgiacomo.gabrielli@arm.com                break;
59714028Sgiacomo.gabrielli@arm.com            } else {
59814028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemSV<int64_t, int32_t,
59914091Sgabor.dozsa@arm.com                                           SveGatherLoadSVMicroop,
60014091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
60114028Sgiacomo.gabrielli@arm.com                    mn, machInst, MemReadOp, zt, pg, rn, zm,
60214091Sgabor.dozsa@arm.com                    offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
60314028Sgiacomo.gabrielli@arm.com            }
60414028Sgiacomo.gabrielli@arm.com          case 0x5:
60514028Sgiacomo.gabrielli@arm.com            if (esizeIs32) {
60614028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemSV<uint32_t, uint32_t,
60714091Sgabor.dozsa@arm.com                                           SveGatherLoadSVMicroop,
60814091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
60914028Sgiacomo.gabrielli@arm.com                    mn, machInst, MemReadOp, zt, pg, rn, zm,
61014091Sgabor.dozsa@arm.com                    offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
61114028Sgiacomo.gabrielli@arm.com            } else {
61214028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemSV<uint64_t, uint32_t,
61314091Sgabor.dozsa@arm.com                                           SveGatherLoadSVMicroop,
61414091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
61514028Sgiacomo.gabrielli@arm.com                    mn, machInst, MemReadOp, zt, pg, rn, zm,
61614091Sgabor.dozsa@arm.com                    offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
61714028Sgiacomo.gabrielli@arm.com            }
61814028Sgiacomo.gabrielli@arm.com          case 0x7:
61914028Sgiacomo.gabrielli@arm.com            if (esizeIs32) {
62014028Sgiacomo.gabrielli@arm.com                break;
62114028Sgiacomo.gabrielli@arm.com            } else {
62214028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemSV<uint64_t, uint64_t,
62314091Sgabor.dozsa@arm.com                                           SveGatherLoadSVMicroop,
62414091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
62514028Sgiacomo.gabrielli@arm.com                    mn, machInst, MemReadOp, zt, pg, rn, zm,
62614091Sgabor.dozsa@arm.com                    offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
62714028Sgiacomo.gabrielli@arm.com            }
62814028Sgiacomo.gabrielli@arm.com        }
62914028Sgiacomo.gabrielli@arm.com        return new Unknown64(machInst);
63014028Sgiacomo.gabrielli@arm.com    }
63114028Sgiacomo.gabrielli@arm.com
63214028Sgiacomo.gabrielli@arm.com    StaticInstPtr
63314028Sgiacomo.gabrielli@arm.com    decodeSveScatterStoreVIInsts(uint8_t msz, ExtMachInst machInst,
63414028Sgiacomo.gabrielli@arm.com                                 IntRegIndex zt, IntRegIndex pg,
63514028Sgiacomo.gabrielli@arm.com                                 IntRegIndex zn, uint64_t imm,
63614028Sgiacomo.gabrielli@arm.com                                 bool esizeIs32)
63714028Sgiacomo.gabrielli@arm.com    {
63814028Sgiacomo.gabrielli@arm.com        const char* mn = "st1";
63914028Sgiacomo.gabrielli@arm.com        switch (msz) {
64014028Sgiacomo.gabrielli@arm.com          case 0x0:
64114028Sgiacomo.gabrielli@arm.com            if (esizeIs32) {
64214028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemVI<uint32_t, uint8_t,
64314091Sgabor.dozsa@arm.com                                           SveScatterStoreVIMicroop,
64414091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
64514091Sgabor.dozsa@arm.com                    mn, machInst, MemWriteOp, zt, pg, zn, imm, false);
64614028Sgiacomo.gabrielli@arm.com            } else {
64714028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemVI<uint64_t, uint8_t,
64814091Sgabor.dozsa@arm.com                                           SveScatterStoreVIMicroop,
64914091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
65014091Sgabor.dozsa@arm.com                    mn, machInst, MemWriteOp, zt, pg, zn, imm, false);
65114028Sgiacomo.gabrielli@arm.com            }
65214028Sgiacomo.gabrielli@arm.com          case 0x1:
65314028Sgiacomo.gabrielli@arm.com            if (esizeIs32) {
65414028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemVI<uint32_t, uint16_t,
65514091Sgabor.dozsa@arm.com                                           SveScatterStoreVIMicroop,
65614091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
65714091Sgabor.dozsa@arm.com                    mn, machInst, MemWriteOp, zt, pg, zn, imm, false);
65814028Sgiacomo.gabrielli@arm.com            } else {
65914028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemVI<uint64_t, uint16_t,
66014091Sgabor.dozsa@arm.com                                           SveScatterStoreVIMicroop,
66114091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
66214091Sgabor.dozsa@arm.com                    mn, machInst, MemWriteOp, zt, pg, zn, imm, false);
66314028Sgiacomo.gabrielli@arm.com            }
66414028Sgiacomo.gabrielli@arm.com          case 0x2:
66514028Sgiacomo.gabrielli@arm.com            if (esizeIs32) {
66614028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemVI<uint32_t, uint32_t,
66714091Sgabor.dozsa@arm.com                                           SveScatterStoreVIMicroop,
66814091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
66914091Sgabor.dozsa@arm.com                    mn, machInst, MemWriteOp, zt, pg, zn, imm, false);
67014028Sgiacomo.gabrielli@arm.com            } else {
67114028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemVI<uint64_t, uint32_t,
67214091Sgabor.dozsa@arm.com                                           SveScatterStoreVIMicroop,
67314091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
67414091Sgabor.dozsa@arm.com                    mn, machInst, MemWriteOp, zt, pg, zn, imm, false);
67514028Sgiacomo.gabrielli@arm.com            }
67614028Sgiacomo.gabrielli@arm.com          case 0x3:
67714028Sgiacomo.gabrielli@arm.com            if (esizeIs32) {
67814028Sgiacomo.gabrielli@arm.com                break;
67914028Sgiacomo.gabrielli@arm.com            } else {
68014028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemVI<uint64_t, uint64_t,
68114091Sgabor.dozsa@arm.com                                           SveScatterStoreVIMicroop,
68214091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
68314091Sgabor.dozsa@arm.com                    mn, machInst, MemWriteOp, zt, pg, zn, imm, false);
68414028Sgiacomo.gabrielli@arm.com            }
68514028Sgiacomo.gabrielli@arm.com        }
68614028Sgiacomo.gabrielli@arm.com        return new Unknown64(machInst);
68714028Sgiacomo.gabrielli@arm.com    }
68814028Sgiacomo.gabrielli@arm.com
68914028Sgiacomo.gabrielli@arm.com    StaticInstPtr
69014028Sgiacomo.gabrielli@arm.com    decodeSveScatterStoreSVInsts(uint8_t msz, ExtMachInst machInst,
69114028Sgiacomo.gabrielli@arm.com                                 IntRegIndex zt, IntRegIndex pg,
69214028Sgiacomo.gabrielli@arm.com                                 IntRegIndex rn, IntRegIndex zm,
69314028Sgiacomo.gabrielli@arm.com                                 bool esizeIs32, bool offsetIs32,
69414028Sgiacomo.gabrielli@arm.com                                 bool offsetIsSigned, bool offsetIsScaled)
69514028Sgiacomo.gabrielli@arm.com    {
69614028Sgiacomo.gabrielli@arm.com        const char* mn = "st1";
69714028Sgiacomo.gabrielli@arm.com        switch (msz) {
69814028Sgiacomo.gabrielli@arm.com          case 0x0:
69914028Sgiacomo.gabrielli@arm.com            if (esizeIs32) {
70014028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemSV<uint32_t, uint8_t,
70114091Sgabor.dozsa@arm.com                                           SveScatterStoreSVMicroop,
70214091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
70314028Sgiacomo.gabrielli@arm.com                    mn, machInst, MemWriteOp, zt, pg, rn, zm,
70414091Sgabor.dozsa@arm.com                    offsetIs32, offsetIsSigned, offsetIsScaled, false);
70514028Sgiacomo.gabrielli@arm.com            } else {
70614028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemSV<uint64_t, uint8_t,
70714091Sgabor.dozsa@arm.com                                           SveScatterStoreSVMicroop,
70814091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
70914028Sgiacomo.gabrielli@arm.com                    mn, machInst, MemWriteOp, zt, pg, rn, zm,
71014091Sgabor.dozsa@arm.com                    offsetIs32, offsetIsSigned, offsetIsScaled, false);
71114028Sgiacomo.gabrielli@arm.com            }
71214028Sgiacomo.gabrielli@arm.com          case 0x1:
71314028Sgiacomo.gabrielli@arm.com            if (esizeIs32) {
71414028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemSV<uint32_t, uint16_t,
71514091Sgabor.dozsa@arm.com                                           SveScatterStoreSVMicroop,
71614091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
71714028Sgiacomo.gabrielli@arm.com                    mn, machInst, MemWriteOp, zt, pg, rn, zm,
71814091Sgabor.dozsa@arm.com                    offsetIs32, offsetIsSigned, offsetIsScaled, false);
71914028Sgiacomo.gabrielli@arm.com            } else {
72014028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemSV<uint64_t, uint16_t,
72114091Sgabor.dozsa@arm.com                                           SveScatterStoreSVMicroop,
72214091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
72314028Sgiacomo.gabrielli@arm.com                    mn, machInst, MemWriteOp, zt, pg, rn, zm,
72414091Sgabor.dozsa@arm.com                    offsetIs32, offsetIsSigned, offsetIsScaled, false);
72514028Sgiacomo.gabrielli@arm.com            }
72614028Sgiacomo.gabrielli@arm.com          case 0x2:
72714028Sgiacomo.gabrielli@arm.com            if (esizeIs32) {
72814028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemSV<uint32_t, uint32_t,
72914091Sgabor.dozsa@arm.com                                           SveScatterStoreSVMicroop,
73014091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
73114028Sgiacomo.gabrielli@arm.com                    mn, machInst, MemWriteOp, zt, pg, rn, zm,
73214091Sgabor.dozsa@arm.com                    offsetIs32, offsetIsSigned, offsetIsScaled, false);
73314028Sgiacomo.gabrielli@arm.com            } else {
73414028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemSV<uint64_t, uint32_t,
73514091Sgabor.dozsa@arm.com                                           SveScatterStoreSVMicroop,
73614091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
73714028Sgiacomo.gabrielli@arm.com                    mn, machInst, MemWriteOp, zt, pg, rn, zm,
73814091Sgabor.dozsa@arm.com                    offsetIs32, offsetIsSigned, offsetIsScaled, false);
73914028Sgiacomo.gabrielli@arm.com            }
74014028Sgiacomo.gabrielli@arm.com          case 0x3:
74114028Sgiacomo.gabrielli@arm.com            if (esizeIs32) {
74214028Sgiacomo.gabrielli@arm.com                break;
74314028Sgiacomo.gabrielli@arm.com            } else {
74414028Sgiacomo.gabrielli@arm.com                return new SveIndexedMemSV<uint64_t, uint64_t,
74514091Sgabor.dozsa@arm.com                                           SveScatterStoreSVMicroop,
74614091Sgabor.dozsa@arm.com                                           SveFirstFaultWritebackMicroop>(
74714028Sgiacomo.gabrielli@arm.com                    mn, machInst, MemWriteOp, zt, pg, rn, zm,
74814091Sgabor.dozsa@arm.com                    offsetIs32, offsetIsSigned, offsetIsScaled, false);
74914028Sgiacomo.gabrielli@arm.com            }
75014028Sgiacomo.gabrielli@arm.com        }
75114028Sgiacomo.gabrielli@arm.com        return new Unknown64(machInst);
75214028Sgiacomo.gabrielli@arm.com    }
75314028Sgiacomo.gabrielli@arm.com
75414028Sgiacomo.gabrielli@arm.com}};
75514028Sgiacomo.gabrielli@arm.com
75614028Sgiacomo.gabrielli@arm.com
75713955Sgiacomo.gabrielli@arm.comlet {{
75813955Sgiacomo.gabrielli@arm.com
75913955Sgiacomo.gabrielli@arm.com    header_output = ''
76013955Sgiacomo.gabrielli@arm.com    exec_output = ''
76113955Sgiacomo.gabrielli@arm.com    decoders = { 'Generic': {} }
76213955Sgiacomo.gabrielli@arm.com
76313955Sgiacomo.gabrielli@arm.com    SPAlignmentCheckCode = '''
76413955Sgiacomo.gabrielli@arm.com        if (this->baseIsSP && bits(XBase, 3, 0) &&
76513955Sgiacomo.gabrielli@arm.com            SPAlignmentCheckEnabled(xc->tcBase())) {
76613955Sgiacomo.gabrielli@arm.com            return std::make_shared<SPAlignmentFault>();
76713955Sgiacomo.gabrielli@arm.com        }
76813955Sgiacomo.gabrielli@arm.com    '''
76913955Sgiacomo.gabrielli@arm.com
77013955Sgiacomo.gabrielli@arm.com    def emitSveMemFillSpill(isPred):
77113955Sgiacomo.gabrielli@arm.com        global header_output, exec_output, decoders
77213955Sgiacomo.gabrielli@arm.com        eaCode = SPAlignmentCheckCode + '''
77313955Sgiacomo.gabrielli@arm.com        int memAccessSize = %(memacc_size)s;
77413955Sgiacomo.gabrielli@arm.com        EA = XBase + ((int64_t) imm * %(memacc_size)s)''' % {
77513955Sgiacomo.gabrielli@arm.com            'memacc_size': 'eCount / 8' if isPred else 'eCount'}
77614091Sgabor.dozsa@arm.com        loadRdEnableCode = '''
77714091Sgabor.dozsa@arm.com        auto rdEn = std::vector<bool>();
77814091Sgabor.dozsa@arm.com        '''
77913955Sgiacomo.gabrielli@arm.com        if isPred:
78013955Sgiacomo.gabrielli@arm.com            loadMemAccCode = '''
78113955Sgiacomo.gabrielli@arm.com            int index = 0;
78213955Sgiacomo.gabrielli@arm.com            uint8_t byte;
78313955Sgiacomo.gabrielli@arm.com            for (int i = 0; i < eCount / 8; i++) {
78413955Sgiacomo.gabrielli@arm.com                byte = memDataView[i];
78513955Sgiacomo.gabrielli@arm.com                for (int j = 0; j < 8; j++, index++) {
78613955Sgiacomo.gabrielli@arm.com                    PDest_x[index] = (byte >> j) & 1;
78713955Sgiacomo.gabrielli@arm.com                }
78813955Sgiacomo.gabrielli@arm.com            }
78913955Sgiacomo.gabrielli@arm.com            '''
79013955Sgiacomo.gabrielli@arm.com            storeMemAccCode = '''
79113955Sgiacomo.gabrielli@arm.com            int index = 0;
79213955Sgiacomo.gabrielli@arm.com            uint8_t byte;
79313955Sgiacomo.gabrielli@arm.com            for (int i = 0; i < eCount / 8; i++) {
79413955Sgiacomo.gabrielli@arm.com                byte = 0;
79513955Sgiacomo.gabrielli@arm.com                for (int j = 0; j < 8; j++, index++) {
79613955Sgiacomo.gabrielli@arm.com                    byte |= PDest_x[index] << j;
79713955Sgiacomo.gabrielli@arm.com                }
79813955Sgiacomo.gabrielli@arm.com                memDataView[i] = byte;
79913955Sgiacomo.gabrielli@arm.com            }
80013955Sgiacomo.gabrielli@arm.com            '''
80113955Sgiacomo.gabrielli@arm.com            storeWrEnableCode = '''
80213955Sgiacomo.gabrielli@arm.com            auto wrEn = std::vector<bool>(eCount / 8, true);
80313955Sgiacomo.gabrielli@arm.com            '''
80413955Sgiacomo.gabrielli@arm.com        else:
80513955Sgiacomo.gabrielli@arm.com            loadMemAccCode = '''
80613955Sgiacomo.gabrielli@arm.com            for (int i = 0; i < eCount; i++) {
80713955Sgiacomo.gabrielli@arm.com                AA64FpDest_x[i] = memDataView[i];
80813955Sgiacomo.gabrielli@arm.com            }
80913955Sgiacomo.gabrielli@arm.com            '''
81013955Sgiacomo.gabrielli@arm.com            storeMemAccCode = '''
81113955Sgiacomo.gabrielli@arm.com            for (int i = 0; i < eCount; i++) {
81213955Sgiacomo.gabrielli@arm.com                memDataView[i] = AA64FpDest_x[i];
81313955Sgiacomo.gabrielli@arm.com            }
81413955Sgiacomo.gabrielli@arm.com            '''
81513955Sgiacomo.gabrielli@arm.com            storeWrEnableCode = '''
81613955Sgiacomo.gabrielli@arm.com            auto wrEn = std::vector<bool>(sizeof(MemElemType) * eCount, true);
81713955Sgiacomo.gabrielli@arm.com            '''
81813955Sgiacomo.gabrielli@arm.com        loadIop = InstObjParams('ldr',
81913955Sgiacomo.gabrielli@arm.com            'SveLdrPred' if isPred else 'SveLdrVec',
82013955Sgiacomo.gabrielli@arm.com            'SveMemPredFillSpill' if isPred else 'SveMemVecFillSpill',
82113955Sgiacomo.gabrielli@arm.com            {'tpl_header': '',
82213955Sgiacomo.gabrielli@arm.com             'tpl_args': '',
82313955Sgiacomo.gabrielli@arm.com             'memacc_code': loadMemAccCode,
82413955Sgiacomo.gabrielli@arm.com             'ea_code' : sveEnabledCheckCode + eaCode,
82514091Sgabor.dozsa@arm.com             'rden_code' : loadRdEnableCode,
82614091Sgabor.dozsa@arm.com             'fault_code' : '',
82713955Sgiacomo.gabrielli@arm.com             'fa_code' : ''},
82813955Sgiacomo.gabrielli@arm.com            ['IsMemRef', 'IsLoad'])
82913955Sgiacomo.gabrielli@arm.com        storeIop = InstObjParams('str',
83013955Sgiacomo.gabrielli@arm.com            'SveStrPred' if isPred else 'SveStrVec',
83113955Sgiacomo.gabrielli@arm.com            'SveMemPredFillSpill' if isPred else 'SveMemVecFillSpill',
83213955Sgiacomo.gabrielli@arm.com            {'tpl_header': '',
83313955Sgiacomo.gabrielli@arm.com             'tpl_args': '',
83413955Sgiacomo.gabrielli@arm.com             'wren_code': storeWrEnableCode,
83513955Sgiacomo.gabrielli@arm.com             'memacc_code': storeMemAccCode,
83613955Sgiacomo.gabrielli@arm.com             'ea_code' : sveEnabledCheckCode + eaCode,
83713955Sgiacomo.gabrielli@arm.com             'fa_code' : ''},
83813955Sgiacomo.gabrielli@arm.com            ['IsMemRef', 'IsStore'])
83913955Sgiacomo.gabrielli@arm.com        header_output += SveMemFillSpillOpDeclare.subst(loadIop)
84013955Sgiacomo.gabrielli@arm.com        header_output += SveMemFillSpillOpDeclare.subst(storeIop)
84113955Sgiacomo.gabrielli@arm.com        exec_output += (
84213955Sgiacomo.gabrielli@arm.com            SveContigLoadExecute.subst(loadIop) +
84313955Sgiacomo.gabrielli@arm.com            SveContigLoadInitiateAcc.subst(loadIop) +
84413955Sgiacomo.gabrielli@arm.com            SveContigLoadCompleteAcc.subst(loadIop) +
84513955Sgiacomo.gabrielli@arm.com            SveContigStoreExecute.subst(storeIop) +
84613955Sgiacomo.gabrielli@arm.com            SveContigStoreInitiateAcc.subst(storeIop) +
84713955Sgiacomo.gabrielli@arm.com            SveContigStoreCompleteAcc.subst(storeIop))
84813955Sgiacomo.gabrielli@arm.com
84913955Sgiacomo.gabrielli@arm.com    loadTplArgs = (
85013955Sgiacomo.gabrielli@arm.com        ('uint8_t', 'uint8_t'),
85113955Sgiacomo.gabrielli@arm.com        ('uint16_t', 'uint8_t'),
85213955Sgiacomo.gabrielli@arm.com        ('uint32_t', 'uint8_t'),
85313955Sgiacomo.gabrielli@arm.com        ('uint64_t', 'uint8_t'),
85413955Sgiacomo.gabrielli@arm.com        ('int64_t', 'int32_t'),
85513955Sgiacomo.gabrielli@arm.com        ('uint16_t', 'uint16_t'),
85613955Sgiacomo.gabrielli@arm.com        ('uint32_t', 'uint16_t'),
85713955Sgiacomo.gabrielli@arm.com        ('uint64_t', 'uint16_t'),
85813955Sgiacomo.gabrielli@arm.com        ('int64_t', 'int16_t'),
85913955Sgiacomo.gabrielli@arm.com        ('int32_t', 'int16_t'),
86013955Sgiacomo.gabrielli@arm.com        ('uint32_t', 'uint32_t'),
86113955Sgiacomo.gabrielli@arm.com        ('uint64_t', 'uint32_t'),
86213955Sgiacomo.gabrielli@arm.com        ('int64_t', 'int8_t'),
86313955Sgiacomo.gabrielli@arm.com        ('int32_t', 'int8_t'),
86413955Sgiacomo.gabrielli@arm.com        ('int16_t', 'int8_t'),
86513955Sgiacomo.gabrielli@arm.com        ('uint64_t', 'uint64_t'),
86613955Sgiacomo.gabrielli@arm.com    )
86713955Sgiacomo.gabrielli@arm.com
86813955Sgiacomo.gabrielli@arm.com    storeTplArgs = (
86913955Sgiacomo.gabrielli@arm.com        ('uint8_t', 'uint8_t'),
87013955Sgiacomo.gabrielli@arm.com        ('uint16_t', 'uint8_t'),
87113955Sgiacomo.gabrielli@arm.com        ('uint32_t', 'uint8_t'),
87213955Sgiacomo.gabrielli@arm.com        ('uint64_t', 'uint8_t'),
87313955Sgiacomo.gabrielli@arm.com        ('uint16_t', 'uint16_t'),
87413955Sgiacomo.gabrielli@arm.com        ('uint32_t', 'uint16_t'),
87513955Sgiacomo.gabrielli@arm.com        ('uint64_t', 'uint16_t'),
87613955Sgiacomo.gabrielli@arm.com        ('uint32_t', 'uint32_t'),
87713955Sgiacomo.gabrielli@arm.com        ('uint64_t', 'uint32_t'),
87813955Sgiacomo.gabrielli@arm.com        ('uint64_t', 'uint64_t'),
87913955Sgiacomo.gabrielli@arm.com    )
88013955Sgiacomo.gabrielli@arm.com
88114028Sgiacomo.gabrielli@arm.com    gatherLoadTplArgs = (
88214028Sgiacomo.gabrielli@arm.com        ('int32_t', 'int8_t'),
88314028Sgiacomo.gabrielli@arm.com        ('int64_t', 'int8_t'),
88414028Sgiacomo.gabrielli@arm.com        ('uint32_t', 'uint8_t'),
88514028Sgiacomo.gabrielli@arm.com        ('uint64_t', 'uint8_t'),
88614028Sgiacomo.gabrielli@arm.com        ('int32_t', 'int16_t'),
88714028Sgiacomo.gabrielli@arm.com        ('int64_t', 'int16_t'),
88814028Sgiacomo.gabrielli@arm.com        ('uint32_t', 'uint16_t'),
88914028Sgiacomo.gabrielli@arm.com        ('uint64_t', 'uint16_t'),
89014028Sgiacomo.gabrielli@arm.com        ('int64_t', 'int32_t'),
89114028Sgiacomo.gabrielli@arm.com        ('uint32_t', 'uint32_t'),
89214028Sgiacomo.gabrielli@arm.com        ('uint64_t', 'uint32_t'),
89314028Sgiacomo.gabrielli@arm.com        ('uint64_t', 'uint64_t'),
89414028Sgiacomo.gabrielli@arm.com    )
89514028Sgiacomo.gabrielli@arm.com
89614028Sgiacomo.gabrielli@arm.com    scatterStoreTplArgs = (
89714028Sgiacomo.gabrielli@arm.com        ('uint32_t', 'uint8_t'),
89814028Sgiacomo.gabrielli@arm.com        ('uint64_t', 'uint8_t'),
89914028Sgiacomo.gabrielli@arm.com        ('uint32_t', 'uint16_t'),
90014028Sgiacomo.gabrielli@arm.com        ('uint64_t', 'uint16_t'),
90114028Sgiacomo.gabrielli@arm.com        ('uint32_t', 'uint32_t'),
90214028Sgiacomo.gabrielli@arm.com        ('uint64_t', 'uint32_t'),
90314028Sgiacomo.gabrielli@arm.com        ('uint64_t', 'uint64_t'),
90414028Sgiacomo.gabrielli@arm.com    )
90514028Sgiacomo.gabrielli@arm.com
90613955Sgiacomo.gabrielli@arm.com    # Generates definitions for SVE contiguous loads
90713955Sgiacomo.gabrielli@arm.com    def emitSveContigMemInsts(offsetIsImm):
90813955Sgiacomo.gabrielli@arm.com        global header_output, exec_output, decoders
90914091Sgabor.dozsa@arm.com        # First-faulting instructions only have a scalar plus scalar form,
91014091Sgabor.dozsa@arm.com        # while non-faulting instructions only a scalar plus immediate form, so
91114091Sgabor.dozsa@arm.com        # `offsetIsImm` is used to determine which class of instructions is
91214091Sgabor.dozsa@arm.com        # generated
91314091Sgabor.dozsa@arm.com        firstFaulting = not offsetIsImm
91413955Sgiacomo.gabrielli@arm.com        tplHeader = 'template <class RegElemType, class MemElemType>'
91513955Sgiacomo.gabrielli@arm.com        tplArgs = '<RegElemType, MemElemType>'
91613955Sgiacomo.gabrielli@arm.com        eaCode = SPAlignmentCheckCode + '''
91713955Sgiacomo.gabrielli@arm.com        int memAccessSize = eCount * sizeof(MemElemType);
91813955Sgiacomo.gabrielli@arm.com        EA = XBase + '''
91913955Sgiacomo.gabrielli@arm.com        if offsetIsImm:
92013955Sgiacomo.gabrielli@arm.com            eaCode += '((int64_t) this->imm * eCount * sizeof(MemElemType))'
92113955Sgiacomo.gabrielli@arm.com        else:
92213955Sgiacomo.gabrielli@arm.com            eaCode += '(XOffset * sizeof(MemElemType));'
92314091Sgabor.dozsa@arm.com        loadRdEnableCode = '''
92414091Sgabor.dozsa@arm.com        auto rdEn = std::vector<bool>(sizeof(MemElemType) * eCount, true);
92514091Sgabor.dozsa@arm.com        for (int i = 0; i < eCount; i++) {
92614091Sgabor.dozsa@arm.com            if (!GpOp_x[i]) {
92714091Sgabor.dozsa@arm.com                for (int j = 0; j < sizeof(MemElemType); j++) {
92814091Sgabor.dozsa@arm.com                    rdEn[sizeof(MemElemType) * i + j] = false;
92914091Sgabor.dozsa@arm.com                }
93014091Sgabor.dozsa@arm.com            }
93114091Sgabor.dozsa@arm.com        }
93214091Sgabor.dozsa@arm.com        '''
93313955Sgiacomo.gabrielli@arm.com        loadMemAccCode = '''
93413955Sgiacomo.gabrielli@arm.com        for (int i = 0; i < eCount; i++) {
93513955Sgiacomo.gabrielli@arm.com            if (GpOp_x[i]) {
93613955Sgiacomo.gabrielli@arm.com                AA64FpDest_x[i] = memDataView[i];
93713955Sgiacomo.gabrielli@arm.com            } else {
93813955Sgiacomo.gabrielli@arm.com                AA64FpDest_x[i] = 0;
93913955Sgiacomo.gabrielli@arm.com            }
94013955Sgiacomo.gabrielli@arm.com        }
94113955Sgiacomo.gabrielli@arm.com        '''
94213955Sgiacomo.gabrielli@arm.com        storeMemAccCode = '''
94313955Sgiacomo.gabrielli@arm.com        for (int i = 0; i < eCount; i++) {
94413955Sgiacomo.gabrielli@arm.com            if (GpOp_x[i]) {
94513955Sgiacomo.gabrielli@arm.com                memDataView[i] = AA64FpDest_x[i];
94613955Sgiacomo.gabrielli@arm.com            } else {
94713955Sgiacomo.gabrielli@arm.com                memDataView[i] = 0;
94813955Sgiacomo.gabrielli@arm.com                for (int j = 0; j < sizeof(MemElemType); j++) {
94913955Sgiacomo.gabrielli@arm.com                    wrEn[sizeof(MemElemType) * i + j] = false;
95013955Sgiacomo.gabrielli@arm.com                }
95113955Sgiacomo.gabrielli@arm.com            }
95213955Sgiacomo.gabrielli@arm.com        }
95313955Sgiacomo.gabrielli@arm.com        '''
95413955Sgiacomo.gabrielli@arm.com        storeWrEnableCode = '''
95513955Sgiacomo.gabrielli@arm.com        auto wrEn = std::vector<bool>(sizeof(MemElemType) * eCount, true);
95613955Sgiacomo.gabrielli@arm.com        '''
95714091Sgabor.dozsa@arm.com        ffrReadBackCode = '''
95814091Sgabor.dozsa@arm.com        auto& firstFaultReg = Ffr;'''
95914091Sgabor.dozsa@arm.com        fautlingLoadmemAccCode = '''
96014091Sgabor.dozsa@arm.com        for (int i = 0; i < eCount; i++) {
96114091Sgabor.dozsa@arm.com            if (GpOp_x[i] && firstFaultReg[i * sizeof(RegElemType)]) {
96214091Sgabor.dozsa@arm.com                AA64FpDest_x[i] = memDataView[i];
96314091Sgabor.dozsa@arm.com            } else {
96414091Sgabor.dozsa@arm.com                AA64FpDest_x[i] = 0;
96514091Sgabor.dozsa@arm.com            }
96614091Sgabor.dozsa@arm.com        }
96714091Sgabor.dozsa@arm.com        '''
96814091Sgabor.dozsa@arm.com        nonFaultingCode = 'true ||'
96914091Sgabor.dozsa@arm.com        faultCode = '''
97014091Sgabor.dozsa@arm.com        Addr fault_addr;
97114091Sgabor.dozsa@arm.com        if (fault == NoFault || getFaultVAddr(fault, fault_addr)) {
97214091Sgabor.dozsa@arm.com            unsigned fault_elem_index;
97314091Sgabor.dozsa@arm.com            if (fault != NoFault) {
97414091Sgabor.dozsa@arm.com                assert(fault_addr >= EA);
97514091Sgabor.dozsa@arm.com                fault_elem_index = (fault_addr - EA) / sizeof(MemElemType);
97614091Sgabor.dozsa@arm.com            } else {
97714091Sgabor.dozsa@arm.com                fault_elem_index = eCount + 1;
97814091Sgabor.dozsa@arm.com            }
97914091Sgabor.dozsa@arm.com            int first_active_index;
98014091Sgabor.dozsa@arm.com            for (first_active_index = 0;
98114091Sgabor.dozsa@arm.com                 first_active_index < eCount && !(GpOp_x[first_active_index]);
98214091Sgabor.dozsa@arm.com                 first_active_index++);
98314091Sgabor.dozsa@arm.com            if (%s first_active_index < fault_elem_index) {
98414091Sgabor.dozsa@arm.com                for (int i = 0; i < eCount; i++) {
98514091Sgabor.dozsa@arm.com                    for (int j = 0; j < sizeof(RegElemType); j++) {
98614091Sgabor.dozsa@arm.com                        if (i < fault_elem_index) {
98714091Sgabor.dozsa@arm.com                            Ffr_ub[i * sizeof(RegElemType) + j] = FfrAux_x[i];
98814091Sgabor.dozsa@arm.com                        } else {
98914091Sgabor.dozsa@arm.com                            Ffr_ub[i * sizeof(RegElemType) + j] = 0;
99014091Sgabor.dozsa@arm.com                        }
99114091Sgabor.dozsa@arm.com                    }
99214091Sgabor.dozsa@arm.com                }
99314091Sgabor.dozsa@arm.com                fault = NoFault;
99414091Sgabor.dozsa@arm.com                if (first_active_index >= fault_elem_index) {
99514091Sgabor.dozsa@arm.com                    // non-faulting load needs this
99614091Sgabor.dozsa@arm.com                    xc->setMemAccPredicate(false);
99714091Sgabor.dozsa@arm.com                }
99814091Sgabor.dozsa@arm.com            }
99914091Sgabor.dozsa@arm.com        }
100014091Sgabor.dozsa@arm.com        ''' % ('' if firstFaulting else nonFaultingCode)
100114091Sgabor.dozsa@arm.com
100213955Sgiacomo.gabrielli@arm.com        loadIop = InstObjParams('ld1',
100313955Sgiacomo.gabrielli@arm.com            'SveContigLoadSI' if offsetIsImm else 'SveContigLoadSS',
100413955Sgiacomo.gabrielli@arm.com            'SveContigMemSI' if offsetIsImm else 'SveContigMemSS',
100513955Sgiacomo.gabrielli@arm.com            {'tpl_header': tplHeader,
100613955Sgiacomo.gabrielli@arm.com             'tpl_args': tplArgs,
100714091Sgabor.dozsa@arm.com             'rden_code' : loadRdEnableCode,
100813955Sgiacomo.gabrielli@arm.com             'memacc_code': loadMemAccCode,
100913955Sgiacomo.gabrielli@arm.com             'ea_code' : sveEnabledCheckCode + eaCode,
101014091Sgabor.dozsa@arm.com             'fault_code' : '',
101113955Sgiacomo.gabrielli@arm.com             'fa_code' : ''},
101213955Sgiacomo.gabrielli@arm.com            ['IsMemRef', 'IsLoad'])
101313955Sgiacomo.gabrielli@arm.com        storeIop = InstObjParams('st1',
101413955Sgiacomo.gabrielli@arm.com            'SveContigStoreSI' if offsetIsImm else 'SveContigStoreSS',
101513955Sgiacomo.gabrielli@arm.com            'SveContigMemSI' if offsetIsImm else 'SveContigMemSS',
101613955Sgiacomo.gabrielli@arm.com            {'tpl_header': tplHeader,
101713955Sgiacomo.gabrielli@arm.com             'tpl_args': tplArgs,
101813955Sgiacomo.gabrielli@arm.com             'wren_code': storeWrEnableCode,
101913955Sgiacomo.gabrielli@arm.com             'memacc_code': storeMemAccCode,
102013955Sgiacomo.gabrielli@arm.com             'ea_code' : sveEnabledCheckCode + eaCode,
102113955Sgiacomo.gabrielli@arm.com             'fa_code' : ''},
102213955Sgiacomo.gabrielli@arm.com            ['IsMemRef', 'IsStore'])
102314091Sgabor.dozsa@arm.com        faultIop = InstObjParams('ldff1' if firstFaulting else 'ldnf1',
102414091Sgabor.dozsa@arm.com            'SveContigFFLoadSS' if firstFaulting else 'SveContigNFLoadSI',
102514091Sgabor.dozsa@arm.com            'SveContigMemSS' if firstFaulting else 'SveContigMemSI',
102614091Sgabor.dozsa@arm.com            {'tpl_header': tplHeader,
102714091Sgabor.dozsa@arm.com             'tpl_args': tplArgs,
102814091Sgabor.dozsa@arm.com             'rden_code' : loadRdEnableCode,
102914091Sgabor.dozsa@arm.com             'memacc_code': fautlingLoadmemAccCode,
103014091Sgabor.dozsa@arm.com             'ea_code' : sveEnabledCheckCode + eaCode,
103114091Sgabor.dozsa@arm.com             'fault_code' : faultCode,
103214091Sgabor.dozsa@arm.com             'fa_code' : ''},
103314091Sgabor.dozsa@arm.com            ['IsMemRef', 'IsLoad'])
103414091Sgabor.dozsa@arm.com        faultIop.snippets['memacc_code'] = (ffrReadBackCode +
103514091Sgabor.dozsa@arm.com                                           faultIop.snippets['memacc_code'])
103613955Sgiacomo.gabrielli@arm.com        if offsetIsImm:
103713955Sgiacomo.gabrielli@arm.com            header_output += SveContigMemSIOpDeclare.subst(loadIop)
103813955Sgiacomo.gabrielli@arm.com            header_output += SveContigMemSIOpDeclare.subst(storeIop)
103914091Sgabor.dozsa@arm.com            header_output += SveContigMemSIOpDeclare.subst(faultIop)
104013955Sgiacomo.gabrielli@arm.com        else:
104113955Sgiacomo.gabrielli@arm.com            header_output += SveContigMemSSOpDeclare.subst(loadIop)
104213955Sgiacomo.gabrielli@arm.com            header_output += SveContigMemSSOpDeclare.subst(storeIop)
104314091Sgabor.dozsa@arm.com            header_output += SveContigMemSSOpDeclare.subst(faultIop)
104413955Sgiacomo.gabrielli@arm.com        exec_output += (
104513955Sgiacomo.gabrielli@arm.com            SveContigLoadExecute.subst(loadIop) +
104613955Sgiacomo.gabrielli@arm.com            SveContigLoadInitiateAcc.subst(loadIop) +
104713955Sgiacomo.gabrielli@arm.com            SveContigLoadCompleteAcc.subst(loadIop) +
104813955Sgiacomo.gabrielli@arm.com            SveContigStoreExecute.subst(storeIop) +
104913955Sgiacomo.gabrielli@arm.com            SveContigStoreInitiateAcc.subst(storeIop) +
105014091Sgabor.dozsa@arm.com            SveContigStoreCompleteAcc.subst(storeIop) +
105114091Sgabor.dozsa@arm.com            SveContigLoadExecute.subst(faultIop) +
105214091Sgabor.dozsa@arm.com            SveContigLoadInitiateAcc.subst(faultIop) +
105314091Sgabor.dozsa@arm.com            SveContigLoadCompleteAcc.subst(faultIop))
105414091Sgabor.dozsa@arm.com
105513955Sgiacomo.gabrielli@arm.com        for args in loadTplArgs:
105613955Sgiacomo.gabrielli@arm.com            substDict = {'tpl_args': '<%s>' % ', '.join(args),
105713955Sgiacomo.gabrielli@arm.com                         'class_name': 'SveContigLoadSI' if offsetIsImm
105813955Sgiacomo.gabrielli@arm.com                                       else 'SveContigLoadSS'}
105913955Sgiacomo.gabrielli@arm.com            exec_output += SveContigMemExecDeclare.subst(substDict)
106013955Sgiacomo.gabrielli@arm.com        for args in storeTplArgs:
106113955Sgiacomo.gabrielli@arm.com            substDict = {'tpl_args': '<%s>' % ', '.join(args),
106213955Sgiacomo.gabrielli@arm.com                         'class_name': 'SveContigStoreSI' if offsetIsImm
106313955Sgiacomo.gabrielli@arm.com                                       else 'SveContigStoreSS'}
106413955Sgiacomo.gabrielli@arm.com            exec_output += SveContigMemExecDeclare.subst(substDict)
106514091Sgabor.dozsa@arm.com        for args in loadTplArgs:
106614091Sgabor.dozsa@arm.com            substDict = {'tpl_args': '<%s>' % ', '.join(args),
106714091Sgabor.dozsa@arm.com                         'class_name': 'SveContigFFLoadSS' if firstFaulting
106814091Sgabor.dozsa@arm.com                                       else 'SveContigNFLoadSI'}
106914091Sgabor.dozsa@arm.com            exec_output += SveContigMemExecDeclare.subst(substDict)
107014091Sgabor.dozsa@arm.com
107113955Sgiacomo.gabrielli@arm.com
107213955Sgiacomo.gabrielli@arm.com    # Generates definitions for SVE load-and-replicate instructions
107313955Sgiacomo.gabrielli@arm.com    def emitSveLoadAndRepl():
107413955Sgiacomo.gabrielli@arm.com        global header_output, exec_output, decoders
107513955Sgiacomo.gabrielli@arm.com        tplHeader = 'template <class RegElemType, class MemElemType>'
107613955Sgiacomo.gabrielli@arm.com        tplArgs = '<RegElemType, MemElemType>'
107713955Sgiacomo.gabrielli@arm.com        eaCode = SPAlignmentCheckCode + '''
107813955Sgiacomo.gabrielli@arm.com        EA = XBase + imm * sizeof(MemElemType);'''
107913955Sgiacomo.gabrielli@arm.com        memAccCode = '''
108013955Sgiacomo.gabrielli@arm.com        for (int i = 0; i < eCount; i++) {
108113955Sgiacomo.gabrielli@arm.com            if (GpOp_x[i]) {
108213955Sgiacomo.gabrielli@arm.com                AA64FpDest_x[i] = memData;
108313955Sgiacomo.gabrielli@arm.com            } else {
108413955Sgiacomo.gabrielli@arm.com                AA64FpDest_x[i] = 0;
108513955Sgiacomo.gabrielli@arm.com            }
108613955Sgiacomo.gabrielli@arm.com        }
108713955Sgiacomo.gabrielli@arm.com        '''
108813955Sgiacomo.gabrielli@arm.com        iop = InstObjParams('ld1r',
108913955Sgiacomo.gabrielli@arm.com            'SveLoadAndRepl',
109013955Sgiacomo.gabrielli@arm.com            'SveContigMemSI',
109113955Sgiacomo.gabrielli@arm.com            {'tpl_header': tplHeader,
109213955Sgiacomo.gabrielli@arm.com             'tpl_args': tplArgs,
109313955Sgiacomo.gabrielli@arm.com             'memacc_code': memAccCode,
109413955Sgiacomo.gabrielli@arm.com             'ea_code' : sveEnabledCheckCode + eaCode,
109513955Sgiacomo.gabrielli@arm.com             'fa_code' : ''},
109613955Sgiacomo.gabrielli@arm.com            ['IsMemRef', 'IsLoad'])
109713955Sgiacomo.gabrielli@arm.com        header_output += SveContigMemSIOpDeclare.subst(iop)
109813955Sgiacomo.gabrielli@arm.com        exec_output += (
109913955Sgiacomo.gabrielli@arm.com            SveLoadAndReplExecute.subst(iop) +
110013955Sgiacomo.gabrielli@arm.com            SveLoadAndReplInitiateAcc.subst(iop) +
110113955Sgiacomo.gabrielli@arm.com            SveLoadAndReplCompleteAcc.subst(iop))
110213955Sgiacomo.gabrielli@arm.com        for args in loadTplArgs:
110313955Sgiacomo.gabrielli@arm.com            substDict = {'tpl_args': '<%s>' % ', '.join(args),
110413955Sgiacomo.gabrielli@arm.com                         'class_name': 'SveLoadAndRepl'}
110513955Sgiacomo.gabrielli@arm.com            exec_output += SveContigMemExecDeclare.subst(substDict)
110613955Sgiacomo.gabrielli@arm.com
110714028Sgiacomo.gabrielli@arm.com    class IndexedAddrForm:
110814028Sgiacomo.gabrielli@arm.com        VEC_PLUS_IMM = 0
110914028Sgiacomo.gabrielli@arm.com        SCA_PLUS_VEC = 1
111014028Sgiacomo.gabrielli@arm.com
111114028Sgiacomo.gabrielli@arm.com    # Generates definitions for the transfer microops of SVE indexed memory
111214028Sgiacomo.gabrielli@arm.com    # operations (gather loads, scatter stores)
111314028Sgiacomo.gabrielli@arm.com    def emitSveIndexedMemMicroops(indexed_addr_form):
111414028Sgiacomo.gabrielli@arm.com        assert indexed_addr_form in (IndexedAddrForm.VEC_PLUS_IMM,
111514028Sgiacomo.gabrielli@arm.com                                     IndexedAddrForm.SCA_PLUS_VEC)
111614028Sgiacomo.gabrielli@arm.com        global header_output, exec_output, decoders
111714028Sgiacomo.gabrielli@arm.com        tplHeader = 'template <class RegElemType, class MemElemType>'
111814028Sgiacomo.gabrielli@arm.com        tplArgs = '<RegElemType, MemElemType>'
111914028Sgiacomo.gabrielli@arm.com        if indexed_addr_form == IndexedAddrForm.VEC_PLUS_IMM:
112014110Sgabor.dozsa@arm.com            eaCode_store = '''
112114028Sgiacomo.gabrielli@arm.com        EA = AA64FpBase_x[elemIndex] + imm * sizeof(MemElemType)'''
112214110Sgabor.dozsa@arm.com            eaCode_load = '''
112314110Sgabor.dozsa@arm.com        EA = AA64FpUreg0_x[elemIndex] + imm * sizeof(MemElemType)'''
112414028Sgiacomo.gabrielli@arm.com        else:
112514110Sgabor.dozsa@arm.com            offset_code = '''
112614028Sgiacomo.gabrielli@arm.com        if (offsetIs32) {
112714028Sgiacomo.gabrielli@arm.com            offset &= (1ULL << 32) - 1;
112814028Sgiacomo.gabrielli@arm.com        }
112914028Sgiacomo.gabrielli@arm.com        if (offsetIsSigned) {
113014028Sgiacomo.gabrielli@arm.com            offset = sext<32>(offset);
113114028Sgiacomo.gabrielli@arm.com        }
113214028Sgiacomo.gabrielli@arm.com        if (offsetIsScaled) {
113314028Sgiacomo.gabrielli@arm.com            offset *= sizeof(MemElemType);
113414028Sgiacomo.gabrielli@arm.com        }
113514028Sgiacomo.gabrielli@arm.com        EA = XBase + offset'''
113614110Sgabor.dozsa@arm.com            eaCode_store = '''
113714110Sgabor.dozsa@arm.com        uint64_t offset = AA64FpOffset_x[elemIndex];''' + offset_code
113814110Sgabor.dozsa@arm.com            eaCode_load = '''
113914110Sgabor.dozsa@arm.com        uint64_t offset = AA64FpUreg0_x[elemIndex];''' + offset_code
114014110Sgabor.dozsa@arm.com
114114028Sgiacomo.gabrielli@arm.com        loadMemAccCode = '''
114214091Sgabor.dozsa@arm.com            AA64FpDest_x[elemIndex] = memData;
114314028Sgiacomo.gabrielli@arm.com        '''
114414028Sgiacomo.gabrielli@arm.com        storeMemAccCode = '''
114514028Sgiacomo.gabrielli@arm.com            memData = AA64FpDest_x[elemIndex];
114614028Sgiacomo.gabrielli@arm.com        '''
114714091Sgabor.dozsa@arm.com        predCheckCode = 'GpOp_x[index]'
114814091Sgabor.dozsa@arm.com        faultStatusSetCode = 'PUreg0_x[elemIndex] = 1;'
114914091Sgabor.dozsa@arm.com        faultStatusResetCode = 'PUreg0_x[elemIndex] = 0;'
115014028Sgiacomo.gabrielli@arm.com        loadIop = InstObjParams('ld1',
115114028Sgiacomo.gabrielli@arm.com            ('SveGatherLoadVIMicroop'
115214028Sgiacomo.gabrielli@arm.com             if indexed_addr_form == IndexedAddrForm.VEC_PLUS_IMM
115314028Sgiacomo.gabrielli@arm.com             else 'SveGatherLoadSVMicroop'),
115414028Sgiacomo.gabrielli@arm.com            'MicroOp',
115514028Sgiacomo.gabrielli@arm.com            {'tpl_header': tplHeader,
115614028Sgiacomo.gabrielli@arm.com             'tpl_args': tplArgs,
115714028Sgiacomo.gabrielli@arm.com             'memacc_code': loadMemAccCode,
115814110Sgabor.dozsa@arm.com             'ea_code' : sveEnabledCheckCode + eaCode_load,
115914091Sgabor.dozsa@arm.com             'fault_status_set_code' : faultStatusSetCode,
116014091Sgabor.dozsa@arm.com             'fault_status_reset_code' : faultStatusResetCode,
116114028Sgiacomo.gabrielli@arm.com             'pred_check_code' : predCheckCode,
116214028Sgiacomo.gabrielli@arm.com             'fa_code' : ''},
116314028Sgiacomo.gabrielli@arm.com            ['IsMicroop', 'IsMemRef', 'IsLoad'])
116414028Sgiacomo.gabrielli@arm.com        storeIop = InstObjParams('st1',
116514028Sgiacomo.gabrielli@arm.com            ('SveScatterStoreVIMicroop'
116614028Sgiacomo.gabrielli@arm.com             if indexed_addr_form == IndexedAddrForm.VEC_PLUS_IMM
116714028Sgiacomo.gabrielli@arm.com             else 'SveScatterStoreSVMicroop'),
116814028Sgiacomo.gabrielli@arm.com            'MicroOp',
116914028Sgiacomo.gabrielli@arm.com            {'tpl_header': tplHeader,
117014028Sgiacomo.gabrielli@arm.com             'tpl_args': tplArgs,
117114028Sgiacomo.gabrielli@arm.com             'memacc_code': storeMemAccCode,
117214110Sgabor.dozsa@arm.com             'ea_code' : sveEnabledCheckCode + eaCode_store,
117314028Sgiacomo.gabrielli@arm.com             'pred_check_code' : predCheckCode,
117414028Sgiacomo.gabrielli@arm.com             'fa_code' : ''},
117514028Sgiacomo.gabrielli@arm.com            ['IsMicroop', 'IsMemRef', 'IsStore'])
117614028Sgiacomo.gabrielli@arm.com        if indexed_addr_form == IndexedAddrForm.VEC_PLUS_IMM:
117714028Sgiacomo.gabrielli@arm.com            header_output += SveIndexedMemVIMicroopDeclare.subst(loadIop)
117814028Sgiacomo.gabrielli@arm.com            header_output += SveIndexedMemVIMicroopDeclare.subst(storeIop)
117914028Sgiacomo.gabrielli@arm.com        else:
118014028Sgiacomo.gabrielli@arm.com            header_output += SveIndexedMemSVMicroopDeclare.subst(loadIop)
118114028Sgiacomo.gabrielli@arm.com            header_output += SveIndexedMemSVMicroopDeclare.subst(storeIop)
118214028Sgiacomo.gabrielli@arm.com        exec_output += (
118314028Sgiacomo.gabrielli@arm.com            SveGatherLoadMicroopExecute.subst(loadIop) +
118414028Sgiacomo.gabrielli@arm.com            SveGatherLoadMicroopInitiateAcc.subst(loadIop) +
118514028Sgiacomo.gabrielli@arm.com            SveGatherLoadMicroopCompleteAcc.subst(loadIop) +
118614028Sgiacomo.gabrielli@arm.com            SveScatterStoreMicroopExecute.subst(storeIop) +
118714028Sgiacomo.gabrielli@arm.com            SveScatterStoreMicroopInitiateAcc.subst(storeIop) +
118814028Sgiacomo.gabrielli@arm.com            SveScatterStoreMicroopCompleteAcc.subst(storeIop))
118914028Sgiacomo.gabrielli@arm.com        for args in gatherLoadTplArgs:
119014028Sgiacomo.gabrielli@arm.com            substDict = {'tpl_args': '<%s>' % ', '.join(args),
119114028Sgiacomo.gabrielli@arm.com                         'class_name': (
119214028Sgiacomo.gabrielli@arm.com                             'SveGatherLoadVIMicroop'
119314028Sgiacomo.gabrielli@arm.com                             if indexed_addr_form == \
119414028Sgiacomo.gabrielli@arm.com                                 IndexedAddrForm.VEC_PLUS_IMM
119514028Sgiacomo.gabrielli@arm.com                             else 'SveGatherLoadSVMicroop')}
119614028Sgiacomo.gabrielli@arm.com            # TODO: this should become SveMemExecDeclare
119714028Sgiacomo.gabrielli@arm.com            exec_output += SveContigMemExecDeclare.subst(substDict)
119814028Sgiacomo.gabrielli@arm.com        for args in scatterStoreTplArgs:
119914028Sgiacomo.gabrielli@arm.com            substDict = {'tpl_args': '<%s>' % ', '.join(args),
120014028Sgiacomo.gabrielli@arm.com                         'class_name': (
120114028Sgiacomo.gabrielli@arm.com                             'SveScatterStoreVIMicroop'
120214028Sgiacomo.gabrielli@arm.com                             if indexed_addr_form == \
120314028Sgiacomo.gabrielli@arm.com                                 IndexedAddrForm.VEC_PLUS_IMM
120414028Sgiacomo.gabrielli@arm.com                             else 'SveScatterStoreSVMicroop')}
120514028Sgiacomo.gabrielli@arm.com            # TODO: this should become SveMemExecDeclare
120614028Sgiacomo.gabrielli@arm.com            exec_output += SveContigMemExecDeclare.subst(substDict)
120714028Sgiacomo.gabrielli@arm.com
120814091Sgabor.dozsa@arm.com    firstFaultTplArgs = ('int32_t', 'int64_t', 'uint32_t', 'uint64_t')
120914091Sgabor.dozsa@arm.com
121014091Sgabor.dozsa@arm.com    def emitSveFirstFaultWritebackMicroop():
121114091Sgabor.dozsa@arm.com        global header_output, exec_output, decoders
121214091Sgabor.dozsa@arm.com        tplHeader = 'template <class RegElemType>'
121314091Sgabor.dozsa@arm.com        tplArgs = '<RegElemType>'
121414091Sgabor.dozsa@arm.com        faultStatusCheckCode = 'PUreg0_x[index]'
121514091Sgabor.dozsa@arm.com        firstFaultResetCode = '''
121614091Sgabor.dozsa@arm.com        for(int j = 0; j < sizeof(RegElemType); j++) {
121714091Sgabor.dozsa@arm.com            Ffr_ub[index * sizeof(RegElemType) + j] = 0;
121814091Sgabor.dozsa@arm.com        }
121914091Sgabor.dozsa@arm.com        '''
122014091Sgabor.dozsa@arm.com        firstFaultForwardCode = '''
122114091Sgabor.dozsa@arm.com        for(int j = 0; j < sizeof(RegElemType); j++) {
122214091Sgabor.dozsa@arm.com            Ffr_ub[index * sizeof(RegElemType) + j] = FfrAux_x[index];
122314091Sgabor.dozsa@arm.com        }
122414091Sgabor.dozsa@arm.com        '''
122514091Sgabor.dozsa@arm.com        iop = InstObjParams('ldff1',
122614091Sgabor.dozsa@arm.com            'SveFirstFaultWritebackMicroop',
122714091Sgabor.dozsa@arm.com            'MicroOp',
122814091Sgabor.dozsa@arm.com            {'tpl_header': tplHeader,
122914091Sgabor.dozsa@arm.com             'tpl_args': tplArgs,
123014091Sgabor.dozsa@arm.com             'fault_status_check_code' : faultStatusCheckCode,
123114091Sgabor.dozsa@arm.com             'first_fault_reset_code' : firstFaultResetCode,
123214091Sgabor.dozsa@arm.com             'first_fault_forward_code' : firstFaultForwardCode},
123314091Sgabor.dozsa@arm.com             ['IsMicroop'])
123414091Sgabor.dozsa@arm.com        header_output += SveFirstFaultWritebackMicroopDeclare.subst(iop)
123514091Sgabor.dozsa@arm.com        exec_output += SveFirstFaultWritebackMicroopExecute.subst(iop)
123614091Sgabor.dozsa@arm.com        for args in firstFaultTplArgs:
123714091Sgabor.dozsa@arm.com            substDict = {'targs': args,
123814091Sgabor.dozsa@arm.com                         'class_name' : 'SveFirstFaultWritebackMicroop' }
123914091Sgabor.dozsa@arm.com            exec_output += SveOpExecDeclare.subst(substDict)
124014091Sgabor.dozsa@arm.com
124114028Sgiacomo.gabrielli@arm.com    # Generates definitions for the first microop of SVE gather loads, required
124214028Sgiacomo.gabrielli@arm.com    # to propagate the source vector register to the transfer microops
124314028Sgiacomo.gabrielli@arm.com    def emitSveGatherLoadCpySrcVecMicroop():
124414028Sgiacomo.gabrielli@arm.com        global header_output, exec_output, decoders
124514028Sgiacomo.gabrielli@arm.com        code = sveEnabledCheckCode + '''
124614028Sgiacomo.gabrielli@arm.com        unsigned eCount = ArmStaticInst::getCurSveVecLen<uint8_t>(
124714028Sgiacomo.gabrielli@arm.com                xc->tcBase());
124814028Sgiacomo.gabrielli@arm.com        for (unsigned i = 0; i < eCount; i++) {
124914028Sgiacomo.gabrielli@arm.com            AA64FpUreg0_ub[i] = AA64FpOp1_ub[i];
125014028Sgiacomo.gabrielli@arm.com        }'''
125114028Sgiacomo.gabrielli@arm.com        iop = InstObjParams('ld1',
125214028Sgiacomo.gabrielli@arm.com            'SveGatherLoadCpySrcVecMicroop',
125314028Sgiacomo.gabrielli@arm.com            'MicroOp',
125414028Sgiacomo.gabrielli@arm.com            {'code': code},
125514028Sgiacomo.gabrielli@arm.com            ['IsMicroop'])
125614028Sgiacomo.gabrielli@arm.com        header_output += SveGatherLoadCpySrcVecMicroopDeclare.subst(iop)
125714028Sgiacomo.gabrielli@arm.com        exec_output += SveGatherLoadCpySrcVecMicroopExecute.subst(iop)
125814028Sgiacomo.gabrielli@arm.com
125914106Sjavier.setoain@arm.com    def emitSveInterleaveMicroop():
126014106Sjavier.setoain@arm.com        global header_output, exec_output, decoders
126114106Sjavier.setoain@arm.com        code2 = sveEnabledCheckCode + '''
126214106Sjavier.setoain@arm.com        unsigned eCount = ArmStaticInst::getCurSveVecLen<Element>(
126314106Sjavier.setoain@arm.com                xc->tcBase());
126414106Sjavier.setoain@arm.com        for (unsigned int i = 0; i < eCount; ++i) {
126514106Sjavier.setoain@arm.com            unsigned int absIdx = regIndex * eCount + i;
126614106Sjavier.setoain@arm.com            unsigned int srcIdx = absIdx / numRegs;
126714106Sjavier.setoain@arm.com            unsigned int srcVec = absIdx % numRegs;
126814106Sjavier.setoain@arm.com            if (srcVec == 0)
126914106Sjavier.setoain@arm.com                AA64FpDest_x[i] = AA64FpOp1V0S_x[srcIdx];
127014106Sjavier.setoain@arm.com            else if (srcVec == 1)
127114106Sjavier.setoain@arm.com                AA64FpDest_x[i] = AA64FpOp1V1S_x[srcIdx];
127214106Sjavier.setoain@arm.com        }'''
127314106Sjavier.setoain@arm.com
127414106Sjavier.setoain@arm.com        code3 = sveEnabledCheckCode + '''
127514106Sjavier.setoain@arm.com        unsigned eCount = ArmStaticInst::getCurSveVecLen<Element>(
127614106Sjavier.setoain@arm.com                xc->tcBase());
127714106Sjavier.setoain@arm.com        for (unsigned int i = 0; i < eCount; ++i) {
127814106Sjavier.setoain@arm.com            unsigned int absIdx = regIndex * eCount + i;
127914106Sjavier.setoain@arm.com            unsigned int srcIdx = absIdx / numRegs;
128014106Sjavier.setoain@arm.com            unsigned int srcVec = absIdx % numRegs;
128114106Sjavier.setoain@arm.com            if (srcVec == 0)
128214106Sjavier.setoain@arm.com                AA64FpDest_x[i] = AA64FpOp1V0S_x[srcIdx];
128314106Sjavier.setoain@arm.com            else if (srcVec == 1)
128414106Sjavier.setoain@arm.com                AA64FpDest_x[i] = AA64FpOp1V1S_x[srcIdx];
128514106Sjavier.setoain@arm.com            else if (srcVec == 2)
128614106Sjavier.setoain@arm.com                AA64FpDest_x[i] = AA64FpOp1V2S_x[srcIdx];
128714106Sjavier.setoain@arm.com        }'''
128814106Sjavier.setoain@arm.com
128914106Sjavier.setoain@arm.com        code4 = sveEnabledCheckCode + '''
129014106Sjavier.setoain@arm.com        unsigned eCount = ArmStaticInst::getCurSveVecLen<Element>(
129114106Sjavier.setoain@arm.com                xc->tcBase());
129214106Sjavier.setoain@arm.com        for (unsigned int i = 0; i < eCount; ++i) {
129314106Sjavier.setoain@arm.com            unsigned int absIdx = regIndex * eCount + i;
129414106Sjavier.setoain@arm.com            unsigned int srcIdx = absIdx / numRegs;
129514106Sjavier.setoain@arm.com            unsigned int srcVec = absIdx % numRegs;
129614106Sjavier.setoain@arm.com            if (srcVec == 0)
129714106Sjavier.setoain@arm.com                AA64FpDest_x[i] = AA64FpOp1V0S_x[srcIdx];
129814106Sjavier.setoain@arm.com            else if (srcVec == 1)
129914106Sjavier.setoain@arm.com                AA64FpDest_x[i] = AA64FpOp1V1S_x[srcIdx];
130014106Sjavier.setoain@arm.com            else if (srcVec == 2)
130114106Sjavier.setoain@arm.com                AA64FpDest_x[i] = AA64FpOp1V2S_x[srcIdx];
130214106Sjavier.setoain@arm.com            else if (srcVec == 3)
130314106Sjavier.setoain@arm.com                AA64FpDest_x[i] = AA64FpOp1V3S_x[srcIdx];
130414106Sjavier.setoain@arm.com        }'''
130514106Sjavier.setoain@arm.com
130614106Sjavier.setoain@arm.com        iop2 = InstObjParams('intrlv',
130714106Sjavier.setoain@arm.com                'SveIntrlv2Microop',
130814106Sjavier.setoain@arm.com                'MicroOp',
130914106Sjavier.setoain@arm.com                {'code': code2},
131014106Sjavier.setoain@arm.com                ['IsMicroop'])
131114106Sjavier.setoain@arm.com        iop3 = InstObjParams('intrlv',
131214106Sjavier.setoain@arm.com                'SveIntrlv3Microop',
131314106Sjavier.setoain@arm.com                'MicroOp',
131414106Sjavier.setoain@arm.com                {'code': code3},
131514106Sjavier.setoain@arm.com                ['IsMicroop'])
131614106Sjavier.setoain@arm.com        iop4 = InstObjParams('intrlv',
131714106Sjavier.setoain@arm.com                'SveIntrlv4Microop',
131814106Sjavier.setoain@arm.com                'MicroOp',
131914106Sjavier.setoain@arm.com                {'code': code4},
132014106Sjavier.setoain@arm.com                ['IsMicroop'])
132114106Sjavier.setoain@arm.com        header_output += SveIntrlvMicroopDeclare.subst(iop2);
132214106Sjavier.setoain@arm.com        header_output += SveIntrlvMicroopDeclare.subst(iop3);
132314106Sjavier.setoain@arm.com        header_output += SveIntrlvMicroopDeclare.subst(iop4);
132414106Sjavier.setoain@arm.com        exec_output += SveIntrlvMicroopExecute.subst(iop2);
132514106Sjavier.setoain@arm.com        exec_output += SveIntrlvMicroopExecute.subst(iop3);
132614106Sjavier.setoain@arm.com        exec_output += SveIntrlvMicroopExecute.subst(iop4);
132714106Sjavier.setoain@arm.com        for type in ('uint8_t', 'uint16_t', 'uint32_t', 'uint64_t'):
132814106Sjavier.setoain@arm.com            for nreg in range(2,5):
132914106Sjavier.setoain@arm.com                substDict = {'targs' : type,
133014106Sjavier.setoain@arm.com                        'class_name' : 'SveIntrlv' + str(nreg) + 'Microop'}
133114106Sjavier.setoain@arm.com                exec_output += SveIntrlvMicroopExecDeclare.subst(substDict)
133214106Sjavier.setoain@arm.com
133314106Sjavier.setoain@arm.com    def emitSveDeInterleaveMicroop():
133414106Sjavier.setoain@arm.com        global header_output, exec_output, decoders
133514106Sjavier.setoain@arm.com        code2 = sveEnabledCheckCode + '''
133614106Sjavier.setoain@arm.com        unsigned eCount = ArmStaticInst::getCurSveVecLen<Element>(
133714106Sjavier.setoain@arm.com                xc->tcBase());
133814106Sjavier.setoain@arm.com        for (unsigned int i = 0; i < eCount; ++i) {
133914106Sjavier.setoain@arm.com            unsigned int absIdx = (regIndex + numRegs * i);
134014106Sjavier.setoain@arm.com            unsigned int srcIdx = absIdx % eCount;
134114106Sjavier.setoain@arm.com            unsigned int srcVec = absIdx / eCount;
134214106Sjavier.setoain@arm.com            if (srcVec == 0)
134314106Sjavier.setoain@arm.com                AA64FpDest_x[i] = AA64IntrlvReg0_x[srcIdx];
134414106Sjavier.setoain@arm.com            else if(srcVec == 1)
134514106Sjavier.setoain@arm.com                AA64FpDest_x[i] = AA64IntrlvReg1_x[srcIdx];
134614106Sjavier.setoain@arm.com        }'''
134714106Sjavier.setoain@arm.com
134814106Sjavier.setoain@arm.com        code3 = sveEnabledCheckCode + '''
134914106Sjavier.setoain@arm.com        unsigned eCount = ArmStaticInst::getCurSveVecLen<Element>(
135014106Sjavier.setoain@arm.com                xc->tcBase());
135114106Sjavier.setoain@arm.com        for (unsigned int i = 0; i < eCount; ++i) {
135214106Sjavier.setoain@arm.com            unsigned int absIdx = (regIndex + numRegs * i);
135314106Sjavier.setoain@arm.com            unsigned int srcIdx = absIdx % eCount;
135414106Sjavier.setoain@arm.com            unsigned int srcVec = absIdx / eCount;
135514106Sjavier.setoain@arm.com            if (srcVec == 0)
135614106Sjavier.setoain@arm.com                AA64FpDest_x[i] = AA64IntrlvReg0_x[srcIdx];
135714106Sjavier.setoain@arm.com            else if(srcVec == 1)
135814106Sjavier.setoain@arm.com                AA64FpDest_x[i] = AA64IntrlvReg1_x[srcIdx];
135914106Sjavier.setoain@arm.com            else if(srcVec == 2)
136014106Sjavier.setoain@arm.com                AA64FpDest_x[i] = AA64IntrlvReg2_x[srcIdx];
136114106Sjavier.setoain@arm.com        }'''
136214106Sjavier.setoain@arm.com
136314106Sjavier.setoain@arm.com        code4 = sveEnabledCheckCode + '''
136414106Sjavier.setoain@arm.com        unsigned eCount = ArmStaticInst::getCurSveVecLen<Element>(
136514106Sjavier.setoain@arm.com                xc->tcBase());
136614106Sjavier.setoain@arm.com        for (unsigned int i = 0; i < eCount; ++i) {
136714106Sjavier.setoain@arm.com            unsigned int absIdx = (regIndex + numRegs * i);
136814106Sjavier.setoain@arm.com            unsigned int srcIdx = absIdx % eCount;
136914106Sjavier.setoain@arm.com            unsigned int srcVec = absIdx / eCount;
137014106Sjavier.setoain@arm.com            if (srcVec == 0)
137114106Sjavier.setoain@arm.com                AA64FpDest_x[i] = AA64IntrlvReg0_x[srcIdx];
137214106Sjavier.setoain@arm.com            else if(srcVec == 1)
137314106Sjavier.setoain@arm.com                AA64FpDest_x[i] = AA64IntrlvReg1_x[srcIdx];
137414106Sjavier.setoain@arm.com            else if(srcVec == 2)
137514106Sjavier.setoain@arm.com                AA64FpDest_x[i] = AA64IntrlvReg2_x[srcIdx];
137614106Sjavier.setoain@arm.com            else if(srcVec == 3)
137714106Sjavier.setoain@arm.com                AA64FpDest_x[i] = AA64IntrlvReg3_x[srcIdx];
137814106Sjavier.setoain@arm.com        }'''
137914106Sjavier.setoain@arm.com
138014106Sjavier.setoain@arm.com        iop2 = InstObjParams('deintrlv',
138114106Sjavier.setoain@arm.com                'SveDeIntrlv2Microop',
138214106Sjavier.setoain@arm.com                'MicroOp',
138314106Sjavier.setoain@arm.com                {'code': code2},
138414106Sjavier.setoain@arm.com                ['IsMicroop'])
138514106Sjavier.setoain@arm.com        iop3 = InstObjParams('deintrlv',
138614106Sjavier.setoain@arm.com                'SveDeIntrlv3Microop',
138714106Sjavier.setoain@arm.com                'MicroOp',
138814106Sjavier.setoain@arm.com                {'code': code3},
138914106Sjavier.setoain@arm.com                ['IsMicroop'])
139014106Sjavier.setoain@arm.com        iop4 = InstObjParams('deintrlv',
139114106Sjavier.setoain@arm.com                'SveDeIntrlv4Microop',
139214106Sjavier.setoain@arm.com                'MicroOp',
139314106Sjavier.setoain@arm.com                {'code': code4},
139414106Sjavier.setoain@arm.com                ['IsMicroop'])
139514106Sjavier.setoain@arm.com        header_output += SveDeIntrlvMicroopDeclare.subst(iop2);
139614106Sjavier.setoain@arm.com        header_output += SveDeIntrlvMicroopDeclare.subst(iop3);
139714106Sjavier.setoain@arm.com        header_output += SveDeIntrlvMicroopDeclare.subst(iop4);
139814106Sjavier.setoain@arm.com        exec_output += SveIntrlvMicroopExecute.subst(iop2);
139914106Sjavier.setoain@arm.com        exec_output += SveIntrlvMicroopExecute.subst(iop3);
140014106Sjavier.setoain@arm.com        exec_output += SveIntrlvMicroopExecute.subst(iop4);
140114106Sjavier.setoain@arm.com        for type in ('uint8_t', 'uint16_t', 'uint32_t', 'uint64_t'):
140214106Sjavier.setoain@arm.com            for nreg in range(2,5):
140314106Sjavier.setoain@arm.com                substDict = {'targs' : type,
140414106Sjavier.setoain@arm.com                        'class_name' : 'SveDeIntrlv' + str(nreg) + 'Microop'}
140514106Sjavier.setoain@arm.com                exec_output += SveIntrlvMicroopExecDeclare.subst(substDict)
140614106Sjavier.setoain@arm.com
140714106Sjavier.setoain@arm.com    # Generates definitions for SVE struct load/store microops
140814106Sjavier.setoain@arm.com    def emitSveStructMemInsts(offsetIsImm):
140914106Sjavier.setoain@arm.com        global header_output, exec_output, decoders
141014106Sjavier.setoain@arm.com        eaCode = SPAlignmentCheckCode + '''
141114106Sjavier.setoain@arm.com        int memAccessSize = eCount * sizeof(Element);
141214106Sjavier.setoain@arm.com        EA = memAccessSize * regIndex + XBase + '''
141314106Sjavier.setoain@arm.com        if offsetIsImm:
141414106Sjavier.setoain@arm.com            eaCode += '((int64_t) this->imm * eCount * sizeof(Element))'
141514106Sjavier.setoain@arm.com        else:
141614106Sjavier.setoain@arm.com            eaCode += '(XOffset * sizeof(Element));'
141714106Sjavier.setoain@arm.com        loadMemAccCode = '''
141814106Sjavier.setoain@arm.com        for (int i = 0; i < eCount; i++) {
141914106Sjavier.setoain@arm.com            int gpIdx = (regIndex * eCount + i) / numRegs;
142014106Sjavier.setoain@arm.com            if (GpOp_x[gpIdx]) {
142114106Sjavier.setoain@arm.com                AA64FpDest_x[i] = memDataView[i];
142214106Sjavier.setoain@arm.com            } else {
142314106Sjavier.setoain@arm.com                AA64FpDest_x[i] = 0;
142414106Sjavier.setoain@arm.com            }
142514106Sjavier.setoain@arm.com        }
142614106Sjavier.setoain@arm.com        '''
142714106Sjavier.setoain@arm.com        storeMemAccCode = '''
142814106Sjavier.setoain@arm.com        for (int i = 0; i < eCount; i++) {
142914106Sjavier.setoain@arm.com            int gpIdx = (regIndex * eCount + i) / numRegs;
143014106Sjavier.setoain@arm.com            if (GpOp_x[gpIdx]) {
143114106Sjavier.setoain@arm.com                memDataView[i] = AA64FpDest_x[i];
143214106Sjavier.setoain@arm.com            } else {
143314106Sjavier.setoain@arm.com                memDataView[i] = 0;
143414106Sjavier.setoain@arm.com                for (int j = 0; j < sizeof(Element); j++) {
143514106Sjavier.setoain@arm.com                    wrEn[sizeof(Element) * i + j] = false;
143614106Sjavier.setoain@arm.com                }
143714106Sjavier.setoain@arm.com            }
143814106Sjavier.setoain@arm.com        }
143914106Sjavier.setoain@arm.com        '''
144014106Sjavier.setoain@arm.com        storeWrEnableCode = '''
144114106Sjavier.setoain@arm.com        auto wrEn = std::vector<bool>(sizeof(Element) * eCount, true);
144214106Sjavier.setoain@arm.com        '''
144314106Sjavier.setoain@arm.com        loadIop = InstObjParams('ldxx',
144414106Sjavier.setoain@arm.com            'SveLoadRegImmMicroop' if offsetIsImm else 'SveLoadRegRegMicroop',
144514106Sjavier.setoain@arm.com            'MicroOp',
144614106Sjavier.setoain@arm.com            {'targs': 'Element',
144714106Sjavier.setoain@arm.com             'memacc_code': loadMemAccCode,
144814106Sjavier.setoain@arm.com             'ea_code' : sveEnabledCheckCode + eaCode,
144914106Sjavier.setoain@arm.com             'fa_code' : ''},
145014106Sjavier.setoain@arm.com            ['IsMemRef', 'IsLoad', 'IsMicroop'])
145114106Sjavier.setoain@arm.com        storeIop = InstObjParams('stxx',
145214106Sjavier.setoain@arm.com            'SveStoreRegImmMicroop' if offsetIsImm
145314106Sjavier.setoain@arm.com                                    else 'SveStoreRegRegMicroop',
145414106Sjavier.setoain@arm.com            'MicroOp',
145514106Sjavier.setoain@arm.com            {'targs': 'Element',
145614106Sjavier.setoain@arm.com             'wren_code': storeWrEnableCode,
145714106Sjavier.setoain@arm.com             'memacc_code': storeMemAccCode,
145814106Sjavier.setoain@arm.com             'ea_code' : sveEnabledCheckCode + eaCode,
145914106Sjavier.setoain@arm.com             'fa_code' : ''},
146014106Sjavier.setoain@arm.com            ['IsMemRef', 'IsStore', 'IsMicroop'])
146114106Sjavier.setoain@arm.com        if offsetIsImm:
146214106Sjavier.setoain@arm.com            header_output += SveStructMemSIMicroopDeclare.subst(loadIop)
146314106Sjavier.setoain@arm.com            header_output += SveStructMemSIMicroopDeclare.subst(storeIop)
146414106Sjavier.setoain@arm.com        else:
146514106Sjavier.setoain@arm.com            header_output += SveStructMemSSMicroopDeclare.subst(loadIop)
146614106Sjavier.setoain@arm.com            header_output += SveStructMemSSMicroopDeclare.subst(storeIop)
146714106Sjavier.setoain@arm.com        exec_output += (
146814106Sjavier.setoain@arm.com            SveStructLoadExecute.subst(loadIop) +
146914106Sjavier.setoain@arm.com            SveStructLoadInitiateAcc.subst(loadIop) +
147014106Sjavier.setoain@arm.com            SveStructLoadCompleteAcc.subst(loadIop) +
147114106Sjavier.setoain@arm.com            SveStructStoreExecute.subst(storeIop) +
147214106Sjavier.setoain@arm.com            SveStructStoreInitiateAcc.subst(storeIop) +
147314106Sjavier.setoain@arm.com            SveStructStoreCompleteAcc.subst(storeIop))
147414106Sjavier.setoain@arm.com        tplArgs = ('uint8_t', 'uint16_t', 'uint32_t', 'uint64_t')
147514106Sjavier.setoain@arm.com        for type in tplArgs:
147614106Sjavier.setoain@arm.com            substDict = {'targs': type,
147714106Sjavier.setoain@arm.com                         'class_name': 'SveLoadRegImmMicroop' if offsetIsImm
147814106Sjavier.setoain@arm.com                                       else 'SveLoadRegRegMicroop'}
147914106Sjavier.setoain@arm.com            exec_output += SveStructMemExecDeclare.subst(substDict)
148014106Sjavier.setoain@arm.com            substDict['class_name'] = ('SveStoreRegImmMicroop' if offsetIsImm
148114106Sjavier.setoain@arm.com                                       else 'SveStoreRegRegMicroop')
148214106Sjavier.setoain@arm.com            exec_output += SveStructMemExecDeclare.subst(substDict)
148314106Sjavier.setoain@arm.com
148414108Sjavier.setoain@arm.com    # Generates definitions for SVE load-and-replicate quadword instructions
148514108Sjavier.setoain@arm.com    def emitSveLoadAndReplQuad(offsetIsImm):
148614108Sjavier.setoain@arm.com        global header_output, exec_output, decoders
148714108Sjavier.setoain@arm.com        tplHeader = 'template <class RegElemType, class MemElemType>'
148814108Sjavier.setoain@arm.com        tplArgs = '<RegElemType, MemElemType>'
148914108Sjavier.setoain@arm.com        eaCode = SPAlignmentCheckCode + '''
149014108Sjavier.setoain@arm.com        int memAccessSize = 16;
149114108Sjavier.setoain@arm.com        EA = XBase + '''
149214108Sjavier.setoain@arm.com        if offsetIsImm:
149314108Sjavier.setoain@arm.com            eaCode += '(((int64_t) this->imm) * 16);'
149414108Sjavier.setoain@arm.com        else:
149514108Sjavier.setoain@arm.com            eaCode += '(XOffset * sizeof(MemElemType));'
149614108Sjavier.setoain@arm.com        loadRdEnableCode = '''
149714108Sjavier.setoain@arm.com        eCount = 16/sizeof(RegElemType);
149814108Sjavier.setoain@arm.com        auto rdEn = std::vector<bool>(16, true);
149914108Sjavier.setoain@arm.com        for (int i = 0; i < eCount; ++i) {
150014108Sjavier.setoain@arm.com            if (!GpOp_x[i]) {
150114108Sjavier.setoain@arm.com                for (int j = 0; j < sizeof(RegElemType); ++j) {
150214108Sjavier.setoain@arm.com                    rdEn[sizeof(RegElemType) * i + j] = false;
150314108Sjavier.setoain@arm.com                }
150414108Sjavier.setoain@arm.com            }
150514108Sjavier.setoain@arm.com        }
150614108Sjavier.setoain@arm.com        '''
150714108Sjavier.setoain@arm.com        memAccCode = '''
150814108Sjavier.setoain@arm.com        __uint128_t qword;
150914108Sjavier.setoain@arm.com        RegElemType* qp = reinterpret_cast<RegElemType*>(&qword);
151014108Sjavier.setoain@arm.com        for (int i = 0; i < 16/sizeof(RegElemType); ++i) {
151114108Sjavier.setoain@arm.com            if (GpOp_x[i]) {
151214108Sjavier.setoain@arm.com                qp[i] = memDataView[i];
151314108Sjavier.setoain@arm.com            } else {
151414108Sjavier.setoain@arm.com                qp[i] = 0;
151514108Sjavier.setoain@arm.com            }
151614108Sjavier.setoain@arm.com        }
151714108Sjavier.setoain@arm.com        eCount = ArmStaticInst::getCurSveVecLen<__uint128_t>(
151814108Sjavier.setoain@arm.com                xc->tcBase());
151914108Sjavier.setoain@arm.com        for (int i = 0; i < eCount; ++i) {
152014108Sjavier.setoain@arm.com            AA64FpDest_uq[i] = qword;
152114108Sjavier.setoain@arm.com        }
152214108Sjavier.setoain@arm.com        '''
152314108Sjavier.setoain@arm.com        iop = InstObjParams('ld1rq',
152414108Sjavier.setoain@arm.com                'SveLd1RqSI' if offsetIsImm else 'SveLd1RqSS',
152514108Sjavier.setoain@arm.com                'SveContigMemSI' if offsetIsImm else 'SveContigMemSS',
152614108Sjavier.setoain@arm.com                {'tpl_header': tplHeader,
152714108Sjavier.setoain@arm.com                 'tpl_args': tplArgs,
152814108Sjavier.setoain@arm.com                 'rden_code': loadRdEnableCode,
152914108Sjavier.setoain@arm.com                 'memacc_code': memAccCode,
153014108Sjavier.setoain@arm.com                 'ea_code': sveEnabledCheckCode + eaCode,
153114108Sjavier.setoain@arm.com                 'fault_code': '',
153214108Sjavier.setoain@arm.com                 'fa_code': ''},
153314108Sjavier.setoain@arm.com                ['IsMemRef', 'IsLoad'])
153414108Sjavier.setoain@arm.com        if offsetIsImm:
153514108Sjavier.setoain@arm.com            header_output += SveContigMemSIOpDeclare.subst(iop)
153614108Sjavier.setoain@arm.com        else:
153714108Sjavier.setoain@arm.com            header_output += SveContigMemSSOpDeclare.subst(iop)
153814108Sjavier.setoain@arm.com        exec_output += (
153914108Sjavier.setoain@arm.com                SveContigLoadExecute.subst(iop) +
154014108Sjavier.setoain@arm.com                SveContigLoadInitiateAcc.subst(iop) +
154114108Sjavier.setoain@arm.com                SveContigLoadCompleteAcc.subst(iop))
154214108Sjavier.setoain@arm.com        for ttype in ('uint8_t', 'uint16_t', 'uint32_t', 'uint64_t'):
154314108Sjavier.setoain@arm.com            substDict = {'tpl_args': '<%s, %s>' % (ttype, ttype),
154414108Sjavier.setoain@arm.com                    'class_name': 'SveLd1RqSI' if offsetIsImm
154514108Sjavier.setoain@arm.com                                  else 'SveLd1RqSS'}
154614108Sjavier.setoain@arm.com            exec_output += SveContigMemExecDeclare.subst(substDict)
154714108Sjavier.setoain@arm.com
154813955Sgiacomo.gabrielli@arm.com    # LD1[S]{B,H,W,D} (scalar plus immediate)
154914028Sgiacomo.gabrielli@arm.com    # ST1[S]{B,H,W,D} (scalar plus immediate)
155014091Sgabor.dozsa@arm.com    # LDNF1[S]{B,H,W,D} (scalar plus immediate)
155113955Sgiacomo.gabrielli@arm.com    emitSveContigMemInsts(True)
155213955Sgiacomo.gabrielli@arm.com    # LD1[S]{B,H,W,D} (scalar plus scalar)
155314028Sgiacomo.gabrielli@arm.com    # ST1[S]{B,H,W,D} (scalar plus scalar)
155414091Sgabor.dozsa@arm.com    # LDFF1[S]{B,H,W,D} (scalar plus vector)
155513955Sgiacomo.gabrielli@arm.com    emitSveContigMemInsts(False)
155613955Sgiacomo.gabrielli@arm.com
155713955Sgiacomo.gabrielli@arm.com    # LD1R[S]{B,H,W,D}
155813955Sgiacomo.gabrielli@arm.com    emitSveLoadAndRepl()
155913955Sgiacomo.gabrielli@arm.com
156014108Sjavier.setoain@arm.com    # LD1RQ{B,H,W,D} (scalar plus immediate)
156114108Sjavier.setoain@arm.com    emitSveLoadAndReplQuad(offsetIsImm = True)
156214108Sjavier.setoain@arm.com    # LD1RQ{B,H,W,D} (scalar plus scalar)
156314108Sjavier.setoain@arm.com    emitSveLoadAndReplQuad(offsetIsImm = False)
156414108Sjavier.setoain@arm.com
156514106Sjavier.setoain@arm.com    # LD{2,3,4}{B,H,W,D} (scalar plus immediate)
156614106Sjavier.setoain@arm.com    # ST{2,3,4}{B,H,W,D} (scalar plus immediate)
156714106Sjavier.setoain@arm.com    emitSveStructMemInsts(offsetIsImm = True)
156814106Sjavier.setoain@arm.com    # LD{2,3,4}{B,H,W,D} (scalar plus scalar)
156914106Sjavier.setoain@arm.com    # ST{2,3,4}{B,H,W,D} (scalar plus scalar)
157014106Sjavier.setoain@arm.com    emitSveStructMemInsts(offsetIsImm = False)
157114106Sjavier.setoain@arm.com
157213955Sgiacomo.gabrielli@arm.com    # LDR (predicate), STR (predicate)
157313955Sgiacomo.gabrielli@arm.com    emitSveMemFillSpill(True)
157413955Sgiacomo.gabrielli@arm.com    # LDR (vector), STR (vector)
157513955Sgiacomo.gabrielli@arm.com    emitSveMemFillSpill(False)
157613955Sgiacomo.gabrielli@arm.com
157714028Sgiacomo.gabrielli@arm.com    # LD1[S]{B,H,W,D} (vector plus immediate)
157814028Sgiacomo.gabrielli@arm.com    # ST1[S]{B,H,W,D} (vector plus immediate)
157914091Sgabor.dozsa@arm.com    # LDFF1[S]{B,H,W,D} (scalar plus immediate)
158014028Sgiacomo.gabrielli@arm.com    emitSveIndexedMemMicroops(IndexedAddrForm.VEC_PLUS_IMM)
158114028Sgiacomo.gabrielli@arm.com    # LD1[S]{B,H,W,D} (scalar plus vector)
158214028Sgiacomo.gabrielli@arm.com    # ST1[S]{B,H,W,D} (scalar plus vector)
158314091Sgabor.dozsa@arm.com    # LDFF1[S]{B,H,W,D} (scalar plus vector)
158414028Sgiacomo.gabrielli@arm.com    emitSveIndexedMemMicroops(IndexedAddrForm.SCA_PLUS_VEC)
158514028Sgiacomo.gabrielli@arm.com
158614091Sgabor.dozsa@arm.com    # FFR writeback microop for gather loads
158714091Sgabor.dozsa@arm.com    emitSveFirstFaultWritebackMicroop()
158814091Sgabor.dozsa@arm.com
158914028Sgiacomo.gabrielli@arm.com    # Source vector copy microop for gather loads
159014028Sgiacomo.gabrielli@arm.com    emitSveGatherLoadCpySrcVecMicroop()
159114106Sjavier.setoain@arm.com
159214106Sjavier.setoain@arm.com    # ST/LD struct de/interleave microops
159314106Sjavier.setoain@arm.com    emitSveInterleaveMicroop()
159414106Sjavier.setoain@arm.com    emitSveDeInterleaveMicroop()
159513955Sgiacomo.gabrielli@arm.com}};
1596