1// Copyright (c) 2017-2019 ARM Limited
2// All rights reserved
3//
4// The license below extends only to copyright in the software and shall
5// not be construed as granting a license to any other intellectual
6// property including but not limited to intellectual property relating
7// to a hardware implementation of the functionality of the software
8// licensed hereunder.  You may use the software subject to the license
9// terms below provided that you ensure that this notice is replicated
10// unmodified and in its entirety in all distributions of the software,
11// modified or unmodified, in source code or in binary form.
12//
13// Redistribution and use in source and binary forms, with or without
14// modification, are permitted provided that the following conditions are
15// met: redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer;
17// redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution;
20// neither the name of the copyright holders nor the names of its
21// contributors may be used to endorse or promote products derived from
22// this software without specific prior written permission.
23//
24// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35//
36// Authors: Giacomo Gabrielli
37
38// @file Definition of SVE memory access instructions.
39
40output header {{
41
42    // Decodes SVE contiguous load instructions, scalar plus scalar form.
43    template <template <typename T1, typename T2> class Base>
44    StaticInstPtr
45    decodeSveContigLoadSSInsts(uint8_t dtype, ExtMachInst machInst,
46                               IntRegIndex zt, IntRegIndex pg, IntRegIndex rn,
47                               IntRegIndex rm, bool firstFaulting)
48    {
49        const char* mn = firstFaulting ? "ldff1" : "ld1";
50        switch (dtype) {
51          case 0x0:
52            return new Base<uint8_t, uint8_t>(mn, machInst, zt, pg, rn, rm);
53          case 0x1:
54            return new Base<uint16_t, uint8_t>(mn, machInst, zt, pg, rn, rm);
55          case 0x2:
56            return new Base<uint32_t, uint8_t>(mn, machInst, zt, pg, rn, rm);
57          case 0x3:
58            return new Base<uint64_t, uint8_t>(mn, machInst, zt, pg, rn, rm);
59          case 0x4:
60            return new Base<int64_t, int32_t>(mn, machInst, zt, pg, rn, rm);
61          case 0x5:
62            return new Base<uint16_t, uint16_t>(mn, machInst, zt, pg, rn, rm);
63          case 0x6:
64            return new Base<uint32_t, uint16_t>(mn, machInst, zt, pg, rn, rm);
65          case 0x7:
66            return new Base<uint64_t, uint16_t>(mn, machInst, zt, pg, rn, rm);
67          case 0x8:
68            return new Base<int64_t, int16_t>(mn, machInst, zt, pg, rn, rm);
69          case 0x9:
70            return new Base<int32_t, int16_t>(mn, machInst, zt, pg, rn, rm);
71          case 0xa:
72            return new Base<uint32_t, uint32_t>(mn, machInst, zt, pg, rn, rm);
73          case 0xb:
74            return new Base<uint64_t, uint32_t>(mn, machInst, zt, pg, rn, rm);
75          case 0xc:
76            return new Base<int64_t, int8_t>(mn, machInst, zt, pg, rn, rm);
77          case 0xd:
78            return new Base<int32_t, int8_t>(mn, machInst, zt, pg, rn, rm);
79          case 0xe:
80            return new Base<int16_t, int8_t>(mn, machInst, zt, pg, rn, rm);
81          case 0xf:
82            return new Base<uint64_t, uint64_t>(mn, machInst, zt, pg, rn, rm);
83        }
84        return new Unknown64(machInst);
85    }
86
87    // Decodes SVE contiguous load instructions, scalar plus immediate form.
88    template <template <typename T1, typename T2> class Base>
89    StaticInstPtr
90    decodeSveContigLoadSIInsts(uint8_t dtype, ExtMachInst machInst,
91                               IntRegIndex zt, IntRegIndex pg, IntRegIndex rn,
92                               uint64_t imm, bool nonFaulting,
93                               bool replicate = false)
94    {
95        assert(!(nonFaulting && replicate));
96        const char* mn = replicate ? "ld1r" : (nonFaulting ? "ldnf1" : "ld1");
97        switch (dtype) {
98          case 0x0:
99            return new Base<uint8_t, uint8_t>(mn, machInst, zt, pg, rn, imm);
100          case 0x1:
101            return new Base<uint16_t, uint8_t>(mn, machInst, zt, pg, rn, imm);
102          case 0x2:
103            return new Base<uint32_t, uint8_t>(mn, machInst, zt, pg, rn, imm);
104          case 0x3:
105            return new Base<uint64_t, uint8_t>(mn, machInst, zt, pg, rn, imm);
106          case 0x4:
107            return new Base<int64_t, int32_t>(mn, machInst, zt, pg, rn, imm);
108          case 0x5:
109            return new Base<uint16_t, uint16_t>(mn, machInst, zt, pg, rn, imm);
110          case 0x6:
111            return new Base<uint32_t, uint16_t>(mn, machInst, zt, pg, rn, imm);
112          case 0x7:
113            return new Base<uint64_t, uint16_t>(mn, machInst, zt, pg, rn, imm);
114          case 0x8:
115            return new Base<int64_t, int16_t>(mn, machInst, zt, pg, rn, imm);
116          case 0x9:
117            return new Base<int32_t, int16_t>(mn, machInst, zt, pg, rn, imm);
118          case 0xa:
119            return new Base<uint32_t, uint32_t>(mn, machInst, zt, pg, rn, imm);
120          case 0xb:
121            return new Base<uint64_t, uint32_t>(mn, machInst, zt, pg, rn, imm);
122          case 0xc:
123            return new Base<int64_t, int8_t>(mn, machInst, zt, pg, rn, imm);
124          case 0xd:
125            return new Base<int32_t, int8_t>(mn, machInst, zt, pg, rn, imm);
126          case 0xe:
127            return new Base<int16_t, int8_t>(mn, machInst, zt, pg, rn, imm);
128          case 0xf:
129            return new Base<uint64_t, uint64_t>(mn, machInst, zt, pg, rn, imm);
130        }
131        return new Unknown64(machInst);
132    }
133
134    // Decodes SVE contiguous store instructions, scalar plus scalar form.
135    template <template <typename T1, typename T2> class Base>
136    StaticInstPtr
137    decodeSveContigStoreSSInsts(uint8_t dtype, ExtMachInst machInst,
138                                IntRegIndex zt, IntRegIndex pg, IntRegIndex rn,
139                                IntRegIndex rm)
140    {
141        const char* mn = "st1";
142        switch (dtype) {
143          case 0x0:
144            return new Base<uint8_t, uint8_t>(mn, machInst, zt, pg, rn, rm);
145          case 0x1:
146            return new Base<uint16_t, uint8_t>(mn, machInst, zt, pg, rn, rm);
147          case 0x2:
148            return new Base<uint32_t, uint8_t>(mn, machInst, zt, pg, rn, rm);
149          case 0x3:
150            return new Base<uint64_t, uint8_t>(mn, machInst, zt, pg, rn, rm);
151          case 0x5:
152            return new Base<uint16_t, uint16_t>(mn, machInst, zt, pg, rn, rm);
153          case 0x6:
154            return new Base<uint32_t, uint16_t>(mn, machInst, zt, pg, rn, rm);
155          case 0x7:
156            return new Base<uint64_t, uint16_t>(mn, machInst, zt, pg, rn, rm);
157          case 0xa:
158            return new Base<uint32_t, uint32_t>(mn, machInst, zt, pg, rn, rm);
159          case 0xb:
160            return new Base<uint64_t, uint32_t>(mn, machInst, zt, pg, rn, rm);
161          case 0xf:
162            return new Base<uint64_t, uint64_t>(mn, machInst, zt, pg, rn, rm);
163        }
164        return new Unknown64(machInst);
165    }
166
167    // Decodes SVE contiguous store instructions, scalar plus immediate form.
168    template <template <typename T1, typename T2> class Base>
169    StaticInstPtr
170    decodeSveContigStoreSIInsts(uint8_t dtype, ExtMachInst machInst,
171                                IntRegIndex zt, IntRegIndex pg, IntRegIndex rn,
172                                int8_t imm)
173    {
174        const char* mn = "st1";
175        switch (dtype) {
176          case 0x0:
177            return new Base<uint8_t, uint8_t>(mn, machInst, zt, pg, rn, imm);
178          case 0x1:
179            return new Base<uint16_t, uint8_t>(mn, machInst, zt, pg, rn, imm);
180          case 0x2:
181            return new Base<uint32_t, uint8_t>(mn, machInst, zt, pg, rn, imm);
182          case 0x3:
183            return new Base<uint64_t, uint8_t>(mn, machInst, zt, pg, rn, imm);
184          case 0x5:
185            return new Base<uint16_t, uint16_t>(mn, machInst, zt, pg, rn, imm);
186          case 0x6:
187            return new Base<uint32_t, uint16_t>(mn, machInst, zt, pg, rn, imm);
188          case 0x7:
189            return new Base<uint64_t, uint16_t>(mn, machInst, zt, pg, rn, imm);
190          case 0xa:
191            return new Base<uint32_t, uint32_t>(mn, machInst, zt, pg, rn, imm);
192          case 0xb:
193            return new Base<uint64_t, uint32_t>(mn, machInst, zt, pg, rn, imm);
194          case 0xf:
195            return new Base<uint64_t, uint64_t>(mn, machInst, zt, pg, rn, imm);
196        }
197        return new Unknown64(machInst);
198    }
199
200    // NOTE: SVE load-and-replicate instructions are decoded with
201    // decodeSveContigLoadSIInsts(...).
202
203}};
204
205output decoder {{
206
207    template <class etype>
208    StaticInstPtr
209    decodeSveStructLoadSIInstsByNReg(uint8_t esize, ExtMachInst machInst,
210            IntRegIndex zt, IntRegIndex pg, IntRegIndex xn,
211            int64_t imm, int numregs)
212    {
213        static const char* nm[5][4] = {
214            { nullptr, nullptr, nullptr, nullptr},
215            { nullptr, nullptr, nullptr, nullptr},
216            { "ld2b", "ld2h", "ld2w", "ld2d" },
217            { "ld3b", "ld3h", "ld3w", "ld3d" },
218            { "ld4b", "ld4h", "ld4w", "ld4d" } };
219
220        switch (numregs) {
221            case 2:
222                return new SveLdStructSI<etype,
223                        SveLoadRegImmMicroop,
224                        SveDeIntrlv2Microop>(
225                               nm[numregs][esize], machInst, MemReadOp,
226                               zt, pg, xn, imm, numregs);
227            case 3:
228                return new SveLdStructSI<etype,
229                        SveLoadRegImmMicroop,
230                        SveDeIntrlv3Microop>(
231                               nm[numregs][esize], machInst, MemReadOp,
232                               zt, pg, xn, imm, numregs);
233            case 4:
234                return new SveLdStructSI<etype,
235                        SveLoadRegImmMicroop,
236                        SveDeIntrlv4Microop>(
237                               nm[numregs][esize], machInst, MemReadOp,
238                               zt, pg, xn, imm, numregs);
239        }
240        return new Unknown64(machInst);
241    }
242
243    StaticInstPtr
244    decodeSveStructLoadSIInsts(uint8_t esize, ExtMachInst machInst,
245            IntRegIndex zt, IntRegIndex pg, IntRegIndex xn,
246            int64_t imm, int numregs)
247    {
248        switch (esize) {
249            case 0:
250                return decodeSveStructLoadSIInstsByNReg<uint8_t>(esize,
251                        machInst, zt, pg, xn, imm, numregs);
252            case 1:
253                return decodeSveStructLoadSIInstsByNReg<uint16_t>(esize,
254                        machInst, zt, pg, xn, imm, numregs);
255            case 2:
256                return decodeSveStructLoadSIInstsByNReg<uint32_t>(esize,
257                        machInst, zt, pg, xn, imm, numregs);
258            case 3:
259                return decodeSveStructLoadSIInstsByNReg<uint64_t>(esize,
260                        machInst, zt, pg, xn, imm, numregs);
261        }
262        return new Unknown64(machInst);
263    }
264
265    template <class etype>
266    StaticInstPtr
267    decodeSveStructStoreSIInstsByNReg(uint8_t esize, ExtMachInst machInst,
268            IntRegIndex zt, IntRegIndex pg, IntRegIndex xn,
269            int64_t imm, int numregs)
270    {
271        static const char* nm[5][4] = {
272            { nullptr, nullptr, nullptr, nullptr},
273            { nullptr, nullptr, nullptr, nullptr},
274            { "st2b", "st2h", "st2w", "st2d" },
275            { "st3b", "st3h", "st3w", "st3d" },
276            { "st4b", "st4h", "st4w", "st4d" } };
277
278        switch (numregs) {
279            case 2:
280                return new SveStStructSI<etype,
281                        SveStoreRegImmMicroop,
282                        SveIntrlv2Microop>(
283                            nm[numregs][esize], machInst, MemWriteOp,
284                            zt, pg, xn, imm, numregs);
285            case 3:
286                return new SveStStructSI<etype,
287                        SveStoreRegImmMicroop,
288                        SveIntrlv3Microop>(
289                            nm[numregs][esize], machInst, MemWriteOp,
290                            zt, pg, xn, imm, numregs);
291           case 4:
292                return new SveStStructSI<etype,
293                        SveStoreRegImmMicroop,
294                        SveIntrlv4Microop>(
295                            nm[numregs][esize], machInst, MemWriteOp,
296                            zt, pg, xn, imm, numregs);
297        }
298        return new Unknown64(machInst);
299    }
300
301    StaticInstPtr
302    decodeSveStructStoreSIInsts(uint8_t esize, ExtMachInst machInst,
303            IntRegIndex zt, IntRegIndex pg, IntRegIndex xn,
304            int64_t imm, int numregs)
305    {
306        switch (esize) {
307            case 0:
308                return decodeSveStructStoreSIInstsByNReg<uint8_t>(esize,
309                    machInst, zt, pg, xn, imm, numregs);
310            case 1:
311                return decodeSveStructStoreSIInstsByNReg<uint16_t>(esize,
312                    machInst, zt, pg, xn, imm, numregs);
313            case 2:
314                return decodeSveStructStoreSIInstsByNReg<uint32_t>(esize,
315                    machInst, zt, pg, xn, imm, numregs);
316            case 3:
317                return decodeSveStructStoreSIInstsByNReg<uint64_t>(esize,
318                    machInst, zt, pg, xn, imm, numregs);
319        }
320        return new Unknown64(machInst);
321    }
322
323    template <class etype>
324    StaticInstPtr
325    decodeSveStructLoadSSInstsByNReg(uint8_t esize, ExtMachInst machInst,
326            IntRegIndex zt, IntRegIndex pg, IntRegIndex xn,
327            IntRegIndex xm, int numregs)
328    {
329        static const char* nm[5][4] = {
330            { nullptr, nullptr, nullptr, nullptr},
331            { nullptr, nullptr, nullptr, nullptr},
332            { "ld2b", "ld2h", "ld2w", "ld2d" },
333            { "ld3b", "ld3h", "ld3w", "ld3d" },
334            { "ld4b", "ld4h", "ld4w", "ld4d" } };
335
336        switch (numregs) {
337            case 2:
338                return new SveLdStructSS<etype,
339                        SveLoadRegRegMicroop,
340                        SveDeIntrlv2Microop>(
341                               nm[numregs][esize], machInst, MemReadOp,
342                               zt, pg, xn, xm, numregs);
343            case 3:
344                return new SveLdStructSS<etype,
345                        SveLoadRegRegMicroop,
346                        SveDeIntrlv3Microop>(
347                               nm[numregs][esize], machInst, MemReadOp,
348                               zt, pg, xn, xm, numregs);
349            case 4:
350                return new SveLdStructSS<etype,
351                        SveLoadRegRegMicroop,
352                        SveDeIntrlv4Microop>(
353                               nm[numregs][esize], machInst, MemReadOp,
354                               zt, pg, xn, xm, numregs);
355        }
356        return new Unknown64(machInst);
357    }
358
359    StaticInstPtr
360    decodeSveStructLoadSSInsts(uint8_t esize, ExtMachInst machInst,
361            IntRegIndex zt, IntRegIndex pg, IntRegIndex xn,
362            IntRegIndex xm, int numregs)
363    {
364        switch (esize) {
365            case 0:
366                return decodeSveStructLoadSSInstsByNReg<uint8_t>(esize,
367                            machInst, zt, pg, xn, xm, numregs);
368            case 1:
369                return decodeSveStructLoadSSInstsByNReg<uint16_t>(esize,
370                            machInst, zt, pg, xn, xm, numregs);
371            case 2:
372                return decodeSveStructLoadSSInstsByNReg<uint32_t>(esize,
373                            machInst, zt, pg, xn, xm, numregs);
374            case 3:
375                return decodeSveStructLoadSSInstsByNReg<uint64_t>(esize,
376                            machInst, zt, pg, xn, xm, numregs);
377        }
378        return new Unknown64(machInst);
379    }
380
381    template <class etype>
382    StaticInstPtr
383    decodeSveStructStoreSSInstsByNReg(uint8_t esize, ExtMachInst machInst,
384            IntRegIndex zt, IntRegIndex pg, IntRegIndex xn,
385            IntRegIndex xm, int numregs)
386    {
387        static const char* nm[5][4] = {
388            { nullptr, nullptr, nullptr, nullptr},
389            { nullptr, nullptr, nullptr, nullptr},
390            { "st2b", "st2h", "st2w", "st2d" },
391            { "st3b", "st3h", "st3w", "st3d" },
392            { "st4b", "st4h", "st4w", "st4d" } };
393
394        switch (numregs) {
395            case 2:
396                return new SveStStructSS<etype,
397                        SveStoreRegRegMicroop,
398                        SveIntrlv2Microop>(
399                               nm[numregs][esize], machInst, MemWriteOp,
400                               zt, pg, xn, xm, numregs);
401            case 3:
402                return new SveStStructSS<etype,
403                        SveStoreRegRegMicroop,
404                        SveIntrlv3Microop>(
405                               nm[numregs][esize], machInst, MemWriteOp,
406                               zt, pg, xn, xm, numregs);
407            case 4:
408                return new SveStStructSS<etype,
409                        SveStoreRegRegMicroop,
410                        SveIntrlv4Microop>(
411                               nm[numregs][esize], machInst, MemWriteOp,
412                               zt, pg, xn, xm, numregs);
413        }
414        return new Unknown64(machInst);
415    }
416
417    StaticInstPtr
418    decodeSveStructStoreSSInsts(uint8_t esize, ExtMachInst machInst,
419            IntRegIndex zt, IntRegIndex pg, IntRegIndex xn,
420            IntRegIndex xm, int numregs)
421    {
422        switch (esize) {
423            case 0:
424                return decodeSveStructStoreSSInstsByNReg<uint8_t>(esize,
425                            machInst, zt, pg, xn, xm, numregs);
426            case 1:
427                return decodeSveStructStoreSSInstsByNReg<uint16_t>(esize,
428                            machInst, zt, pg, xn, xm, numregs);
429            case 2:
430                return decodeSveStructStoreSSInstsByNReg<uint32_t>(esize,
431                            machInst, zt, pg, xn, xm, numregs);
432            case 3:
433                return decodeSveStructStoreSSInstsByNReg<uint64_t>(esize,
434                            machInst, zt, pg, xn, xm, numregs);
435        }
436        return new Unknown64(machInst);
437    }
438
439    StaticInstPtr
440    decodeSveGatherLoadVIInsts(uint8_t dtype, ExtMachInst machInst,
441                               IntRegIndex zt, IntRegIndex pg, IntRegIndex zn,
442                               uint64_t imm, bool esizeIs32,
443                               bool firstFault)
444    {
445        const char* mn = firstFault ? "ldff1" : "ld1";
446        switch (dtype) {
447          case 0x0:
448            if (esizeIs32) {
449                return new SveIndexedMemVI<int32_t, int8_t,
450                                           SveGatherLoadVIMicroop,
451                                           SveFirstFaultWritebackMicroop>(
452                    mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
453            } else {
454                return new SveIndexedMemVI<int64_t, int8_t,
455                                           SveGatherLoadVIMicroop,
456                                           SveFirstFaultWritebackMicroop>(
457                    mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
458            }
459          case 0x1:
460            if (esizeIs32) {
461                return new SveIndexedMemVI<uint32_t, uint8_t,
462                                           SveGatherLoadVIMicroop,
463                                           SveFirstFaultWritebackMicroop>(
464                    mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
465            } else {
466                return new SveIndexedMemVI<uint64_t, uint8_t,
467                                           SveGatherLoadVIMicroop,
468                                           SveFirstFaultWritebackMicroop>(
469                    mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
470            }
471          case 0x2:
472            if (esizeIs32) {
473                return new SveIndexedMemVI<int32_t, int16_t,
474                                           SveGatherLoadVIMicroop,
475                                           SveFirstFaultWritebackMicroop>(
476                    mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
477            } else {
478                return new SveIndexedMemVI<int64_t, int16_t,
479                                           SveGatherLoadVIMicroop,
480                                           SveFirstFaultWritebackMicroop>(
481                    mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
482            }
483          case 0x3:
484            if (esizeIs32) {
485                return new SveIndexedMemVI<uint32_t, uint16_t,
486                                           SveGatherLoadVIMicroop,
487                                           SveFirstFaultWritebackMicroop>(
488                    mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
489            } else {
490                return new SveIndexedMemVI<uint64_t, uint16_t,
491                                           SveGatherLoadVIMicroop,
492                                           SveFirstFaultWritebackMicroop>(
493                    mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
494            }
495          case 0x4:
496            if (esizeIs32) {
497                break;
498            } else {
499                return new SveIndexedMemVI<int64_t, int32_t,
500                                           SveGatherLoadVIMicroop,
501                                           SveFirstFaultWritebackMicroop>(
502                    mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
503            }
504          case 0x5:
505            if (esizeIs32) {
506                return new SveIndexedMemVI<uint32_t, uint32_t,
507                                           SveGatherLoadVIMicroop,
508                                           SveFirstFaultWritebackMicroop>(
509                    mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
510            } else {
511                return new SveIndexedMemVI<uint64_t, uint32_t,
512                                           SveGatherLoadVIMicroop,
513                                           SveFirstFaultWritebackMicroop>(
514                    mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
515            }
516          case 0x7:
517            if (esizeIs32) {
518                break;
519            } else {
520                return new SveIndexedMemVI<uint64_t, uint64_t,
521                                           SveGatherLoadVIMicroop,
522                                           SveFirstFaultWritebackMicroop>(
523                    mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
524            }
525        }
526        return new Unknown64(machInst);
527    }
528
529    StaticInstPtr
530    decodeSveGatherLoadSVInsts(uint8_t dtype, ExtMachInst machInst,
531                               IntRegIndex zt, IntRegIndex pg, IntRegIndex rn,
532                               IntRegIndex zm, bool esizeIs32, bool offsetIs32,
533                               bool offsetIsSigned, bool offsetIsScaled,
534                               bool firstFault)
535    {
536        const char* mn = firstFault ? "ldff1" : "ld1";
537        switch (dtype) {
538          case 0x0:
539            if (esizeIs32) {
540                return new SveIndexedMemSV<int32_t, int8_t,
541                                           SveGatherLoadSVMicroop,
542                                           SveFirstFaultWritebackMicroop>(
543                    mn, machInst, MemReadOp, zt, pg, rn, zm,
544                    offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
545            } else {
546                return new SveIndexedMemSV<int64_t, int8_t,
547                                           SveGatherLoadSVMicroop,
548                                           SveFirstFaultWritebackMicroop>(
549                    mn, machInst, MemReadOp, zt, pg, rn, zm,
550                    offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
551            }
552          case 0x1:
553            if (esizeIs32) {
554                return new SveIndexedMemSV<uint32_t, uint8_t,
555                                           SveGatherLoadSVMicroop,
556                                           SveFirstFaultWritebackMicroop>(
557                    mn, machInst, MemReadOp, zt, pg, rn, zm,
558                    offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
559            } else {
560                return new SveIndexedMemSV<uint64_t, uint8_t,
561                                           SveGatherLoadSVMicroop,
562                                           SveFirstFaultWritebackMicroop>(
563                    mn, machInst, MemReadOp, zt, pg, rn, zm,
564                    offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
565            }
566          case 0x2:
567            if (esizeIs32) {
568                return new SveIndexedMemSV<int32_t, int16_t,
569                                           SveGatherLoadSVMicroop,
570                                           SveFirstFaultWritebackMicroop>(
571                    mn, machInst, MemReadOp, zt, pg, rn, zm,
572                    offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
573            } else {
574                return new SveIndexedMemSV<int64_t, int16_t,
575                                           SveGatherLoadSVMicroop,
576                                           SveFirstFaultWritebackMicroop>(
577                    mn, machInst, MemReadOp, zt, pg, rn, zm,
578                    offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
579            }
580          case 0x3:
581            if (esizeIs32) {
582                return new SveIndexedMemSV<uint32_t, uint16_t,
583                                           SveGatherLoadSVMicroop,
584                                           SveFirstFaultWritebackMicroop>(
585                    mn, machInst, MemReadOp, zt, pg, rn, zm,
586                    offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
587            } else {
588                return new SveIndexedMemSV<uint64_t, uint16_t,
589                                           SveGatherLoadSVMicroop,
590                                           SveFirstFaultWritebackMicroop>(
591                    mn, machInst, MemReadOp, zt, pg, rn, zm,
592                    offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
593            }
594          case 0x4:
595            if (esizeIs32) {
596                break;
597            } else {
598                return new SveIndexedMemSV<int64_t, int32_t,
599                                           SveGatherLoadSVMicroop,
600                                           SveFirstFaultWritebackMicroop>(
601                    mn, machInst, MemReadOp, zt, pg, rn, zm,
602                    offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
603            }
604          case 0x5:
605            if (esizeIs32) {
606                return new SveIndexedMemSV<uint32_t, uint32_t,
607                                           SveGatherLoadSVMicroop,
608                                           SveFirstFaultWritebackMicroop>(
609                    mn, machInst, MemReadOp, zt, pg, rn, zm,
610                    offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
611            } else {
612                return new SveIndexedMemSV<uint64_t, uint32_t,
613                                           SveGatherLoadSVMicroop,
614                                           SveFirstFaultWritebackMicroop>(
615                    mn, machInst, MemReadOp, zt, pg, rn, zm,
616                    offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
617            }
618          case 0x7:
619            if (esizeIs32) {
620                break;
621            } else {
622                return new SveIndexedMemSV<uint64_t, uint64_t,
623                                           SveGatherLoadSVMicroop,
624                                           SveFirstFaultWritebackMicroop>(
625                    mn, machInst, MemReadOp, zt, pg, rn, zm,
626                    offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
627            }
628        }
629        return new Unknown64(machInst);
630    }
631
632    StaticInstPtr
633    decodeSveScatterStoreVIInsts(uint8_t msz, ExtMachInst machInst,
634                                 IntRegIndex zt, IntRegIndex pg,
635                                 IntRegIndex zn, uint64_t imm,
636                                 bool esizeIs32)
637    {
638        const char* mn = "st1";
639        switch (msz) {
640          case 0x0:
641            if (esizeIs32) {
642                return new SveIndexedMemVI<uint32_t, uint8_t,
643                                           SveScatterStoreVIMicroop,
644                                           SveFirstFaultWritebackMicroop>(
645                    mn, machInst, MemWriteOp, zt, pg, zn, imm, false);
646            } else {
647                return new SveIndexedMemVI<uint64_t, uint8_t,
648                                           SveScatterStoreVIMicroop,
649                                           SveFirstFaultWritebackMicroop>(
650                    mn, machInst, MemWriteOp, zt, pg, zn, imm, false);
651            }
652          case 0x1:
653            if (esizeIs32) {
654                return new SveIndexedMemVI<uint32_t, uint16_t,
655                                           SveScatterStoreVIMicroop,
656                                           SveFirstFaultWritebackMicroop>(
657                    mn, machInst, MemWriteOp, zt, pg, zn, imm, false);
658            } else {
659                return new SveIndexedMemVI<uint64_t, uint16_t,
660                                           SveScatterStoreVIMicroop,
661                                           SveFirstFaultWritebackMicroop>(
662                    mn, machInst, MemWriteOp, zt, pg, zn, imm, false);
663            }
664          case 0x2:
665            if (esizeIs32) {
666                return new SveIndexedMemVI<uint32_t, uint32_t,
667                                           SveScatterStoreVIMicroop,
668                                           SveFirstFaultWritebackMicroop>(
669                    mn, machInst, MemWriteOp, zt, pg, zn, imm, false);
670            } else {
671                return new SveIndexedMemVI<uint64_t, uint32_t,
672                                           SveScatterStoreVIMicroop,
673                                           SveFirstFaultWritebackMicroop>(
674                    mn, machInst, MemWriteOp, zt, pg, zn, imm, false);
675            }
676          case 0x3:
677            if (esizeIs32) {
678                break;
679            } else {
680                return new SveIndexedMemVI<uint64_t, uint64_t,
681                                           SveScatterStoreVIMicroop,
682                                           SveFirstFaultWritebackMicroop>(
683                    mn, machInst, MemWriteOp, zt, pg, zn, imm, false);
684            }
685        }
686        return new Unknown64(machInst);
687    }
688
689    StaticInstPtr
690    decodeSveScatterStoreSVInsts(uint8_t msz, ExtMachInst machInst,
691                                 IntRegIndex zt, IntRegIndex pg,
692                                 IntRegIndex rn, IntRegIndex zm,
693                                 bool esizeIs32, bool offsetIs32,
694                                 bool offsetIsSigned, bool offsetIsScaled)
695    {
696        const char* mn = "st1";
697        switch (msz) {
698          case 0x0:
699            if (esizeIs32) {
700                return new SveIndexedMemSV<uint32_t, uint8_t,
701                                           SveScatterStoreSVMicroop,
702                                           SveFirstFaultWritebackMicroop>(
703                    mn, machInst, MemWriteOp, zt, pg, rn, zm,
704                    offsetIs32, offsetIsSigned, offsetIsScaled, false);
705            } else {
706                return new SveIndexedMemSV<uint64_t, uint8_t,
707                                           SveScatterStoreSVMicroop,
708                                           SveFirstFaultWritebackMicroop>(
709                    mn, machInst, MemWriteOp, zt, pg, rn, zm,
710                    offsetIs32, offsetIsSigned, offsetIsScaled, false);
711            }
712          case 0x1:
713            if (esizeIs32) {
714                return new SveIndexedMemSV<uint32_t, uint16_t,
715                                           SveScatterStoreSVMicroop,
716                                           SveFirstFaultWritebackMicroop>(
717                    mn, machInst, MemWriteOp, zt, pg, rn, zm,
718                    offsetIs32, offsetIsSigned, offsetIsScaled, false);
719            } else {
720                return new SveIndexedMemSV<uint64_t, uint16_t,
721                                           SveScatterStoreSVMicroop,
722                                           SveFirstFaultWritebackMicroop>(
723                    mn, machInst, MemWriteOp, zt, pg, rn, zm,
724                    offsetIs32, offsetIsSigned, offsetIsScaled, false);
725            }
726          case 0x2:
727            if (esizeIs32) {
728                return new SveIndexedMemSV<uint32_t, uint32_t,
729                                           SveScatterStoreSVMicroop,
730                                           SveFirstFaultWritebackMicroop>(
731                    mn, machInst, MemWriteOp, zt, pg, rn, zm,
732                    offsetIs32, offsetIsSigned, offsetIsScaled, false);
733            } else {
734                return new SveIndexedMemSV<uint64_t, uint32_t,
735                                           SveScatterStoreSVMicroop,
736                                           SveFirstFaultWritebackMicroop>(
737                    mn, machInst, MemWriteOp, zt, pg, rn, zm,
738                    offsetIs32, offsetIsSigned, offsetIsScaled, false);
739            }
740          case 0x3:
741            if (esizeIs32) {
742                break;
743            } else {
744                return new SveIndexedMemSV<uint64_t, uint64_t,
745                                           SveScatterStoreSVMicroop,
746                                           SveFirstFaultWritebackMicroop>(
747                    mn, machInst, MemWriteOp, zt, pg, rn, zm,
748                    offsetIs32, offsetIsSigned, offsetIsScaled, false);
749            }
750        }
751        return new Unknown64(machInst);
752    }
753
754}};
755
756
757let {{
758
759    header_output = ''
760    exec_output = ''
761    decoders = { 'Generic': {} }
762
763    SPAlignmentCheckCode = '''
764        if (this->baseIsSP && bits(XBase, 3, 0) &&
765            SPAlignmentCheckEnabled(xc->tcBase())) {
766            return std::make_shared<SPAlignmentFault>();
767        }
768    '''
769
770    def emitSveMemFillSpill(isPred):
771        global header_output, exec_output, decoders
772        eaCode = SPAlignmentCheckCode + '''
773        int memAccessSize = %(memacc_size)s;
774        EA = XBase + ((int64_t) imm * %(memacc_size)s)''' % {
775            'memacc_size': 'eCount / 8' if isPred else 'eCount'}
776        loadRdEnableCode = '''
777        auto rdEn = std::vector<bool>();
778        '''
779        if isPred:
780            loadMemAccCode = '''
781            int index = 0;
782            uint8_t byte;
783            for (int i = 0; i < eCount / 8; i++) {
784                byte = memDataView[i];
785                for (int j = 0; j < 8; j++, index++) {
786                    PDest_x[index] = (byte >> j) & 1;
787                }
788            }
789            '''
790            storeMemAccCode = '''
791            int index = 0;
792            uint8_t byte;
793            for (int i = 0; i < eCount / 8; i++) {
794                byte = 0;
795                for (int j = 0; j < 8; j++, index++) {
796                    byte |= PDest_x[index] << j;
797                }
798                memDataView[i] = byte;
799            }
800            '''
801            storeWrEnableCode = '''
802            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_store = '''
1121        EA = AA64FpBase_x[elemIndex] + imm * sizeof(MemElemType)'''
1122            eaCode_load = '''
1123        EA = AA64FpUreg0_x[elemIndex] + imm * sizeof(MemElemType)'''
1124        else:
1125            offset_code = '''
1126        if (offsetIs32) {
1127            offset &= (1ULL << 32) - 1;
1128        }
1129        if (offsetIsSigned) {
1130            offset = sext<32>(offset);
1131        }
1132        if (offsetIsScaled) {
1133            offset *= sizeof(MemElemType);
1134        }
1135        EA = XBase + offset'''
1136            eaCode_store = '''
1137        uint64_t offset = AA64FpOffset_x[elemIndex];''' + offset_code
1138            eaCode_load = '''
1139        uint64_t offset = AA64FpUreg0_x[elemIndex];''' + offset_code
1140
1141        loadMemAccCode = '''
1142            AA64FpDest_x[elemIndex] = memData;
1143        '''
1144        storeMemAccCode = '''
1145            memData = AA64FpDest_x[elemIndex];
1146        '''
1147        predCheckCode = 'GpOp_x[index]'
1148        faultStatusSetCode = 'PUreg0_x[elemIndex] = 1;'
1149        faultStatusResetCode = 'PUreg0_x[elemIndex] = 0;'
1150        loadIop = InstObjParams('ld1',
1151            ('SveGatherLoadVIMicroop'
1152             if indexed_addr_form == IndexedAddrForm.VEC_PLUS_IMM
1153             else 'SveGatherLoadSVMicroop'),
1154            'MicroOp',
1155            {'tpl_header': tplHeader,
1156             'tpl_args': tplArgs,
1157             'memacc_code': loadMemAccCode,
1158             'ea_code' : sveEnabledCheckCode + eaCode_load,
1159             'fault_status_set_code' : faultStatusSetCode,
1160             'fault_status_reset_code' : faultStatusResetCode,
1161             'pred_check_code' : predCheckCode,
1162             'fa_code' : ''},
1163            ['IsMicroop', 'IsMemRef', 'IsLoad'])
1164        storeIop = InstObjParams('st1',
1165            ('SveScatterStoreVIMicroop'
1166             if indexed_addr_form == IndexedAddrForm.VEC_PLUS_IMM
1167             else 'SveScatterStoreSVMicroop'),
1168            'MicroOp',
1169            {'tpl_header': tplHeader,
1170             'tpl_args': tplArgs,
1171             'memacc_code': storeMemAccCode,
1172             'ea_code' : sveEnabledCheckCode + eaCode_store,
1173             'pred_check_code' : predCheckCode,
1174             'fa_code' : ''},
1175            ['IsMicroop', 'IsMemRef', 'IsStore'])
1176        if indexed_addr_form == IndexedAddrForm.VEC_PLUS_IMM:
1177            header_output += SveIndexedMemVIMicroopDeclare.subst(loadIop)
1178            header_output += SveIndexedMemVIMicroopDeclare.subst(storeIop)
1179        else:
1180            header_output += SveIndexedMemSVMicroopDeclare.subst(loadIop)
1181            header_output += SveIndexedMemSVMicroopDeclare.subst(storeIop)
1182        exec_output += (
1183            SveGatherLoadMicroopExecute.subst(loadIop) +
1184            SveGatherLoadMicroopInitiateAcc.subst(loadIop) +
1185            SveGatherLoadMicroopCompleteAcc.subst(loadIop) +
1186            SveScatterStoreMicroopExecute.subst(storeIop) +
1187            SveScatterStoreMicroopInitiateAcc.subst(storeIop) +
1188            SveScatterStoreMicroopCompleteAcc.subst(storeIop))
1189        for args in gatherLoadTplArgs:
1190            substDict = {'tpl_args': '<%s>' % ', '.join(args),
1191                         'class_name': (
1192                             'SveGatherLoadVIMicroop'
1193                             if indexed_addr_form == \
1194                                 IndexedAddrForm.VEC_PLUS_IMM
1195                             else 'SveGatherLoadSVMicroop')}
1196            # TODO: this should become SveMemExecDeclare
1197            exec_output += SveContigMemExecDeclare.subst(substDict)
1198        for args in scatterStoreTplArgs:
1199            substDict = {'tpl_args': '<%s>' % ', '.join(args),
1200                         'class_name': (
1201                             'SveScatterStoreVIMicroop'
1202                             if indexed_addr_form == \
1203                                 IndexedAddrForm.VEC_PLUS_IMM
1204                             else 'SveScatterStoreSVMicroop')}
1205            # TODO: this should become SveMemExecDeclare
1206            exec_output += SveContigMemExecDeclare.subst(substDict)
1207
1208    firstFaultTplArgs = ('int32_t', 'int64_t', 'uint32_t', 'uint64_t')
1209
1210    def emitSveFirstFaultWritebackMicroop():
1211        global header_output, exec_output, decoders
1212        tplHeader = 'template <class RegElemType>'
1213        tplArgs = '<RegElemType>'
1214        faultStatusCheckCode = 'PUreg0_x[index]'
1215        firstFaultResetCode = '''
1216        for(int j = 0; j < sizeof(RegElemType); j++) {
1217            Ffr_ub[index * sizeof(RegElemType) + j] = 0;
1218        }
1219        '''
1220        firstFaultForwardCode = '''
1221        for(int j = 0; j < sizeof(RegElemType); j++) {
1222            Ffr_ub[index * sizeof(RegElemType) + j] = FfrAux_x[index];
1223        }
1224        '''
1225        iop = InstObjParams('ldff1',
1226            'SveFirstFaultWritebackMicroop',
1227            'MicroOp',
1228            {'tpl_header': tplHeader,
1229             'tpl_args': tplArgs,
1230             'fault_status_check_code' : faultStatusCheckCode,
1231             'first_fault_reset_code' : firstFaultResetCode,
1232             'first_fault_forward_code' : firstFaultForwardCode},
1233             ['IsMicroop'])
1234        header_output += SveFirstFaultWritebackMicroopDeclare.subst(iop)
1235        exec_output += SveFirstFaultWritebackMicroopExecute.subst(iop)
1236        for args in firstFaultTplArgs:
1237            substDict = {'targs': args,
1238                         'class_name' : 'SveFirstFaultWritebackMicroop' }
1239            exec_output += SveOpExecDeclare.subst(substDict)
1240
1241    # Generates definitions for the first microop of SVE gather loads, required
1242    # to propagate the source vector register to the transfer microops
1243    def emitSveGatherLoadCpySrcVecMicroop():
1244        global header_output, exec_output, decoders
1245        code = sveEnabledCheckCode + '''
1246        unsigned eCount = ArmStaticInst::getCurSveVecLen<uint8_t>(
1247                xc->tcBase());
1248        for (unsigned i = 0; i < eCount; i++) {
1249            AA64FpUreg0_ub[i] = AA64FpOp1_ub[i];
1250        }'''
1251        iop = InstObjParams('ld1',
1252            'SveGatherLoadCpySrcVecMicroop',
1253            'MicroOp',
1254            {'code': code},
1255            ['IsMicroop'])
1256        header_output += SveGatherLoadCpySrcVecMicroopDeclare.subst(iop)
1257        exec_output += SveGatherLoadCpySrcVecMicroopExecute.subst(iop)
1258
1259    def emitSveInterleaveMicroop():
1260        global header_output, exec_output, decoders
1261        code2 = sveEnabledCheckCode + '''
1262        unsigned eCount = ArmStaticInst::getCurSveVecLen<Element>(
1263                xc->tcBase());
1264        for (unsigned int i = 0; i < eCount; ++i) {
1265            unsigned int absIdx = regIndex * eCount + i;
1266            unsigned int srcIdx = absIdx / numRegs;
1267            unsigned int srcVec = absIdx % numRegs;
1268            if (srcVec == 0)
1269                AA64FpDest_x[i] = AA64FpOp1V0S_x[srcIdx];
1270            else if (srcVec == 1)
1271                AA64FpDest_x[i] = AA64FpOp1V1S_x[srcIdx];
1272        }'''
1273
1274        code3 = sveEnabledCheckCode + '''
1275        unsigned eCount = ArmStaticInst::getCurSveVecLen<Element>(
1276                xc->tcBase());
1277        for (unsigned int i = 0; i < eCount; ++i) {
1278            unsigned int absIdx = regIndex * eCount + i;
1279            unsigned int srcIdx = absIdx / numRegs;
1280            unsigned int srcVec = absIdx % numRegs;
1281            if (srcVec == 0)
1282                AA64FpDest_x[i] = AA64FpOp1V0S_x[srcIdx];
1283            else if (srcVec == 1)
1284                AA64FpDest_x[i] = AA64FpOp1V1S_x[srcIdx];
1285            else if (srcVec == 2)
1286                AA64FpDest_x[i] = AA64FpOp1V2S_x[srcIdx];
1287        }'''
1288
1289        code4 = sveEnabledCheckCode + '''
1290        unsigned eCount = ArmStaticInst::getCurSveVecLen<Element>(
1291                xc->tcBase());
1292        for (unsigned int i = 0; i < eCount; ++i) {
1293            unsigned int absIdx = regIndex * eCount + i;
1294            unsigned int srcIdx = absIdx / numRegs;
1295            unsigned int srcVec = absIdx % numRegs;
1296            if (srcVec == 0)
1297                AA64FpDest_x[i] = AA64FpOp1V0S_x[srcIdx];
1298            else if (srcVec == 1)
1299                AA64FpDest_x[i] = AA64FpOp1V1S_x[srcIdx];
1300            else if (srcVec == 2)
1301                AA64FpDest_x[i] = AA64FpOp1V2S_x[srcIdx];
1302            else if (srcVec == 3)
1303                AA64FpDest_x[i] = AA64FpOp1V3S_x[srcIdx];
1304        }'''
1305
1306        iop2 = InstObjParams('intrlv',
1307                'SveIntrlv2Microop',
1308                'MicroOp',
1309                {'code': code2},
1310                ['IsMicroop'])
1311        iop3 = InstObjParams('intrlv',
1312                'SveIntrlv3Microop',
1313                'MicroOp',
1314                {'code': code3},
1315                ['IsMicroop'])
1316        iop4 = InstObjParams('intrlv',
1317                'SveIntrlv4Microop',
1318                'MicroOp',
1319                {'code': code4},
1320                ['IsMicroop'])
1321        header_output += SveIntrlvMicroopDeclare.subst(iop2);
1322        header_output += SveIntrlvMicroopDeclare.subst(iop3);
1323        header_output += SveIntrlvMicroopDeclare.subst(iop4);
1324        exec_output += SveIntrlvMicroopExecute.subst(iop2);
1325        exec_output += SveIntrlvMicroopExecute.subst(iop3);
1326        exec_output += SveIntrlvMicroopExecute.subst(iop4);
1327        for type in ('uint8_t', 'uint16_t', 'uint32_t', 'uint64_t'):
1328            for nreg in range(2,5):
1329                substDict = {'targs' : type,
1330                        'class_name' : 'SveIntrlv' + str(nreg) + 'Microop'}
1331                exec_output += SveIntrlvMicroopExecDeclare.subst(substDict)
1332
1333    def emitSveDeInterleaveMicroop():
1334        global header_output, exec_output, decoders
1335        code2 = sveEnabledCheckCode + '''
1336        unsigned eCount = ArmStaticInst::getCurSveVecLen<Element>(
1337                xc->tcBase());
1338        for (unsigned int i = 0; i < eCount; ++i) {
1339            unsigned int absIdx = (regIndex + numRegs * i);
1340            unsigned int srcIdx = absIdx % eCount;
1341            unsigned int srcVec = absIdx / eCount;
1342            if (srcVec == 0)
1343                AA64FpDest_x[i] = AA64IntrlvReg0_x[srcIdx];
1344            else if(srcVec == 1)
1345                AA64FpDest_x[i] = AA64IntrlvReg1_x[srcIdx];
1346        }'''
1347
1348        code3 = sveEnabledCheckCode + '''
1349        unsigned eCount = ArmStaticInst::getCurSveVecLen<Element>(
1350                xc->tcBase());
1351        for (unsigned int i = 0; i < eCount; ++i) {
1352            unsigned int absIdx = (regIndex + numRegs * i);
1353            unsigned int srcIdx = absIdx % eCount;
1354            unsigned int srcVec = absIdx / eCount;
1355            if (srcVec == 0)
1356                AA64FpDest_x[i] = AA64IntrlvReg0_x[srcIdx];
1357            else if(srcVec == 1)
1358                AA64FpDest_x[i] = AA64IntrlvReg1_x[srcIdx];
1359            else if(srcVec == 2)
1360                AA64FpDest_x[i] = AA64IntrlvReg2_x[srcIdx];
1361        }'''
1362
1363        code4 = sveEnabledCheckCode + '''
1364        unsigned eCount = ArmStaticInst::getCurSveVecLen<Element>(
1365                xc->tcBase());
1366        for (unsigned int i = 0; i < eCount; ++i) {
1367            unsigned int absIdx = (regIndex + numRegs * i);
1368            unsigned int srcIdx = absIdx % eCount;
1369            unsigned int srcVec = absIdx / eCount;
1370            if (srcVec == 0)
1371                AA64FpDest_x[i] = AA64IntrlvReg0_x[srcIdx];
1372            else if(srcVec == 1)
1373                AA64FpDest_x[i] = AA64IntrlvReg1_x[srcIdx];
1374            else if(srcVec == 2)
1375                AA64FpDest_x[i] = AA64IntrlvReg2_x[srcIdx];
1376            else if(srcVec == 3)
1377                AA64FpDest_x[i] = AA64IntrlvReg3_x[srcIdx];
1378        }'''
1379
1380        iop2 = InstObjParams('deintrlv',
1381                'SveDeIntrlv2Microop',
1382                'MicroOp',
1383                {'code': code2},
1384                ['IsMicroop'])
1385        iop3 = InstObjParams('deintrlv',
1386                'SveDeIntrlv3Microop',
1387                'MicroOp',
1388                {'code': code3},
1389                ['IsMicroop'])
1390        iop4 = InstObjParams('deintrlv',
1391                'SveDeIntrlv4Microop',
1392                'MicroOp',
1393                {'code': code4},
1394                ['IsMicroop'])
1395        header_output += SveDeIntrlvMicroopDeclare.subst(iop2);
1396        header_output += SveDeIntrlvMicroopDeclare.subst(iop3);
1397        header_output += SveDeIntrlvMicroopDeclare.subst(iop4);
1398        exec_output += SveIntrlvMicroopExecute.subst(iop2);
1399        exec_output += SveIntrlvMicroopExecute.subst(iop3);
1400        exec_output += SveIntrlvMicroopExecute.subst(iop4);
1401        for type in ('uint8_t', 'uint16_t', 'uint32_t', 'uint64_t'):
1402            for nreg in range(2,5):
1403                substDict = {'targs' : type,
1404                        'class_name' : 'SveDeIntrlv' + str(nreg) + 'Microop'}
1405                exec_output += SveIntrlvMicroopExecDeclare.subst(substDict)
1406
1407    # Generates definitions for SVE struct load/store microops
1408    def emitSveStructMemInsts(offsetIsImm):
1409        global header_output, exec_output, decoders
1410        eaCode = SPAlignmentCheckCode + '''
1411        int memAccessSize = eCount * sizeof(Element);
1412        EA = memAccessSize * regIndex + XBase + '''
1413        if offsetIsImm:
1414            eaCode += '((int64_t) this->imm * eCount * sizeof(Element))'
1415        else:
1416            eaCode += '(XOffset * sizeof(Element));'
1417        loadMemAccCode = '''
1418        for (int i = 0; i < eCount; i++) {
1419            int gpIdx = (regIndex * eCount + i) / numRegs;
1420            if (GpOp_x[gpIdx]) {
1421                AA64FpDest_x[i] = memDataView[i];
1422            } else {
1423                AA64FpDest_x[i] = 0;
1424            }
1425        }
1426        '''
1427        storeMemAccCode = '''
1428        for (int i = 0; i < eCount; i++) {
1429            int gpIdx = (regIndex * eCount + i) / numRegs;
1430            if (GpOp_x[gpIdx]) {
1431                memDataView[i] = AA64FpDest_x[i];
1432            } else {
1433                memDataView[i] = 0;
1434                for (int j = 0; j < sizeof(Element); j++) {
1435                    wrEn[sizeof(Element) * i + j] = false;
1436                }
1437            }
1438        }
1439        '''
1440        storeWrEnableCode = '''
1441        auto wrEn = std::vector<bool>(sizeof(Element) * eCount, true);
1442        '''
1443        loadIop = InstObjParams('ldxx',
1444            'SveLoadRegImmMicroop' if offsetIsImm else 'SveLoadRegRegMicroop',
1445            'MicroOp',
1446            {'targs': 'Element',
1447             'memacc_code': loadMemAccCode,
1448             'ea_code' : sveEnabledCheckCode + eaCode,
1449             'fa_code' : ''},
1450            ['IsMemRef', 'IsLoad', 'IsMicroop'])
1451        storeIop = InstObjParams('stxx',
1452            'SveStoreRegImmMicroop' if offsetIsImm
1453                                    else 'SveStoreRegRegMicroop',
1454            'MicroOp',
1455            {'targs': 'Element',
1456             'wren_code': storeWrEnableCode,
1457             'memacc_code': storeMemAccCode,
1458             'ea_code' : sveEnabledCheckCode + eaCode,
1459             'fa_code' : ''},
1460            ['IsMemRef', 'IsStore', 'IsMicroop'])
1461        if offsetIsImm:
1462            header_output += SveStructMemSIMicroopDeclare.subst(loadIop)
1463            header_output += SveStructMemSIMicroopDeclare.subst(storeIop)
1464        else:
1465            header_output += SveStructMemSSMicroopDeclare.subst(loadIop)
1466            header_output += SveStructMemSSMicroopDeclare.subst(storeIop)
1467        exec_output += (
1468            SveStructLoadExecute.subst(loadIop) +
1469            SveStructLoadInitiateAcc.subst(loadIop) +
1470            SveStructLoadCompleteAcc.subst(loadIop) +
1471            SveStructStoreExecute.subst(storeIop) +
1472            SveStructStoreInitiateAcc.subst(storeIop) +
1473            SveStructStoreCompleteAcc.subst(storeIop))
1474        tplArgs = ('uint8_t', 'uint16_t', 'uint32_t', 'uint64_t')
1475        for type in tplArgs:
1476            substDict = {'targs': type,
1477                         'class_name': 'SveLoadRegImmMicroop' if offsetIsImm
1478                                       else 'SveLoadRegRegMicroop'}
1479            exec_output += SveStructMemExecDeclare.subst(substDict)
1480            substDict['class_name'] = ('SveStoreRegImmMicroop' if offsetIsImm
1481                                       else 'SveStoreRegRegMicroop')
1482            exec_output += SveStructMemExecDeclare.subst(substDict)
1483
1484    # Generates definitions for SVE load-and-replicate quadword instructions
1485    def emitSveLoadAndReplQuad(offsetIsImm):
1486        global header_output, exec_output, decoders
1487        tplHeader = 'template <class RegElemType, class MemElemType>'
1488        tplArgs = '<RegElemType, MemElemType>'
1489        eaCode = SPAlignmentCheckCode + '''
1490        int memAccessSize = 16;
1491        EA = XBase + '''
1492        if offsetIsImm:
1493            eaCode += '(((int64_t) this->imm) * 16);'
1494        else:
1495            eaCode += '(XOffset * sizeof(MemElemType));'
1496        loadRdEnableCode = '''
1497        eCount = 16/sizeof(RegElemType);
1498        auto rdEn = std::vector<bool>(16, true);
1499        for (int i = 0; i < eCount; ++i) {
1500            if (!GpOp_x[i]) {
1501                for (int j = 0; j < sizeof(RegElemType); ++j) {
1502                    rdEn[sizeof(RegElemType) * i + j] = false;
1503                }
1504            }
1505        }
1506        '''
1507        memAccCode = '''
1508        __uint128_t qword;
1509        RegElemType* qp = reinterpret_cast<RegElemType*>(&qword);
1510        for (int i = 0; i < 16/sizeof(RegElemType); ++i) {
1511            if (GpOp_x[i]) {
1512                qp[i] = memDataView[i];
1513            } else {
1514                qp[i] = 0;
1515            }
1516        }
1517        eCount = ArmStaticInst::getCurSveVecLen<__uint128_t>(
1518                xc->tcBase());
1519        for (int i = 0; i < eCount; ++i) {
1520            AA64FpDest_uq[i] = qword;
1521        }
1522        '''
1523        iop = InstObjParams('ld1rq',
1524                'SveLd1RqSI' if offsetIsImm else 'SveLd1RqSS',
1525                'SveContigMemSI' if offsetIsImm else 'SveContigMemSS',
1526                {'tpl_header': tplHeader,
1527                 'tpl_args': tplArgs,
1528                 'rden_code': loadRdEnableCode,
1529                 'memacc_code': memAccCode,
1530                 'ea_code': sveEnabledCheckCode + eaCode,
1531                 'fault_code': '',
1532                 'fa_code': ''},
1533                ['IsMemRef', 'IsLoad'])
1534        if offsetIsImm:
1535            header_output += SveContigMemSIOpDeclare.subst(iop)
1536        else:
1537            header_output += SveContigMemSSOpDeclare.subst(iop)
1538        exec_output += (
1539                SveContigLoadExecute.subst(iop) +
1540                SveContigLoadInitiateAcc.subst(iop) +
1541                SveContigLoadCompleteAcc.subst(iop))
1542        for ttype in ('uint8_t', 'uint16_t', 'uint32_t', 'uint64_t'):
1543            substDict = {'tpl_args': '<%s, %s>' % (ttype, ttype),
1544                    'class_name': 'SveLd1RqSI' if offsetIsImm
1545                                  else 'SveLd1RqSS'}
1546            exec_output += SveContigMemExecDeclare.subst(substDict)
1547
1548    # LD1[S]{B,H,W,D} (scalar plus immediate)
1549    # ST1[S]{B,H,W,D} (scalar plus immediate)
1550    # LDNF1[S]{B,H,W,D} (scalar plus immediate)
1551    emitSveContigMemInsts(True)
1552    # LD1[S]{B,H,W,D} (scalar plus scalar)
1553    # ST1[S]{B,H,W,D} (scalar plus scalar)
1554    # LDFF1[S]{B,H,W,D} (scalar plus vector)
1555    emitSveContigMemInsts(False)
1556
1557    # LD1R[S]{B,H,W,D}
1558    emitSveLoadAndRepl()
1559
1560    # LD1RQ{B,H,W,D} (scalar plus immediate)
1561    emitSveLoadAndReplQuad(offsetIsImm = True)
1562    # LD1RQ{B,H,W,D} (scalar plus scalar)
1563    emitSveLoadAndReplQuad(offsetIsImm = False)
1564
1565    # LD{2,3,4}{B,H,W,D} (scalar plus immediate)
1566    # ST{2,3,4}{B,H,W,D} (scalar plus immediate)
1567    emitSveStructMemInsts(offsetIsImm = True)
1568    # LD{2,3,4}{B,H,W,D} (scalar plus scalar)
1569    # ST{2,3,4}{B,H,W,D} (scalar plus scalar)
1570    emitSveStructMemInsts(offsetIsImm = False)
1571
1572    # LDR (predicate), STR (predicate)
1573    emitSveMemFillSpill(True)
1574    # LDR (vector), STR (vector)
1575    emitSveMemFillSpill(False)
1576
1577    # LD1[S]{B,H,W,D} (vector plus immediate)
1578    # ST1[S]{B,H,W,D} (vector plus immediate)
1579    # LDFF1[S]{B,H,W,D} (scalar plus immediate)
1580    emitSveIndexedMemMicroops(IndexedAddrForm.VEC_PLUS_IMM)
1581    # LD1[S]{B,H,W,D} (scalar plus vector)
1582    # ST1[S]{B,H,W,D} (scalar plus vector)
1583    # LDFF1[S]{B,H,W,D} (scalar plus vector)
1584    emitSveIndexedMemMicroops(IndexedAddrForm.SCA_PLUS_VEC)
1585
1586    # FFR writeback microop for gather loads
1587    emitSveFirstFaultWritebackMicroop()
1588
1589    # Source vector copy microop for gather loads
1590    emitSveGatherLoadCpySrcVecMicroop()
1591
1592    # ST/LD struct de/interleave microops
1593    emitSveInterleaveMicroop()
1594    emitSveDeInterleaveMicroop()
1595}};
1596