xref: /freebsd/contrib/llvm-project/clang/include/clang/Basic/arm_sve_sme_incl.td (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1//===--- arm_sve_sme_incl.td - ARM SVE/SME compiler interface -------------===//
2//
3//  Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4//  See https://llvm.org/LICENSE.txt for license information.
5//  SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9//  This file defines common properites of TableGen definitions use for both
10//  SVE and SME intrinsics.
11//
12//      https://developer.arm.com/architectures/system-architectures/software-standards/acle
13//
14//===----------------------------------------------------------------------===//
15
16//===----------------------------------------------------------------------===//
17// Instruction definitions
18//===----------------------------------------------------------------------===//
19// Every intrinsic subclasses "Inst". An intrinsic has a name, a prototype and
20// a sequence of typespecs.
21//
22// The name is the base name of the intrinsic, for example "svld1". This is
23// then mangled by the tblgen backend to add type information ("svld1_s16").
24//
25// A typespec is a sequence of uppercase characters (modifiers) followed by one
26// lowercase character. A typespec encodes a particular "base type" of the
27// intrinsic.
28//
29// An example typespec is "Us" - unsigned short - svuint16_t. The available
30// typespec codes are given below.
31//
32// The string given to an Inst class is a sequence of typespecs. The intrinsic
33// is instantiated for every typespec in the sequence. For example "sdUsUd".
34//
35// The prototype is a string that defines the return type of the intrinsic
36// and the type of each argument. The return type and every argument gets a
37// "modifier" that can change in some way the "base type" of the intrinsic.
38//
39// The modifier 'd' means "default" and does not modify the base type in any
40// way. The available modifiers are given below.
41//
42// Typespecs
43// ---------
44// c: char
45// s: short
46// i: int
47// l: long
48// q: int128_t
49// f: float
50// h: half-float
51// d: double
52// b: bfloat
53
54// Typespec modifiers
55// ------------------
56// P: boolean
57// U: unsigned
58// Q: svcount
59
60// Prototype modifiers
61// -------------------
62// prototype: return (arg, arg, ...)
63//
64// 2,3,4: array of vectors
65// .: indicator for multi-vector modifier that will follow (e.g. 2.x)
66// v: void
67// x: vector of signed integers
68// u: vector of unsigned integers
69// d: default
70// c: const pointer type
71// P: predicate type
72// s: scalar of element type
73// a: scalar of element type (splat to vector type)
74// R: scalar of 1/2 width element type (splat to vector type)
75// r: scalar of 1/4 width element type (splat to vector type)
76// @: unsigned scalar of 1/4 width element type (splat to vector type)
77// e: 1/2 width unsigned elements, 2x element count
78// b: 1/4 width unsigned elements, 4x element count
79// h: 1/2 width elements, 2x element count
80// q: 1/4 width elements, 4x element count
81// o: 4x width elements, 1/4 element count
82//
83// w: vector of element type promoted to 64bits, vector maintains
84//    signedness of its element type.
85// f: element type promoted to uint64_t (splat to vector type)
86// j: element type promoted to 64bits (splat to vector type)
87// K: element type bitcast to a signed integer (splat to vector type)
88// L: element type bitcast to an unsigned integer (splat to vector type)
89//
90// i: constant uint64_t
91// k: int32_t
92// l: int64_t
93// m: uint32_t
94// n: uint64_t
95
96// [: svuint8_t
97// t: svint32_t
98// z: svuint32_t
99// g: svuint64_t
100// O: svfloat16_t
101// M: svfloat32_t
102// N: svfloat64_t
103// $: svbfloat16_t
104
105// J: Prefetch type (sv_prfop)
106
107// %: pointer to void
108
109// A: pointer to int8_t
110// B: pointer to int16_t
111// C: pointer to int32_t
112// D: pointer to int64_t
113
114// E: pointer to uint8_t
115// F: pointer to uint16_t
116// G: pointer to uint32_t
117// H: pointer to uint64_t
118
119// Q: const pointer to void
120
121// S: const pointer to int8_t
122// T: const pointer to int16_t
123// U: const pointer to int32_t
124// V: const pointer to int64_t
125//
126// W: const pointer to uint8_t
127// X: const pointer to uint16_t
128// Y: const pointer to uint32_t
129// Z: const pointer to uint64_t
130
131// Prototype modifiers added for SVE2p1
132// {: 128b vector
133// }: svcount_t
134
135class MergeType<int val, string suffix=""> {
136  int Value = val;
137  string Suffix = suffix;
138}
139def MergeNone    : MergeType<0>;
140def MergeAny     : MergeType<1, "_x">;
141def MergeOp1     : MergeType<2, "_m">;
142def MergeZero    : MergeType<3, "_z">;
143def MergeAnyExp  : MergeType<4, "_x">; // Use merged builtin with explicit
144def MergeZeroExp : MergeType<5, "_z">; // generation of its inactive argument.
145
146class EltType<int val> {
147  int Value = val;
148}
149def EltTyInvalid : EltType<0>;
150def EltTyInt8    : EltType<1>;
151def EltTyInt16   : EltType<2>;
152def EltTyInt32   : EltType<3>;
153def EltTyInt64   : EltType<4>;
154def EltTyInt128  : EltType<5>;
155def EltTyFloat16 : EltType<6>;
156def EltTyFloat32 : EltType<7>;
157def EltTyFloat64 : EltType<8>;
158def EltTyBool8   : EltType<9>;
159def EltTyBool16  : EltType<10>;
160def EltTyBool32  : EltType<11>;
161def EltTyBool64  : EltType<12>;
162def EltTyBFloat16 : EltType<13>;
163
164class MemEltType<int val> {
165  int Value = val;
166}
167def MemEltTyDefault   : MemEltType<0>;
168def MemEltTyInt8      : MemEltType<1>;
169def MemEltTyInt16     : MemEltType<2>;
170def MemEltTyInt32     : MemEltType<3>;
171def MemEltTyInt64     : MemEltType<4>;
172
173class FlagType<int val> {
174  int Value = val;
175}
176
177// These must be kept in sync with the flags in utils/TableGen/SveEmitter.h
178// and include/clang/Basic/TargetBuiltins.h
179def NoFlags                   : FlagType<0x00000000>;
180def FirstEltType              : FlagType<0x00000001>;
181//      :                                     :
182//      :                                     :
183def EltTypeMask               : FlagType<0x0000000f>;
184def FirstMemEltType           : FlagType<0x00000010>;
185//      :                                     :
186//      :                                     :
187def MemEltTypeMask            : FlagType<0x00000070>;
188def FirstMergeTypeMask        : FlagType<0x00000080>;
189//      :                                     :
190//      :                                     :
191def MergeTypeMask             : FlagType<0x00000380>;
192def FirstSplatOperand         : FlagType<0x00000400>;
193//      :                                     :
194// These flags are used to specify which scalar operand
195// needs to be duplicated/splatted into a vector.
196//      :                                     :
197def SplatOperandMask                : FlagType<0x00001C00>;
198def IsLoad                          : FlagType<0x00002000>;
199def IsStore                         : FlagType<0x00004000>;
200def IsGatherLoad                    : FlagType<0x00008000>;
201def IsScatterStore                  : FlagType<0x00010000>;
202def IsStructLoad                    : FlagType<0x00020000>;
203def IsStructStore                   : FlagType<0x00040000>;
204def IsZExtReturn                    : FlagType<0x00080000>; // Return value is sign-extend by default
205def IsOverloadNone                  : FlagType<0x00100000>; // Intrinsic does not take any overloaded types.
206def IsOverloadWhileOrMultiVecCvt    : FlagType<0x00200000>; // Use {default type, typeof(operand1)} as overloaded types.
207def IsOverloadWhileRW               : FlagType<0x00400000>; // Use {pred(default type), typeof(operand0)} as overloaded types.
208def IsOverloadCvt                   : FlagType<0x00800000>; // Use {typeof(operand0), typeof(last operand)} as overloaded types.
209def OverloadKindMask                : FlagType<0x00E00000>; // When the masked values are all '0', the default type is used as overload type.
210def IsByteIndexed                   : FlagType<0x01000000>;
211def IsAppendSVALL                   : FlagType<0x02000000>; // Appends SV_ALL as the last operand.
212def IsInsertOp1SVALL                : FlagType<0x04000000>; // Inserts SV_ALL as the second operand.
213def IsPrefetch                      : FlagType<0x08000000>; // Contiguous prefetches.
214def IsGatherPrefetch                : FlagType<0x10000000>;
215def ReverseCompare                  : FlagType<0x20000000>; // Compare operands must be swapped.
216def ReverseUSDOT                    : FlagType<0x40000000>; // Unsigned/signed operands must be swapped.
217def IsUndef                         : FlagType<0x80000000>; // Codegen `undef` of given type.
218def IsTupleCreate                   : FlagType<0x100000000>;
219def IsTupleGet                      : FlagType<0x200000000>;
220def IsTupleSet                      : FlagType<0x400000000>;
221def ReverseMergeAnyBinOp            : FlagType<0x800000000>; // e.g. Implement SUBR_X using SUB_X.
222def ReverseMergeAnyAccOp            : FlagType<0x1000000000>; // e.g. Implement MSB_X using MLS_X.
223def IsStreaming                     : FlagType<0x2000000000>;
224def IsStreamingCompatible           : FlagType<0x4000000000>;
225def IsReadZA                        : FlagType<0x8000000000>;
226def IsWriteZA                       : FlagType<0x10000000000>;
227def IsReductionQV                   : FlagType<0x20000000000>;
228def VerifyRuntimeMode               : FlagType<0x40000000000>; // Use for intrinsics that are common between SVE and SME.
229def IsInZA                          : FlagType<0x80000000000>;
230def IsOutZA                         : FlagType<0x100000000000>;
231def IsInOutZA                       : FlagType<0x200000000000>;
232def IsInZT0                         : FlagType<0x400000000000>;
233def IsOutZT0                        : FlagType<0x800000000000>;
234def IsInOutZT0                      : FlagType<0x1000000000000>;
235
236// These must be kept in sync with the flags in include/clang/Basic/TargetBuiltins.h
237class ImmCheckType<int val> {
238  int Value = val;
239}
240def ImmCheck0_31                : ImmCheckType<0>;  // 0..31 (used for e.g. predicate patterns)
241def ImmCheck1_16                : ImmCheckType<1>;  // 1..16
242def ImmCheckExtract             : ImmCheckType<2>;  // 0..(2048/sizeinbits(elt) - 1)
243def ImmCheckShiftRight          : ImmCheckType<3>;  // 1..sizeinbits(elt)
244def ImmCheckShiftRightNarrow    : ImmCheckType<4>;  // 1..sizeinbits(elt)/2
245def ImmCheckShiftLeft           : ImmCheckType<5>;  // 0..(sizeinbits(elt) - 1)
246def ImmCheck0_7                 : ImmCheckType<6>;  // 0..7
247def ImmCheckLaneIndex           : ImmCheckType<7>;  // 0..(128/(1*sizeinbits(elt)) - 1)
248def ImmCheckLaneIndexCompRotate : ImmCheckType<8>;  // 0..(128/(2*sizeinbits(elt)) - 1)
249def ImmCheckLaneIndexDot        : ImmCheckType<9>;  // 0..(128/(4*sizeinbits(elt)) - 1)
250def ImmCheckComplexRot90_270    : ImmCheckType<10>; // [90,270]
251def ImmCheckComplexRotAll90     : ImmCheckType<11>; // [0, 90, 180,270]
252def ImmCheck0_13                : ImmCheckType<12>; // 0..13
253def ImmCheck0_1                 : ImmCheckType<13>; // 0..1
254def ImmCheck0_2                 : ImmCheckType<14>; // 0..2
255def ImmCheck0_3                 : ImmCheckType<15>; // 0..3
256def ImmCheck0_0                 : ImmCheckType<16>; // 0..0
257def ImmCheck0_15                : ImmCheckType<17>; // 0..15
258def ImmCheck0_255               : ImmCheckType<18>; // 0..255
259def ImmCheck2_4_Mul2            : ImmCheckType<19>; // 2, 4
260def ImmCheck1_1                 : ImmCheckType<20>; // 1..1
261def ImmCheck1_3                 : ImmCheckType<21>; // 1..3
262def ImmCheck1_7                 : ImmCheckType<22>; // 1..7
263
264class ImmCheck<int arg, ImmCheckType kind, int eltSizeArg = -1> {
265  int Arg = arg;
266  int EltSizeArg = eltSizeArg;
267  ImmCheckType Kind = kind;
268}
269
270defvar InvalidMode = "";
271
272class Inst<string n, string p, string t, MergeType mt, string i,
273           list<FlagType> ft, list<ImmCheck> ch, MemEltType met = MemEltTyDefault> {
274  string Name = n;
275  string Prototype = p;
276  string Types = t;
277  string SVETargetGuard = "sve";
278  string SMETargetGuard = "sme";
279  int Merge = mt.Value;
280  string MergeSuffix = mt.Suffix;
281  string LLVMIntrinsic = i;
282  list<FlagType> Flags = ft;
283  list<ImmCheck> ImmChecks = ch;
284  int MemEltType = met.Value;
285}
286
287// SInst: Instruction with signed/unsigned suffix (e.g., "s8", "u8")
288class SInst<string n, string p, string t, MergeType mt, string i = "",
289            list<FlagType> ft = [], list<ImmCheck> ch = []>
290    : Inst<n, p, t, mt, i, ft, ch, MemEltTyDefault> {
291}
292
293// MInst: Instructions which access memory
294class MInst<string n, string p, string t, list<FlagType> f,
295            MemEltType met = MemEltTyDefault, string i = "",
296            list<ImmCheck> ch = []>
297    : Inst<n, p, t, MergeNone, i, f, ch, met> {
298}
299