sve_mem.isa revision 14106
12SN/A// Copyright (c) 2017-2018 ARM Limited
21762SN/A// All rights reserved
32SN/A//
42SN/A// The license below extends only to copyright in the software and shall
52SN/A// not be construed as granting a license to any other intellectual
62SN/A// property including but not limited to intellectual property relating
72SN/A// to a hardware implementation of the functionality of the software
82SN/A// licensed hereunder.  You may use the software subject to the license
92SN/A// terms below provided that you ensure that this notice is replicated
102SN/A// unmodified and in its entirety in all distributions of the software,
112SN/A// modified or unmodified, in source code or in binary form.
122SN/A//
132SN/A// Redistribution and use in source and binary forms, with or without
142SN/A// modification, are permitted provided that the following conditions are
152SN/A// met: redistributions of source code must retain the above copyright
162SN/A// notice, this list of conditions and the following disclaimer;
172SN/A// redistributions in binary form must reproduce the above copyright
182SN/A// notice, this list of conditions and the following disclaimer in the
192SN/A// documentation and/or other materials provided with the distribution;
202SN/A// neither the name of the copyright holders nor the names of its
212SN/A// contributors may be used to endorse or promote products derived from
222SN/A// this software without specific prior written permission.
232SN/A//
242SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
252SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
262SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
272665Ssaidi@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
282665Ssaidi@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
292665Ssaidi@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
302665Ssaidi@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
312SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
322SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
332SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
342SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
356712Snate@binkert.org//
366712Snate@binkert.org// Authors: Giacomo Gabrielli
372SN/A
382SN/A// @file Definition of SVE memory access instructions.
393971Sgblack@eecs.umich.edu
4056SN/Aoutput header {{
4156SN/A
421158SN/A    // Decodes SVE contiguous load instructions, scalar plus scalar form.
43146SN/A    template <template <typename T1, typename T2> class Base>
441858SN/A    StaticInstPtr
456658Snate@binkert.org    decodeSveContigLoadSSInsts(uint8_t dtype, ExtMachInst machInst,
462680Sktlim@umich.edu                               IntRegIndex zt, IntRegIndex pg, IntRegIndex rn,
472378SN/A                               IntRegIndex rm, bool firstFaulting)
482522SN/A    {
492401SN/A        const char* mn = firstFaulting ? "ldff1" : "ld1";
505154Sgblack@eecs.umich.edu        switch (dtype) {
514762Snate@binkert.org          case 0x0:
525512SMichael.Adler@intel.com            return new Base<uint8_t, uint8_t>(mn, machInst, zt, pg, rn, rm);
53360SN/A          case 0x1:
544434Ssaidi@eecs.umich.edu            return new Base<uint16_t, uint8_t>(mn, machInst, zt, pg, rn, rm);
55695SN/A          case 0x2:
562093SN/A            return new Base<uint32_t, uint8_t>(mn, machInst, zt, pg, rn, rm);
572378SN/A          case 0x3:
582SN/A            return new Base<uint64_t, uint8_t>(mn, machInst, zt, pg, rn, rm);
592715Sstever@eecs.umich.edu          case 0x4:
602715Sstever@eecs.umich.edu            return new Base<int64_t, int32_t>(mn, machInst, zt, pg, rn, rm);
612715Sstever@eecs.umich.edu          case 0x5:
622715Sstever@eecs.umich.edu            return new Base<uint16_t, uint16_t>(mn, machInst, zt, pg, rn, rm);
632715Sstever@eecs.umich.edu          case 0x6:
642715Sstever@eecs.umich.edu            return new Base<uint32_t, uint16_t>(mn, machInst, zt, pg, rn, rm);
652715Sstever@eecs.umich.edu          case 0x7:
662715Sstever@eecs.umich.edu            return new Base<uint64_t, uint16_t>(mn, machInst, zt, pg, rn, rm);
675335Shines@cs.fsu.edu          case 0x8:
685335Shines@cs.fsu.edu            return new Base<int64_t, int16_t>(mn, machInst, zt, pg, rn, rm);
694157Sgblack@eecs.umich.edu          case 0x9:
704166Sgblack@eecs.umich.edu            return new Base<int32_t, int16_t>(mn, machInst, zt, pg, rn, rm);
716691Stjones1@inf.ed.ac.uk          case 0xa:
726691Stjones1@inf.ed.ac.uk            return new Base<uint32_t, uint32_t>(mn, machInst, zt, pg, rn, rm);
732715Sstever@eecs.umich.edu          case 0xb:
742715Sstever@eecs.umich.edu            return new Base<uint64_t, uint32_t>(mn, machInst, zt, pg, rn, rm);
752715Sstever@eecs.umich.edu          case 0xc:
762715Sstever@eecs.umich.edu            return new Base<int64_t, int8_t>(mn, machInst, zt, pg, rn, rm);
772715Sstever@eecs.umich.edu          case 0xd:
782SN/A            return new Base<int32_t, int8_t>(mn, machInst, zt, pg, rn, rm);
792107SN/A          case 0xe:
802SN/A            return new Base<int16_t, int8_t>(mn, machInst, zt, pg, rn, rm);
812SN/A          case 0xf:
822SN/A            return new Base<uint64_t, uint64_t>(mn, machInst, zt, pg, rn, rm);
832SN/A        }
842SN/A        return new Unknown64(machInst);
852SN/A    }
861858SN/A
87360SN/A    // Decodes SVE contiguous load instructions, scalar plus immediate form.
882SN/A    template <template <typename T1, typename T2> class Base>
892SN/A    StaticInstPtr
902SN/A    decodeSveContigLoadSIInsts(uint8_t dtype, ExtMachInst machInst,
912SN/A                               IntRegIndex zt, IntRegIndex pg, IntRegIndex rn,
922SN/A                               uint64_t imm, bool nonFaulting,
935758Shsul@eecs.umich.edu                               bool replicate = false)
945771Shsul@eecs.umich.edu    {
955758Shsul@eecs.umich.edu        assert(!(nonFaulting && replicate));
965758Shsul@eecs.umich.edu        const char* mn = replicate ? "ld1r" : (nonFaulting ? "ldnf1" : "ld1");
975758Shsul@eecs.umich.edu        switch (dtype) {
985758Shsul@eecs.umich.edu          case 0x0:
995758Shsul@eecs.umich.edu            return new Base<uint8_t, uint8_t>(mn, machInst, zt, pg, rn, imm);
1005771Shsul@eecs.umich.edu          case 0x1:
1015771Shsul@eecs.umich.edu            return new Base<uint16_t, uint8_t>(mn, machInst, zt, pg, rn, imm);
1025758Shsul@eecs.umich.edu          case 0x2:
1035154Sgblack@eecs.umich.edu            return new Base<uint32_t, uint8_t>(mn, machInst, zt, pg, rn, imm);
1045183Ssaidi@eecs.umich.edu          case 0x3:
1055154Sgblack@eecs.umich.edu            return new Base<uint64_t, uint8_t>(mn, machInst, zt, pg, rn, imm);
1062SN/A          case 0x4:
1075154Sgblack@eecs.umich.edu            return new Base<int64_t, int32_t>(mn, machInst, zt, pg, rn, imm);
1085154Sgblack@eecs.umich.edu          case 0x5:
1095514SMichael.Adler@intel.com            return new Base<uint16_t, uint16_t>(mn, machInst, zt, pg, rn, imm);
1105154Sgblack@eecs.umich.edu          case 0x6:
1115154Sgblack@eecs.umich.edu            return new Base<uint32_t, uint16_t>(mn, machInst, zt, pg, rn, imm);
1125154Sgblack@eecs.umich.edu          case 0x7:
1135154Sgblack@eecs.umich.edu            return new Base<uint64_t, uint16_t>(mn, machInst, zt, pg, rn, imm);
1145154Sgblack@eecs.umich.edu          case 0x8:
1155154Sgblack@eecs.umich.edu            return new Base<int64_t, int16_t>(mn, machInst, zt, pg, rn, imm);
1165154Sgblack@eecs.umich.edu          case 0x9:
1175154Sgblack@eecs.umich.edu            return new Base<int32_t, int16_t>(mn, machInst, zt, pg, rn, imm);
1185154Sgblack@eecs.umich.edu          case 0xa:
1195154Sgblack@eecs.umich.edu            return new Base<uint32_t, uint32_t>(mn, machInst, zt, pg, rn, imm);
1205154Sgblack@eecs.umich.edu          case 0xb:
1215154Sgblack@eecs.umich.edu            return new Base<uint64_t, uint32_t>(mn, machInst, zt, pg, rn, imm);
1225154Sgblack@eecs.umich.edu          case 0xc:
1235154Sgblack@eecs.umich.edu            return new Base<int64_t, int8_t>(mn, machInst, zt, pg, rn, imm);
1245154Sgblack@eecs.umich.edu          case 0xd:
1255154Sgblack@eecs.umich.edu            return new Base<int32_t, int8_t>(mn, machInst, zt, pg, rn, imm);
1265154Sgblack@eecs.umich.edu          case 0xe:
1275154Sgblack@eecs.umich.edu            return new Base<int16_t, int8_t>(mn, machInst, zt, pg, rn, imm);
1285154Sgblack@eecs.umich.edu          case 0xf:
1295154Sgblack@eecs.umich.edu            return new Base<uint64_t, uint64_t>(mn, machInst, zt, pg, rn, imm);
1305514SMichael.Adler@intel.com        }
1315514SMichael.Adler@intel.com        return new Unknown64(machInst);
1325514SMichael.Adler@intel.com    }
1335514SMichael.Adler@intel.com
1345514SMichael.Adler@intel.com    // Decodes SVE contiguous store instructions, scalar plus scalar form.
1355514SMichael.Adler@intel.com    template <template <typename T1, typename T2> class Base>
1365514SMichael.Adler@intel.com    StaticInstPtr
1375514SMichael.Adler@intel.com    decodeSveContigStoreSSInsts(uint8_t dtype, ExtMachInst machInst,
1385514SMichael.Adler@intel.com                                IntRegIndex zt, IntRegIndex pg, IntRegIndex rn,
1395514SMichael.Adler@intel.com                                IntRegIndex rm)
1405154Sgblack@eecs.umich.edu    {
1414997Sgblack@eecs.umich.edu        const char* mn = "st1";
1422SN/A        switch (dtype) {
1435282Srstrong@cs.ucsd.edu          case 0x0:
1445282Srstrong@cs.ucsd.edu            return new Base<uint8_t, uint8_t>(mn, machInst, zt, pg, rn, rm);
1455282Srstrong@cs.ucsd.edu          case 0x1:
1465282Srstrong@cs.ucsd.edu            return new Base<uint16_t, uint8_t>(mn, machInst, zt, pg, rn, rm);
1475282Srstrong@cs.ucsd.edu          case 0x2:
1485282Srstrong@cs.ucsd.edu            return new Base<uint32_t, uint8_t>(mn, machInst, zt, pg, rn, rm);
1495282Srstrong@cs.ucsd.edu          case 0x3:
1505282Srstrong@cs.ucsd.edu            return new Base<uint64_t, uint8_t>(mn, machInst, zt, pg, rn, rm);
1515282Srstrong@cs.ucsd.edu          case 0x5:
1525282Srstrong@cs.ucsd.edu            return new Base<uint16_t, uint16_t>(mn, machInst, zt, pg, rn, rm);
1535282Srstrong@cs.ucsd.edu          case 0x6:
1545282Srstrong@cs.ucsd.edu            return new Base<uint32_t, uint16_t>(mn, machInst, zt, pg, rn, rm);
1555282Srstrong@cs.ucsd.edu          case 0x7:
1565282Srstrong@cs.ucsd.edu            return new Base<uint64_t, uint16_t>(mn, machInst, zt, pg, rn, rm);
1575282Srstrong@cs.ucsd.edu          case 0xa:
1585282Srstrong@cs.ucsd.edu            return new Base<uint32_t, uint32_t>(mn, machInst, zt, pg, rn, rm);
1595514SMichael.Adler@intel.com          case 0xb:
1605282Srstrong@cs.ucsd.edu            return new Base<uint64_t, uint32_t>(mn, machInst, zt, pg, rn, rm);
1615282Srstrong@cs.ucsd.edu          case 0xf:
1625282Srstrong@cs.ucsd.edu            return new Base<uint64_t, uint64_t>(mn, machInst, zt, pg, rn, rm);
1635282Srstrong@cs.ucsd.edu        }
1642SN/A        return new Unknown64(machInst);
1652SN/A    }
1662SN/A
1675282Srstrong@cs.ucsd.edu    // Decodes SVE contiguous store instructions, scalar plus immediate form.
1685282Srstrong@cs.ucsd.edu    template <template <typename T1, typename T2> class Base>
1692SN/A    StaticInstPtr
1702SN/A    decodeSveContigStoreSIInsts(uint8_t dtype, ExtMachInst machInst,
1711450SN/A                                IntRegIndex zt, IntRegIndex pg, IntRegIndex rn,
1721514SN/A                                int8_t imm)
1735184Sgblack@eecs.umich.edu    {
1742SN/A        const char* mn = "st1";
1752SN/A        switch (dtype) {
1762SN/A          case 0x0:
1772378SN/A            return new Base<uint8_t, uint8_t>(mn, machInst, zt, pg, rn, imm);
1782SN/A          case 0x1:
1792SN/A            return new Base<uint16_t, uint8_t>(mn, machInst, zt, pg, rn, imm);
1802SN/A          case 0x2:
181729SN/A            return new Base<uint32_t, uint8_t>(mn, machInst, zt, pg, rn, imm);
1822SN/A          case 0x3:
1832SN/A            return new Base<uint64_t, uint8_t>(mn, machInst, zt, pg, rn, imm);
1842SN/A          case 0x5:
1852SN/A            return new Base<uint16_t, uint16_t>(mn, machInst, zt, pg, rn, imm);
1862SN/A          case 0x6:
1872SN/A            return new Base<uint32_t, uint16_t>(mn, machInst, zt, pg, rn, imm);
1882SN/A          case 0x7:
1892SN/A            return new Base<uint64_t, uint16_t>(mn, machInst, zt, pg, rn, imm);
1902SN/A          case 0xa:
1912SN/A            return new Base<uint32_t, uint32_t>(mn, machInst, zt, pg, rn, imm);
1922SN/A          case 0xb:
1932SN/A            return new Base<uint64_t, uint32_t>(mn, machInst, zt, pg, rn, imm);
1942SN/A          case 0xf:
1952SN/A            return new Base<uint64_t, uint64_t>(mn, machInst, zt, pg, rn, imm);
1962SN/A        }
1972SN/A        return new Unknown64(machInst);
1982SN/A    }
1992SN/A
2002SN/A    // NOTE: SVE load-and-replicate instructions are decoded with
2012SN/A    // decodeSveContigLoadSIInsts(...).
2022SN/A
2032SN/A}};
2042SN/A
2052SN/Aoutput decoder {{
2062SN/A
2072SN/A    template <class etype>
2082SN/A    StaticInstPtr
2092SN/A    decodeSveStructLoadSIInstsByNReg(uint8_t esize, ExtMachInst machInst,
2105514SMichael.Adler@intel.com            IntRegIndex zt, IntRegIndex pg, IntRegIndex xn,
2112SN/A            int64_t imm, int numregs)
2122SN/A    {
2132SN/A        static const char* nm[5][4] = {
2142SN/A            { nullptr, nullptr, nullptr, nullptr},
2152SN/A            { nullptr, nullptr, nullptr, nullptr},
2162SN/A            { "ld2b", "ld2h", "ld2w", "ld2d" },
2172SN/A            { "ld3b", "ld3h", "ld3w", "ld3d" },
2182SN/A            { "ld4b", "ld4h", "ld4w", "ld4d" } };
2192SN/A
2202SN/A        switch (numregs) {
2215713Shsul@eecs.umich.edu            case 2:
2225713Shsul@eecs.umich.edu                return new SveLdStructSI<etype,
2232SN/A                        SveLoadRegImmMicroop,
2245713Shsul@eecs.umich.edu                        SveDeIntrlv2Microop>(
2255713Shsul@eecs.umich.edu                               nm[numregs][esize], machInst, MemReadOp,
2265713Shsul@eecs.umich.edu                               zt, pg, xn, imm, numregs);
2275713Shsul@eecs.umich.edu            case 3:
2286029Ssteve.reinhardt@amd.com                return new SveLdStructSI<etype,
2295713Shsul@eecs.umich.edu                        SveLoadRegImmMicroop,
2305713Shsul@eecs.umich.edu                        SveDeIntrlv3Microop>(
2315713Shsul@eecs.umich.edu                               nm[numregs][esize], machInst, MemReadOp,
2325512SMichael.Adler@intel.com                               zt, pg, xn, imm, numregs);
2335713Shsul@eecs.umich.edu            case 4:
2342SN/A                return new SveLdStructSI<etype,
2352SN/A                        SveLoadRegImmMicroop,
2361395SN/A                        SveDeIntrlv4Microop>(
2371395SN/A                               nm[numregs][esize], machInst, MemReadOp,
2381395SN/A                               zt, pg, xn, imm, numregs);
2395713Shsul@eecs.umich.edu        }
2405713Shsul@eecs.umich.edu        return new Unknown64(machInst);
2412378SN/A    }
2422680Sktlim@umich.edu
2435713Shsul@eecs.umich.edu    StaticInstPtr
2441395SN/A    decodeSveStructLoadSIInsts(uint8_t esize, ExtMachInst machInst,
2451634SN/A            IntRegIndex zt, IntRegIndex pg, IntRegIndex xn,
2462680Sktlim@umich.edu            int64_t imm, int numregs)
2472462SN/A    {
2482519SN/A        switch (esize) {
2492519SN/A            case 0:
2504434Ssaidi@eecs.umich.edu                return decodeSveStructLoadSIInstsByNReg<uint8_t>(esize,
2514434Ssaidi@eecs.umich.edu                        machInst, zt, pg, xn, imm, numregs);
2522519SN/A            case 1:
2532519SN/A                return decodeSveStructLoadSIInstsByNReg<uint16_t>(esize,
2541395SN/A                        machInst, zt, pg, xn, imm, numregs);
2552SN/A            case 2:
2562SN/A                return decodeSveStructLoadSIInstsByNReg<uint32_t>(esize,
2572SN/A                        machInst, zt, pg, xn, imm, numregs);
2582SN/A            case 3:
2592SN/A                return decodeSveStructLoadSIInstsByNReg<uint64_t>(esize,
2602SN/A                        machInst, zt, pg, xn, imm, numregs);
2612SN/A        }
2622SN/A        return new Unknown64(machInst);
2635282Srstrong@cs.ucsd.edu    }
2645282Srstrong@cs.ucsd.edu
2652SN/A    template <class etype>
2662SN/A    StaticInstPtr
2672SN/A    decodeSveStructStoreSIInstsByNReg(uint8_t esize, ExtMachInst machInst,
2682SN/A            IntRegIndex zt, IntRegIndex pg, IntRegIndex xn,
2692SN/A            int64_t imm, int numregs)
2705282Srstrong@cs.ucsd.edu    {
2712SN/A        static const char* nm[5][4] = {
2722SN/A            { nullptr, nullptr, nullptr, nullptr},
2732SN/A            { nullptr, nullptr, nullptr, nullptr},
2742SN/A            { "st2b", "st2h", "st2w", "st2d" },
2752SN/A            { "st3b", "st3h", "st3w", "st3d" },
2762SN/A            { "st4b", "st4h", "st4w", "st4d" } };
2775282Srstrong@cs.ucsd.edu
2785282Srstrong@cs.ucsd.edu        switch (numregs) {
2795282Srstrong@cs.ucsd.edu            case 2:
2805282Srstrong@cs.ucsd.edu                return new SveStStructSI<etype,
2815282Srstrong@cs.ucsd.edu                        SveStoreRegImmMicroop,
2825282Srstrong@cs.ucsd.edu                        SveIntrlv2Microop>(
2835282Srstrong@cs.ucsd.edu                            nm[numregs][esize], machInst, MemWriteOp,
2845282Srstrong@cs.ucsd.edu                            zt, pg, xn, imm, numregs);
2855282Srstrong@cs.ucsd.edu            case 3:
2865282Srstrong@cs.ucsd.edu                return new SveStStructSI<etype,
2871970SN/A                        SveStoreRegImmMicroop,
2881970SN/A                        SveIntrlv3Microop>(
2892SN/A                            nm[numregs][esize], machInst, MemWriteOp,
2902SN/A                            zt, pg, xn, imm, numregs);
2911970SN/A           case 4:
2921970SN/A                return new SveStStructSI<etype,
2932SN/A                        SveStoreRegImmMicroop,
2941970SN/A                        SveIntrlv4Microop>(
2951970SN/A                            nm[numregs][esize], machInst, MemWriteOp,
2961970SN/A                            zt, pg, xn, imm, numregs);
2971970SN/A        }
2981970SN/A        return new Unknown64(machInst);
2995282Srstrong@cs.ucsd.edu    }
3005282Srstrong@cs.ucsd.edu
3011970SN/A    StaticInstPtr
3021970SN/A    decodeSveStructStoreSIInsts(uint8_t esize, ExtMachInst machInst,
3035282Srstrong@cs.ucsd.edu            IntRegIndex zt, IntRegIndex pg, IntRegIndex xn,
3045282Srstrong@cs.ucsd.edu            int64_t imm, int numregs)
3055282Srstrong@cs.ucsd.edu    {
3065282Srstrong@cs.ucsd.edu        switch (esize) {
3075282Srstrong@cs.ucsd.edu            case 0:
3085282Srstrong@cs.ucsd.edu                return decodeSveStructStoreSIInstsByNReg<uint8_t>(esize,
3095282Srstrong@cs.ucsd.edu                    machInst, zt, pg, xn, imm, numregs);
3102SN/A            case 1:
3112SN/A                return decodeSveStructStoreSIInstsByNReg<uint16_t>(esize,
3122SN/A                    machInst, zt, pg, xn, imm, numregs);
3132SN/A            case 2:
3142SN/A                return decodeSveStructStoreSIInstsByNReg<uint32_t>(esize,
3152SN/A                    machInst, zt, pg, xn, imm, numregs);
3162SN/A            case 3:
3172SN/A                return decodeSveStructStoreSIInstsByNReg<uint64_t>(esize,
3182SN/A                    machInst, zt, pg, xn, imm, numregs);
3192SN/A        }
3205282Srstrong@cs.ucsd.edu        return new Unknown64(machInst);
3212SN/A    }
3222SN/A
3235282Srstrong@cs.ucsd.edu    template <class etype>
3245282Srstrong@cs.ucsd.edu    StaticInstPtr
3255282Srstrong@cs.ucsd.edu    decodeSveStructLoadSSInstsByNReg(uint8_t esize, ExtMachInst machInst,
3265282Srstrong@cs.ucsd.edu            IntRegIndex zt, IntRegIndex pg, IntRegIndex xn,
3275282Srstrong@cs.ucsd.edu            IntRegIndex xm, int numregs)
3285282Srstrong@cs.ucsd.edu    {
3295282Srstrong@cs.ucsd.edu        static const char* nm[5][4] = {
3305282Srstrong@cs.ucsd.edu            { nullptr, nullptr, nullptr, nullptr},
3314434Ssaidi@eecs.umich.edu            { nullptr, nullptr, nullptr, nullptr},
3324434Ssaidi@eecs.umich.edu            { "ld2b", "ld2h", "ld2w", "ld2d" },
3334434Ssaidi@eecs.umich.edu            { "ld3b", "ld3h", "ld3w", "ld3d" },
3344434Ssaidi@eecs.umich.edu            { "ld4b", "ld4h", "ld4w", "ld4d" } };
3354434Ssaidi@eecs.umich.edu
3364434Ssaidi@eecs.umich.edu        switch (numregs) {
3374434Ssaidi@eecs.umich.edu            case 2:
3384434Ssaidi@eecs.umich.edu                return new SveLdStructSS<etype,
3394434Ssaidi@eecs.umich.edu                        SveLoadRegRegMicroop,
3404434Ssaidi@eecs.umich.edu                        SveDeIntrlv2Microop>(
3414434Ssaidi@eecs.umich.edu                               nm[numregs][esize], machInst, MemReadOp,
3425154Sgblack@eecs.umich.edu                               zt, pg, xn, xm, numregs);
3435154Sgblack@eecs.umich.edu            case 3:
3445154Sgblack@eecs.umich.edu                return new SveLdStructSS<etype,
3455154Sgblack@eecs.umich.edu                        SveLoadRegRegMicroop,
3465154Sgblack@eecs.umich.edu                        SveDeIntrlv3Microop>(
3475154Sgblack@eecs.umich.edu                               nm[numregs][esize], machInst, MemReadOp,
3485154Sgblack@eecs.umich.edu                               zt, pg, xn, xm, numregs);
3495154Sgblack@eecs.umich.edu            case 4:
3505823Ssaidi@eecs.umich.edu                return new SveLdStructSS<etype,
3515154Sgblack@eecs.umich.edu                        SveLoadRegRegMicroop,
3524434Ssaidi@eecs.umich.edu                        SveDeIntrlv4Microop>(
3534434Ssaidi@eecs.umich.edu                               nm[numregs][esize], machInst, MemReadOp,
3544434Ssaidi@eecs.umich.edu                               zt, pg, xn, xm, numregs);
3554434Ssaidi@eecs.umich.edu        }
3564434Ssaidi@eecs.umich.edu        return new Unknown64(machInst);
3575282Srstrong@cs.ucsd.edu    }
3585282Srstrong@cs.ucsd.edu
3595282Srstrong@cs.ucsd.edu    StaticInstPtr
3605282Srstrong@cs.ucsd.edu    decodeSveStructLoadSSInsts(uint8_t esize, ExtMachInst machInst,
3615282Srstrong@cs.ucsd.edu            IntRegIndex zt, IntRegIndex pg, IntRegIndex xn,
3625282Srstrong@cs.ucsd.edu            IntRegIndex xm, int numregs)
3635282Srstrong@cs.ucsd.edu    {
3645282Srstrong@cs.ucsd.edu        switch (esize) {
3655514SMichael.Adler@intel.com            case 0:
3665282Srstrong@cs.ucsd.edu                return decodeSveStructLoadSSInstsByNReg<uint8_t>(esize,
3675282Srstrong@cs.ucsd.edu                            machInst, zt, pg, xn, xm, numregs);
3685282Srstrong@cs.ucsd.edu            case 1:
3695282Srstrong@cs.ucsd.edu                return decodeSveStructLoadSSInstsByNReg<uint16_t>(esize,
3705282Srstrong@cs.ucsd.edu                            machInst, zt, pg, xn, xm, numregs);
3715282Srstrong@cs.ucsd.edu            case 2:
3725282Srstrong@cs.ucsd.edu                return decodeSveStructLoadSSInstsByNReg<uint32_t>(esize,
3735282Srstrong@cs.ucsd.edu                            machInst, zt, pg, xn, xm, numregs);
3745282Srstrong@cs.ucsd.edu            case 3:
3755282Srstrong@cs.ucsd.edu                return decodeSveStructLoadSSInstsByNReg<uint64_t>(esize,
3765282Srstrong@cs.ucsd.edu                            machInst, zt, pg, xn, xm, numregs);
3775282Srstrong@cs.ucsd.edu        }
3785282Srstrong@cs.ucsd.edu        return new Unknown64(machInst);
3795282Srstrong@cs.ucsd.edu    }
3805282Srstrong@cs.ucsd.edu
3815282Srstrong@cs.ucsd.edu    template <class etype>
3825282Srstrong@cs.ucsd.edu    StaticInstPtr
3835282Srstrong@cs.ucsd.edu    decodeSveStructStoreSSInstsByNReg(uint8_t esize, ExtMachInst machInst,
3845282Srstrong@cs.ucsd.edu            IntRegIndex zt, IntRegIndex pg, IntRegIndex xn,
3855282Srstrong@cs.ucsd.edu            IntRegIndex xm, int numregs)
3865282Srstrong@cs.ucsd.edu    {
3875282Srstrong@cs.ucsd.edu        static const char* nm[5][4] = {
3885282Srstrong@cs.ucsd.edu            { nullptr, nullptr, nullptr, nullptr},
3895514SMichael.Adler@intel.com            { nullptr, nullptr, nullptr, nullptr},
3905514SMichael.Adler@intel.com            { "st2b", "st2h", "st2w", "st2d" },
3915282Srstrong@cs.ucsd.edu            { "st3b", "st3h", "st3w", "st3d" },
3925282Srstrong@cs.ucsd.edu            { "st4b", "st4h", "st4w", "st4d" } };
3935514SMichael.Adler@intel.com
3945514SMichael.Adler@intel.com        switch (numregs) {
3955514SMichael.Adler@intel.com            case 2:
3965514SMichael.Adler@intel.com                return new SveStStructSS<etype,
3975514SMichael.Adler@intel.com                        SveStoreRegRegMicroop,
3985514SMichael.Adler@intel.com                        SveIntrlv2Microop>(
3995514SMichael.Adler@intel.com                               nm[numregs][esize], machInst, MemWriteOp,
4005514SMichael.Adler@intel.com                               zt, pg, xn, xm, numregs);
4015514SMichael.Adler@intel.com            case 3:
4025514SMichael.Adler@intel.com                return new SveStStructSS<etype,
4035514SMichael.Adler@intel.com                        SveStoreRegRegMicroop,
4045514SMichael.Adler@intel.com                        SveIntrlv3Microop>(
4055514SMichael.Adler@intel.com                               nm[numregs][esize], machInst, MemWriteOp,
4065282Srstrong@cs.ucsd.edu                               zt, pg, xn, xm, numregs);
4075282Srstrong@cs.ucsd.edu            case 4:
4085282Srstrong@cs.ucsd.edu                return new SveStStructSS<etype,
4095282Srstrong@cs.ucsd.edu                        SveStoreRegRegMicroop,
4105282Srstrong@cs.ucsd.edu                        SveIntrlv4Microop>(
4115282Srstrong@cs.ucsd.edu                               nm[numregs][esize], machInst, MemWriteOp,
4125282Srstrong@cs.ucsd.edu                               zt, pg, xn, xm, numregs);
4135282Srstrong@cs.ucsd.edu        }
4145282Srstrong@cs.ucsd.edu        return new Unknown64(machInst);
4155282Srstrong@cs.ucsd.edu    }
4165282Srstrong@cs.ucsd.edu
4175282Srstrong@cs.ucsd.edu    StaticInstPtr
4185282Srstrong@cs.ucsd.edu    decodeSveStructStoreSSInsts(uint8_t esize, ExtMachInst machInst,
4195282Srstrong@cs.ucsd.edu            IntRegIndex zt, IntRegIndex pg, IntRegIndex xn,
4205282Srstrong@cs.ucsd.edu            IntRegIndex xm, int numregs)
4215282Srstrong@cs.ucsd.edu    {
4225282Srstrong@cs.ucsd.edu        switch (esize) {
4235282Srstrong@cs.ucsd.edu            case 0:
4245282Srstrong@cs.ucsd.edu                return decodeSveStructStoreSSInstsByNReg<uint8_t>(esize,
4255282Srstrong@cs.ucsd.edu                            machInst, zt, pg, xn, xm, numregs);
4265282Srstrong@cs.ucsd.edu            case 1:
4275282Srstrong@cs.ucsd.edu                return decodeSveStructStoreSSInstsByNReg<uint16_t>(esize,
4285282Srstrong@cs.ucsd.edu                            machInst, zt, pg, xn, xm, numregs);
4295282Srstrong@cs.ucsd.edu            case 2:
4305282Srstrong@cs.ucsd.edu                return decodeSveStructStoreSSInstsByNReg<uint32_t>(esize,
4315282Srstrong@cs.ucsd.edu                            machInst, zt, pg, xn, xm, numregs);
4325282Srstrong@cs.ucsd.edu            case 3:
4335282Srstrong@cs.ucsd.edu                return decodeSveStructStoreSSInstsByNReg<uint64_t>(esize,
4345282Srstrong@cs.ucsd.edu                            machInst, zt, pg, xn, xm, numregs);
4355282Srstrong@cs.ucsd.edu        }
4365282Srstrong@cs.ucsd.edu        return new Unknown64(machInst);
4375282Srstrong@cs.ucsd.edu    }
4385282Srstrong@cs.ucsd.edu
4395282Srstrong@cs.ucsd.edu    StaticInstPtr
4405282Srstrong@cs.ucsd.edu    decodeSveGatherLoadVIInsts(uint8_t dtype, ExtMachInst machInst,
4415282Srstrong@cs.ucsd.edu                               IntRegIndex zt, IntRegIndex pg, IntRegIndex zn,
4425282Srstrong@cs.ucsd.edu                               uint64_t imm, bool esizeIs32,
4435282Srstrong@cs.ucsd.edu                               bool firstFault)
4445282Srstrong@cs.ucsd.edu    {
4455282Srstrong@cs.ucsd.edu        const char* mn = firstFault ? "ldff1" : "ld1";
4465282Srstrong@cs.ucsd.edu        switch (dtype) {
4475282Srstrong@cs.ucsd.edu          case 0x0:
4485282Srstrong@cs.ucsd.edu            if (esizeIs32) {
4495282Srstrong@cs.ucsd.edu                return new SveIndexedMemVI<int32_t, int8_t,
4505282Srstrong@cs.ucsd.edu                                           SveGatherLoadVIMicroop,
4515282Srstrong@cs.ucsd.edu                                           SveFirstFaultWritebackMicroop>(
4525282Srstrong@cs.ucsd.edu                    mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
4535282Srstrong@cs.ucsd.edu            } else {
4545282Srstrong@cs.ucsd.edu                return new SveIndexedMemVI<int64_t, int8_t,
4555282Srstrong@cs.ucsd.edu                                           SveGatherLoadVIMicroop,
4565282Srstrong@cs.ucsd.edu                                           SveFirstFaultWritebackMicroop>(
4575282Srstrong@cs.ucsd.edu                    mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
4585282Srstrong@cs.ucsd.edu            }
4595282Srstrong@cs.ucsd.edu          case 0x1:
4605282Srstrong@cs.ucsd.edu            if (esizeIs32) {
4615282Srstrong@cs.ucsd.edu                return new SveIndexedMemVI<uint32_t, uint8_t,
4625282Srstrong@cs.ucsd.edu                                           SveGatherLoadVIMicroop,
4635282Srstrong@cs.ucsd.edu                                           SveFirstFaultWritebackMicroop>(
4645282Srstrong@cs.ucsd.edu                    mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
4655282Srstrong@cs.ucsd.edu            } else {
4665282Srstrong@cs.ucsd.edu                return new SveIndexedMemVI<uint64_t, uint8_t,
4675282Srstrong@cs.ucsd.edu                                           SveGatherLoadVIMicroop,
4685282Srstrong@cs.ucsd.edu                                           SveFirstFaultWritebackMicroop>(
4695282Srstrong@cs.ucsd.edu                    mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
4705282Srstrong@cs.ucsd.edu            }
4715282Srstrong@cs.ucsd.edu          case 0x2:
4725282Srstrong@cs.ucsd.edu            if (esizeIs32) {
4735282Srstrong@cs.ucsd.edu                return new SveIndexedMemVI<int32_t, int16_t,
4745282Srstrong@cs.ucsd.edu                                           SveGatherLoadVIMicroop,
4755282Srstrong@cs.ucsd.edu                                           SveFirstFaultWritebackMicroop>(
4765282Srstrong@cs.ucsd.edu                    mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
4775282Srstrong@cs.ucsd.edu            } else {
4785282Srstrong@cs.ucsd.edu                return new SveIndexedMemVI<int64_t, int16_t,
4795282Srstrong@cs.ucsd.edu                                           SveGatherLoadVIMicroop,
4805282Srstrong@cs.ucsd.edu                                           SveFirstFaultWritebackMicroop>(
4815282Srstrong@cs.ucsd.edu                    mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
4825282Srstrong@cs.ucsd.edu            }
4835282Srstrong@cs.ucsd.edu          case 0x3:
4845282Srstrong@cs.ucsd.edu            if (esizeIs32) {
4855282Srstrong@cs.ucsd.edu                return new SveIndexedMemVI<uint32_t, uint16_t,
4865282Srstrong@cs.ucsd.edu                                           SveGatherLoadVIMicroop,
4875282Srstrong@cs.ucsd.edu                                           SveFirstFaultWritebackMicroop>(
4885282Srstrong@cs.ucsd.edu                    mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
4895282Srstrong@cs.ucsd.edu            } else {
4905282Srstrong@cs.ucsd.edu                return new SveIndexedMemVI<uint64_t, uint16_t,
4913311Ssaidi@eecs.umich.edu                                           SveGatherLoadVIMicroop,
4923311Ssaidi@eecs.umich.edu                                           SveFirstFaultWritebackMicroop>(
4933311Ssaidi@eecs.umich.edu                    mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
4943311Ssaidi@eecs.umich.edu            }
4953311Ssaidi@eecs.umich.edu          case 0x4:
4963311Ssaidi@eecs.umich.edu            if (esizeIs32) {
4973311Ssaidi@eecs.umich.edu                break;
4983311Ssaidi@eecs.umich.edu            } else {
4993311Ssaidi@eecs.umich.edu                return new SveIndexedMemVI<int64_t, int32_t,
5003311Ssaidi@eecs.umich.edu                                           SveGatherLoadVIMicroop,
5013311Ssaidi@eecs.umich.edu                                           SveFirstFaultWritebackMicroop>(
5023311Ssaidi@eecs.umich.edu                    mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
5033311Ssaidi@eecs.umich.edu            }
5045282Srstrong@cs.ucsd.edu          case 0x5:
5055282Srstrong@cs.ucsd.edu            if (esizeIs32) {
5065282Srstrong@cs.ucsd.edu                return new SveIndexedMemVI<uint32_t, uint32_t,
5075282Srstrong@cs.ucsd.edu                                           SveGatherLoadVIMicroop,
5085282Srstrong@cs.ucsd.edu                                           SveFirstFaultWritebackMicroop>(
5095282Srstrong@cs.ucsd.edu                    mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
5106820SLisa.Hsu@amd.com            } else {
5113311Ssaidi@eecs.umich.edu                return new SveIndexedMemVI<uint64_t, uint32_t,
5123311Ssaidi@eecs.umich.edu                                           SveGatherLoadVIMicroop,
5133311Ssaidi@eecs.umich.edu                                           SveFirstFaultWritebackMicroop>(
5143311Ssaidi@eecs.umich.edu                    mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
5153311Ssaidi@eecs.umich.edu            }
5163311Ssaidi@eecs.umich.edu          case 0x7:
5173311Ssaidi@eecs.umich.edu            if (esizeIs32) {
5183311Ssaidi@eecs.umich.edu                break;
5193311Ssaidi@eecs.umich.edu            } else {
5203311Ssaidi@eecs.umich.edu                return new SveIndexedMemVI<uint64_t, uint64_t,
5213311Ssaidi@eecs.umich.edu                                           SveGatherLoadVIMicroop,
5223311Ssaidi@eecs.umich.edu                                           SveFirstFaultWritebackMicroop>(
5233311Ssaidi@eecs.umich.edu                    mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
5243311Ssaidi@eecs.umich.edu            }
5253311Ssaidi@eecs.umich.edu        }
5263311Ssaidi@eecs.umich.edu        return new Unknown64(machInst);
5273311Ssaidi@eecs.umich.edu    }
5285282Srstrong@cs.ucsd.edu
5295282Srstrong@cs.ucsd.edu    StaticInstPtr
5305282Srstrong@cs.ucsd.edu    decodeSveGatherLoadSVInsts(uint8_t dtype, ExtMachInst machInst,
5315282Srstrong@cs.ucsd.edu                               IntRegIndex zt, IntRegIndex pg, IntRegIndex rn,
5326820SLisa.Hsu@amd.com                               IntRegIndex zm, bool esizeIs32, bool offsetIs32,
5336820SLisa.Hsu@amd.com                               bool offsetIsSigned, bool offsetIsScaled,
5346820SLisa.Hsu@amd.com                               bool firstFault)
5356820SLisa.Hsu@amd.com    {
5366820SLisa.Hsu@amd.com        const char* mn = firstFault ? "ldff1" : "ld1";
5375183Ssaidi@eecs.umich.edu        switch (dtype) {
5385183Ssaidi@eecs.umich.edu          case 0x0:
5395183Ssaidi@eecs.umich.edu            if (esizeIs32) {
5403311Ssaidi@eecs.umich.edu                return new SveIndexedMemSV<int32_t, int8_t,
5412SN/A                                           SveGatherLoadSVMicroop,
5422SN/A                                           SveFirstFaultWritebackMicroop>(
5432SN/A                    mn, machInst, MemReadOp, zt, pg, rn, zm,
5442SN/A                    offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
5452SN/A            } else {
5462SN/A                return new SveIndexedMemSV<int64_t, int8_t,
5472SN/A                                           SveGatherLoadSVMicroop,
5482SN/A                                           SveFirstFaultWritebackMicroop>(
54912SN/A                    mn, machInst, MemReadOp, zt, pg, rn, zm,
5505154Sgblack@eecs.umich.edu                    offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
5515154Sgblack@eecs.umich.edu            }
5525154Sgblack@eecs.umich.edu          case 0x1:
5532SN/A            if (esizeIs32) {
5545154Sgblack@eecs.umich.edu                return new SveIndexedMemSV<uint32_t, uint8_t,
5555154Sgblack@eecs.umich.edu                                           SveGatherLoadSVMicroop,
5565154Sgblack@eecs.umich.edu                                           SveFirstFaultWritebackMicroop>(
5575154Sgblack@eecs.umich.edu                    mn, machInst, MemReadOp, zt, pg, rn, zm,
5585154Sgblack@eecs.umich.edu                    offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
5595154Sgblack@eecs.umich.edu            } else {
5603114Sgblack@eecs.umich.edu                return new SveIndexedMemSV<uint64_t, uint8_t,
5615154Sgblack@eecs.umich.edu                                           SveGatherLoadSVMicroop,
56212SN/A                                           SveFirstFaultWritebackMicroop>(
5631158SN/A                    mn, machInst, MemReadOp, zt, pg, rn, zm,
5641158SN/A                    offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
5651158SN/A            }
5661158SN/A          case 0x2:
5671158SN/A            if (esizeIs32) {
5681158SN/A                return new SveIndexedMemSV<int32_t, int16_t,
5691158SN/A                                           SveGatherLoadSVMicroop,
5701158SN/A                                           SveFirstFaultWritebackMicroop>(
5711158SN/A                    mn, machInst, MemReadOp, zt, pg, rn, zm,
5721158SN/A                    offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
5731158SN/A            } else {
5742378SN/A                return new SveIndexedMemSV<int64_t, int16_t,
5751158SN/A                                           SveGatherLoadSVMicroop,
5762378SN/A                                           SveFirstFaultWritebackMicroop>(
5772474SN/A                    mn, machInst, MemReadOp, zt, pg, rn, zm,
5782378SN/A                    offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
5792378SN/A            }
58012SN/A          case 0x3:
5812378SN/A            if (esizeIs32) {
5822378SN/A                return new SveIndexedMemSV<uint32_t, uint16_t,
58312SN/A                                           SveGatherLoadSVMicroop,
58412SN/A                                           SveFirstFaultWritebackMicroop>(
5852474SN/A                    mn, machInst, MemReadOp, zt, pg, rn, zm,
5862474SN/A                    offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
58712SN/A            } else {
5886227Snate@binkert.org                return new SveIndexedMemSV<uint64_t, uint16_t,
58912SN/A                                           SveGatherLoadSVMicroop,
59012SN/A                                           SveFirstFaultWritebackMicroop>(
59112SN/A                    mn, machInst, MemReadOp, zt, pg, rn, zm,
5926227Snate@binkert.org                    offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
59312SN/A            }
59412SN/A          case 0x4:
59512SN/A            if (esizeIs32) {
59612SN/A                break;
59712SN/A            } else {
5983005Sstever@eecs.umich.edu                return new SveIndexedMemSV<int64_t, int32_t,
5993005Sstever@eecs.umich.edu                                           SveGatherLoadSVMicroop,
60012SN/A                                           SveFirstFaultWritebackMicroop>(
60112SN/A                    mn, machInst, MemReadOp, zt, pg, rn, zm,
60212SN/A                    offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
60312SN/A            }
6042800Ssaidi@eecs.umich.edu          case 0x5:
60512SN/A            if (esizeIs32) {
6062378SN/A                return new SveIndexedMemSV<uint32_t, uint32_t,
6072800Ssaidi@eecs.umich.edu                                           SveGatherLoadSVMicroop,
60812SN/A                                           SveFirstFaultWritebackMicroop>(
60912SN/A                    mn, machInst, MemReadOp, zt, pg, rn, zm,
6102523SN/A                    offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
61112SN/A            } else {
61212SN/A                return new SveIndexedMemSV<uint64_t, uint32_t,
61312SN/A                                           SveGatherLoadSVMicroop,
61412SN/A                                           SveFirstFaultWritebackMicroop>(
61512SN/A                    mn, machInst, MemReadOp, zt, pg, rn, zm,
61612SN/A                    offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
6172474SN/A            }
6182474SN/A          case 0x7:
6192474SN/A            if (esizeIs32) {
6202474SN/A                break;
6212474SN/A            } else {
6222474SN/A                return new SveIndexedMemSV<uint64_t, uint64_t,
6232474SN/A                                           SveGatherLoadSVMicroop,
6242474SN/A                                           SveFirstFaultWritebackMicroop>(
62512SN/A                    mn, machInst, MemReadOp, zt, pg, rn, zm,
6262378SN/A                    offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
6272378SN/A            }
62812SN/A        }
6295713Shsul@eecs.umich.edu        return new Unknown64(machInst);
6305713Shsul@eecs.umich.edu    }
6315958Sgblack@eecs.umich.edu
6325958Sgblack@eecs.umich.edu    StaticInstPtr
6335713Shsul@eecs.umich.edu    decodeSveScatterStoreVIInsts(uint8_t msz, ExtMachInst machInst,
6342451SN/A                                 IntRegIndex zt, IntRegIndex pg,
6352451SN/A                                 IntRegIndex zn, uint64_t imm,
6365713Shsul@eecs.umich.edu                                 bool esizeIs32)
6375713Shsul@eecs.umich.edu    {
6382817Sksewell@umich.edu        const char* mn = "st1";
6396691Stjones1@inf.ed.ac.uk        switch (msz) {
6405713Shsul@eecs.umich.edu          case 0x0:
6412817Sksewell@umich.edu            if (esizeIs32) {
6422378SN/A                return new SveIndexedMemVI<uint32_t, uint8_t,
6432378SN/A                                           SveScatterStoreVIMicroop,
6442SN/A                                           SveFirstFaultWritebackMicroop>(
6452SN/A                    mn, machInst, MemWriteOp, zt, pg, zn, imm, false);
6462093SN/A            } else {
6472680Sktlim@umich.edu                return new SveIndexedMemVI<uint64_t, uint8_t,
6482093SN/A                                           SveScatterStoreVIMicroop,
6492093SN/A                                           SveFirstFaultWritebackMicroop>(
6502093SN/A                    mn, machInst, MemWriteOp, zt, pg, zn, imm, false);
6512093SN/A            }
6522093SN/A          case 0x1:
6532093SN/A            if (esizeIs32) {
6542093SN/A                return new SveIndexedMemVI<uint32_t, uint16_t,
6552680Sktlim@umich.edu                                           SveScatterStoreVIMicroop,
6562093SN/A                                           SveFirstFaultWritebackMicroop>(
6572SN/A                    mn, machInst, MemWriteOp, zt, pg, zn, imm, false);
6586701Sgblack@eecs.umich.edu            } else {
6596701Sgblack@eecs.umich.edu                return new SveIndexedMemVI<uint64_t, uint16_t,
6606701Sgblack@eecs.umich.edu                                           SveScatterStoreVIMicroop,
6616701Sgblack@eecs.umich.edu                                           SveFirstFaultWritebackMicroop>(
6626701Sgblack@eecs.umich.edu                    mn, machInst, MemWriteOp, zt, pg, zn, imm, false);
6636701Sgblack@eecs.umich.edu            }
6642715Sstever@eecs.umich.edu          case 0x2:
6655154Sgblack@eecs.umich.edu            if (esizeIs32) {
6662715Sstever@eecs.umich.edu                return new SveIndexedMemVI<uint32_t, uint32_t,
6672715Sstever@eecs.umich.edu                                           SveScatterStoreVIMicroop,
6682715Sstever@eecs.umich.edu                                           SveFirstFaultWritebackMicroop>(
6695154Sgblack@eecs.umich.edu                    mn, machInst, MemWriteOp, zt, pg, zn, imm, false);
6705154Sgblack@eecs.umich.edu            } else {
6712715Sstever@eecs.umich.edu                return new SveIndexedMemVI<uint64_t, uint32_t,
6722715Sstever@eecs.umich.edu                                           SveScatterStoreVIMicroop,
6732715Sstever@eecs.umich.edu                                           SveFirstFaultWritebackMicroop>(
6742715Sstever@eecs.umich.edu                    mn, machInst, MemWriteOp, zt, pg, zn, imm, false);
6752715Sstever@eecs.umich.edu            }
6763917Ssaidi@eecs.umich.edu          case 0x3:
6773917Ssaidi@eecs.umich.edu            if (esizeIs32) {
6785070Ssaidi@eecs.umich.edu                break;
6793917Ssaidi@eecs.umich.edu            } else {
6803917Ssaidi@eecs.umich.edu                return new SveIndexedMemVI<uint64_t, uint64_t,
6815089Sgblack@eecs.umich.edu                                           SveScatterStoreVIMicroop,
6825753Ssteve.reinhardt@amd.com                                           SveFirstFaultWritebackMicroop>(
6835753Ssteve.reinhardt@amd.com                    mn, machInst, MemWriteOp, zt, pg, zn, imm, false);
6845753Ssteve.reinhardt@amd.com            }
6852715Sstever@eecs.umich.edu        }
6862715Sstever@eecs.umich.edu        return new Unknown64(machInst);
6875154Sgblack@eecs.umich.edu    }
6882715Sstever@eecs.umich.edu
6892715Sstever@eecs.umich.edu    StaticInstPtr
6905753Ssteve.reinhardt@amd.com    decodeSveScatterStoreSVInsts(uint8_t msz, ExtMachInst machInst,
6915753Ssteve.reinhardt@amd.com                                 IntRegIndex zt, IntRegIndex pg,
6925753Ssteve.reinhardt@amd.com                                 IntRegIndex rn, IntRegIndex zm,
6932715Sstever@eecs.umich.edu                                 bool esizeIs32, bool offsetIs32,
6945154Sgblack@eecs.umich.edu                                 bool offsetIsSigned, bool offsetIsScaled)
6952715Sstever@eecs.umich.edu    {
6962715Sstever@eecs.umich.edu        const char* mn = "st1";
6972715Sstever@eecs.umich.edu        switch (msz) {
6982715Sstever@eecs.umich.edu          case 0x0:
6992715Sstever@eecs.umich.edu            if (esizeIs32) {
7002715Sstever@eecs.umich.edu                return new SveIndexedMemSV<uint32_t, uint8_t,
7015753Ssteve.reinhardt@amd.com                                           SveScatterStoreSVMicroop,
7025753Ssteve.reinhardt@amd.com                                           SveFirstFaultWritebackMicroop>(
7032715Sstever@eecs.umich.edu                    mn, machInst, MemWriteOp, zt, pg, rn, zm,
7042715Sstever@eecs.umich.edu                    offsetIs32, offsetIsSigned, offsetIsScaled, false);
7055753Ssteve.reinhardt@amd.com            } else {
7065753Ssteve.reinhardt@amd.com                return new SveIndexedMemSV<uint64_t, uint8_t,
7075753Ssteve.reinhardt@amd.com                                           SveScatterStoreSVMicroop,
7082715Sstever@eecs.umich.edu                                           SveFirstFaultWritebackMicroop>(
7094111Sgblack@eecs.umich.edu                    mn, machInst, MemWriteOp, zt, pg, rn, zm,
7105154Sgblack@eecs.umich.edu                    offsetIs32, offsetIsSigned, offsetIsScaled, false);
7114111Sgblack@eecs.umich.edu            }
7125154Sgblack@eecs.umich.edu          case 0x1:
7134111Sgblack@eecs.umich.edu            if (esizeIs32) {
7142715Sstever@eecs.umich.edu                return new SveIndexedMemSV<uint32_t, uint16_t,
7152715Sstever@eecs.umich.edu                                           SveScatterStoreSVMicroop,
7162715Sstever@eecs.umich.edu                                           SveFirstFaultWritebackMicroop>(
7172715Sstever@eecs.umich.edu                    mn, machInst, MemWriteOp, zt, pg, rn, zm,
7185154Sgblack@eecs.umich.edu                    offsetIs32, offsetIsSigned, offsetIsScaled, false);
7192715Sstever@eecs.umich.edu            } else {
7205753Ssteve.reinhardt@amd.com                return new SveIndexedMemSV<uint64_t, uint16_t,
7212715Sstever@eecs.umich.edu                                           SveScatterStoreSVMicroop,
7222715Sstever@eecs.umich.edu                                           SveFirstFaultWritebackMicroop>(
7232715Sstever@eecs.umich.edu                    mn, machInst, MemWriteOp, zt, pg, rn, zm,
7244157Sgblack@eecs.umich.edu                    offsetIs32, offsetIsSigned, offsetIsScaled, false);
7255874Sgblack@eecs.umich.edu            }
7265874Sgblack@eecs.umich.edu          case 0x2:
7274166Sgblack@eecs.umich.edu            if (esizeIs32) {
7284157Sgblack@eecs.umich.edu                return new SveIndexedMemSV<uint32_t, uint32_t,
7295753Ssteve.reinhardt@amd.com                                           SveScatterStoreSVMicroop,
7305753Ssteve.reinhardt@amd.com                                           SveFirstFaultWritebackMicroop>(
7315753Ssteve.reinhardt@amd.com                    mn, machInst, MemWriteOp, zt, pg, rn, zm,
7324166Sgblack@eecs.umich.edu                    offsetIs32, offsetIsSigned, offsetIsScaled, false);
7335874Sgblack@eecs.umich.edu            } else {
7345955Sgblack@eecs.umich.edu                return new SveIndexedMemSV<uint64_t, uint32_t,
7355874Sgblack@eecs.umich.edu                                           SveScatterStoreSVMicroop,
7365955Sgblack@eecs.umich.edu                                           SveFirstFaultWritebackMicroop>(
7375874Sgblack@eecs.umich.edu                    mn, machInst, MemWriteOp, zt, pg, rn, zm,
7384166Sgblack@eecs.umich.edu                    offsetIs32, offsetIsSigned, offsetIsScaled, false);
7395753Ssteve.reinhardt@amd.com            }
7404157Sgblack@eecs.umich.edu          case 0x3:
7414157Sgblack@eecs.umich.edu            if (esizeIs32) {
7424157Sgblack@eecs.umich.edu                break;
7432715Sstever@eecs.umich.edu            } else {
7442715Sstever@eecs.umich.edu                return new SveIndexedMemSV<uint64_t, uint64_t,
7452715Sstever@eecs.umich.edu                                           SveScatterStoreSVMicroop,
7462715Sstever@eecs.umich.edu                                           SveFirstFaultWritebackMicroop>(
7475753Ssteve.reinhardt@amd.com                    mn, machInst, MemWriteOp, zt, pg, rn, zm,
7485753Ssteve.reinhardt@amd.com                    offsetIs32, offsetIsSigned, offsetIsScaled, false);
7495753Ssteve.reinhardt@amd.com            }
7502715Sstever@eecs.umich.edu        }
7515154Sgblack@eecs.umich.edu        return new Unknown64(machInst);
7522715Sstever@eecs.umich.edu    }
7532715Sstever@eecs.umich.edu
7542715Sstever@eecs.umich.edu}};
7552715Sstever@eecs.umich.edu
7562715Sstever@eecs.umich.edu
7575335Shines@cs.fsu.edulet {{
7587095Sgblack@eecs.umich.edu
7597095Sgblack@eecs.umich.edu    header_output = ''
7605335Shines@cs.fsu.edu    exec_output = ''
7615335Shines@cs.fsu.edu    decoders = { 'Generic': {} }
7625753Ssteve.reinhardt@amd.com
7635753Ssteve.reinhardt@amd.com    SPAlignmentCheckCode = '''
7645753Ssteve.reinhardt@amd.com        if (this->baseIsSP && bits(XBase, 3, 0) &&
7655335Shines@cs.fsu.edu            SPAlignmentCheckEnabled(xc->tcBase())) {
7667096Sgblack@eecs.umich.edu            return std::make_shared<SPAlignmentFault>();
7675335Shines@cs.fsu.edu        }
7686392Ssaidi@eecs.umich.edu    '''
7696392Ssaidi@eecs.umich.edu
7706392Ssaidi@eecs.umich.edu    def emitSveMemFillSpill(isPred):
7715335Shines@cs.fsu.edu        global header_output, exec_output, decoders
7725335Shines@cs.fsu.edu        eaCode = SPAlignmentCheckCode + '''
7735335Shines@cs.fsu.edu        int memAccessSize = %(memacc_size)s;
7746691Stjones1@inf.ed.ac.uk        EA = XBase + ((int64_t) imm * %(memacc_size)s)''' % {
7756691Stjones1@inf.ed.ac.uk            'memacc_size': 'eCount / 8' if isPred else 'eCount'}
7766691Stjones1@inf.ed.ac.uk        loadRdEnableCode = '''
7776691Stjones1@inf.ed.ac.uk        auto rdEn = std::vector<bool>();
7786691Stjones1@inf.ed.ac.uk        '''
7796691Stjones1@inf.ed.ac.uk        if isPred:
7806691Stjones1@inf.ed.ac.uk            loadMemAccCode = '''
7816691Stjones1@inf.ed.ac.uk            int index = 0;
7826691Stjones1@inf.ed.ac.uk            uint8_t byte;
7836691Stjones1@inf.ed.ac.uk            for (int i = 0; i < eCount / 8; i++) {
7846691Stjones1@inf.ed.ac.uk                byte = memDataView[i];
7856691Stjones1@inf.ed.ac.uk                for (int j = 0; j < 8; j++, index++) {
7866691Stjones1@inf.ed.ac.uk                    PDest_x[index] = (byte >> j) & 1;
7876691Stjones1@inf.ed.ac.uk                }
7882715Sstever@eecs.umich.edu            }
7892715Sstever@eecs.umich.edu            '''
7902715Sstever@eecs.umich.edu            storeMemAccCode = '''
7912715Sstever@eecs.umich.edu            int index = 0;
7922715Sstever@eecs.umich.edu            uint8_t byte;
7932715Sstever@eecs.umich.edu            for (int i = 0; i < eCount / 8; i++) {
7942715Sstever@eecs.umich.edu                byte = 0;
7952715Sstever@eecs.umich.edu                for (int j = 0; j < 8; j++, index++) {
7962715Sstever@eecs.umich.edu                    byte |= PDest_x[index] << j;
7972715Sstever@eecs.umich.edu                }
7984762Snate@binkert.org                memDataView[i] = byte;
7994762Snate@binkert.org            }
8002715Sstever@eecs.umich.edu            '''
8015154Sgblack@eecs.umich.edu            storeWrEnableCode = '''
8022715Sstever@eecs.umich.edu            auto wrEn = std::vector<bool>(eCount / 8, true);
803            '''
804        else:
805            loadMemAccCode = '''
806            for (int i = 0; i < eCount; i++) {
807                AA64FpDest_x[i] = memDataView[i];
808            }
809            '''
810            storeMemAccCode = '''
811            for (int i = 0; i < eCount; i++) {
812                memDataView[i] = AA64FpDest_x[i];
813            }
814            '''
815            storeWrEnableCode = '''
816            auto wrEn = std::vector<bool>(sizeof(MemElemType) * eCount, true);
817            '''
818        loadIop = InstObjParams('ldr',
819            'SveLdrPred' if isPred else 'SveLdrVec',
820            'SveMemPredFillSpill' if isPred else 'SveMemVecFillSpill',
821            {'tpl_header': '',
822             'tpl_args': '',
823             'memacc_code': loadMemAccCode,
824             'ea_code' : sveEnabledCheckCode + eaCode,
825             'rden_code' : loadRdEnableCode,
826             'fault_code' : '',
827             'fa_code' : ''},
828            ['IsMemRef', 'IsLoad'])
829        storeIop = InstObjParams('str',
830            'SveStrPred' if isPred else 'SveStrVec',
831            'SveMemPredFillSpill' if isPred else 'SveMemVecFillSpill',
832            {'tpl_header': '',
833             'tpl_args': '',
834             'wren_code': storeWrEnableCode,
835             'memacc_code': storeMemAccCode,
836             'ea_code' : sveEnabledCheckCode + eaCode,
837             'fa_code' : ''},
838            ['IsMemRef', 'IsStore'])
839        header_output += SveMemFillSpillOpDeclare.subst(loadIop)
840        header_output += SveMemFillSpillOpDeclare.subst(storeIop)
841        exec_output += (
842            SveContigLoadExecute.subst(loadIop) +
843            SveContigLoadInitiateAcc.subst(loadIop) +
844            SveContigLoadCompleteAcc.subst(loadIop) +
845            SveContigStoreExecute.subst(storeIop) +
846            SveContigStoreInitiateAcc.subst(storeIop) +
847            SveContigStoreCompleteAcc.subst(storeIop))
848
849    loadTplArgs = (
850        ('uint8_t', 'uint8_t'),
851        ('uint16_t', 'uint8_t'),
852        ('uint32_t', 'uint8_t'),
853        ('uint64_t', 'uint8_t'),
854        ('int64_t', 'int32_t'),
855        ('uint16_t', 'uint16_t'),
856        ('uint32_t', 'uint16_t'),
857        ('uint64_t', 'uint16_t'),
858        ('int64_t', 'int16_t'),
859        ('int32_t', 'int16_t'),
860        ('uint32_t', 'uint32_t'),
861        ('uint64_t', 'uint32_t'),
862        ('int64_t', 'int8_t'),
863        ('int32_t', 'int8_t'),
864        ('int16_t', 'int8_t'),
865        ('uint64_t', 'uint64_t'),
866    )
867
868    storeTplArgs = (
869        ('uint8_t', 'uint8_t'),
870        ('uint16_t', 'uint8_t'),
871        ('uint32_t', 'uint8_t'),
872        ('uint64_t', 'uint8_t'),
873        ('uint16_t', 'uint16_t'),
874        ('uint32_t', 'uint16_t'),
875        ('uint64_t', 'uint16_t'),
876        ('uint32_t', 'uint32_t'),
877        ('uint64_t', 'uint32_t'),
878        ('uint64_t', 'uint64_t'),
879    )
880
881    gatherLoadTplArgs = (
882        ('int32_t', 'int8_t'),
883        ('int64_t', 'int8_t'),
884        ('uint32_t', 'uint8_t'),
885        ('uint64_t', 'uint8_t'),
886        ('int32_t', 'int16_t'),
887        ('int64_t', 'int16_t'),
888        ('uint32_t', 'uint16_t'),
889        ('uint64_t', 'uint16_t'),
890        ('int64_t', 'int32_t'),
891        ('uint32_t', 'uint32_t'),
892        ('uint64_t', 'uint32_t'),
893        ('uint64_t', 'uint64_t'),
894    )
895
896    scatterStoreTplArgs = (
897        ('uint32_t', 'uint8_t'),
898        ('uint64_t', 'uint8_t'),
899        ('uint32_t', 'uint16_t'),
900        ('uint64_t', 'uint16_t'),
901        ('uint32_t', 'uint32_t'),
902        ('uint64_t', 'uint32_t'),
903        ('uint64_t', 'uint64_t'),
904    )
905
906    # Generates definitions for SVE contiguous loads
907    def emitSveContigMemInsts(offsetIsImm):
908        global header_output, exec_output, decoders
909        # First-faulting instructions only have a scalar plus scalar form,
910        # while non-faulting instructions only a scalar plus immediate form, so
911        # `offsetIsImm` is used to determine which class of instructions is
912        # generated
913        firstFaulting = not offsetIsImm
914        tplHeader = 'template <class RegElemType, class MemElemType>'
915        tplArgs = '<RegElemType, MemElemType>'
916        eaCode = SPAlignmentCheckCode + '''
917        int memAccessSize = eCount * sizeof(MemElemType);
918        EA = XBase + '''
919        if offsetIsImm:
920            eaCode += '((int64_t) this->imm * eCount * sizeof(MemElemType))'
921        else:
922            eaCode += '(XOffset * sizeof(MemElemType));'
923        loadRdEnableCode = '''
924        auto rdEn = std::vector<bool>(sizeof(MemElemType) * eCount, true);
925        for (int i = 0; i < eCount; i++) {
926            if (!GpOp_x[i]) {
927                for (int j = 0; j < sizeof(MemElemType); j++) {
928                    rdEn[sizeof(MemElemType) * i + j] = false;
929                }
930            }
931        }
932        '''
933        loadMemAccCode = '''
934        for (int i = 0; i < eCount; i++) {
935            if (GpOp_x[i]) {
936                AA64FpDest_x[i] = memDataView[i];
937            } else {
938                AA64FpDest_x[i] = 0;
939            }
940        }
941        '''
942        storeMemAccCode = '''
943        for (int i = 0; i < eCount; i++) {
944            if (GpOp_x[i]) {
945                memDataView[i] = AA64FpDest_x[i];
946            } else {
947                memDataView[i] = 0;
948                for (int j = 0; j < sizeof(MemElemType); j++) {
949                    wrEn[sizeof(MemElemType) * i + j] = false;
950                }
951            }
952        }
953        '''
954        storeWrEnableCode = '''
955        auto wrEn = std::vector<bool>(sizeof(MemElemType) * eCount, true);
956        '''
957        ffrReadBackCode = '''
958        auto& firstFaultReg = Ffr;'''
959        fautlingLoadmemAccCode = '''
960        for (int i = 0; i < eCount; i++) {
961            if (GpOp_x[i] && firstFaultReg[i * sizeof(RegElemType)]) {
962                AA64FpDest_x[i] = memDataView[i];
963            } else {
964                AA64FpDest_x[i] = 0;
965            }
966        }
967        '''
968        nonFaultingCode = 'true ||'
969        faultCode = '''
970        Addr fault_addr;
971        if (fault == NoFault || getFaultVAddr(fault, fault_addr)) {
972            unsigned fault_elem_index;
973            if (fault != NoFault) {
974                assert(fault_addr >= EA);
975                fault_elem_index = (fault_addr - EA) / sizeof(MemElemType);
976            } else {
977                fault_elem_index = eCount + 1;
978            }
979            int first_active_index;
980            for (first_active_index = 0;
981                 first_active_index < eCount && !(GpOp_x[first_active_index]);
982                 first_active_index++);
983            if (%s first_active_index < fault_elem_index) {
984                for (int i = 0; i < eCount; i++) {
985                    for (int j = 0; j < sizeof(RegElemType); j++) {
986                        if (i < fault_elem_index) {
987                            Ffr_ub[i * sizeof(RegElemType) + j] = FfrAux_x[i];
988                        } else {
989                            Ffr_ub[i * sizeof(RegElemType) + j] = 0;
990                        }
991                    }
992                }
993                fault = NoFault;
994                if (first_active_index >= fault_elem_index) {
995                    // non-faulting load needs this
996                    xc->setMemAccPredicate(false);
997                }
998            }
999        }
1000        ''' % ('' if firstFaulting else nonFaultingCode)
1001
1002        loadIop = InstObjParams('ld1',
1003            'SveContigLoadSI' if offsetIsImm else 'SveContigLoadSS',
1004            'SveContigMemSI' if offsetIsImm else 'SveContigMemSS',
1005            {'tpl_header': tplHeader,
1006             'tpl_args': tplArgs,
1007             'rden_code' : loadRdEnableCode,
1008             'memacc_code': loadMemAccCode,
1009             'ea_code' : sveEnabledCheckCode + eaCode,
1010             'fault_code' : '',
1011             'fa_code' : ''},
1012            ['IsMemRef', 'IsLoad'])
1013        storeIop = InstObjParams('st1',
1014            'SveContigStoreSI' if offsetIsImm else 'SveContigStoreSS',
1015            'SveContigMemSI' if offsetIsImm else 'SveContigMemSS',
1016            {'tpl_header': tplHeader,
1017             'tpl_args': tplArgs,
1018             'wren_code': storeWrEnableCode,
1019             'memacc_code': storeMemAccCode,
1020             'ea_code' : sveEnabledCheckCode + eaCode,
1021             'fa_code' : ''},
1022            ['IsMemRef', 'IsStore'])
1023        faultIop = InstObjParams('ldff1' if firstFaulting else 'ldnf1',
1024            'SveContigFFLoadSS' if firstFaulting else 'SveContigNFLoadSI',
1025            'SveContigMemSS' if firstFaulting else 'SveContigMemSI',
1026            {'tpl_header': tplHeader,
1027             'tpl_args': tplArgs,
1028             'rden_code' : loadRdEnableCode,
1029             'memacc_code': fautlingLoadmemAccCode,
1030             'ea_code' : sveEnabledCheckCode + eaCode,
1031             'fault_code' : faultCode,
1032             'fa_code' : ''},
1033            ['IsMemRef', 'IsLoad'])
1034        faultIop.snippets['memacc_code'] = (ffrReadBackCode +
1035                                           faultIop.snippets['memacc_code'])
1036        if offsetIsImm:
1037            header_output += SveContigMemSIOpDeclare.subst(loadIop)
1038            header_output += SveContigMemSIOpDeclare.subst(storeIop)
1039            header_output += SveContigMemSIOpDeclare.subst(faultIop)
1040        else:
1041            header_output += SveContigMemSSOpDeclare.subst(loadIop)
1042            header_output += SveContigMemSSOpDeclare.subst(storeIop)
1043            header_output += SveContigMemSSOpDeclare.subst(faultIop)
1044        exec_output += (
1045            SveContigLoadExecute.subst(loadIop) +
1046            SveContigLoadInitiateAcc.subst(loadIop) +
1047            SveContigLoadCompleteAcc.subst(loadIop) +
1048            SveContigStoreExecute.subst(storeIop) +
1049            SveContigStoreInitiateAcc.subst(storeIop) +
1050            SveContigStoreCompleteAcc.subst(storeIop) +
1051            SveContigLoadExecute.subst(faultIop) +
1052            SveContigLoadInitiateAcc.subst(faultIop) +
1053            SveContigLoadCompleteAcc.subst(faultIop))
1054
1055        for args in loadTplArgs:
1056            substDict = {'tpl_args': '<%s>' % ', '.join(args),
1057                         'class_name': 'SveContigLoadSI' if offsetIsImm
1058                                       else 'SveContigLoadSS'}
1059            exec_output += SveContigMemExecDeclare.subst(substDict)
1060        for args in storeTplArgs:
1061            substDict = {'tpl_args': '<%s>' % ', '.join(args),
1062                         'class_name': 'SveContigStoreSI' if offsetIsImm
1063                                       else 'SveContigStoreSS'}
1064            exec_output += SveContigMemExecDeclare.subst(substDict)
1065        for args in loadTplArgs:
1066            substDict = {'tpl_args': '<%s>' % ', '.join(args),
1067                         'class_name': 'SveContigFFLoadSS' if firstFaulting
1068                                       else 'SveContigNFLoadSI'}
1069            exec_output += SveContigMemExecDeclare.subst(substDict)
1070
1071
1072    # Generates definitions for SVE load-and-replicate instructions
1073    def emitSveLoadAndRepl():
1074        global header_output, exec_output, decoders
1075        tplHeader = 'template <class RegElemType, class MemElemType>'
1076        tplArgs = '<RegElemType, MemElemType>'
1077        eaCode = SPAlignmentCheckCode + '''
1078        EA = XBase + imm * sizeof(MemElemType);'''
1079        memAccCode = '''
1080        for (int i = 0; i < eCount; i++) {
1081            if (GpOp_x[i]) {
1082                AA64FpDest_x[i] = memData;
1083            } else {
1084                AA64FpDest_x[i] = 0;
1085            }
1086        }
1087        '''
1088        iop = InstObjParams('ld1r',
1089            'SveLoadAndRepl',
1090            'SveContigMemSI',
1091            {'tpl_header': tplHeader,
1092             'tpl_args': tplArgs,
1093             'memacc_code': memAccCode,
1094             'ea_code' : sveEnabledCheckCode + eaCode,
1095             'fa_code' : ''},
1096            ['IsMemRef', 'IsLoad'])
1097        header_output += SveContigMemSIOpDeclare.subst(iop)
1098        exec_output += (
1099            SveLoadAndReplExecute.subst(iop) +
1100            SveLoadAndReplInitiateAcc.subst(iop) +
1101            SveLoadAndReplCompleteAcc.subst(iop))
1102        for args in loadTplArgs:
1103            substDict = {'tpl_args': '<%s>' % ', '.join(args),
1104                         'class_name': 'SveLoadAndRepl'}
1105            exec_output += SveContigMemExecDeclare.subst(substDict)
1106
1107    class IndexedAddrForm:
1108        VEC_PLUS_IMM = 0
1109        SCA_PLUS_VEC = 1
1110
1111    # Generates definitions for the transfer microops of SVE indexed memory
1112    # operations (gather loads, scatter stores)
1113    def emitSveIndexedMemMicroops(indexed_addr_form):
1114        assert indexed_addr_form in (IndexedAddrForm.VEC_PLUS_IMM,
1115                                     IndexedAddrForm.SCA_PLUS_VEC)
1116        global header_output, exec_output, decoders
1117        tplHeader = 'template <class RegElemType, class MemElemType>'
1118        tplArgs = '<RegElemType, MemElemType>'
1119        if indexed_addr_form == IndexedAddrForm.VEC_PLUS_IMM:
1120            eaCode = '''
1121        EA = AA64FpBase_x[elemIndex] + imm * sizeof(MemElemType)'''
1122        else:
1123            eaCode = '''
1124        uint64_t offset = AA64FpOffset_x[elemIndex];
1125        if (offsetIs32) {
1126            offset &= (1ULL << 32) - 1;
1127        }
1128        if (offsetIsSigned) {
1129            offset = sext<32>(offset);
1130        }
1131        if (offsetIsScaled) {
1132            offset *= sizeof(MemElemType);
1133        }
1134        EA = XBase + offset'''
1135        loadMemAccCode = '''
1136            AA64FpDest_x[elemIndex] = memData;
1137        '''
1138        storeMemAccCode = '''
1139            memData = AA64FpDest_x[elemIndex];
1140        '''
1141        predCheckCode = 'GpOp_x[index]'
1142        faultStatusSetCode = 'PUreg0_x[elemIndex] = 1;'
1143        faultStatusResetCode = 'PUreg0_x[elemIndex] = 0;'
1144        loadIop = InstObjParams('ld1',
1145            ('SveGatherLoadVIMicroop'
1146             if indexed_addr_form == IndexedAddrForm.VEC_PLUS_IMM
1147             else 'SveGatherLoadSVMicroop'),
1148            'MicroOp',
1149            {'tpl_header': tplHeader,
1150             'tpl_args': tplArgs,
1151             'memacc_code': loadMemAccCode,
1152             'ea_code' : sveEnabledCheckCode + eaCode,
1153             'fault_status_set_code' : faultStatusSetCode,
1154             'fault_status_reset_code' : faultStatusResetCode,
1155             'pred_check_code' : predCheckCode,
1156             'fa_code' : ''},
1157            ['IsMicroop', 'IsMemRef', 'IsLoad'])
1158        storeIop = InstObjParams('st1',
1159            ('SveScatterStoreVIMicroop'
1160             if indexed_addr_form == IndexedAddrForm.VEC_PLUS_IMM
1161             else 'SveScatterStoreSVMicroop'),
1162            'MicroOp',
1163            {'tpl_header': tplHeader,
1164             'tpl_args': tplArgs,
1165             'memacc_code': storeMemAccCode,
1166             'ea_code' : sveEnabledCheckCode + eaCode,
1167             'pred_check_code' : predCheckCode,
1168             'fa_code' : ''},
1169            ['IsMicroop', 'IsMemRef', 'IsStore'])
1170        if indexed_addr_form == IndexedAddrForm.VEC_PLUS_IMM:
1171            header_output += SveIndexedMemVIMicroopDeclare.subst(loadIop)
1172            header_output += SveIndexedMemVIMicroopDeclare.subst(storeIop)
1173        else:
1174            header_output += SveIndexedMemSVMicroopDeclare.subst(loadIop)
1175            header_output += SveIndexedMemSVMicroopDeclare.subst(storeIop)
1176        exec_output += (
1177            SveGatherLoadMicroopExecute.subst(loadIop) +
1178            SveGatherLoadMicroopInitiateAcc.subst(loadIop) +
1179            SveGatherLoadMicroopCompleteAcc.subst(loadIop) +
1180            SveScatterStoreMicroopExecute.subst(storeIop) +
1181            SveScatterStoreMicroopInitiateAcc.subst(storeIop) +
1182            SveScatterStoreMicroopCompleteAcc.subst(storeIop))
1183        for args in gatherLoadTplArgs:
1184            substDict = {'tpl_args': '<%s>' % ', '.join(args),
1185                         'class_name': (
1186                             'SveGatherLoadVIMicroop'
1187                             if indexed_addr_form == \
1188                                 IndexedAddrForm.VEC_PLUS_IMM
1189                             else 'SveGatherLoadSVMicroop')}
1190            # TODO: this should become SveMemExecDeclare
1191            exec_output += SveContigMemExecDeclare.subst(substDict)
1192        for args in scatterStoreTplArgs:
1193            substDict = {'tpl_args': '<%s>' % ', '.join(args),
1194                         'class_name': (
1195                             'SveScatterStoreVIMicroop'
1196                             if indexed_addr_form == \
1197                                 IndexedAddrForm.VEC_PLUS_IMM
1198                             else 'SveScatterStoreSVMicroop')}
1199            # TODO: this should become SveMemExecDeclare
1200            exec_output += SveContigMemExecDeclare.subst(substDict)
1201
1202    firstFaultTplArgs = ('int32_t', 'int64_t', 'uint32_t', 'uint64_t')
1203
1204    def emitSveFirstFaultWritebackMicroop():
1205        global header_output, exec_output, decoders
1206        tplHeader = 'template <class RegElemType>'
1207        tplArgs = '<RegElemType>'
1208        faultStatusCheckCode = 'PUreg0_x[index]'
1209        firstFaultResetCode = '''
1210        for(int j = 0; j < sizeof(RegElemType); j++) {
1211            Ffr_ub[index * sizeof(RegElemType) + j] = 0;
1212        }
1213        '''
1214        firstFaultForwardCode = '''
1215        for(int j = 0; j < sizeof(RegElemType); j++) {
1216            Ffr_ub[index * sizeof(RegElemType) + j] = FfrAux_x[index];
1217        }
1218        '''
1219        iop = InstObjParams('ldff1',
1220            'SveFirstFaultWritebackMicroop',
1221            'MicroOp',
1222            {'tpl_header': tplHeader,
1223             'tpl_args': tplArgs,
1224             'fault_status_check_code' : faultStatusCheckCode,
1225             'first_fault_reset_code' : firstFaultResetCode,
1226             'first_fault_forward_code' : firstFaultForwardCode},
1227             ['IsMicroop'])
1228        header_output += SveFirstFaultWritebackMicroopDeclare.subst(iop)
1229        exec_output += SveFirstFaultWritebackMicroopExecute.subst(iop)
1230        for args in firstFaultTplArgs:
1231            substDict = {'targs': args,
1232                         'class_name' : 'SveFirstFaultWritebackMicroop' }
1233            exec_output += SveOpExecDeclare.subst(substDict)
1234
1235    # Generates definitions for the first microop of SVE gather loads, required
1236    # to propagate the source vector register to the transfer microops
1237    def emitSveGatherLoadCpySrcVecMicroop():
1238        global header_output, exec_output, decoders
1239        code = sveEnabledCheckCode + '''
1240        unsigned eCount = ArmStaticInst::getCurSveVecLen<uint8_t>(
1241                xc->tcBase());
1242        for (unsigned i = 0; i < eCount; i++) {
1243            AA64FpUreg0_ub[i] = AA64FpOp1_ub[i];
1244        }'''
1245        iop = InstObjParams('ld1',
1246            'SveGatherLoadCpySrcVecMicroop',
1247            'MicroOp',
1248            {'code': code},
1249            ['IsMicroop'])
1250        header_output += SveGatherLoadCpySrcVecMicroopDeclare.subst(iop)
1251        exec_output += SveGatherLoadCpySrcVecMicroopExecute.subst(iop)
1252
1253    def emitSveInterleaveMicroop():
1254        global header_output, exec_output, decoders
1255        code2 = sveEnabledCheckCode + '''
1256        unsigned eCount = ArmStaticInst::getCurSveVecLen<Element>(
1257                xc->tcBase());
1258        for (unsigned int i = 0; i < eCount; ++i) {
1259            unsigned int absIdx = regIndex * eCount + i;
1260            unsigned int srcIdx = absIdx / numRegs;
1261            unsigned int srcVec = absIdx % numRegs;
1262            if (srcVec == 0)
1263                AA64FpDest_x[i] = AA64FpOp1V0S_x[srcIdx];
1264            else if (srcVec == 1)
1265                AA64FpDest_x[i] = AA64FpOp1V1S_x[srcIdx];
1266        }'''
1267
1268        code3 = sveEnabledCheckCode + '''
1269        unsigned eCount = ArmStaticInst::getCurSveVecLen<Element>(
1270                xc->tcBase());
1271        for (unsigned int i = 0; i < eCount; ++i) {
1272            unsigned int absIdx = regIndex * eCount + i;
1273            unsigned int srcIdx = absIdx / numRegs;
1274            unsigned int srcVec = absIdx % numRegs;
1275            if (srcVec == 0)
1276                AA64FpDest_x[i] = AA64FpOp1V0S_x[srcIdx];
1277            else if (srcVec == 1)
1278                AA64FpDest_x[i] = AA64FpOp1V1S_x[srcIdx];
1279            else if (srcVec == 2)
1280                AA64FpDest_x[i] = AA64FpOp1V2S_x[srcIdx];
1281        }'''
1282
1283        code4 = sveEnabledCheckCode + '''
1284        unsigned eCount = ArmStaticInst::getCurSveVecLen<Element>(
1285                xc->tcBase());
1286        for (unsigned int i = 0; i < eCount; ++i) {
1287            unsigned int absIdx = regIndex * eCount + i;
1288            unsigned int srcIdx = absIdx / numRegs;
1289            unsigned int srcVec = absIdx % numRegs;
1290            if (srcVec == 0)
1291                AA64FpDest_x[i] = AA64FpOp1V0S_x[srcIdx];
1292            else if (srcVec == 1)
1293                AA64FpDest_x[i] = AA64FpOp1V1S_x[srcIdx];
1294            else if (srcVec == 2)
1295                AA64FpDest_x[i] = AA64FpOp1V2S_x[srcIdx];
1296            else if (srcVec == 3)
1297                AA64FpDest_x[i] = AA64FpOp1V3S_x[srcIdx];
1298        }'''
1299
1300        iop2 = InstObjParams('intrlv',
1301                'SveIntrlv2Microop',
1302                'MicroOp',
1303                {'code': code2},
1304                ['IsMicroop'])
1305        iop3 = InstObjParams('intrlv',
1306                'SveIntrlv3Microop',
1307                'MicroOp',
1308                {'code': code3},
1309                ['IsMicroop'])
1310        iop4 = InstObjParams('intrlv',
1311                'SveIntrlv4Microop',
1312                'MicroOp',
1313                {'code': code4},
1314                ['IsMicroop'])
1315        header_output += SveIntrlvMicroopDeclare.subst(iop2);
1316        header_output += SveIntrlvMicroopDeclare.subst(iop3);
1317        header_output += SveIntrlvMicroopDeclare.subst(iop4);
1318        exec_output += SveIntrlvMicroopExecute.subst(iop2);
1319        exec_output += SveIntrlvMicroopExecute.subst(iop3);
1320        exec_output += SveIntrlvMicroopExecute.subst(iop4);
1321        for type in ('uint8_t', 'uint16_t', 'uint32_t', 'uint64_t'):
1322            for nreg in range(2,5):
1323                substDict = {'targs' : type,
1324                        'class_name' : 'SveIntrlv' + str(nreg) + 'Microop'}
1325                exec_output += SveIntrlvMicroopExecDeclare.subst(substDict)
1326
1327    def emitSveDeInterleaveMicroop():
1328        global header_output, exec_output, decoders
1329        code2 = sveEnabledCheckCode + '''
1330        unsigned eCount = ArmStaticInst::getCurSveVecLen<Element>(
1331                xc->tcBase());
1332        for (unsigned int i = 0; i < eCount; ++i) {
1333            unsigned int absIdx = (regIndex + numRegs * i);
1334            unsigned int srcIdx = absIdx % eCount;
1335            unsigned int srcVec = absIdx / eCount;
1336            if (srcVec == 0)
1337                AA64FpDest_x[i] = AA64IntrlvReg0_x[srcIdx];
1338            else if(srcVec == 1)
1339                AA64FpDest_x[i] = AA64IntrlvReg1_x[srcIdx];
1340        }'''
1341
1342        code3 = sveEnabledCheckCode + '''
1343        unsigned eCount = ArmStaticInst::getCurSveVecLen<Element>(
1344                xc->tcBase());
1345        for (unsigned int i = 0; i < eCount; ++i) {
1346            unsigned int absIdx = (regIndex + numRegs * i);
1347            unsigned int srcIdx = absIdx % eCount;
1348            unsigned int srcVec = absIdx / eCount;
1349            if (srcVec == 0)
1350                AA64FpDest_x[i] = AA64IntrlvReg0_x[srcIdx];
1351            else if(srcVec == 1)
1352                AA64FpDest_x[i] = AA64IntrlvReg1_x[srcIdx];
1353            else if(srcVec == 2)
1354                AA64FpDest_x[i] = AA64IntrlvReg2_x[srcIdx];
1355        }'''
1356
1357        code4 = sveEnabledCheckCode + '''
1358        unsigned eCount = ArmStaticInst::getCurSveVecLen<Element>(
1359                xc->tcBase());
1360        for (unsigned int i = 0; i < eCount; ++i) {
1361            unsigned int absIdx = (regIndex + numRegs * i);
1362            unsigned int srcIdx = absIdx % eCount;
1363            unsigned int srcVec = absIdx / eCount;
1364            if (srcVec == 0)
1365                AA64FpDest_x[i] = AA64IntrlvReg0_x[srcIdx];
1366            else if(srcVec == 1)
1367                AA64FpDest_x[i] = AA64IntrlvReg1_x[srcIdx];
1368            else if(srcVec == 2)
1369                AA64FpDest_x[i] = AA64IntrlvReg2_x[srcIdx];
1370            else if(srcVec == 3)
1371                AA64FpDest_x[i] = AA64IntrlvReg3_x[srcIdx];
1372        }'''
1373
1374        iop2 = InstObjParams('deintrlv',
1375                'SveDeIntrlv2Microop',
1376                'MicroOp',
1377                {'code': code2},
1378                ['IsMicroop'])
1379        iop3 = InstObjParams('deintrlv',
1380                'SveDeIntrlv3Microop',
1381                'MicroOp',
1382                {'code': code3},
1383                ['IsMicroop'])
1384        iop4 = InstObjParams('deintrlv',
1385                'SveDeIntrlv4Microop',
1386                'MicroOp',
1387                {'code': code4},
1388                ['IsMicroop'])
1389        header_output += SveDeIntrlvMicroopDeclare.subst(iop2);
1390        header_output += SveDeIntrlvMicroopDeclare.subst(iop3);
1391        header_output += SveDeIntrlvMicroopDeclare.subst(iop4);
1392        exec_output += SveIntrlvMicroopExecute.subst(iop2);
1393        exec_output += SveIntrlvMicroopExecute.subst(iop3);
1394        exec_output += SveIntrlvMicroopExecute.subst(iop4);
1395        for type in ('uint8_t', 'uint16_t', 'uint32_t', 'uint64_t'):
1396            for nreg in range(2,5):
1397                substDict = {'targs' : type,
1398                        'class_name' : 'SveDeIntrlv' + str(nreg) + 'Microop'}
1399                exec_output += SveIntrlvMicroopExecDeclare.subst(substDict)
1400
1401    # Generates definitions for SVE struct load/store microops
1402    def emitSveStructMemInsts(offsetIsImm):
1403        global header_output, exec_output, decoders
1404        eaCode = SPAlignmentCheckCode + '''
1405        int memAccessSize = eCount * sizeof(Element);
1406        EA = memAccessSize * regIndex + XBase + '''
1407        if offsetIsImm:
1408            eaCode += '((int64_t) this->imm * eCount * sizeof(Element))'
1409        else:
1410            eaCode += '(XOffset * sizeof(Element));'
1411        loadMemAccCode = '''
1412        for (int i = 0; i < eCount; i++) {
1413            int gpIdx = (regIndex * eCount + i) / numRegs;
1414            if (GpOp_x[gpIdx]) {
1415                AA64FpDest_x[i] = memDataView[i];
1416            } else {
1417                AA64FpDest_x[i] = 0;
1418            }
1419        }
1420        '''
1421        storeMemAccCode = '''
1422        for (int i = 0; i < eCount; i++) {
1423            int gpIdx = (regIndex * eCount + i) / numRegs;
1424            if (GpOp_x[gpIdx]) {
1425                memDataView[i] = AA64FpDest_x[i];
1426            } else {
1427                memDataView[i] = 0;
1428                for (int j = 0; j < sizeof(Element); j++) {
1429                    wrEn[sizeof(Element) * i + j] = false;
1430                }
1431            }
1432        }
1433        '''
1434        storeWrEnableCode = '''
1435        auto wrEn = std::vector<bool>(sizeof(Element) * eCount, true);
1436        '''
1437        loadIop = InstObjParams('ldxx',
1438            'SveLoadRegImmMicroop' if offsetIsImm else 'SveLoadRegRegMicroop',
1439            'MicroOp',
1440            {'targs': 'Element',
1441             'memacc_code': loadMemAccCode,
1442             'ea_code' : sveEnabledCheckCode + eaCode,
1443             'fa_code' : ''},
1444            ['IsMemRef', 'IsLoad', 'IsMicroop'])
1445        storeIop = InstObjParams('stxx',
1446            'SveStoreRegImmMicroop' if offsetIsImm
1447                                    else 'SveStoreRegRegMicroop',
1448            'MicroOp',
1449            {'targs': 'Element',
1450             'wren_code': storeWrEnableCode,
1451             'memacc_code': storeMemAccCode,
1452             'ea_code' : sveEnabledCheckCode + eaCode,
1453             'fa_code' : ''},
1454            ['IsMemRef', 'IsStore', 'IsMicroop'])
1455        if offsetIsImm:
1456            header_output += SveStructMemSIMicroopDeclare.subst(loadIop)
1457            header_output += SveStructMemSIMicroopDeclare.subst(storeIop)
1458        else:
1459            header_output += SveStructMemSSMicroopDeclare.subst(loadIop)
1460            header_output += SveStructMemSSMicroopDeclare.subst(storeIop)
1461        exec_output += (
1462            SveStructLoadExecute.subst(loadIop) +
1463            SveStructLoadInitiateAcc.subst(loadIop) +
1464            SveStructLoadCompleteAcc.subst(loadIop) +
1465            SveStructStoreExecute.subst(storeIop) +
1466            SveStructStoreInitiateAcc.subst(storeIop) +
1467            SveStructStoreCompleteAcc.subst(storeIop))
1468        tplArgs = ('uint8_t', 'uint16_t', 'uint32_t', 'uint64_t')
1469        for type in tplArgs:
1470            substDict = {'targs': type,
1471                         'class_name': 'SveLoadRegImmMicroop' if offsetIsImm
1472                                       else 'SveLoadRegRegMicroop'}
1473            exec_output += SveStructMemExecDeclare.subst(substDict)
1474            substDict['class_name'] = ('SveStoreRegImmMicroop' if offsetIsImm
1475                                       else 'SveStoreRegRegMicroop')
1476            exec_output += SveStructMemExecDeclare.subst(substDict)
1477
1478    # LD1[S]{B,H,W,D} (scalar plus immediate)
1479    # ST1[S]{B,H,W,D} (scalar plus immediate)
1480    # LDNF1[S]{B,H,W,D} (scalar plus immediate)
1481    emitSveContigMemInsts(True)
1482    # LD1[S]{B,H,W,D} (scalar plus scalar)
1483    # ST1[S]{B,H,W,D} (scalar plus scalar)
1484    # LDFF1[S]{B,H,W,D} (scalar plus vector)
1485    emitSveContigMemInsts(False)
1486
1487    # LD1R[S]{B,H,W,D}
1488    emitSveLoadAndRepl()
1489
1490    # LD{2,3,4}{B,H,W,D} (scalar plus immediate)
1491    # ST{2,3,4}{B,H,W,D} (scalar plus immediate)
1492    emitSveStructMemInsts(offsetIsImm = True)
1493    # LD{2,3,4}{B,H,W,D} (scalar plus scalar)
1494    # ST{2,3,4}{B,H,W,D} (scalar plus scalar)
1495    emitSveStructMemInsts(offsetIsImm = False)
1496
1497    # LDR (predicate), STR (predicate)
1498    emitSveMemFillSpill(True)
1499    # LDR (vector), STR (vector)
1500    emitSveMemFillSpill(False)
1501
1502    # LD1[S]{B,H,W,D} (vector plus immediate)
1503    # ST1[S]{B,H,W,D} (vector plus immediate)
1504    # LDFF1[S]{B,H,W,D} (scalar plus immediate)
1505    emitSveIndexedMemMicroops(IndexedAddrForm.VEC_PLUS_IMM)
1506    # LD1[S]{B,H,W,D} (scalar plus vector)
1507    # ST1[S]{B,H,W,D} (scalar plus vector)
1508    # LDFF1[S]{B,H,W,D} (scalar plus vector)
1509    emitSveIndexedMemMicroops(IndexedAddrForm.SCA_PLUS_VEC)
1510
1511    # FFR writeback microop for gather loads
1512    emitSveFirstFaultWritebackMicroop()
1513
1514    # Source vector copy microop for gather loads
1515    emitSveGatherLoadCpySrcVecMicroop()
1516
1517    # ST/LD struct de/interleave microops
1518    emitSveInterleaveMicroop()
1519    emitSveDeInterleaveMicroop()
1520}};
1521