1 #pragma once
2 /*******************************************************************************
3  * Copyright 2019-2021 FUJITSU LIMITED
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *******************************************************************************/
17 
18 #include <cassert>
19 
20 class Operand {
21 public:
22   static const int VL = 4;
23   enum Kind { NONE, RREG, VREG_SC, VREG_VEC, ZREG, PREG_Z, PREG_M, OPMASK };
24 
25   enum Code {
26     X0 = 0,
27     X1,
28     X2,
29     X3,
30     X4,
31     X5,
32     X6,
33     X7,
34     X8,
35     X9,
36     X10,
37     X11,
38     X12,
39     X13,
40     X14,
41     X15,
42     X16 = 16,
43     X17,
44     X18,
45     X19,
46     X20,
47     X21,
48     X22,
49     X23,
50     X24,
51     X25,
52     X26,
53     X27,
54     X28,
55     X29,
56     X30,
57     SP = 31,
58     XZR = 31,
59     W0 = 0,
60     W1,
61     W2,
62     W3,
63     W4,
64     W5,
65     W6,
66     W7,
67     W8,
68     W9,
69     W10,
70     W11,
71     W12,
72     W13,
73     W14,
74     W15,
75     W16 = 16,
76     W17,
77     W18,
78     W19,
79     W20,
80     W21,
81     W22,
82     W23,
83     W24,
84     W25,
85     W26,
86     W27,
87     W28,
88     W29,
89     W30,
90     WSP = 31,
91     WZR = 31,
92   };
93 
94 private:
95   Kind kind_;
96   uint32_t bit_;
97 
98 public:
Operand(Kind kind,uint32_t bit)99   explicit Operand(Kind kind, uint32_t bit) : kind_(kind), bit_(bit) {}
getBit()100   uint32_t getBit() const { return bit_; }
isRReg()101   bool isRReg() const { return is(RREG); }
isVRegSc()102   bool isVRegSc() const { return is(VREG_SC); }
isVRegVec()103   bool isVRegVec() const { return is(VREG_VEC); }
isZReg()104   bool isZReg() const { return is(ZREG); }
isPRegZ()105   bool isPRegZ() const { return is(PREG_Z); }
isPRegM()106   bool isPRegM() const { return is(PREG_M); }
107 
108 private:
is(Kind kind)109   bool is(Kind kind) const { return (kind_ == kind); }
110 };
111 
112 class Reg : public Operand {
113   uint32_t index_;
114 
115 public:
Reg(uint32_t index,Kind kind,uint32_t bit)116   explicit Reg(uint32_t index, Kind kind, uint32_t bit) : Operand(kind, bit), index_(index) {}
getIdx()117   uint32_t getIdx() const { return index_; }
118 };
119 
120 // General Purpose Register
121 class RReg : public Reg {
122 public:
RReg(uint32_t index,uint32_t bit)123   explicit RReg(uint32_t index, uint32_t bit) : Reg(index, RREG, bit) {}
124 };
125 
126 class XReg : public RReg {
127 public:
XReg(uint32_t index)128   explicit XReg(uint32_t index) : RReg(index, 64) {}
129 };
130 
131 class WReg : public RReg {
132 public:
WReg(uint32_t index)133   explicit WReg(uint32_t index) : RReg(index, 32) {}
134 };
135 
136 // SIMD & FP scalar regisetr
137 class VRegSc : public Reg {
138 public:
VRegSc(uint32_t index,uint32_t bit)139   explicit VRegSc(uint32_t index, uint32_t bit) : Reg(index, VREG_SC, bit) {}
140 };
141 
142 class BReg : public VRegSc {
143 public:
BReg(uint32_t index)144   explicit BReg(uint32_t index) : VRegSc(index, 8) {}
145 };
146 class HReg : public VRegSc {
147 public:
HReg(uint32_t index)148   explicit HReg(uint32_t index) : VRegSc(index, 16) {}
149 };
150 class SReg : public VRegSc {
151 public:
SReg(uint32_t index)152   explicit SReg(uint32_t index) : VRegSc(index, 32) {}
153 };
154 class DReg : public VRegSc {
155 public:
DReg(uint32_t index)156   explicit DReg(uint32_t index) : VRegSc(index, 64) {}
157 };
158 class QReg : public VRegSc {
159 public:
QReg(uint32_t index)160   explicit QReg(uint32_t index) : VRegSc(index, 128) {}
161 };
162 
163 // base for SIMD vector regisetr
164 class VRegVec : public Reg {
165   uint32_t lane_;
166 
167 public:
VRegVec(uint32_t index,uint32_t bits,uint32_t lane)168   explicit VRegVec(uint32_t index, uint32_t bits, uint32_t lane) : Reg(index, VREG_VEC, bits), lane_(lane){};
getLane()169   uint32_t getLane() const { return lane_; }
170 };
171 
172 // SIMD vector regisetr element
173 class VRegElem : public VRegVec {
174   uint32_t elem_idx_;
175 
176 public:
VRegElem(uint32_t index,uint32_t eidx,uint32_t bit,uint32_t lane)177   explicit VRegElem(uint32_t index, uint32_t eidx, uint32_t bit, uint32_t lane) : VRegVec(index, bit, lane), elem_idx_(eidx) {}
getElemIdx()178   uint32_t getElemIdx() const { return elem_idx_; }
179 };
180 
181 // base for SIMD Vector Register List
182 class VRegList : public VRegVec {
183   uint32_t len_;
184 
185 public:
VRegList(const VRegVec & s)186   explicit VRegList(const VRegVec &s) : VRegVec(s.getIdx(), s.getBit(), s.getLane()), len_(s.getIdx() - s.getIdx() + 1) {}
VRegList(const VRegVec & s,const VRegVec & e)187   explicit VRegList(const VRegVec &s, const VRegVec &e) : VRegVec(s.getIdx(), s.getBit(), s.getLane()), len_(((e.getIdx() + 32 - s.getIdx()) % 32) + 1) {}
getLen()188   uint32_t getLen() const { return len_; }
189 };
190 
191 class VReg4B;
192 class VReg8B;
193 class VReg16B;
194 class VReg2H;
195 class VReg4H;
196 class VReg8H;
197 class VReg2S;
198 class VReg4S;
199 class VReg1D;
200 class VReg2D;
201 class VReg1Q;
202 
203 class VRegBElem : public VRegElem {
204 public:
VRegBElem(uint32_t index,uint32_t eidx,uint32_t lane)205   explicit VRegBElem(uint32_t index, uint32_t eidx, uint32_t lane) : VRegElem(index, eidx, 8, lane) {}
206 };
207 class VRegHElem : public VRegElem {
208 public:
VRegHElem(uint32_t index,uint32_t eidx,uint32_t lane)209   explicit VRegHElem(uint32_t index, uint32_t eidx, uint32_t lane) : VRegElem(index, eidx, 16, lane) {}
210 };
211 class VRegSElem : public VRegElem {
212 public:
VRegSElem(uint32_t index,uint32_t eidx,uint32_t lane)213   explicit VRegSElem(uint32_t index, uint32_t eidx, uint32_t lane) : VRegElem(index, eidx, 32, lane) {}
214 };
215 class VRegDElem : public VRegElem {
216 public:
VRegDElem(uint32_t index,uint32_t eidx,uint32_t lane)217   explicit VRegDElem(uint32_t index, uint32_t eidx, uint32_t lane) : VRegElem(index, eidx, 64, lane) {}
218 };
219 class VRegQElem : public VRegElem {
220 public:
VRegQElem(uint32_t index,uint32_t eidx,uint32_t lane)221   explicit VRegQElem(uint32_t index, uint32_t eidx, uint32_t lane) : VRegElem(index, eidx, 128, lane) {}
222 };
223 
224 class VReg4BList : public VRegList {
225 public:
226   VReg4BList(const VReg4B &s);
VReg4BList(const VRegVec & s,const VRegVec & e)227   VReg4BList(const VRegVec &s, const VRegVec &e) : VRegList(s, e) {}
228   VRegBElem operator[](uint32_t i) const {
229     assert(getLane() > i);
230     return VRegBElem(getIdx(), i, getLane());
231   }
232 };
233 class VReg8BList : public VRegList {
234 public:
235   VReg8BList(const VReg8B &s);
VReg8BList(const VRegVec & s,const VRegVec & e)236   VReg8BList(const VRegVec &s, const VRegVec &e) : VRegList(s, e) {}
237   VRegBElem operator[](uint32_t i) const {
238     assert(getLane() > i);
239     return VRegBElem(getIdx(), i, getLane());
240   }
241 };
242 class VReg16BList : public VRegList {
243 public:
244   VReg16BList(const VReg16B &s);
VReg16BList(const VRegVec & s,const VRegVec & e)245   VReg16BList(const VRegVec &s, const VRegVec &e) : VRegList(s, e) {}
246   VRegBElem operator[](uint32_t i) const {
247     assert(getLane() > i);
248     return VRegBElem(getIdx(), i, getLane());
249   }
250 };
251 class VReg2HList : public VRegList {
252 public:
253   VReg2HList(const VReg2H &s);
VReg2HList(const VRegVec & s,const VRegVec & e)254   VReg2HList(const VRegVec &s, const VRegVec &e) : VRegList(s, e) {}
255   VRegHElem operator[](uint32_t i) const {
256     assert(getLane() > i);
257     return VRegHElem(getIdx(), i, getLane());
258   }
259 };
260 class VReg4HList : public VRegList {
261 public:
262   VReg4HList(const VReg4H &s);
VReg4HList(const VRegVec & s,const VRegVec & e)263   VReg4HList(const VRegVec &s, const VRegVec &e) : VRegList(s, e) {}
264   VRegHElem operator[](uint32_t i) const {
265     assert(getLane() > i);
266     return VRegHElem(getIdx(), i, getLane());
267   }
268 };
269 class VReg8HList : public VRegList {
270 public:
271   VReg8HList(const VReg8H &s);
VReg8HList(const VRegVec & s,const VRegVec & e)272   VReg8HList(const VRegVec &s, const VRegVec &e) : VRegList(s, e) {}
273   VRegHElem operator[](uint32_t i) const {
274     assert(getLane() > i);
275     return VRegHElem(getIdx(), i, getLane());
276   }
277 };
278 class VReg2SList : public VRegList {
279 public:
280   VReg2SList(const VReg2S &s);
VReg2SList(const VRegVec & s,const VRegVec & e)281   VReg2SList(const VRegVec &s, const VRegVec &e) : VRegList(s, e) {}
282   VRegSElem operator[](uint32_t i) const {
283     assert(getLane() > i);
284     return VRegSElem(getIdx(), i, getLane());
285   }
286 };
287 class VReg4SList : public VRegList {
288 public:
289   VReg4SList(const VReg4S &s);
VReg4SList(const VRegVec & s,const VRegVec & e)290   VReg4SList(const VRegVec &s, const VRegVec &e) : VRegList(s, e) {}
291   VRegSElem operator[](uint32_t i) const {
292     assert(getLane() > i);
293     return VRegSElem(getIdx(), i, getLane());
294   }
295 };
296 class VReg1DList : public VRegList {
297 public:
298   VReg1DList(const VReg1D &s);
VReg1DList(const VRegVec & s,const VRegVec & e)299   VReg1DList(const VRegVec &s, const VRegVec &e) : VRegList(s, e) {}
300   VRegDElem operator[](uint32_t i) const {
301     assert(getLane() > i);
302     return VRegDElem(getIdx(), i, getLane());
303   }
304 };
305 class VReg2DList : public VRegList {
306 public:
307   VReg2DList(const VReg2D &s);
VReg2DList(const VRegVec & s,const VRegVec & e)308   VReg2DList(const VRegVec &s, const VRegVec &e) : VRegList(s, e) {}
309   VRegDElem operator[](uint32_t i) const {
310     assert(getLane() > i);
311     return VRegDElem(getIdx(), i, getLane());
312   }
313 };
314 class VReg1QList : public VRegList {
315 public:
316   VReg1QList(const VReg1Q &s);
VReg1QList(const VRegVec & s,const VRegVec & e)317   VReg1QList(const VRegVec &s, const VRegVec &e) : VRegList(s, e) {}
318   VRegQElem operator[](uint32_t i) const {
319     assert(getLane() > i);
320     return VRegQElem(getIdx(), i, getLane());
321   }
322 };
323 
324 class VReg4B : public VRegVec {
325 public:
VReg4B(uint32_t index)326   explicit VReg4B(uint32_t index) : VRegVec(index, 8, 4) {}
327   VRegBElem operator[](uint32_t i) const {
328     assert(getLane() > i);
329     return VRegBElem(getIdx(), i, getLane());
330   }
331   VReg4BList operator-(const VReg4B &other) const { return VReg4BList(*this, other); }
332 };
333 class VReg8B : public VRegVec {
334 public:
VReg8B(uint32_t index)335   explicit VReg8B(uint32_t index) : VRegVec(index, 8, 8) {}
336   VRegBElem operator[](uint32_t i) const {
337     assert(getLane() > i);
338     return VRegBElem(getIdx(), i, getLane());
339   }
340   VReg8BList operator-(const VReg8B &other) const { return VReg8BList(*this, other); }
341 };
342 class VReg16B : public VRegVec {
343 public:
VReg16B(uint32_t index)344   explicit VReg16B(uint32_t index) : VRegVec(index, 8, 16) {}
345   VRegBElem operator[](uint32_t i) const {
346     assert(getLane() > i);
347     return VRegBElem(getIdx(), i, getLane());
348   }
349   VReg16BList operator-(const VReg16B &other) const { return VReg16BList(*this, other); }
350 };
351 class VReg2H : public VRegVec {
352 public:
VReg2H(uint32_t index)353   explicit VReg2H(uint32_t index) : VRegVec(index, 16, 2) {}
354   VRegHElem operator[](uint32_t i) const {
355     assert(getLane() > i);
356     return VRegHElem(getIdx(), i, getLane());
357   }
358   VReg2HList operator-(const VReg2H &other) const { return VReg2HList(*this, other); }
359 };
360 class VReg4H : public VRegVec {
361 public:
VReg4H(uint32_t index)362   explicit VReg4H(uint32_t index) : VRegVec(index, 16, 4) {}
363   VRegHElem operator[](uint32_t i) const {
364     assert(getLane() > i);
365     return VRegHElem(getIdx(), i, getLane());
366   }
367   VReg4HList operator-(const VReg4H &other) const { return VReg4HList(*this, other); }
368 };
369 class VReg8H : public VRegVec {
370 public:
VReg8H(uint32_t index)371   explicit VReg8H(uint32_t index) : VRegVec(index, 16, 8) {}
372   VRegHElem operator[](uint32_t i) const {
373     assert(getLane() > i);
374     return VRegHElem(getIdx(), i, getLane());
375   }
376   VReg8HList operator-(const VReg8H &other) const { return VReg8HList(*this, other); }
377 };
378 class VReg2S : public VRegVec {
379 public:
VReg2S(uint32_t index)380   explicit VReg2S(uint32_t index) : VRegVec(index, 32, 2) {}
381   VRegSElem operator[](uint32_t i) const {
382     assert(getLane() > i);
383     return VRegSElem(getIdx(), i, getLane());
384   }
385   VReg2SList operator-(const VReg2S &other) const { return VReg2SList(*this, other); }
386 };
387 class VReg4S : public VRegVec {
388 public:
VReg4S(uint32_t index)389   explicit VReg4S(uint32_t index) : VRegVec(index, 32, 4) {}
390   VRegSElem operator[](uint32_t i) const {
391     assert(getLane() > i);
392     return VRegSElem(getIdx(), i, getLane());
393   }
394   VReg4SList operator-(const VReg4S &other) const { return VReg4SList(*this, other); }
395 };
396 class VReg1D : public VRegVec {
397 public:
VReg1D(uint32_t index)398   explicit VReg1D(uint32_t index) : VRegVec(index, 64, 1) {}
399   VRegDElem operator[](uint32_t i) const {
400     assert(getLane() > i);
401     return VRegDElem(getIdx(), i, getLane());
402   }
403   VReg1DList operator-(const VReg1D &other) const { return VReg1DList(*this, other); }
404 };
405 class VReg2D : public VRegVec {
406 public:
VReg2D(uint32_t index)407   explicit VReg2D(uint32_t index) : VRegVec(index, 64, 2) {}
408   VRegDElem operator[](uint32_t i) const {
409     assert(getLane() > i);
410     return VRegDElem(getIdx(), i, getLane());
411   }
412   VReg2DList operator-(const VReg2D &other) const { return VReg2DList(*this, other); }
413 };
414 class VReg1Q : public VRegVec {
415 public:
VReg1Q(uint32_t index)416   explicit VReg1Q(uint32_t index) : VRegVec(index, 128, 1) {}
417   VRegQElem operator[](uint32_t i) const {
418     assert(getLane() > i);
419     return VRegQElem(getIdx(), i, getLane());
420   }
421   VReg1QList operator-(const VReg1Q &other) const { return VReg1QList(*this, other); }
422 };
423 
VReg4BList(const VReg4B & s)424 inline VReg4BList::VReg4BList(const VReg4B &s) : VRegList(s, s) {}
VReg8BList(const VReg8B & s)425 inline VReg8BList::VReg8BList(const VReg8B &s) : VRegList(s, s) {}
VReg16BList(const VReg16B & s)426 inline VReg16BList::VReg16BList(const VReg16B &s) : VRegList(s, s) {}
VReg2HList(const VReg2H & s)427 inline VReg2HList::VReg2HList(const VReg2H &s) : VRegList(s, s) {}
VReg4HList(const VReg4H & s)428 inline VReg4HList::VReg4HList(const VReg4H &s) : VRegList(s, s) {}
VReg8HList(const VReg8H & s)429 inline VReg8HList::VReg8HList(const VReg8H &s) : VRegList(s, s) {}
VReg2SList(const VReg2S & s)430 inline VReg2SList::VReg2SList(const VReg2S &s) : VRegList(s, s) {}
VReg4SList(const VReg4S & s)431 inline VReg4SList::VReg4SList(const VReg4S &s) : VRegList(s, s) {}
VReg1DList(const VReg1D & s)432 inline VReg1DList::VReg1DList(const VReg1D &s) : VRegList(s, s) {}
VReg2DList(const VReg2D & s)433 inline VReg2DList::VReg2DList(const VReg2D &s) : VRegList(s, s) {}
VReg1QList(const VReg1Q & s)434 inline VReg1QList::VReg1QList(const VReg1Q &s) : VRegList(s, s) {}
435 
436 // SIMD vector regisetr
437 class VReg : public VRegVec {
438 public:
VReg(uint32_t index)439   explicit VReg(uint32_t index) : VRegVec(index, 128, 1), b4(index), b8(index), b16(index), b(index), h2(index), h4(index), h8(index), h(index), s2(index), s4(index), s(index), d1(index), d2(index), d(index), q1(index), q(index) {}
440 
441   VReg4B b4;
442   VReg8B b8;
443   VReg16B b16;
444   VReg16B b;
445   VReg2H h2;
446   VReg4H h4;
447   VReg8H h8;
448   VReg8H h;
449   VReg2S s2;
450   VReg4S s4;
451   VReg4S s;
452   VReg1D d1;
453   VReg2D d2;
454   VReg2D d;
455   VReg1Q q1;
456   VReg1Q q;
457 };
458 
459 // SVE SIMD Vector Register Base
460 class _ZReg : public Reg {
461 public:
Reg(index,ZREG,bits)462   explicit _ZReg(uint32_t index, uint32_t bits = 128 * VL) : Reg(index, ZREG, bits) {}
463 };
464 
465 // SVE SIMD Vector Register Element
466 class ZRegElem : public _ZReg {
467   uint32_t elem_idx_;
468 
469 public:
ZRegElem(uint32_t index,uint32_t eidx,uint32_t bit)470   explicit ZRegElem(uint32_t index, uint32_t eidx, uint32_t bit) : _ZReg(index, bit), elem_idx_(eidx) {}
getElemIdx()471   uint32_t getElemIdx() const { return elem_idx_; }
472 };
473 
474 // base for SVE SIMD Vector Register List
475 class ZRegList : public _ZReg {
476   uint32_t len_;
477 
478 public:
ZRegList(const _ZReg & s)479   explicit ZRegList(const _ZReg &s) : _ZReg(s.getIdx(), s.getBit()), len_(s.getIdx() - s.getIdx() + 1) {}
ZRegList(const _ZReg & s,const _ZReg & e)480   explicit ZRegList(const _ZReg &s, const _ZReg &e) : _ZReg(s.getIdx(), s.getBit()), len_(e.getIdx() - s.getIdx() + 1) {}
getLen()481   uint32_t getLen() const { return len_; }
482 };
483 
484 class ZRegB;
485 class ZRegH;
486 class ZRegS;
487 class ZRegD;
488 class ZRegQ;
489 
490 class ZRegBElem : public ZRegElem {
491 public:
ZRegBElem(uint32_t index,uint32_t eidx)492   explicit ZRegBElem(uint32_t index, uint32_t eidx) : ZRegElem(index, eidx, 8) {}
493 };
494 class ZRegHElem : public ZRegElem {
495 public:
ZRegHElem(uint32_t index,uint32_t eidx)496   explicit ZRegHElem(uint32_t index, uint32_t eidx) : ZRegElem(index, eidx, 16) {}
497 };
498 class ZRegSElem : public ZRegElem {
499 public:
ZRegSElem(uint32_t index,uint32_t eidx)500   explicit ZRegSElem(uint32_t index, uint32_t eidx) : ZRegElem(index, eidx, 32) {}
501 };
502 class ZRegDElem : public ZRegElem {
503 public:
ZRegDElem(uint32_t index,uint32_t eidx)504   explicit ZRegDElem(uint32_t index, uint32_t eidx) : ZRegElem(index, eidx, 64) {}
505 };
506 class ZRegQElem : public ZRegElem {
507 public:
ZRegQElem(uint32_t index,uint32_t eidx)508   explicit ZRegQElem(uint32_t index, uint32_t eidx) : ZRegElem(index, eidx, 128) {}
509 };
510 
511 class ZRegBList : public ZRegList {
512 public:
513   ZRegBList(const ZRegB &s);
ZRegBList(const _ZReg & s,const _ZReg & e)514   explicit ZRegBList(const _ZReg &s, const _ZReg &e) : ZRegList(s, e) {}
515   ZRegBElem operator[](uint32_t i) const { return ZRegBElem(getIdx(), i); }
516 };
517 class ZRegHList : public ZRegList {
518 public:
519   ZRegHList(const ZRegH &s);
ZRegHList(const _ZReg & s,const _ZReg & e)520   explicit ZRegHList(const _ZReg &s, const _ZReg &e) : ZRegList(s, e) {}
521   ZRegHElem operator[](uint32_t i) const { return ZRegHElem(getIdx(), i); }
522 };
523 class ZRegSList : public ZRegList {
524 public:
525   ZRegSList(const ZRegS &s);
ZRegSList(const _ZReg & s,const _ZReg & e)526   explicit ZRegSList(const _ZReg &s, const _ZReg &e) : ZRegList(s, e) {}
527   ZRegSElem operator[](uint32_t i) const { return ZRegSElem(getIdx(), i); }
528 };
529 class ZRegDList : public ZRegList {
530 public:
531   ZRegDList(const ZRegD &s);
ZRegDList(const _ZReg & s,const _ZReg & e)532   explicit ZRegDList(const _ZReg &s, const _ZReg &e) : ZRegList(s, e) {}
533   ZRegDElem operator[](uint32_t i) const { return ZRegDElem(getIdx(), i); }
534 };
535 class ZRegQList : public ZRegList {
536 public:
537   ZRegQList(const ZRegQ &s);
ZRegQList(const _ZReg & s,const _ZReg & e)538   explicit ZRegQList(const _ZReg &s, const _ZReg &e) : ZRegList(s, e) {}
539   ZRegQElem operator[](uint32_t i) const { return ZRegQElem(getIdx(), i); }
540 };
541 
542 class ZRegB : public _ZReg {
543 public:
ZRegB(uint32_t index)544   explicit ZRegB(uint32_t index) : _ZReg(index, 8) {}
545   ZRegBElem operator[](uint32_t i) const { return ZRegBElem(getIdx(), i); }
546   ZRegBList operator-(const ZRegB &other) const { return ZRegBList(*this, other); }
547 };
548 class ZRegH : public _ZReg {
549 public:
ZRegH(uint32_t index)550   explicit ZRegH(uint32_t index) : _ZReg(index, 16) {}
551   ZRegHElem operator[](uint32_t i) const { return ZRegHElem(getIdx(), i); }
552   ZRegHList operator-(const ZRegH &other) const { return ZRegHList(*this, other); }
553 };
554 class ZRegS : public _ZReg {
555 public:
ZRegS(uint32_t index)556   explicit ZRegS(uint32_t index) : _ZReg(index, 32) {}
557   ZRegSElem operator[](uint32_t i) const { return ZRegSElem(getIdx(), i); }
558   ZRegSList operator-(const ZRegS &other) const { return ZRegSList(*this, other); }
559 };
560 class ZRegD : public _ZReg {
561 public:
ZRegD(uint32_t index)562   explicit ZRegD(uint32_t index) : _ZReg(index, 64) {}
563   ZRegDElem operator[](uint32_t i) const { return ZRegDElem(getIdx(), i); }
564   ZRegDList operator-(const ZRegD &other) const { return ZRegDList(*this, other); }
565 };
566 class ZRegQ : public _ZReg {
567 public:
ZRegQ(uint32_t index)568   explicit ZRegQ(uint32_t index) : _ZReg(index, 128) {}
569   ZRegQElem operator[](uint32_t i) const { return ZRegQElem(getIdx(), i); }
570   ZRegQList operator-(const ZRegQ &other) const { return ZRegQList(*this, other); }
571 };
572 
573 // SIMD Vector Regisetr for SVE
574 class ZReg : public _ZReg {
575 public:
ZReg(uint32_t index)576   explicit ZReg(uint32_t index) : _ZReg(index), b(index), h(index), s(index), d(index), q(index) {}
577 
578   ZRegB b;
579   ZRegH h;
580   ZRegS s;
581   ZRegD d;
582   ZRegQ q;
583 };
584 
585 class _PReg : public Reg {
586 public:
587   explicit _PReg(uint32_t index, bool M = false, uint32_t bits = 16 * VL) : Reg(index, ((M == 0) ? PREG_Z : PREG_M), bits) {}
isM()588   bool isM() const { return isPRegM(); }
isZ()589   bool isZ() const { return isPRegZ(); }
590 };
591 
592 class PRegB : public _PReg {
593 public:
PRegB(uint32_t index)594   explicit PRegB(uint32_t index) : _PReg(index, false, 8) {}
595 };
596 class PRegH : public _PReg {
597 public:
PRegH(uint32_t index)598   explicit PRegH(uint32_t index) : _PReg(index, false, 16) {}
599 };
600 class PRegS : public _PReg {
601 public:
PRegS(uint32_t index)602   explicit PRegS(uint32_t index) : _PReg(index, false, 32) {}
603 };
604 class PRegD : public _PReg {
605 public:
PRegD(uint32_t index)606   explicit PRegD(uint32_t index) : _PReg(index, false, 64) {}
607 };
608 
609 enum PredType {
610   T_z, // Zeroing predication
611   T_m  // Merging predication
612 };
613 
614 class PReg : public _PReg {
615 public:
_PReg(index,M)616   explicit PReg(uint32_t index, bool M = false) : _PReg(index, M), b(index), h(index), s(index), d(index) {}
617   _PReg operator/(PredType t) const { return (t == T_z) ? _PReg(getIdx(), false) : _PReg(getIdx(), true); }
618 
619   PRegB b;
620   PRegH h;
621   PRegS s;
622   PRegD d;
623 };
624