1/*
2 * Copyright (c) 2017-2019 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder.  You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Giacomo Gabrielli
38 */
39
40#ifndef __ARCH_ARM_INSTS_SVE_HH__
41#define __ARCH_ARM_INSTS_SVE_HH__
42
43#include "arch/arm/insts/static_inst.hh"
44
45namespace ArmISA {
46
47enum class SvePredType {
48    NONE,
49    MERGE,
50    ZERO,
51    SELECT
52};
53
54/// Returns the specifier for the predication type `pt` as a string.
55const char* svePredTypeToStr(SvePredType pt);
56
57/// Index generation instruction, immediate operands
58class SveIndexIIOp : public ArmStaticInst {
59  protected:
60    IntRegIndex dest;
61    int8_t imm1;
62    int8_t imm2;
63
64    SveIndexIIOp(const char* mnem, ExtMachInst _machInst,
65            OpClass __opClass, IntRegIndex _dest,
66            int8_t _imm1, int8_t _imm2) :
67        ArmStaticInst(mnem, _machInst, __opClass),
68        dest(_dest), imm1(_imm1), imm2(_imm2)
69    {}
70    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
71};
72
73class SveIndexIROp : public ArmStaticInst {
74  protected:
75    IntRegIndex dest;
76    int8_t imm1;
77    IntRegIndex op2;
78
79    SveIndexIROp(const char* mnem, ExtMachInst _machInst,
80            OpClass __opClass, IntRegIndex _dest,
81            int8_t _imm1, IntRegIndex _op2) :
82        ArmStaticInst(mnem, _machInst, __opClass),
83          dest(_dest), imm1(_imm1), op2(_op2)
84    {}
85    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
86};
87
88class SveIndexRIOp : public ArmStaticInst {
89  protected:
90    IntRegIndex dest;
91    IntRegIndex op1;
92    int8_t imm2;
93
94    SveIndexRIOp(const char* mnem, ExtMachInst _machInst,
95            OpClass __opClass, IntRegIndex _dest,
96            IntRegIndex _op1, int8_t _imm2) :
97        ArmStaticInst(mnem, _machInst, __opClass),
98        dest(_dest), op1(_op1), imm2(_imm2)
99    {}
100    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
101};
102
103class SveIndexRROp : public ArmStaticInst {
104  protected:
105    IntRegIndex dest;
106    IntRegIndex op1;
107    IntRegIndex op2;
108
109    SveIndexRROp(const char* mnem, ExtMachInst _machInst,
110            OpClass __opClass, IntRegIndex _dest,
111            IntRegIndex _op1, IntRegIndex _op2) :
112        ArmStaticInst(mnem, _machInst, __opClass),
113        dest(_dest), op1(_op1), op2(_op2)
114    {}
115    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
116};
117
118// Predicate count SVE instruction.
119class SvePredCountOp : public ArmStaticInst {
120  protected:
121    IntRegIndex dest;
122    IntRegIndex gp;
123    bool srcIs32b;
124    bool destIsVec;
125
126    SvePredCountOp(const char* mnem, ExtMachInst _machInst,
127            OpClass __opClass, IntRegIndex _dest, IntRegIndex _gp,
128            bool _srcIs32b = false, bool _destIsVec = false) :
129        ArmStaticInst(mnem, _machInst, __opClass),
130        dest(_dest), gp(_gp),
131        srcIs32b(_srcIs32b), destIsVec(_destIsVec)
132    {}
133    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
134};
135
136// Predicate count SVE instruction (predicated).
137class SvePredCountPredOp : public ArmStaticInst {
138  protected:
139    IntRegIndex dest;
140    IntRegIndex op1;
141    IntRegIndex gp;
142
143    SvePredCountPredOp(const char* mnem, ExtMachInst _machInst,
144            OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1,
145            IntRegIndex _gp) :
146        ArmStaticInst(mnem, _machInst, __opClass),
147        dest(_dest), op1(_op1), gp(_gp)
148    {}
149    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
150};
151
152/// While predicate generation SVE instruction.
153class SveWhileOp : public ArmStaticInst {
154  protected:
155    IntRegIndex dest, op1, op2;
156    bool srcIs32b;
157
158    SveWhileOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass,
159               IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2,
160               bool _srcIs32b) :
161        ArmStaticInst(mnem, _machInst, __opClass),
162        dest(_dest), op1(_op1), op2(_op2), srcIs32b(_srcIs32b)
163    {}
164    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
165};
166
167/// Compare and terminate loop SVE instruction.
168class SveCompTermOp : public ArmStaticInst {
169  protected:
170    IntRegIndex op1, op2;
171
172    SveCompTermOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass,
173                  IntRegIndex _op1, IntRegIndex _op2) :
174        ArmStaticInst(mnem, _machInst, __opClass),
175        op1(_op1), op2(_op2)
176    {}
177    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
178};
179
180/// Unary, constructive, predicated (merging) SVE instruction.
181class SveUnaryPredOp : public ArmStaticInst {
182  protected:
183    IntRegIndex dest, op1, gp;
184
185    SveUnaryPredOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass,
186                   IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _gp) :
187        ArmStaticInst(mnem, _machInst, __opClass),
188        dest(_dest), op1(_op1), gp(_gp)
189    {}
190
191    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
192};
193
194/// Unary, constructive, unpredicated SVE instruction.
195class SveUnaryUnpredOp : public ArmStaticInst {
196  protected:
197    IntRegIndex dest, op1;
198
199    SveUnaryUnpredOp(const char* mnem, ExtMachInst _machInst,
200                     OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1) :
201        ArmStaticInst(mnem, _machInst, __opClass),
202        dest(_dest), op1(_op1)
203    {}
204
205    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
206};
207
208/// Unary with wide immediate, constructive, unpredicated SVE instruction.
209class SveUnaryWideImmUnpredOp : public ArmStaticInst {
210  protected:
211    IntRegIndex dest;
212    uint64_t imm;
213
214    SveUnaryWideImmUnpredOp(const char* mnem, ExtMachInst _machInst,
215                            OpClass __opClass, IntRegIndex _dest,
216                            uint64_t _imm) :
217        ArmStaticInst(mnem, _machInst, __opClass),
218        dest(_dest), imm(_imm)
219    {}
220
221    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
222};
223
224/// Unary with wide immediate, constructive, predicated SVE instruction.
225class SveUnaryWideImmPredOp : public ArmStaticInst {
226  protected:
227    IntRegIndex dest;
228    uint64_t imm;
229    IntRegIndex gp;
230
231    bool isMerging;
232
233    SveUnaryWideImmPredOp(const char* mnem, ExtMachInst _machInst,
234                          OpClass __opClass, IntRegIndex _dest,
235                          uint64_t _imm, IntRegIndex _gp, bool _isMerging) :
236        ArmStaticInst(mnem, _machInst, __opClass),
237        dest(_dest), imm(_imm), gp(_gp), isMerging(_isMerging)
238    {}
239
240    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
241};
242
243/// Binary with immediate, destructive, unpredicated SVE instruction.
244class SveBinImmUnpredConstrOp : public ArmStaticInst {
245  protected:
246    IntRegIndex dest, op1;
247    uint64_t imm;
248
249    SveBinImmUnpredConstrOp(const char* mnem, ExtMachInst _machInst,
250            OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1,
251            uint64_t _imm) :
252        ArmStaticInst(mnem, _machInst, __opClass),
253        dest(_dest), op1(_op1), imm(_imm)
254    {}
255
256    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
257};
258
259/// Binary with immediate, destructive, predicated (merging) SVE instruction.
260class SveBinImmPredOp : public ArmStaticInst {
261  protected:
262    IntRegIndex dest, gp;
263    uint64_t imm;
264
265    SveBinImmPredOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass,
266                    IntRegIndex _dest, uint64_t _imm, IntRegIndex _gp) :
267        ArmStaticInst(mnem, _machInst, __opClass),
268        dest(_dest), gp(_gp), imm(_imm)
269    {}
270
271    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
272};
273
274/// Binary with wide immediate, destructive, unpredicated SVE instruction.
275class SveBinWideImmUnpredOp : public ArmStaticInst {
276  protected:
277    IntRegIndex dest;
278    uint64_t imm;
279
280    SveBinWideImmUnpredOp(const char* mnem, ExtMachInst _machInst,
281                          OpClass __opClass, IntRegIndex _dest,
282                          uint64_t _imm) :
283        ArmStaticInst(mnem, _machInst, __opClass),
284        dest(_dest), imm(_imm)
285    {}
286
287    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
288};
289
290/// Binary, destructive, predicated (merging) SVE instruction.
291class SveBinDestrPredOp : public ArmStaticInst {
292  protected:
293    IntRegIndex dest, op2, gp;
294
295    SveBinDestrPredOp(const char* mnem, ExtMachInst _machInst,
296                      OpClass __opClass, IntRegIndex _dest, IntRegIndex _op2,
297                      IntRegIndex _gp) :
298        ArmStaticInst(mnem, _machInst, __opClass),
299        dest(_dest), op2(_op2), gp(_gp)
300    {}
301
302    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
303};
304
305/// Binary, constructive, predicated SVE instruction.
306class SveBinConstrPredOp : public ArmStaticInst {
307  protected:
308    IntRegIndex dest, op1, op2, gp;
309    SvePredType predType;
310
311    SveBinConstrPredOp(const char* mnem, ExtMachInst _machInst,
312                       OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1,
313                       IntRegIndex _op2, IntRegIndex _gp,
314                       SvePredType _predType) :
315        ArmStaticInst(mnem, _machInst, __opClass),
316        dest(_dest), op1(_op1), op2(_op2), gp(_gp), predType(_predType)
317    {}
318
319    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
320};
321
322/// Binary, unpredicated SVE instruction with indexed operand
323class SveBinUnpredOp : public ArmStaticInst {
324  protected:
325    IntRegIndex dest, op1, op2;
326
327    SveBinUnpredOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass,
328                   IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2) :
329        ArmStaticInst(mnem, _machInst, __opClass),
330        dest(_dest), op1(_op1), op2(_op2)
331    {}
332
333    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
334};
335
336/// Binary, unpredicated SVE instruction
337class SveBinIdxUnpredOp : public ArmStaticInst {
338  protected:
339    IntRegIndex dest, op1, op2;
340    uint8_t index;
341
342    SveBinIdxUnpredOp(const char* mnem, ExtMachInst _machInst,
343                      OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1,
344                      IntRegIndex _op2, uint8_t _index) :
345        ArmStaticInst(mnem, _machInst, __opClass),
346        dest(_dest), op1(_op1), op2(_op2), index(_index)
347    {}
348
349    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
350};
351
352/// Predicate logical instruction.
353class SvePredLogicalOp : public ArmStaticInst {
354  protected:
355    IntRegIndex dest, op1, op2, gp;
356    bool isSel;
357
358    SvePredLogicalOp(const char* mnem, ExtMachInst _machInst,
359                     OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1,
360                     IntRegIndex _op2, IntRegIndex _gp, bool _isSel = false) :
361        ArmStaticInst(mnem, _machInst, __opClass),
362        dest(_dest), op1(_op1), op2(_op2), gp(_gp), isSel(_isSel)
363    {}
364
365    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
366};
367
368/// Predicate binary permute instruction.
369class SvePredBinPermOp : public ArmStaticInst {
370  protected:
371    IntRegIndex dest, op1, op2;
372
373    SvePredBinPermOp(const char* mnem, ExtMachInst _machInst,
374                     OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1,
375                     IntRegIndex _op2) :
376        ArmStaticInst(mnem, _machInst, __opClass),
377        dest(_dest), op1(_op1), op2(_op2)
378    {}
379
380    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
381};
382
383/// SVE compare instructions, predicated (zeroing).
384class SveCmpOp : public ArmStaticInst {
385  protected:
386    IntRegIndex dest, gp, op1, op2;
387
388    SveCmpOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass,
389             IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2,
390             IntRegIndex _gp) :
391        ArmStaticInst(mnem, _machInst, __opClass),
392        dest(_dest), gp(_gp), op1(_op1), op2(_op2)
393    {}
394
395    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
396};
397
398/// SVE compare-with-immediate instructions, predicated (zeroing).
399class SveCmpImmOp : public ArmStaticInst {
400  protected:
401    IntRegIndex dest, gp, op1;
402    uint64_t imm;
403
404    SveCmpImmOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass,
405                IntRegIndex _dest, IntRegIndex _op1, uint64_t _imm,
406                IntRegIndex _gp) :
407        ArmStaticInst(mnem, _machInst, __opClass),
408        dest(_dest), gp(_gp), op1(_op1), imm(_imm)
409    {}
410
411    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
412};
413
414/// Ternary, destructive, predicated (merging) SVE instruction.
415class SveTerPredOp : public ArmStaticInst {
416  protected:
417    IntRegIndex dest, op1, op2, gp;
418
419    SveTerPredOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass,
420                 IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2,
421                 IntRegIndex _gp) :
422        ArmStaticInst(mnem, _machInst, __opClass),
423        dest(_dest), op1(_op1), op2(_op2), gp(_gp)
424    {}
425
426    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
427};
428
429/// Ternary with immediate, destructive, unpredicated SVE instruction.
430class SveTerImmUnpredOp : public ArmStaticInst {
431  protected:
432    IntRegIndex dest, op2;
433    uint64_t imm;
434
435    SveTerImmUnpredOp(const char* mnem, ExtMachInst _machInst,
436                      OpClass __opClass, IntRegIndex _dest, IntRegIndex _op2,
437                      uint64_t _imm) :
438        ArmStaticInst(mnem, _machInst, __opClass),
439        dest(_dest), op2(_op2), imm(_imm)
440    {}
441
442    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
443};
444
445/// SVE reductions.
446class SveReducOp : public ArmStaticInst {
447  protected:
448    IntRegIndex dest, op1, gp;
449
450    SveReducOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass,
451               IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _gp) :
452        ArmStaticInst(mnem, _machInst, __opClass),
453        dest(_dest), op1(_op1), gp(_gp)
454    {}
455
456    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
457};
458
459/// SVE ordered reductions.
460class SveOrdReducOp : public ArmStaticInst {
461  protected:
462    IntRegIndex dest, op1, gp;
463
464    SveOrdReducOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass,
465               IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _gp) :
466        ArmStaticInst(mnem, _machInst, __opClass),
467        dest(_dest), op1(_op1), gp(_gp)
468    {}
469
470    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
471};
472
473/// PTRUE, PTRUES.
474class SvePtrueOp : public ArmStaticInst {
475  protected:
476    IntRegIndex dest;
477    uint8_t imm;
478
479    SvePtrueOp(const char* mnem, ExtMachInst _machInst,
480               OpClass __opClass, IntRegIndex _dest, uint8_t _imm) :
481        ArmStaticInst(mnem, _machInst, __opClass),
482        dest(_dest), imm(_imm)
483    {}
484
485    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
486};
487
488/// Integer compare SVE instruction.
489class SveIntCmpOp : public ArmStaticInst {
490  protected:
491    IntRegIndex dest;
492    IntRegIndex op1, op2;
493    IntRegIndex gp;
494    bool op2IsWide;
495
496    SveIntCmpOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass,
497                  IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2,
498                  IntRegIndex _gp, bool _op2IsWide = false) :
499        ArmStaticInst(mnem, _machInst, __opClass),
500        dest(_dest), op1(_op1), op2(_op2), gp(_gp), op2IsWide(_op2IsWide)
501    {}
502    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
503};
504
505/// Integer compare with immediate SVE instruction.
506class SveIntCmpImmOp : public ArmStaticInst {
507  protected:
508    IntRegIndex dest;
509    IntRegIndex op1;
510    int64_t imm;
511    IntRegIndex gp;
512
513    SveIntCmpImmOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass,
514                  IntRegIndex _dest, IntRegIndex _op1, int64_t _imm,
515                  IntRegIndex _gp) :
516        ArmStaticInst(mnem, _machInst, __opClass),
517        dest(_dest), op1(_op1), imm(_imm), gp(_gp)
518    {}
519    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
520};
521
522/// ADR.
523class SveAdrOp : public ArmStaticInst {
524  public:
525   enum SveAdrOffsetFormat {
526       SveAdrOffsetPacked,
527       SveAdrOffsetUnpackedSigned,
528       SveAdrOffsetUnpackedUnsigned
529   };
530
531  protected:
532    IntRegIndex dest, op1, op2;
533    uint8_t mult;
534    SveAdrOffsetFormat offsetFormat;
535
536    SveAdrOp(const char* mnem, ExtMachInst _machInst,
537             OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1,
538             IntRegIndex _op2, uint8_t _mult,
539             SveAdrOffsetFormat _offsetFormat) :
540        ArmStaticInst(mnem, _machInst, __opClass),
541        dest(_dest), op1(_op1), op2(_op2), mult(_mult),
542        offsetFormat(_offsetFormat)
543    {}
544    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
545};
546
547/// Element count SVE instruction.
548class SveElemCountOp : public ArmStaticInst {
549  protected:
550    IntRegIndex dest;
551    uint8_t pattern;
552    uint8_t imm;
553    bool dstIsVec;
554    bool dstIs32b;
555    uint8_t esize;
556
557    SveElemCountOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass,
558                  IntRegIndex _dest, uint8_t _pattern, uint8_t _imm,
559                  bool _dstIsVec, bool _dstIs32b) :
560        ArmStaticInst(mnem, _machInst, __opClass),
561        dest(_dest), pattern(_pattern), imm(_imm), dstIsVec(_dstIsVec),
562        dstIs32b(_dstIs32b)
563    {}
564    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
565};
566
567/// Partition break SVE instruction.
568class SvePartBrkOp : public ArmStaticInst {
569  protected:
570    IntRegIndex dest;
571    IntRegIndex gp;
572    IntRegIndex op1;
573    bool isMerging;
574
575    SvePartBrkOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass,
576                  IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _op1,
577                  bool _isMerging) :
578        ArmStaticInst(mnem, _machInst, __opClass),
579        dest(_dest), gp(_gp), op1(_op1), isMerging(_isMerging)
580    {}
581    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
582};
583
584/// Partition break with propagation SVE instruction.
585class SvePartBrkPropOp : public ArmStaticInst {
586  protected:
587    IntRegIndex dest;
588    IntRegIndex op1;
589    IntRegIndex op2;
590    IntRegIndex gp;
591
592    SvePartBrkPropOp(const char* mnem, ExtMachInst _machInst,
593                     OpClass __opClass, IntRegIndex _dest,
594                     IntRegIndex _op1, IntRegIndex _op2, IntRegIndex _gp) :
595        ArmStaticInst(mnem, _machInst, __opClass),
596        dest(_dest), op1(_op1), op2(_op2), gp(_gp)
597    {}
598    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
599};
600
601/// Scalar element select SVE instruction.
602class SveSelectOp : public ArmStaticInst {
603  protected:
604    IntRegIndex dest;
605    IntRegIndex op1;
606    IntRegIndex gp;
607    bool conditional;
608    bool scalar;
609    bool simdFp;
610    size_t scalar_width;
611
612    SveSelectOp(const char* mnem, ExtMachInst _machInst,
613                      OpClass __opClass, IntRegIndex _dest,
614                      IntRegIndex _op1, IntRegIndex _gp,
615                      bool _conditional, bool _scalar,
616                      bool _simdFp) :
617        ArmStaticInst(mnem, _machInst, __opClass),
618        dest(_dest), op1(_op1), gp(_gp), conditional(_conditional),
619        scalar(_scalar), simdFp(_simdFp)
620    {}
621    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
622};
623
624/// SVE unary operation on predicate (predicated)
625class SveUnaryPredPredOp : public ArmStaticInst {
626  protected:
627    IntRegIndex dest;
628    IntRegIndex op1;
629    IntRegIndex gp;
630
631    SveUnaryPredPredOp(const char* mnem, ExtMachInst _machInst,
632                       OpClass __opClass, IntRegIndex _dest,
633                       IntRegIndex _op1, IntRegIndex _gp) :
634        ArmStaticInst(mnem, _machInst, __opClass),
635        dest(_dest), op1(_op1), gp(_gp)
636    {}
637    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
638};
639
640/// SVE table lookup/permute using vector of element indices (TBL)
641class SveTblOp : public ArmStaticInst {
642  protected:
643    IntRegIndex dest;
644    IntRegIndex op1;
645    IntRegIndex op2;
646
647    SveTblOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass,
648            IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2) :
649        ArmStaticInst(mnem, _machInst, __opClass),
650        dest(_dest), op1(_op1), op2(_op2)
651    {}
652    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
653};
654
655/// SVE unpack and widen predicate
656class SveUnpackOp : public ArmStaticInst {
657  protected:
658    IntRegIndex dest;
659    IntRegIndex op1;
660
661    SveUnpackOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass,
662                IntRegIndex _dest, IntRegIndex _op1) :
663        ArmStaticInst(mnem, _machInst, __opClass),
664        dest(_dest), op1(_op1)
665    {}
666    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
667};
668
669/// SVE predicate test
670class SvePredTestOp : public ArmStaticInst {
671  protected:
672    IntRegIndex op1;
673    IntRegIndex gp;
674
675    SvePredTestOp(const char* mnem, ExtMachInst _machInst, OpClass __opClass,
676                IntRegIndex _op1, IntRegIndex _gp) :
677        ArmStaticInst(mnem, _machInst, __opClass),
678        op1(_op1), gp(_gp)
679    {}
680    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
681};
682
683/// SVE unary predicate instructions with implicit source operand
684class SvePredUnaryWImplicitSrcOp : public ArmStaticInst {
685  protected:
686    IntRegIndex dest;
687
688    SvePredUnaryWImplicitSrcOp(const char* mnem, ExtMachInst _machInst,
689                               OpClass __opClass, IntRegIndex _dest) :
690        ArmStaticInst(mnem, _machInst, __opClass),
691        dest(_dest)
692    {}
693    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
694};
695
696/// SVE unary predicate instructions, predicated, with implicit source operand
697class SvePredUnaryWImplicitSrcPredOp : public ArmStaticInst {
698  protected:
699    IntRegIndex dest;
700    IntRegIndex gp;
701
702    SvePredUnaryWImplicitSrcPredOp(const char* mnem, ExtMachInst _machInst,
703                                   OpClass __opClass, IntRegIndex _dest,
704                                   IntRegIndex _gp) :
705        ArmStaticInst(mnem, _machInst, __opClass),
706        dest(_dest), gp(_gp)
707    {}
708    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
709};
710
711/// SVE unary predicate instructions with implicit destination operand
712class SvePredUnaryWImplicitDstOp : public ArmStaticInst {
713  protected:
714    IntRegIndex op1;
715
716    SvePredUnaryWImplicitDstOp(const char* mnem, ExtMachInst _machInst,
717                               OpClass __opClass, IntRegIndex _op1) :
718        ArmStaticInst(mnem, _machInst, __opClass),
719        op1(_op1)
720    {}
721    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
722};
723
724/// SVE unary predicate instructions with implicit destination operand
725class SveWImplicitSrcDstOp : public ArmStaticInst {
726  protected:
727    SveWImplicitSrcDstOp(const char* mnem, ExtMachInst _machInst,
728                         OpClass __opClass) :
729        ArmStaticInst(mnem, _machInst, __opClass)
730    {}
731    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
732};
733
734/// SVE vector - immediate binary operation
735class SveBinImmUnpredDestrOp : public ArmStaticInst {
736  protected:
737    IntRegIndex dest;
738    IntRegIndex op1;
739    uint64_t imm;
740
741    SveBinImmUnpredDestrOp(const char* mnem, ExtMachInst _machInst,
742            OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1,
743            uint64_t _imm) :
744        ArmStaticInst(mnem, _machInst, __opClass),
745        dest(_dest), op1(_op1), imm(_imm)
746    {}
747    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
748};
749
750/// Binary with immediate index, destructive, unpredicated SVE instruction.
751class SveBinImmIdxUnpredOp : public ArmStaticInst {
752  protected:
753    IntRegIndex dest, op1;
754    uint64_t imm;
755
756    SveBinImmIdxUnpredOp(const char* mnem, ExtMachInst _machInst,
757            OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1,
758            uint64_t _imm) :
759        ArmStaticInst(mnem, _machInst, __opClass),
760        dest(_dest), op1(_op1), imm(_imm)
761    {}
762
763    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
764};
765
766/// Unary unpredicated scalar to vector instruction
767class SveUnarySca2VecUnpredOp : public ArmStaticInst {
768  protected:
769    IntRegIndex dest, op1;
770    bool simdFp;
771
772    SveUnarySca2VecUnpredOp(const char* mnem, ExtMachInst _machInst,
773            OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1,
774            bool _simdFp) :
775        ArmStaticInst(mnem, _machInst, __opClass),
776        dest(_dest), op1(_op1), simdFp(_simdFp)
777    {}
778
779    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
780};
781
782/// SVE dot product instruction (indexed)
783class SveDotProdIdxOp : public ArmStaticInst {
784  protected:
785    IntRegIndex dest, op1, op2;
786    uint64_t imm;
787    uint8_t esize;
788
789  public:
790    SveDotProdIdxOp(const char* mnem, ExtMachInst _machInst,
791            OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1,
792            IntRegIndex _op2, uint64_t _imm) :
793        ArmStaticInst(mnem, _machInst, __opClass),
794        dest(_dest), op1(_op1), op2(_op2), imm(_imm)
795    {}
796
797    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
798};
799
800/// SVE dot product instruction (vectors)
801class SveDotProdOp : public ArmStaticInst {
802  protected:
803    IntRegIndex dest, op1, op2;
804    uint8_t esize;
805
806  public:
807    SveDotProdOp(const char* mnem, ExtMachInst _machInst,
808            OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1,
809            IntRegIndex _op2) :
810        ArmStaticInst(mnem, _machInst, __opClass),
811        dest(_dest), op1(_op1), op2(_op2)
812    {}
813
814    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
815};
816
817/// SVE Complex Instructions (vectors)
818class SveComplexOp : public ArmStaticInst {
819  protected:
820    IntRegIndex dest, op1, op2, gp;
821    uint8_t rot;
822
823  public:
824    SveComplexOp(const char* mnem, ExtMachInst _machInst,
825            OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1,
826            IntRegIndex _op2, IntRegIndex _gp, uint8_t _rot) :
827        ArmStaticInst(mnem, _machInst, __opClass),
828        dest(_dest), op1(_op1), op2(_op2), gp(_gp), rot(_rot)
829    {}
830
831    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
832};
833
834/// SVE Complex Instructions (indexed)
835class SveComplexIdxOp : public ArmStaticInst {
836  protected:
837    IntRegIndex dest, op1, op2;
838    uint8_t rot, imm;
839
840  public:
841    SveComplexIdxOp(const char* mnem, ExtMachInst _machInst,
842            OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1,
843            IntRegIndex _op2, uint8_t _rot, uint8_t _imm) :
844        ArmStaticInst(mnem, _machInst, __opClass),
845        dest(_dest), op1(_op1), op2(_op2), rot(_rot), imm(_imm)
846    {}
847
848    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
849};
850
851
852/// Returns the symbolic name associated with pattern `imm` for PTRUE(S)
853/// instructions.
854std::string sveDisasmPredCountImm(uint8_t imm);
855
856/// Returns the actual number of elements active for PTRUE(S) instructions.
857/// @param imm 5-bit immediate encoding the predicate pattern.
858/// @param num_elems Current number of elements per vector (depending on
859/// current vector length and element size).
860unsigned int sveDecodePredCount(uint8_t imm, unsigned int num_elems);
861
862/// Expand 1-bit floating-point immediate to 0.5 or 1.0 (FADD, FSUB, FSUBR).
863/// @param imm 1-bit immediate.
864/// @param size Encoding of the vector element size.
865/// @return Encoding of the expanded value.
866uint64_t sveExpandFpImmAddSub(uint8_t imm, uint8_t size);
867
868/// Expand 1-bit floating-point immediate to 0.0 or 1.0 (FMAX, FMAXNM, FMIN,
869/// FMINNM).
870/// @param imm 1-bit immediate.
871/// @param size Encoding of the vector element size.
872/// @return Encoding of the expanded value.
873uint64_t sveExpandFpImmMaxMin(uint8_t imm, uint8_t size);
874
875/// Expand 1-bit floating-point immediate to 0.5 or 2.0 (FMUL).
876/// @param imm 1-bit immediate.
877/// @param size Encoding of the vector element size.
878/// @return Encoding of the expanded value.
879uint64_t sveExpandFpImmMul(uint8_t imm, uint8_t size);
880
881}  // namespace ArmISA
882
883#endif  // __ARCH_ARM_INSTS_SVE_HH__
884