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