xref: /netbsd-src/external/apache2/llvm/dist/clang/include/clang/Basic/riscv_vector.td (revision e038c9c4676b0f19b1b7dd08a940c6ed64a6d5ae)
1//==--- riscv_vector.td - RISC-V V-ext Builtin function list --------------===//
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 the builtins for RISC-V V-extension. See:
10//
11//     https://github.com/riscv/rvv-intrinsic-doc
12//
13//===----------------------------------------------------------------------===//
14
15//===----------------------------------------------------------------------===//
16// Instruction definitions
17//===----------------------------------------------------------------------===//
18// Each record of the class RVVBuiltin defines a collection of builtins (i.e.
19// "def vadd : RVVBuiltin" will be used to define things like "vadd_vv_i32m1",
20// "vadd_vv_i32m2", etc).
21//
22// The elements of this collection are defined by an instantiation process the
23// range of which is specified by the cross product of the LMUL attribute and
24// every element in the attribute TypeRange. By default builtins have LMUL = [1,
25// 2, 4, 8, 1/2, 1/4, 1/8] so the process is repeated 7 times. In tablegen we
26// use the Log2LMUL [0, 1, 2, 3, -1, -2, -3] to represent the LMUL.
27//
28// LMUL represents the fact that the types of values used by that builtin are
29// values generated by instructions that are executed under that LMUL. However,
30// this does not mean the builtin is necessarily lowered into an instruction
31// that executes under the specified LMUL. An example where this happens are
32// loads and stores of masks. A mask like `vbool8_t` can be generated, for
33// instance, by comparing two `__rvv_int8m1_t` (this is LMUL=1) or comparing two
34// `__rvv_int16m2_t` (this is LMUL=2). The actual load or store, however, will
35// be performed under LMUL=1 because mask registers are not grouped.
36//
37// TypeRange is a non-empty sequence of basic types:
38//
39//   c: int8_t (i8)
40//   s: int16_t (i16)
41//   i: int32_t (i32)
42//   l: int64_t (i64)
43//   h: float16_t (half)
44//   f: float32_t (float)
45//   d: float64_t (double)
46//
47// This way, given an LMUL, a record with a TypeRange "sil" will cause the
48// definition of 3 builtins. Each type "t" in the TypeRange (in this example
49// they are int16_t, int32_t, int64_t) is used as a parameter that drives the
50// definition of that particular builtin (for the given LMUL).
51//
52// During the instantiation, types can be transformed or modified using type
53// transformers. Given a type "t" the following primitive type transformers can
54// be applied to it to yield another type.
55//
56//   e: type of "t" as is (identity)
57//   v: computes a vector type whose element type is "t" for the current LMUL
58//   w: computes a vector type identical to what 'v' computes except for the
59//      element type which is twice as wide as the element type of 'v'
60//   q: computes a vector type identical to what 'v' computes except for the
61//      element type which is four times as wide as the element type of 'v'
62//   o: computes a vector type identical to what 'v' computes except for the
63//      element type which is eight times as wide as the element type of 'v'
64//   m: computes a vector type identical to what 'v' computes except for the
65//      element type which is bool
66//   0: void type, ignores "t"
67//   z: size_t, ignores "t"
68//   t: ptrdiff_t, ignores "t"
69//   u: unsigned long, ignores "t"
70//   l: long, ignores "t"
71//
72// So for instance if t is "i", i.e. int, then "e" will yield int again. "v"
73// will yield an RVV vector type (assume LMUL=1), so __rvv_int32m1_t.
74// Accordingly "w" would yield __rvv_int64m2_t.
75//
76// A type transformer can be prefixed by other non-primitive type transformers.
77//
78//   P: constructs a pointer to the current type
79//   C: adds const to the type
80//   K: requires the integer type to be a constant expression
81//   U: given an integer type or vector type, computes its unsigned variant
82//   I: given a vector type, compute the vector type with integer type
83//      elements of the same width
84//   F: given a vector type, compute the vector type with floating-point type
85//      elements of the same width
86//   S: given a vector type, computes its equivalent one for LMUL=1. This is a
87//      no-op if the vector was already LMUL=1
88//   (Log2EEW:Value): Log2EEW value could be 3/4/5/6 (8/16/32/64), given a
89//      vector type (SEW and LMUL) and EEW (8/16/32/64), computes its
90//      equivalent integer vector type with EEW and corresponding ELMUL (elmul =
91//      (eew/sew) * lmul). For example, vector type is __rvv_float16m4
92//      (SEW=16, LMUL=4) and Log2EEW is 3 (EEW=8), and then equivalent vector
93//      type is __rvv_uint8m2_t (elmul=(8/16)*4 = 2). Ignore to define a new
94//      builtins if its equivalent type has illegal lmul.
95//   (FixedSEW:Value): Given a vector type (SEW and LMUL), and computes another
96//      vector type which only changed SEW as given value. Ignore to define a new
97//      builtin if its equivalent type has illegal lmul or the SEW does not changed.
98//   (SFixedLog2LMUL:Value): Smaller Fixed Log2LMUL. Given a vector type (SEW
99//      and LMUL), and computes another vector type which only changed LMUL as
100//      given value. The new LMUL should be smaller than the old one. Ignore to
101//      define a new builtin if its equivalent type has illegal lmul.
102//   (LFixedLog2LMUL:Value): Larger Fixed Log2LMUL. Given a vector type (SEW
103//      and LMUL), and computes another vector type which only changed LMUL as
104//      given value. The new LMUL should be larger than the old one. Ignore to
105//      define a new builtin if its equivalent type has illegal lmul.
106//
107// Following with the example above, if t is "i", then "Ue" will yield unsigned
108// int and "Fv" will yield __rvv_float32m1_t (again assuming LMUL=1), Fw would
109// yield __rvv_float64m2_t, etc.
110//
111// Each builtin is then defined by applying each type in TypeRange against the
112// sequence of type transformers described in Suffix and Prototype.
113//
114// The name of the builtin is defined by the Name attribute (which defaults to
115// the name of the class) appended (separated with an underscore) the Suffix
116// attribute. For instance with Name="foo", Suffix = "v" and TypeRange = "il",
117// the builtin generated will be __builtin_rvv_foo_i32m1 and
118// __builtin_rvv_foo_i64m1 (under LMUL=1). If Suffix contains more than one
119// type transformer (say "vv") each of the types is separated with an
120// underscore as in "__builtin_rvv_foo_i32m1_i32m1".
121//
122// The C/C++ prototype of the builtin is defined by the Prototype attribute.
123// Prototype is a non-empty sequence of type transformers, the first of which
124// is the return type of the builtin and the rest are the parameters of the
125// builtin, in order. For instance if Prototype is "wvv" and TypeRange is "si"
126// a first builtin will have type
127// __rvv_int32m2_t (__rvv_int16m1_t, __rvv_int16m1_t) and the second builtin
128// will have type __rvv_int64m2_t (__rvv_int32m1_t, __rvv_int32m1_t) (again
129// under LMUL=1).
130//
131// There are a number of attributes that are used to constraint the number and
132// shape of the builtins generated. Refer to the comments below for them.
133class RVVBuiltin<string suffix, string prototype, string type_range,
134                 string managed_suffix = ""> {
135  // Base name that will be prepended in __builtin_rvv_ and appended the
136  // computed Suffix.
137  string Name = NAME;
138
139  // If not empty, each instantiated builtin will have this appended after an
140  // underscore (_). It is instantiated like Prototype.
141  string Suffix = suffix;
142
143  // If empty, default MangledName is sub string of `Name` which end of first
144  // '_'. For example, the default mangled name  is `vadd` for Name `vadd_vv`.
145  // It's used for describe some special naming cases.
146  string MangledName = "";
147
148  // The different variants of the builtin, parameterised with a type.
149  string TypeRange = type_range;
150
151  // We use each type described in TypeRange and LMUL with prototype to
152  // instantiate a specific element of the set of builtins being defined.
153  // Prototype attribute defines the C/C++ prototype of the builtin. It is a
154  // non-empty sequence of type transformers, the first of which is the return
155  // type of the builtin and the rest are the parameters of the builtin, in
156  // order. For instance if Prototype is "wvv", TypeRange is "si" and LMUL=1, a
157  // first builtin will have type
158  // __rvv_int32m2_t (__rvv_int16m1_t, __rvv_int16m1_t), and the second builtin
159  // will have type __rvv_int64m2_t (__rvv_int32m1_t, __rvv_int32m1_t).
160  string Prototype = prototype;
161
162  // This builtin has a masked form.
163  bit HasMask = true;
164
165  // If HasMask, this flag states that this builtin has a maskedoff operand. It
166  // is always the first operand in builtin and IR intrinsic.
167  bit HasMaskedOffOperand = true;
168
169  // This builtin has a granted vector length parameter in the last position.
170  bit HasVL = true;
171
172  // This builtin supports non-masked function overloading api.
173  // All masked operations support overloading api.
174  bit HasNoMaskedOverloaded = true;
175
176  // Reads or writes "memory" or has other side-effects.
177  bit HasSideEffects = false;
178
179  // This builtin is valid for the given Log2LMULs.
180  list<int> Log2LMUL = [0, 1, 2, 3, -1, -2, -3];
181
182  // Manual code in clang codegen riscv_vector_builtin_cg.inc
183  code ManualCodegen = [{}];
184  code ManualCodegenMask = [{}];
185
186  // When emit the automatic clang codegen, it describes what types we have to use
187  // to obtain the specific LLVM intrinsic. -1 means the return type, otherwise,
188  // k >= 0 meaning the k-th operand (counting from zero) of the codegen'd
189  // parameter of the unmasked version. k can't be the mask operand's position.
190  list<int> IntrinsicTypes = [];
191
192  // If these names are not empty, this is the ID of the LLVM intrinsic
193  // we want to lower to.
194  string IRName = NAME;
195
196  // If HasMask, this is the ID of the LLVM intrinsic we want to lower to.
197  string IRNameMask = NAME #"_mask";
198
199  // If non empty, this is the code emitted in the header, otherwise
200  // an automatic definition in header is emitted.
201  string HeaderCode = "";
202
203  // Sub extension of vector spec. Currently only support Zvamo or Zvlsseg.
204  string RequiredExtension = "";
205
206}
207
208//===----------------------------------------------------------------------===//
209// Basic classes with automatic codegen.
210//===----------------------------------------------------------------------===//
211
212class RVVOutBuiltin<string suffix, string prototype, string type_range>
213    : RVVBuiltin<suffix, prototype, type_range> {
214  let IntrinsicTypes = [-1];
215}
216
217class RVVOp0Builtin<string suffix, string prototype, string type_range>
218    : RVVBuiltin<suffix, prototype, type_range> {
219  let IntrinsicTypes = [0];
220}
221
222class RVVOutOp1Builtin<string suffix, string prototype, string type_range>
223    : RVVBuiltin<suffix, prototype, type_range> {
224  let IntrinsicTypes = [-1, 1];
225}
226
227class RVVOutOp0Op1Builtin<string suffix, string prototype, string type_range>
228    : RVVBuiltin<suffix, prototype, type_range> {
229  let IntrinsicTypes = [-1, 0, 1];
230}
231
232multiclass RVVBuiltinSet<string intrinsic_name, string type_range,
233                         list<list<string>> suffixes_prototypes,
234                         list<int> intrinsic_types> {
235  let IRName = intrinsic_name, IRNameMask = intrinsic_name # "_mask",
236      IntrinsicTypes = intrinsic_types in {
237    foreach s_p = suffixes_prototypes in {
238      let Name = NAME # "_" # s_p[0] in {
239        defvar suffix = s_p[1];
240        defvar prototype = s_p[2];
241        def : RVVBuiltin<suffix, prototype, type_range>;
242      }
243    }
244  }
245}
246
247// IntrinsicTypes is output, op0, op1 [-1, 0, 1]
248multiclass RVVOutOp0Op1BuiltinSet<string intrinsic_name, string type_range,
249                                  list<list<string>> suffixes_prototypes>
250    : RVVBuiltinSet<intrinsic_name, type_range, suffixes_prototypes,
251                            [-1, 0, 1]>;
252
253multiclass RVVOutBuiltinSet<string intrinsic_name, string type_range,
254                            list<list<string>> suffixes_prototypes>
255    : RVVBuiltinSet<intrinsic_name, type_range, suffixes_prototypes, [-1]>;
256
257multiclass RVVOp0BuiltinSet<string intrinsic_name, string type_range,
258                            list<list<string>> suffixes_prototypes>
259    : RVVBuiltinSet<intrinsic_name, type_range, suffixes_prototypes, [0]>;
260
261// IntrinsicTypes is output, op1 [-1, 1]
262multiclass RVVOutOp1BuiltinSet<string intrinsic_name, string type_range,
263                               list<list<string>> suffixes_prototypes>
264    : RVVBuiltinSet<intrinsic_name, type_range, suffixes_prototypes, [-1, 1]>;
265
266multiclass RVVOp0Op1BuiltinSet<string intrinsic_name, string type_range,
267                               list<list<string>> suffixes_prototypes>
268    : RVVBuiltinSet<intrinsic_name, type_range, suffixes_prototypes, [0, 1]>;
269
270multiclass RVVOutOp1Op2BuiltinSet<string intrinsic_name, string type_range,
271                                  list<list<string>> suffixes_prototypes>
272    : RVVBuiltinSet<intrinsic_name, type_range, suffixes_prototypes, [-1, 1, 2]>;
273
274multiclass RVVSignedBinBuiltinSet
275    : RVVOutOp1BuiltinSet<NAME, "csil",
276                          [["vv", "v", "vvv"],
277                           ["vx", "v", "vve"]]>;
278
279multiclass RVVUnsignedBinBuiltinSet
280    : RVVOutOp1BuiltinSet<NAME, "csil",
281                          [["vv", "Uv", "UvUvUv"],
282                           ["vx", "Uv", "UvUvUe"]]>;
283
284multiclass RVVIntBinBuiltinSet
285    : RVVSignedBinBuiltinSet,
286      RVVUnsignedBinBuiltinSet;
287
288multiclass RVVSlideOneBuiltinSet
289    : RVVOutOp1BuiltinSet<NAME, "csil",
290                          [["vx", "v", "vve"],
291                           ["vx", "Uv", "UvUve"]]>;
292
293multiclass RVVSignedShiftBuiltinSet
294    : RVVOutOp1BuiltinSet<NAME, "csil",
295                          [["vv", "v", "vvUv"],
296                           ["vx", "v", "vvz"]]>;
297
298multiclass RVVUnsignedShiftBuiltinSet
299    : RVVOutOp1BuiltinSet<NAME, "csil",
300                          [["vv", "Uv", "UvUvUv"],
301                           ["vx", "Uv", "UvUvz"]]>;
302
303multiclass RVVShiftBuiltinSet
304    : RVVSignedShiftBuiltinSet,
305      RVVUnsignedShiftBuiltinSet;
306
307let Log2LMUL = [-3, -2, -1, 0, 1, 2] in {
308  multiclass RVVSignedNShiftBuiltinSet
309      : RVVOutOp0Op1BuiltinSet<NAME, "csil",
310                                     [["wv", "v", "vwUv"],
311                                      ["wx", "v", "vwz"]]>;
312  multiclass RVVUnsignedNShiftBuiltinSet
313      : RVVOutOp0Op1BuiltinSet<NAME, "csil",
314                                     [["wv", "Uv", "UvUwUv"],
315                                      ["wx", "Uv", "UvUwz"]]>;
316}
317
318multiclass RVVCarryinBuiltinSet
319    : RVVOutOp1BuiltinSet<NAME, "csil",
320                          [["vvm", "v", "vvvm"],
321                           ["vxm", "v", "vvem"],
322                           ["vvm", "Uv", "UvUvUvm"],
323                           ["vxm", "Uv", "UvUvUem"]]>;
324
325multiclass RVVCarryOutInBuiltinSet<string intrinsic_name>
326    : RVVOp0Op1BuiltinSet<intrinsic_name, "csil",
327                          [["vvm", "vm", "mvvm"],
328                           ["vxm", "vm", "mvem"],
329                           ["vvm", "Uvm", "mUvUvm"],
330                           ["vxm", "Uvm", "mUvUem"]]>;
331
332multiclass RVVSignedMaskOutBuiltinSet
333    : RVVOp0Op1BuiltinSet<NAME, "csil",
334                          [["vv", "vm", "mvv"],
335                           ["vx", "vm", "mve"]]>;
336
337multiclass RVVUnsignedMaskOutBuiltinSet
338    : RVVOp0Op1BuiltinSet<NAME, "csil",
339                          [["vv", "Uvm", "mUvUv"],
340                           ["vx", "Uvm", "mUvUe"]]>;
341
342multiclass RVVIntMaskOutBuiltinSet
343    : RVVSignedMaskOutBuiltinSet,
344      RVVUnsignedMaskOutBuiltinSet;
345
346class RVVIntExt<string intrinsic_name, string suffix, string prototype,
347                string type_range>
348    : RVVBuiltin<suffix, prototype, type_range> {
349  let IRName = intrinsic_name;
350  let IRNameMask = intrinsic_name # "_mask";
351  let MangledName = NAME;
352  let IntrinsicTypes = [-1, 0];
353}
354
355let HasMaskedOffOperand = false in {
356  multiclass RVVIntTerBuiltinSet {
357    defm "" : RVVOutOp1BuiltinSet<NAME, "csil",
358                                  [["vv", "v", "vvvv"],
359                                   ["vx", "v", "vvev"],
360                                   ["vv", "Uv", "UvUvUvUv"],
361                                   ["vx", "Uv", "UvUvUeUv"]]>;
362  }
363  multiclass RVVFloatingTerBuiltinSet {
364    defm "" : RVVOutOp1BuiltinSet<NAME, "fd",
365                                  [["vv", "v", "vvvv"],
366                                   ["vf", "v", "vvev"]]>;
367  }
368}
369
370let HasMaskedOffOperand = false, Log2LMUL = [-1, 0, 1, 2] in {
371  multiclass RVVFloatingWidenTerBuiltinSet {
372    defm ""  : RVVOutOp1Op2BuiltinSet<NAME, "f",
373                                      [["vv", "w", "wwvv"],
374                                       ["vf", "w", "wwev"]]>;
375  }
376}
377
378multiclass RVVFloatingBinBuiltinSet
379    : RVVOutOp1BuiltinSet<NAME, "fd",
380                          [["vv", "v", "vvv"],
381                           ["vf", "v", "vve"]]>;
382
383multiclass RVVFloatingBinVFBuiltinSet
384    : RVVOutOp1BuiltinSet<NAME, "fd",
385                          [["vf", "v", "vve"]]>;
386
387multiclass RVVFloatingMaskOutBuiltinSet
388    : RVVOp0Op1BuiltinSet<NAME, "fd",
389                          [["vv", "vm", "mvv"],
390                           ["vf", "vm", "mve"]]>;
391
392multiclass RVVFloatingMaskOutVFBuiltinSet
393    : RVVOp0Op1BuiltinSet<NAME, "fd",
394                          [["vf", "vm", "mve"]]>;
395
396class RVVMaskBinBuiltin : RVVOutBuiltin<"m", "mmm", "c"> {
397  let Name = NAME # "_mm";
398  let HasMask = false;
399}
400
401class RVVMaskUnaryBuiltin : RVVOutBuiltin<"m", "mm", "c"> {
402  let Name = NAME # "_m";
403}
404
405class RVVMaskNullaryBuiltin : RVVOutBuiltin<"m", "m", "c"> {
406  let Name = NAME # "_m";
407  let HasMask = false;
408  let HasNoMaskedOverloaded = false;
409}
410
411class RVVMaskOp0Builtin<string prototype> : RVVOp0Builtin<"m", prototype, "c"> {
412  let Name = NAME # "_m";
413  let HasMaskedOffOperand = false;
414}
415
416let HasMaskedOffOperand = false in {
417  multiclass RVVSlideBuiltinSet {
418    defm "" : RVVOutBuiltinSet<NAME, "csilfd",
419                               [["vx","v", "vvvz"]]>;
420    defm "" : RVVOutBuiltinSet<NAME, "csil",
421                               [["vx","Uv", "UvUvUvz"]]>;
422  }
423}
424
425class RVVFloatingUnaryBuiltin<string builtin_suffix, string ir_suffix,
426                              string prototype>
427    : RVVOutBuiltin<ir_suffix, prototype, "fd"> {
428  let Name = NAME # "_" # builtin_suffix;
429}
430
431class RVVFloatingUnaryVVBuiltin : RVVFloatingUnaryBuiltin<"v", "v", "vv">;
432
433class RVVConvBuiltin<string suffix, string prototype, string type_range,
434                     string mangled_name>
435    : RVVBuiltin<suffix, prototype, type_range> {
436  let IntrinsicTypes = [-1, 0];
437  let MangledName = mangled_name;
438}
439
440class RVVConvToSignedBuiltin<string mangled_name>
441    : RVVConvBuiltin<"Iv", "Ivv", "fd", mangled_name>;
442
443class RVVConvToUnsignedBuiltin<string mangled_name>
444    : RVVConvBuiltin<"Uv", "Uvv", "fd", mangled_name>;
445
446class RVVConvToWidenSignedBuiltin<string mangled_name>
447    : RVVConvBuiltin<"Iw", "Iwv", "f", mangled_name>;
448
449class RVVConvToWidenUnsignedBuiltin<string mangled_name>
450    : RVVConvBuiltin<"Uw", "Uwv", "f", mangled_name>;
451
452class RVVConvToNarrowingSignedBuiltin<string mangled_name>
453    : RVVConvBuiltin<"Iv", "IvFw", "si", mangled_name>;
454
455class RVVConvToNarrowingUnsignedBuiltin<string mangled_name>
456    : RVVConvBuiltin<"Uv", "UvFw", "si", mangled_name>;
457
458let HasMaskedOffOperand = false in {
459  multiclass RVVSignedReductionBuiltin {
460    defm "" : RVVOutOp1BuiltinSet<NAME, "csil",
461                                  [["vs", "vSv", "SvSvvSv"]]>;
462  }
463  multiclass RVVUnsignedReductionBuiltin {
464    defm "" : RVVOutOp1BuiltinSet<NAME, "csil",
465                                  [["vs", "UvUSv", "USvUSvUvUSv"]]>;
466  }
467  multiclass RVVFloatingReductionBuiltin {
468    defm "" : RVVOutOp1BuiltinSet<NAME, "fd",
469                                  [["vs", "vSv", "SvSvvSv"]]>;
470  }
471  multiclass RVVFloatingWidenReductionBuiltin {
472    defm "" : RVVOutOp1BuiltinSet<NAME, "f",
473                                  [["vs", "vSw", "SwSwvSw"]]>;
474  }
475}
476
477multiclass RVVIntReductionBuiltinSet
478    : RVVSignedReductionBuiltin,
479      RVVUnsignedReductionBuiltin;
480
481// For widen operation which has different mangling name.
482multiclass RVVWidenBuiltinSet<string intrinsic_name, string type_range,
483                              list<list<string>> suffixes_prototypes> {
484  let Log2LMUL = [-3, -2, -1, 0, 1, 2],
485      IRName = intrinsic_name, IRNameMask = intrinsic_name # "_mask" in {
486    foreach s_p = suffixes_prototypes in {
487      let Name = NAME # "_" # s_p[0],
488          MangledName = NAME # "_" # s_p[0] in {
489        defvar suffix = s_p[1];
490        defvar prototype = s_p[2];
491        def : RVVOutOp0Op1Builtin<suffix, prototype, type_range>;
492      }
493    }
494  }
495}
496
497// For widen operation with widen operand which has different mangling name.
498multiclass RVVWidenWOp0BuiltinSet<string intrinsic_name, string type_range,
499                                  list<list<string>> suffixes_prototypes> {
500  let Log2LMUL = [-3, -2, -1, 0, 1, 2],
501      IRName = intrinsic_name, IRNameMask = intrinsic_name # "_mask" in {
502    foreach s_p = suffixes_prototypes in {
503      let Name = NAME # "_" # s_p[0],
504          MangledName = NAME # "_" # s_p[0] in {
505        defvar suffix = s_p[1];
506        defvar prototype = s_p[2];
507        def : RVVOutOp1Builtin<suffix, prototype, type_range>;
508      }
509    }
510  }
511}
512
513multiclass RVVSignedWidenBinBuiltinSet
514    : RVVWidenBuiltinSet<NAME, "csi",
515                         [["vv", "w", "wvv"],
516                          ["vx", "w", "wve"]]>;
517
518multiclass RVVSignedWidenOp0BinBuiltinSet
519    : RVVWidenWOp0BuiltinSet<NAME # "_w", "csi",
520                             [["wv", "w", "wwv"],
521                              ["wx", "w", "wwe"]]>;
522
523multiclass RVVUnsignedWidenBinBuiltinSet
524    : RVVWidenBuiltinSet<NAME, "csi",
525                         [["vv", "Uw", "UwUvUv"],
526                          ["vx", "Uw", "UwUvUe"]]>;
527
528multiclass RVVUnsignedWidenOp0BinBuiltinSet
529    : RVVWidenWOp0BuiltinSet<NAME # "_w", "csi",
530                             [["wv", "Uw", "UwUwUv"],
531                              ["wx", "Uw", "UwUwUe"]]>;
532
533multiclass RVVFloatingWidenBinBuiltinSet
534    : RVVWidenBuiltinSet<NAME, "f",
535                         [["vv", "w", "wvv"],
536                          ["vf", "w", "wve"]]>;
537
538multiclass RVVFloatingWidenOp0BinBuiltinSet
539    : RVVWidenWOp0BuiltinSet<NAME # "_w", "f",
540                             [["wv", "w", "wwv"],
541                              ["wf", "w", "wwe"]]>;
542
543defvar TypeList = ["c","s","i","l","f","d"];
544defvar EEWList = [["8", "(Log2EEW:3)"],
545                  ["16", "(Log2EEW:4)"],
546                  ["32", "(Log2EEW:5)"],
547                  ["64", "(Log2EEW:6)"]];
548
549class IsFloat<string type> {
550  bit val = !or(!eq(type, "h"), !eq(type, "f"), !eq(type, "d"));
551}
552
553let HasNoMaskedOverloaded = false,
554    ManualCodegen = [{
555      IntrinsicTypes = {ResultType, Ops[1]->getType()};
556      Ops[0] = Builder.CreateBitCast(Ops[0], ResultType->getPointerTo());
557    }],
558    ManualCodegenMask= [{
559      // Move mask to right before vl.
560      std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
561      IntrinsicTypes = {ResultType, Ops[3]->getType()};
562      Ops[1] = Builder.CreateBitCast(Ops[1], ResultType->getPointerTo());
563    }] in {
564  class RVVVLEMaskBuiltin : RVVBuiltin<"m", "mPCUe", "c"> {
565    let Name = "vle1_v";
566    let IRName = "vle1";
567    let HasMask = false;
568  }
569  multiclass RVVVLEBuiltin<list<string> types> {
570    let Name = NAME # "_v",
571        IRName = "vle",
572        IRNameMask ="vle_mask" in {
573      foreach type = types in {
574        def : RVVBuiltin<"v", "vPCe", type>;
575        if !not(IsFloat<type>.val) then {
576          def : RVVBuiltin<"Uv", "UvPCUe", type>;
577        }
578      }
579    }
580  }
581}
582
583multiclass RVVVLEFFBuiltin<list<string> types> {
584  let Name = NAME # "_v",
585      IRName = "vleff",
586      IRNameMask = "vleff_mask",
587      HasNoMaskedOverloaded = false,
588      ManualCodegen = [{
589      {
590        IntrinsicTypes = {ResultType, Ops[2]->getType()};
591        Ops[0] = Builder.CreateBitCast(Ops[0], ResultType->getPointerTo());
592        Value *NewVL = Ops[1];
593        Ops.erase(Ops.begin() + 1);
594        llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
595        llvm::Value *LoadValue = Builder.CreateCall(F, Ops, "");
596        llvm::Value *V = Builder.CreateExtractValue(LoadValue, {0});
597        // Store new_vl.
598        clang::CharUnits Align =
599            CGM.getNaturalTypeAlignment(getContext().getSizeType());
600        Builder.CreateStore(Builder.CreateExtractValue(LoadValue, {1}),
601                            Address(NewVL, Align));
602        return V;
603      }
604      }],
605      ManualCodegenMask = [{
606      {
607        // Move mask to right before vl.
608        std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
609        IntrinsicTypes = {ResultType, Ops[4]->getType()};
610        Ops[1] = Builder.CreateBitCast(Ops[1], ResultType->getPointerTo());
611        Value *NewVL = Ops[2];
612        Ops.erase(Ops.begin() + 2);
613        llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
614        llvm::Value *LoadValue = Builder.CreateCall(F, Ops, "");
615        llvm::Value *V = Builder.CreateExtractValue(LoadValue, {0});
616        // Store new_vl.
617        clang::CharUnits Align =
618            CGM.getNaturalTypeAlignment(getContext().getSizeType());
619        Builder.CreateStore(Builder.CreateExtractValue(LoadValue, {1}),
620                            Address(NewVL, Align));
621        return V;
622      }
623      }] in {
624    foreach type = types in {
625      def : RVVBuiltin<"v", "vPCePz", type>;
626      // Skip floating types for unsigned versions.
627      if !not(IsFloat<type>.val) then {
628        def : RVVBuiltin<"Uv", "UvPCUePz", type>;
629      }
630    }
631  }
632}
633
634multiclass RVVVLSEBuiltin<list<string> types> {
635  let Name = NAME # "_v",
636      IRName = "vlse",
637      IRNameMask ="vlse_mask",
638      HasNoMaskedOverloaded = false,
639      ManualCodegen = [{
640        IntrinsicTypes = {ResultType, Ops[2]->getType()};
641        Ops[0] = Builder.CreateBitCast(Ops[0], ResultType->getPointerTo());
642      }],
643      ManualCodegenMask= [{
644        // Move mask to right before vl.
645        std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
646        IntrinsicTypes = {ResultType, Ops[4]->getType()};
647        Ops[1] = Builder.CreateBitCast(Ops[1], ResultType->getPointerTo());
648      }] in {
649    foreach type = types in {
650      def : RVVBuiltin<"v", "vPCet", type>;
651      if !not(IsFloat<type>.val) then {
652        def : RVVBuiltin<"Uv", "UvPCUet", type>;
653      }
654    }
655  }
656}
657
658multiclass RVVIndexedLoad<string op> {
659  let ManualCodegen = [{
660        IntrinsicTypes = {ResultType, Ops[1]->getType(), Ops[2]->getType()};
661        Ops[0] = Builder.CreateBitCast(Ops[0], ResultType->getPointerTo());
662      }],
663      ManualCodegenMask = [{
664        // Move mask to right before vl.
665        std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
666        IntrinsicTypes = {ResultType, Ops[2]->getType(), Ops[4]->getType()};
667        Ops[1] = Builder.CreateBitCast(Ops[1], ResultType->getPointerTo());
668      }] in {
669      foreach type = TypeList in {
670        foreach eew_list = EEWList in {
671          defvar eew = eew_list[0];
672          defvar eew_type = eew_list[1];
673          let Name = op # eew # "_v", IRName = op, IRNameMask = op # "_mask" in {
674            def: RVVBuiltin<"v", "vPCe" # eew_type # "Uv", type>;
675              if !not(IsFloat<type>.val) then {
676                def: RVVBuiltin<"Uv", "UvPCUe" # eew_type # "Uv", type>;
677              }
678          }
679        }
680      }
681  }
682}
683
684let HasMaskedOffOperand = false,
685    ManualCodegen = [{
686      // Builtin: (ptr, value, vl). Intrinsic: (value, ptr, vl)
687      std::swap(Ops[0], Ops[1]);
688      Ops[1] = Builder.CreateBitCast(Ops[1], Ops[0]->getType()->getPointerTo());
689      IntrinsicTypes = {Ops[0]->getType(), Ops[2]->getType()};
690    }],
691    ManualCodegenMask= [{
692      // Builtin: (mask, ptr, value, vl). Intrinsic: (value, ptr, mask, vl)
693      std::swap(Ops[0], Ops[2]);
694      Ops[1] = Builder.CreateBitCast(Ops[1], Ops[0]->getType()->getPointerTo());
695      IntrinsicTypes = {Ops[0]->getType(), Ops[3]->getType()};
696    }] in {
697  class RVVVSEMaskBuiltin : RVVBuiltin<"m", "0PUem", "c"> {
698    let Name = "vse1_v";
699    let IRName = "vse1";
700    let HasMask = false;
701  }
702  multiclass RVVVSEBuiltin<list<string> types> {
703    let Name = NAME # "_v",
704        IRName = "vse",
705        IRNameMask = "vse_mask" in {
706      foreach type = types in {
707        def : RVVBuiltin<"v", "0Pev", type>;
708        if !not(IsFloat<type>.val) then {
709          def : RVVBuiltin<"Uv", "0PUeUv", type>;
710        }
711      }
712    }
713  }
714}
715
716multiclass RVVVSSEBuiltin<list<string> types> {
717  let Name = NAME # "_v",
718      IRName = "vsse",
719      IRNameMask = "vsse_mask",
720      HasMaskedOffOperand = false,
721      ManualCodegen = [{
722        // Builtin: (ptr, stride, value, vl). Intrinsic: (value, ptr, stride, vl)
723        std::rotate(Ops.begin(), Ops.begin() + 2, Ops.begin() + 3);
724        Ops[1] = Builder.CreateBitCast(Ops[1], Ops[0]->getType()->getPointerTo());
725        IntrinsicTypes = {Ops[0]->getType(), Ops[3]->getType()};
726      }],
727      ManualCodegenMask= [{
728        // Builtin: (mask, ptr, stride, value, vl). Intrinsic: (value, ptr, stride, mask, vl)
729        std::swap(Ops[0], Ops[3]);
730        Ops[1] = Builder.CreateBitCast(Ops[1], Ops[0]->getType()->getPointerTo());
731        IntrinsicTypes = {Ops[0]->getType(), Ops[4]->getType()};
732      }] in {
733    foreach type = types in {
734      def : RVVBuiltin<"v", "0Petv", type>;
735      if !not(IsFloat<type>.val) then {
736        def : RVVBuiltin<"Uv", "0PUetUv", type>;
737      }
738    }
739  }
740}
741
742multiclass RVVIndexedStore<string op> {
743  let HasMaskedOffOperand = false,
744      ManualCodegen = [{
745        // Builtin: (ptr, index, value, vl). Intrinsic: (value, ptr, index, vl)
746        std::rotate(Ops.begin(), Ops.begin() + 2, Ops.begin() + 3);
747        Ops[1] = Builder.CreateBitCast(Ops[1],Ops[0]->getType()->getPointerTo());
748        IntrinsicTypes = {Ops[0]->getType(), Ops[2]->getType(), Ops[3]->getType()};
749      }],
750      ManualCodegenMask= [{
751        // Builtin: (mask, ptr, index, value, vl). Intrinsic: (value, ptr, index, mask, vl)
752        std::swap(Ops[0], Ops[3]);
753        Ops[1] = Builder.CreateBitCast(Ops[1], Ops[0]->getType()->getPointerTo());
754        IntrinsicTypes = {Ops[0]->getType(), Ops[2]->getType(), Ops[4]->getType()};
755      }] in {
756      foreach type = TypeList in {
757        foreach eew_list = EEWList in {
758          defvar eew = eew_list[0];
759          defvar eew_type = eew_list[1];
760          let Name = op # eew  # "_v", IRName = op, IRNameMask = op # "_mask" in  {
761            def : RVVBuiltin<"v", "0Pe" # eew_type # "Uvv", type>;
762            if !not(IsFloat<type>.val) then {
763              def : RVVBuiltin<"Uv", "0PUe" # eew_type # "UvUv", type>;
764            }
765          }
766        }
767      }
768  }
769}
770
771multiclass RVVAMOBuiltinSet<bit has_signed = false, bit has_unsigned = false,
772                            bit has_fp = false> {
773  defvar type_list = !if(has_fp, ["i","l","f","d"], ["i","l"]);
774  foreach type = type_list in
775    foreach eew_list = EEWList in {
776      defvar eew = eew_list[0];
777      defvar eew_index = eew_list[1];
778      let Name = NAME # "ei" # eew # "_" # "v",
779          IRName = NAME,
780          IRNameMask = NAME # "_mask",
781          HasMaskedOffOperand = false,
782          ManualCodegen = [{
783            // base, bindex, value, vl
784            IntrinsicTypes = {ResultType, Ops[1]->getType(), Ops[3]->getType()};
785            Ops[0] = Builder.CreateBitCast(Ops[0], ResultType->getPointerTo());
786          }],
787          ManualCodegenMask = [{
788            std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
789            IntrinsicTypes = {ResultType, Ops[1]->getType(), Ops[4]->getType()};
790            Ops[0] = Builder.CreateBitCast(Ops[0], ResultType->getPointerTo());
791          }] in {
792        if has_signed then
793          def : RVVBuiltin<"v", "vPe" # eew_index # "Uvv", type>;
794        if !and(!not(IsFloat<type>.val), has_unsigned) then
795          def : RVVBuiltin<"Uv", "UvPUe" # eew_index # "UvUv", type>;
796      }
797    }
798}
799
800multiclass RVVPseudoUnaryBuiltin<string IR, string type_range> {
801  let Name = NAME,
802      IRName = IR,
803      IRNameMask = IR # "_mask",
804      ManualCodegen = [{
805      {
806        // op1, vl
807        IntrinsicTypes = {ResultType,
808                          cast<llvm::VectorType>(ResultType)->getElementType(),
809                          Ops[1]->getType()};
810        Ops.insert(Ops.begin() + 1, llvm::Constant::getNullValue(IntrinsicTypes[1]));
811        break;
812      }
813      }],
814      ManualCodegenMask = [{
815      {
816        std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
817        // maskedoff, op1, mask, vl
818        IntrinsicTypes = {ResultType,
819                          cast<llvm::VectorType>(ResultType)->getElementType(),
820                          Ops[3]->getType()};
821        Ops.insert(Ops.begin() + 2, llvm::Constant::getNullValue(IntrinsicTypes[1]));
822        break;
823      }
824      }] in {
825        def : RVVBuiltin<"v", "vv", type_range>;
826  }
827}
828
829multiclass RVVPseudoVNotBuiltin<string IR, string type_range> {
830  let Name = NAME,
831      IRName = IR,
832      IRNameMask = IR # "_mask",
833      ManualCodegen = [{
834      {
835        // op1, vl
836        IntrinsicTypes = {ResultType,
837                          cast<llvm::VectorType>(ResultType)->getElementType(),
838                          Ops[1]->getType()};
839        Ops.insert(Ops.begin() + 1,
840                   llvm::Constant::getAllOnesValue(IntrinsicTypes[1]));
841        break;
842      }
843      }],
844      ManualCodegenMask = [{
845      {
846        std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
847        // maskedoff, op1, mask, vl
848        IntrinsicTypes = {ResultType,
849                          cast<llvm::VectorType>(ResultType)->getElementType(),
850                          Ops[3]->getType()};
851        Ops.insert(Ops.begin() + 2,
852                   llvm::Constant::getAllOnesValue(IntrinsicTypes[1]));
853        break;
854      }
855      }] in {
856        def : RVVBuiltin<"v", "vv", type_range>;
857        def : RVVBuiltin<"Uv", "UvUv", type_range>;
858  }
859}
860
861multiclass RVVPseudoMaskBuiltin<string IR, string type_range> {
862  let Name = NAME,
863      IRName = IR,
864      HasMask = false,
865      ManualCodegen = [{
866      {
867        // op1, vl
868        IntrinsicTypes = {ResultType,
869                          Ops[1]->getType()};
870        Ops.insert(Ops.begin() + 1, Ops[0]);
871        break;
872      }
873      }] in {
874        def : RVVBuiltin<"m", "mm", type_range>;
875  }
876}
877
878multiclass RVVPseudoVFUnaryBuiltin<string IR, string type_range> {
879  let Name = NAME,
880      IRName = IR,
881      IRNameMask = IR # "_mask",
882      ManualCodegen = [{
883      {
884        // op1, vl
885        IntrinsicTypes = {ResultType,
886                          Ops[0]->getType(), Ops[1]->getType()};
887        Ops.insert(Ops.begin() + 1, Ops[0]);
888        break;
889      }
890      }],
891      ManualCodegenMask = [{
892      {
893        std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
894        // maskedoff, op1, mask, vl
895        IntrinsicTypes = {ResultType,
896                          Ops[1]->getType(),
897                          Ops[3]->getType()};
898        Ops.insert(Ops.begin() + 2, Ops[1]);
899        break;
900      }
901      }] in {
902        def : RVVBuiltin<"v", "vv", type_range>;
903  }
904}
905
906multiclass RVVPseudoVWCVTBuiltin<string IR, string MName, string type_range,
907                                 list<list<string>> suffixes_prototypes> {
908  let Name = NAME,
909      MangledName = MName,
910      IRName = IR,
911      IRNameMask = IR # "_mask",
912      ManualCodegen = [{
913      {
914        // op1, vl
915        IntrinsicTypes = {ResultType,
916                          Ops[0]->getType(),
917                          cast<llvm::VectorType>(Ops[0]->getType())->getElementType(),
918                          Ops[1]->getType()};
919        Ops.insert(Ops.begin() + 1, llvm::Constant::getNullValue(IntrinsicTypes[2]));
920        break;
921      }
922      }],
923      ManualCodegenMask = [{
924      {
925        std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
926        // maskedoff, op1, mask, vl
927        IntrinsicTypes = {ResultType,
928                          Ops[1]->getType(),
929                          cast<llvm::VectorType>(Ops[1]->getType())->getElementType(),
930                          Ops[3]->getType()};
931        Ops.insert(Ops.begin() + 2, llvm::Constant::getNullValue(IntrinsicTypes[2]));
932        break;
933      }
934      }] in {
935        foreach s_p = suffixes_prototypes in {
936          def : RVVBuiltin<s_p[0], s_p[1], type_range>;
937        }
938  }
939}
940
941multiclass RVVPseudoVNCVTBuiltin<string IR, string MName, string type_range,
942                                 list<list<string>> suffixes_prototypes> {
943  let Name = NAME,
944      MangledName = MName,
945      IRName = IR,
946      IRNameMask = IR # "_mask",
947      ManualCodegen = [{
948      {
949        // op1, vl
950        IntrinsicTypes = {ResultType,
951                          Ops[0]->getType(),
952                          Ops[1]->getType(),
953                          Ops[1]->getType()};
954        Ops.insert(Ops.begin() + 1, llvm::Constant::getNullValue(IntrinsicTypes[2]));
955        break;
956      }
957      }],
958      ManualCodegenMask = [{
959      {
960        std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
961        // maskedoff, op1, mask, vl
962        IntrinsicTypes = {ResultType,
963                          Ops[1]->getType(),
964                          Ops[3]->getType(),
965                          Ops[3]->getType()};
966        Ops.insert(Ops.begin() + 2, llvm::Constant::getNullValue(IntrinsicTypes[2]));
967        break;
968      }
969      }] in {
970        foreach s_p = suffixes_prototypes in {
971          def : RVVBuiltin<s_p[0], s_p[1], type_range>;
972        }
973  }
974}
975
976// 6. Configuration-Setting Instructions
977// 6.1. vsetvli/vsetvl instructions
978let HasVL = false,
979    HasMask = false,
980    HasSideEffects = true,
981    Log2LMUL = [0],
982    ManualCodegen = [{IntrinsicTypes = {ResultType};}] in // Set XLEN type
983{
984  // vsetvl is a macro because for it require constant integers in SEW and LMUL.
985  let HeaderCode =
986[{
987#define vsetvl_e8mf8(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 5)
988#define vsetvl_e8mf4(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 6)
989#define vsetvl_e8mf2(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 7)
990#define vsetvl_e8m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 0)
991#define vsetvl_e8m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 1)
992#define vsetvl_e8m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 2)
993#define vsetvl_e8m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 3)
994
995#define vsetvl_e16mf4(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 6)
996#define vsetvl_e16mf2(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 7)
997#define vsetvl_e16m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 0)
998#define vsetvl_e16m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 1)
999#define vsetvl_e16m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 2)
1000#define vsetvl_e16m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 3)
1001
1002#define vsetvl_e32mf2(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 7)
1003#define vsetvl_e32m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 0)
1004#define vsetvl_e32m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 1)
1005#define vsetvl_e32m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 2)
1006#define vsetvl_e32m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 3)
1007
1008#define vsetvl_e64m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 0)
1009#define vsetvl_e64m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 1)
1010#define vsetvl_e64m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 2)
1011#define vsetvl_e64m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 3)
1012
1013}] in
1014  def vsetvli : RVVBuiltin<"", "zzKzKz", "i">;
1015
1016  let HeaderCode =
1017[{
1018#define vsetvlmax_e8mf8() __builtin_rvv_vsetvlimax(0, 5)
1019#define vsetvlmax_e8mf4() __builtin_rvv_vsetvlimax(0, 6)
1020#define vsetvlmax_e8mf2() __builtin_rvv_vsetvlimax(0, 7)
1021#define vsetvlmax_e8m1() __builtin_rvv_vsetvlimax(0, 0)
1022#define vsetvlmax_e8m2() __builtin_rvv_vsetvlimax(0, 1)
1023#define vsetvlmax_e8m4() __builtin_rvv_vsetvlimax(0, 2)
1024#define vsetvlmax_e8m8() __builtin_rvv_vsetvlimax(0, 3)
1025
1026#define vsetvlmax_e16mf4() __builtin_rvv_vsetvlimax(1, 6)
1027#define vsetvlmax_e16mf2() __builtin_rvv_vsetvlimax(1, 7)
1028#define vsetvlmax_e16m1() __builtin_rvv_vsetvlimax(1, 0)
1029#define vsetvlmax_e16m2() __builtin_rvv_vsetvlimax(1, 1)
1030#define vsetvlmax_e16m4() __builtin_rvv_vsetvlimax(1, 2)
1031#define vsetvlmax_e16m8() __builtin_rvv_vsetvlimax(1, 3)
1032
1033#define vsetvlmax_e32mf2() __builtin_rvv_vsetvlimax(2, 7)
1034#define vsetvlmax_e32m1() __builtin_rvv_vsetvlimax(2, 0)
1035#define vsetvlmax_e32m2() __builtin_rvv_vsetvlimax(2, 1)
1036#define vsetvlmax_e32m4() __builtin_rvv_vsetvlimax(2, 2)
1037#define vsetvlmax_e32m8() __builtin_rvv_vsetvlimax(2, 3)
1038
1039#define vsetvlmax_e64m1() __builtin_rvv_vsetvlimax(3, 0)
1040#define vsetvlmax_e64m2() __builtin_rvv_vsetvlimax(3, 1)
1041#define vsetvlmax_e64m4() __builtin_rvv_vsetvlimax(3, 2)
1042#define vsetvlmax_e64m8() __builtin_rvv_vsetvlimax(3, 3)
1043
1044}] in
1045  def vsetvlimax : RVVBuiltin<"", "zKzKz", "i">;
1046}
1047
1048// 7. Vector Loads and Stores
1049// 7.4. Vector Unit-Stride Instructions
1050def vle1: RVVVLEMaskBuiltin;
1051defm vle8: RVVVLEBuiltin<["c"]>;
1052defm vle16: RVVVLEBuiltin<["s"]>;
1053defm vle32: RVVVLEBuiltin<["i","f"]>;
1054defm vle64: RVVVLEBuiltin<["l","d"]>;
1055
1056def vse1 : RVVVSEMaskBuiltin;
1057defm vse8 : RVVVSEBuiltin<["c"]>;
1058defm vse16: RVVVSEBuiltin<["s"]>;
1059defm vse32: RVVVSEBuiltin<["i","f"]>;
1060defm vse64: RVVVSEBuiltin<["l","d"]>;
1061
1062// 7.5. Vector Strided Instructions
1063defm vlse8: RVVVLSEBuiltin<["c"]>;
1064defm vlse16: RVVVLSEBuiltin<["s"]>;
1065defm vlse32: RVVVLSEBuiltin<["i","f"]>;
1066defm vlse64: RVVVLSEBuiltin<["l","d"]>;
1067
1068defm vsse8 : RVVVSSEBuiltin<["c"]>;
1069defm vsse16: RVVVSSEBuiltin<["s"]>;
1070defm vsse32: RVVVSSEBuiltin<["i","f"]>;
1071defm vsse64: RVVVSSEBuiltin<["l","d"]>;
1072
1073// 7.6. Vector Indexed Instructions
1074defm : RVVIndexedLoad<"vluxei">;
1075defm : RVVIndexedLoad<"vloxei">;
1076
1077defm : RVVIndexedStore<"vsuxei">;
1078defm : RVVIndexedStore<"vsoxei">;
1079
1080// 7.7. Unit-stride Fault-Only-First Loads
1081defm vle8ff: RVVVLEFFBuiltin<["c"]>;
1082defm vle16ff: RVVVLEFFBuiltin<["s"]>;
1083defm vle32ff: RVVVLEFFBuiltin<["i", "f"]>;
1084defm vle64ff: RVVVLEFFBuiltin<["l", "d"]>;
1085
1086// 8. Vector AMO Operations
1087let RequiredExtension = "Zvamo" in {
1088defm vamoswap : RVVAMOBuiltinSet< /* hasSigned */ true, /* hasUnsigned */ true, /* hasFP */ true>;
1089defm vamoadd : RVVAMOBuiltinSet< /* hasSigned */ true, /* hasUnsigned */ true>;
1090defm vamoxor : RVVAMOBuiltinSet< /* hasSigned */ true, /* hasUnsigned */ true>;
1091defm vamoand : RVVAMOBuiltinSet< /* hasSigned */ true, /* hasUnsigned */ true>;
1092defm vamoor : RVVAMOBuiltinSet< /* hasSigned */ true, /* hasUnsigned */ true>;
1093defm vamomin : RVVAMOBuiltinSet< /* hasSigned */ true>;
1094defm vamomax : RVVAMOBuiltinSet< /* hasSigned */ true>;
1095defm vamominu : RVVAMOBuiltinSet< /* hasSigned */ false, /* hasUnsigned */ true>;
1096defm vamomaxu : RVVAMOBuiltinSet< /* hasSigned */ false, /* hasUnsigned */ true>;
1097}
1098
1099// 12. Vector Integer Arithmetic Instructions
1100// 12.1. Vector Single-Width Integer Add and Subtract
1101defm vadd : RVVIntBinBuiltinSet;
1102defm vsub : RVVIntBinBuiltinSet;
1103defm vrsub : RVVOutOp1BuiltinSet<"vrsub", "csil",
1104                                 [["vx", "v", "vve"],
1105                                  ["vx", "Uv", "UvUvUe"]]>;
1106defm vneg_v : RVVPseudoUnaryBuiltin<"vrsub", "csil">;
1107
1108// 12.2. Vector Widening Integer Add/Subtract
1109// Widening unsigned integer add/subtract, 2*SEW = SEW +/- SEW
1110defm vwaddu : RVVUnsignedWidenBinBuiltinSet;
1111defm vwsubu : RVVUnsignedWidenBinBuiltinSet;
1112// Widening signed integer add/subtract, 2*SEW = SEW +/- SEW
1113defm vwadd : RVVSignedWidenBinBuiltinSet;
1114defm vwsub : RVVSignedWidenBinBuiltinSet;
1115// Widening unsigned integer add/subtract, 2*SEW = 2*SEW +/- SEW
1116defm vwaddu : RVVUnsignedWidenOp0BinBuiltinSet;
1117defm vwsubu : RVVUnsignedWidenOp0BinBuiltinSet;
1118// Widening signed integer add/subtract, 2*SEW = 2*SEW +/- SEW
1119defm vwadd : RVVSignedWidenOp0BinBuiltinSet;
1120defm vwsub : RVVSignedWidenOp0BinBuiltinSet;
1121defm vwcvtu_x_x_v : RVVPseudoVWCVTBuiltin<"vwaddu", "vwcvtu_x", "csi",
1122                                          [["Uw", "UwUv"]]>;
1123defm vwcvt_x_x_v : RVVPseudoVWCVTBuiltin<"vwadd", "vwcvt_x", "csi",
1124                                         [["w", "wv"]]>;
1125
1126// 12.3. Vector Integer Extension
1127let Log2LMUL = [-3, -2, -1, 0, 1, 2] in {
1128  def vsext_vf2 : RVVIntExt<"vsext", "w", "wv", "csi">;
1129  def vzext_vf2 : RVVIntExt<"vzext", "Uw", "UwUv", "csi">;
1130}
1131let Log2LMUL = [-3, -2, -1, 0, 1] in {
1132  def vsext_vf4 : RVVIntExt<"vsext", "q", "qv", "cs">;
1133  def vzext_vf4 : RVVIntExt<"vzext", "Uq", "UqUv", "cs">;
1134}
1135let Log2LMUL = [-3, -2, -1, 0] in {
1136  def vsext_vf8 : RVVIntExt<"vsext", "o", "ov", "c">;
1137  def vzext_vf8 : RVVIntExt<"vzext", "Uo", "UoUv", "c">;
1138}
1139
1140// 12.4. Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions
1141let HasMask = false in {
1142  defm vadc : RVVCarryinBuiltinSet;
1143  defm vmadc : RVVCarryOutInBuiltinSet<"vmadc_carry_in">;
1144  defm vmadc : RVVIntMaskOutBuiltinSet;
1145  defm vsbc : RVVCarryinBuiltinSet;
1146  defm vmsbc : RVVCarryOutInBuiltinSet<"vmsbc_borrow_in">;
1147  defm vmsbc : RVVIntMaskOutBuiltinSet;
1148}
1149
1150// 12.5. Vector Bitwise Logical Instructions
1151defm vand : RVVIntBinBuiltinSet;
1152defm vxor : RVVIntBinBuiltinSet;
1153defm vor : RVVIntBinBuiltinSet;
1154defm vnot_v : RVVPseudoVNotBuiltin<"vxor", "csil">;
1155
1156// 12.6. Vector Single-Width Bit Shift Instructions
1157defm vsll : RVVShiftBuiltinSet;
1158defm vsrl : RVVUnsignedShiftBuiltinSet;
1159defm vsra : RVVSignedShiftBuiltinSet;
1160
1161// 12.7. Vector Narrowing Integer Right Shift Instructions
1162defm vnsrl : RVVUnsignedNShiftBuiltinSet;
1163defm vnsra : RVVSignedNShiftBuiltinSet;
1164defm vncvt_x_x_w : RVVPseudoVNCVTBuiltin<"vnsrl", "vncvt_x", "csi",
1165                                         [["v", "vw"],
1166                                          ["Uv", "UvUw"]]>;
1167
1168// 12.8. Vector Integer Comparison Instructions
1169defm vmseq : RVVIntMaskOutBuiltinSet;
1170defm vmsne : RVVIntMaskOutBuiltinSet;
1171defm vmsltu : RVVUnsignedMaskOutBuiltinSet;
1172defm vmslt : RVVSignedMaskOutBuiltinSet;
1173defm vmsleu : RVVUnsignedMaskOutBuiltinSet;
1174defm vmsle : RVVSignedMaskOutBuiltinSet;
1175defm vmsgtu : RVVUnsignedMaskOutBuiltinSet;
1176defm vmsgt : RVVSignedMaskOutBuiltinSet;
1177defm vmsgeu : RVVUnsignedMaskOutBuiltinSet;
1178defm vmsge : RVVSignedMaskOutBuiltinSet;
1179
1180// 12.9. Vector Integer Min/Max Instructions
1181defm vminu : RVVUnsignedBinBuiltinSet;
1182defm vmin : RVVSignedBinBuiltinSet;
1183defm vmaxu : RVVUnsignedBinBuiltinSet;
1184defm vmax : RVVSignedBinBuiltinSet;
1185
1186// 12.10. Vector Single-Width Integer Multiply Instructions
1187defm vmul : RVVIntBinBuiltinSet;
1188defm vmulh : RVVSignedBinBuiltinSet;
1189defm vmulhu : RVVUnsignedBinBuiltinSet;
1190defm vmulhsu : RVVOutOp1BuiltinSet<"vmulhsu", "csil",
1191                                   [["vv", "v", "vvUv"],
1192                                    ["vx", "v", "vvUe"]]>;
1193
1194// 12.11. Vector Integer Divide Instructions
1195defm vdivu : RVVUnsignedBinBuiltinSet;
1196defm vdiv : RVVSignedBinBuiltinSet;
1197defm vremu : RVVUnsignedBinBuiltinSet;
1198defm vrem : RVVSignedBinBuiltinSet;
1199
1200// 12.12. Vector Widening Integer Multiply Instructions
1201let Log2LMUL = [-3, -2, -1, 0, 1, 2] in {
1202defm vwmul : RVVOutOp0Op1BuiltinSet<"vwmul", "csi",
1203                                    [["vv", "w", "wvv"],
1204                                     ["vx", "w", "wve"]]>;
1205defm vwmulu : RVVOutOp0Op1BuiltinSet<"vwmulu", "csi",
1206                                     [["vv", "Uw", "UwUvUv"],
1207                                      ["vx", "Uw", "UwUvUe"]]>;
1208defm vwmulsu : RVVOutOp0Op1BuiltinSet<"vwmulsu", "csi",
1209                                      [["vv", "w", "wvUv"],
1210                                       ["vx", "w", "wvUe"]]>;
1211}
1212
1213// 12.13. Vector Single-Width Integer Multiply-Add Instructions
1214defm vmacc  : RVVIntTerBuiltinSet;
1215defm vnmsac : RVVIntTerBuiltinSet;
1216defm vmadd  : RVVIntTerBuiltinSet;
1217defm vnmsub : RVVIntTerBuiltinSet;
1218
1219// 12.14. Vector Widening Integer Multiply-Add Instructions
1220let HasMaskedOffOperand = false,
1221    Log2LMUL = [-3, -2, -1, 0, 1, 2] in {
1222defm vwmaccu : RVVOutOp1Op2BuiltinSet<"vwmaccu", "csi",
1223                                      [["vv", "Uw", "UwUwUvUv"],
1224                                       ["vx", "Uw", "UwUwUeUv"]]>;
1225defm vwmacc : RVVOutOp1Op2BuiltinSet<"vwmacc", "csi",
1226                                     [["vv", "w", "wwvv"],
1227                                      ["vx", "w", "wwev"]]>;
1228defm vwmaccsu : RVVOutOp1Op2BuiltinSet<"vwmaccsu", "csi",
1229                                       [["vv", "w", "wwvUv"],
1230                                        ["vx", "w", "wweUv"]]>;
1231defm vwmaccus : RVVOutOp1Op2BuiltinSet<"vwmaccus", "csi",
1232                                       [["vx", "w", "wwUev"]]>;
1233}
1234
1235// 12.15. Vector Integer Merge Instructions
1236// C/C++ Operand: (mask, op1, op2, vl), Intrinsic: (op1, op2, mask, vl)
1237let HasMask = false,
1238    ManualCodegen = [{
1239      std::rotate(Ops.begin(), Ops.begin() + 1, Ops.begin() + 3);
1240      IntrinsicTypes = {ResultType, Ops[1]->getType(), Ops[3]->getType()};
1241    }] in {
1242  defm vmerge : RVVOutOp1BuiltinSet<"vmerge", "csil",
1243                                    [["vvm", "v", "vmvv"],
1244                                     ["vxm", "v", "vmve"],
1245                                     ["vvm", "Uv", "UvmUvUv"],
1246                                     ["vxm", "Uv", "UvmUvUe"]]>;
1247}
1248
1249// 12.16. Vector Integer Move Instructions
1250let HasMask = false in {
1251  let MangledName = "vmv_v" in {
1252    defm vmv_v : RVVOutBuiltinSet<"vmv_v_v", "csil",
1253                                   [["v", "Uv", "UvUv"]]>;
1254    defm vmv_v : RVVOutBuiltinSet<"vmv_v_v", "csilfd",
1255                                   [["v", "v", "vv"]]>;
1256  }
1257  let HasNoMaskedOverloaded = false in
1258    defm vmv_v : RVVOutBuiltinSet<"vmv_v_x", "csil",
1259                                   [["x", "v", "ve"],
1260                                    ["x", "Uv", "UvUe"]]>;
1261}
1262
1263// 13. Vector Fixed-Point Arithmetic Instructions
1264// 13.1. Vector Single-Width Saturating Add and Subtract
1265defm vsaddu : RVVUnsignedBinBuiltinSet;
1266defm vsadd : RVVSignedBinBuiltinSet;
1267defm vssubu : RVVUnsignedBinBuiltinSet;
1268defm vssub : RVVSignedBinBuiltinSet;
1269
1270// 13.2. Vector Single-Width Averaging Add and Subtract
1271defm vaaddu : RVVUnsignedBinBuiltinSet;
1272defm vaadd : RVVSignedBinBuiltinSet;
1273defm vasubu : RVVUnsignedBinBuiltinSet;
1274defm vasub : RVVSignedBinBuiltinSet;
1275
1276// 13.3. Vector Single-Width Fractional Multiply with Rounding and Saturation
1277defm vsmul : RVVSignedBinBuiltinSet;
1278
1279// 13.4. Vector Single-Width Scaling Shift Instructions
1280defm vssrl : RVVUnsignedShiftBuiltinSet;
1281defm vssra : RVVSignedShiftBuiltinSet;
1282
1283// 13.5. Vector Narrowing Fixed-Point Clip Instructions
1284defm vnclipu : RVVUnsignedNShiftBuiltinSet;
1285defm vnclip : RVVSignedNShiftBuiltinSet;
1286
1287// 14. Vector Floating-Point Instructions
1288// 14.2. Vector Single-Width Floating-Point Add/Subtract Instructions
1289defm vfadd  : RVVFloatingBinBuiltinSet;
1290defm vfsub  : RVVFloatingBinBuiltinSet;
1291defm vfrsub : RVVFloatingBinVFBuiltinSet;
1292
1293// 14.3. Vector Widening Floating-Point Add/Subtract Instructions
1294// Widening FP add/subtract, 2*SEW = SEW +/- SEW
1295defm vfwadd : RVVFloatingWidenBinBuiltinSet;
1296defm vfwsub : RVVFloatingWidenBinBuiltinSet;
1297// Widening FP add/subtract, 2*SEW = 2*SEW +/- SEW
1298defm vfwadd : RVVFloatingWidenOp0BinBuiltinSet;
1299defm vfwsub : RVVFloatingWidenOp0BinBuiltinSet;
1300
1301// 14.4. Vector Single-Width Floating-Point Multiply/Divide Instructions
1302defm vfmul  : RVVFloatingBinBuiltinSet;
1303defm vfdiv  : RVVFloatingBinBuiltinSet;
1304defm vfrdiv : RVVFloatingBinVFBuiltinSet;
1305
1306// 14.5. Vector Widening Floating-Point Multiply
1307let Log2LMUL = [-1, 0, 1, 2] in {
1308  defm vfwmul : RVVOutOp0Op1BuiltinSet<"vfwmul", "f",
1309                                       [["vv", "w", "wvv"],
1310                                        ["vf", "w", "wve"]]>;
1311}
1312
1313// 14.6. Vector Single-Width Floating-Point Fused Multiply-Add Instructions
1314defm vfmacc  : RVVFloatingTerBuiltinSet;
1315defm vfnmacc : RVVFloatingTerBuiltinSet;
1316defm vfmsac  : RVVFloatingTerBuiltinSet;
1317defm vfnmsac : RVVFloatingTerBuiltinSet;
1318defm vfmadd  : RVVFloatingTerBuiltinSet;
1319defm vfnmadd : RVVFloatingTerBuiltinSet;
1320defm vfmsub  : RVVFloatingTerBuiltinSet;
1321defm vfnmsub : RVVFloatingTerBuiltinSet;
1322
1323// 14.7. Vector Widening Floating-Point Fused Multiply-Add Instructions
1324defm vfwmacc  : RVVFloatingWidenTerBuiltinSet;
1325defm vfwnmacc : RVVFloatingWidenTerBuiltinSet;
1326defm vfwmsac  : RVVFloatingWidenTerBuiltinSet;
1327defm vfwnmsac : RVVFloatingWidenTerBuiltinSet;
1328
1329// 14.8. Vector Floating-Point Square-Root Instruction
1330def vfsqrt : RVVFloatingUnaryVVBuiltin;
1331
1332// 14.9. Vector Floating-Point Reciprocal Square-Root Estimate Instruction
1333def vfrsqrt7 : RVVFloatingUnaryVVBuiltin;
1334
1335// 14.10. Vector Floating-Point Reciprocal Estimate Instruction
1336def vfrec7 : RVVFloatingUnaryVVBuiltin;
1337
1338// 14.11. Vector Floating-Point MIN/MAX Instructions
1339defm vfmin : RVVFloatingBinBuiltinSet;
1340defm vfmax : RVVFloatingBinBuiltinSet;
1341
1342// 14.12. Vector Floating-Point Sign-Injection Instructions
1343defm vfsgnj  : RVVFloatingBinBuiltinSet;
1344defm vfsgnjn : RVVFloatingBinBuiltinSet;
1345defm vfsgnjx : RVVFloatingBinBuiltinSet;
1346defm vfneg_v : RVVPseudoVFUnaryBuiltin<"vfsgnjn", "fd">;
1347defm vfabs_v : RVVPseudoVFUnaryBuiltin<"vfsgnjx", "fd">;
1348
1349// 14.13. Vector Floating-Point Compare Instructions
1350defm vmfeq : RVVFloatingMaskOutBuiltinSet;
1351defm vmfne : RVVFloatingMaskOutBuiltinSet;
1352defm vmflt : RVVFloatingMaskOutBuiltinSet;
1353defm vmfle : RVVFloatingMaskOutBuiltinSet;
1354defm vmfgt : RVVFloatingMaskOutBuiltinSet;
1355defm vmfge : RVVFloatingMaskOutBuiltinSet;
1356
1357// 14.14. Vector Floating-Point Classify Instruction
1358let Name = "vfclass_v" in
1359  def vfclass : RVVOp0Builtin<"Uv", "Uvv", "fd">;
1360
1361// 14.15. Vector Floating-Point Merge Instructio
1362// C/C++ Operand: (mask, op1, op2, vl), Builtin: (op1, op2, mask, vl)
1363let HasMask = false,
1364    ManualCodegen = [{
1365      std::rotate(Ops.begin(), Ops.begin() + 1, Ops.begin() + 3);
1366      IntrinsicTypes = {ResultType, Ops[1]->getType(), Ops[3]->getType()};
1367    }] in {
1368  defm vmerge : RVVOutOp1BuiltinSet<"vfmerge", "fd",
1369                                    [["vvm", "v", "vmvv"]]>;
1370  defm vfmerge : RVVOutOp1BuiltinSet<"vfmerge", "fd",
1371                                    [["vfm", "v", "vmve"]]>;
1372}
1373
1374// 14.16. Vector Floating-Point Move Instruction
1375let HasMask = false, HasNoMaskedOverloaded = false in
1376  defm vfmv_v : RVVOutBuiltinSet<"vfmv_v_f", "fd",
1377                                  [["f", "v", "ve"]]>;
1378
1379// 14.17. Single-Width Floating-Point/Integer Type-Convert Instructions
1380def vfcvt_xu_f_v : RVVConvToUnsignedBuiltin<"vfcvt_xu">;
1381def vfcvt_x_f_v : RVVConvToSignedBuiltin<"vfcvt_x">;
1382def vfcvt_rtz_xu_f_v : RVVConvToUnsignedBuiltin<"vfcvt_rtz_xu">;
1383def vfcvt_rtz_x_f_v : RVVConvToSignedBuiltin<"vfcvt_rtz_x">;
1384def vfcvt_f_xu_v : RVVConvBuiltin<"Fv", "FvUv", "sil", "vfcvt_f">;
1385def vfcvt_f_x_v : RVVConvBuiltin<"Fv", "Fvv", "sil", "vfcvt_f">;
1386
1387// 14.18. Widening Floating-Point/Integer Type-Convert Instructions
1388let Log2LMUL = [-3, -2, -1, 0, 1, 2] in {
1389  def vfwcvt_xu_f_v : RVVConvToWidenUnsignedBuiltin<"vfwcvt_xu">;
1390  def vfwcvt_x_f_v : RVVConvToWidenSignedBuiltin<"vfwcvt_x">;
1391  def vfwcvt_rtz_xu_f_v : RVVConvToWidenUnsignedBuiltin<"vfwcvt_rtz_xu">;
1392  def vfwcvt_rtz_x_f_v : RVVConvToWidenSignedBuiltin<"vfwcvt_rtz_x">;
1393  def vfwcvt_f_xu_v : RVVConvBuiltin<"Fw", "FwUv", "csi", "vfwcvt_f">;
1394  def vfwcvt_f_x_v : RVVConvBuiltin<"Fw", "Fwv", "csi", "vfwcvt_f">;
1395  def vfwcvt_f_f_v : RVVConvBuiltin<"w", "wv", "hf", "vfwcvt_f">;
1396}
1397
1398// 14.19. Narrowing Floating-Point/Integer Type-Convert Instructions
1399let Log2LMUL = [-3, -2, -1, 0, 1, 2] in {
1400  def vfncvt_xu_f_w : RVVConvToNarrowingUnsignedBuiltin<"vfncvt_xu">;
1401  def vfncvt_x_f_w : RVVConvToNarrowingSignedBuiltin<"vfncvt_x">;
1402  def vfncvt_rtz_xu_f_w : RVVConvToNarrowingUnsignedBuiltin<"vfncvt_rtz_xu">;
1403  def vfncvt_rtz_x_f_w : RVVConvToNarrowingSignedBuiltin<"vfncvt_rtz_x">;
1404  def vfncvt_f_xu_w : RVVConvBuiltin<"Fv", "FvUw", "si", "vfncvt_f">;
1405  def vfncvt_f_x_w : RVVConvBuiltin<"Fv", "Fvw", "si", "vfncvt_f">;
1406  def vfncvt_f_f_w : RVVConvBuiltin<"v", "vw", "f", "vfncvt_f">;
1407  def vfncvt_rod_f_f_w : RVVConvBuiltin<"v", "vw", "f", "vfncvt_rod_f">;
1408}
1409
1410// 15. Vector Reduction Operations
1411// 15.1. Vector Single-Width Integer Reduction Instructions
1412defm vredsum : RVVIntReductionBuiltinSet;
1413defm vredmaxu : RVVUnsignedReductionBuiltin;
1414defm vredmax : RVVSignedReductionBuiltin;
1415defm vredminu : RVVUnsignedReductionBuiltin;
1416defm vredmin : RVVSignedReductionBuiltin;
1417defm vredand : RVVIntReductionBuiltinSet;
1418defm vredor : RVVIntReductionBuiltinSet;
1419defm vredxor : RVVIntReductionBuiltinSet;
1420
1421// 15.2. Vector Widening Integer Reduction Instructions
1422// Vector Widening Integer Reduction Operations
1423let HasMaskedOffOperand = false in {
1424  defm vwredsum : RVVOutOp1BuiltinSet<"vwredsum", "csi",
1425                                      [["vs", "vSw", "SwSwvSw"]]>;
1426  defm vwredsumu : RVVOutOp1BuiltinSet<"vwredsumu", "csi",
1427                                       [["vs", "UvUSw", "USwUSwUvUSw"]]>;
1428}
1429
1430// 15.3. Vector Single-Width Floating-Point Reduction Instructions
1431defm vfredmax : RVVFloatingReductionBuiltin;
1432defm vfredmin : RVVFloatingReductionBuiltin;
1433defm vfredsum : RVVFloatingReductionBuiltin;
1434defm vfredosum : RVVFloatingReductionBuiltin;
1435
1436// 15.4. Vector Widening Floating-Point Reduction Instructions
1437defm vfwredsum : RVVFloatingWidenReductionBuiltin;
1438defm vfwredosum : RVVFloatingWidenReductionBuiltin;
1439
1440// 16. Vector Mask Instructions
1441// 16.1. Vector Mask-Register Logical Instructions
1442def vmand    : RVVMaskBinBuiltin;
1443def vmnand   : RVVMaskBinBuiltin;
1444def vmandnot : RVVMaskBinBuiltin;
1445def vmxor    : RVVMaskBinBuiltin;
1446def vmor     : RVVMaskBinBuiltin;
1447def vmnor    : RVVMaskBinBuiltin;
1448def vmornot  : RVVMaskBinBuiltin;
1449def vmxnor   : RVVMaskBinBuiltin;
1450// pseudoinstructions
1451def vmclr    : RVVMaskNullaryBuiltin;
1452def vmset    : RVVMaskNullaryBuiltin;
1453defm vmmv_m : RVVPseudoMaskBuiltin<"vmand", "c">;
1454defm vmnot_m : RVVPseudoMaskBuiltin<"vmnand", "c">;
1455
1456// 16.2. Vector mask population count vpopc
1457def vpopc : RVVMaskOp0Builtin<"um">;
1458
1459// 16.3. vfirst find-first-set mask bit
1460def vfirst : RVVMaskOp0Builtin<"lm">;
1461
1462// 16.4. vmsbf.m set-before-first mask bit
1463def vmsbf : RVVMaskUnaryBuiltin;
1464
1465// 16.5. vmsif.m set-including-first mask bit
1466def vmsif : RVVMaskUnaryBuiltin;
1467
1468// 16.6. vmsof.m set-only-first mask bit
1469def vmsof : RVVMaskUnaryBuiltin;
1470
1471let HasNoMaskedOverloaded = false in {
1472  // 16.8. Vector Iota Instruction
1473  defm viota : RVVOutBuiltinSet<"viota", "csil", [["m", "Uv", "Uvm"]]>;
1474
1475  // 16.9. Vector Element Index Instruction
1476  defm vid : RVVOutBuiltinSet<"vid", "csil", [["v", "v", "v"],
1477                                              ["v", "Uv", "Uv"]]>;
1478}
1479
1480// 17. Vector Permutation Instructions
1481// 17.1. Integer Scalar Move Instructions
1482let HasMask = false in {
1483  let HasVL = false, MangledName = "vmv_x" in
1484    defm vmv_x : RVVOp0BuiltinSet<"vmv_x_s", "csil",
1485                                   [["s", "ve", "ev"],
1486                                    ["s", "UvUe", "UeUv"]]>;
1487  let MangledName = "vmv_s" in
1488    defm vmv_s : RVVOutBuiltinSet<"vmv_s_x", "csil",
1489                                   [["x", "v", "vve"],
1490                                    ["x", "Uv", "UvUvUe"]]>;
1491}
1492
1493// 17.2. Floating-Point Scalar Move Instructions
1494let HasMask = false in {
1495  let HasVL = false, MangledName = "vfmv_f" in
1496    defm vfmv_f : RVVOp0BuiltinSet<"vfmv_f_s", "fd",
1497                                     [["s", "ve", "ev"]]>;
1498  let MangledName = "vfmv_s" in
1499    defm vfmv_s : RVVOutBuiltinSet<"vfmv_s_f", "fd",
1500                                     [["f", "v", "vve"],
1501                                      ["x", "Uv", "UvUvUe"]]>;
1502}
1503
1504// 17.3. Vector Slide Instructions
1505// 17.3.1. Vector Slideup Instructions
1506defm vslideup   : RVVSlideBuiltinSet;
1507// 17.3.2. Vector Slidedown Instructions
1508defm vslidedown : RVVSlideBuiltinSet;
1509
1510// 17.3.3. Vector Slide1up Instructions
1511defm vslide1up : RVVSlideOneBuiltinSet;
1512defm vfslide1up : RVVFloatingBinVFBuiltinSet;
1513
1514// 17.3.4. Vector Slide1down Instruction
1515defm vslide1down : RVVSlideOneBuiltinSet;
1516defm vfslide1down : RVVFloatingBinVFBuiltinSet;
1517
1518// 17.4. Vector Register Gather Instructions
1519// signed and floating type
1520defm vrgather : RVVOutBuiltinSet<"vrgather_vv", "csilfd",
1521                                 [["vv", "v", "vvUv"]]>;
1522defm vrgather : RVVOutBuiltinSet<"vrgather_vx", "csilfd",
1523                                 [["vx", "v", "vvz"]]>;
1524defm vrgatherei16 : RVVOutBuiltinSet<"vrgatherei16_vv", "csilfd",
1525                                     [["vv", "v", "vv(Log2EEW:4)Uv"]]>;
1526// unsigned type
1527defm vrgather : RVVOutBuiltinSet<"vrgather_vv", "csil",
1528                                 [["vv", "Uv", "UvUvUv"]]>;
1529defm vrgather : RVVOutBuiltinSet<"vrgather_vx", "csil",
1530                                 [["vx", "Uv", "UvUvz"]]>;
1531defm vrgatherei16 : RVVOutBuiltinSet<"vrgatherei16_vv", "csil",
1532                                     [["vv", "Uv", "UvUv(Log2EEW:4)Uv"]]>;
1533
1534// 17.5. Vector Compress Instruction
1535let HasMask = false,
1536    ManualCodegen = [{
1537      std::rotate(Ops.begin(), Ops.begin() + 1, Ops.begin() + 3);
1538      ID = Intrinsic::riscv_vcompress;
1539       IntrinsicTypes = {ResultType, Ops[3]->getType()};
1540    }] in {
1541  // signed and floating type
1542  defm vcompress : RVVOutBuiltinSet<"vcompress", "csilfd",
1543                                    [["vm", "v", "vmvv"]]>;
1544  // unsigned type
1545  defm vcompress : RVVOutBuiltinSet<"vcompress", "csil",
1546                                    [["vm", "Uv", "UvmUvUv"]]>;
1547}
1548
1549// Miscellaneous
1550let HasMask = false, HasVL = false, HasNoMaskedOverloaded = false,
1551    IRName = "" in {
1552  let Name = "vreinterpret_v",
1553      ManualCodegen = [{
1554        return Builder.CreateBitCast(Ops[0], ResultType);
1555      }] in {
1556    // Reinterpret between different type under the same SEW and LMUL
1557    def vreinterpret_i_u : RVVBuiltin<"Uvv", "vUv", "csil">;
1558    def vreinterpret_i_f : RVVBuiltin<"Fvv", "vFv", "il">;
1559    def vreinterpret_u_i : RVVBuiltin<"vUv", "Uvv", "csil">;
1560    def vreinterpret_u_f : RVVBuiltin<"FvUv", "UvFv", "il">;
1561    def vreinterpret_f_i : RVVBuiltin<"vFv", "Fvv", "il">;
1562    def vreinterpret_f_u : RVVBuiltin<"UvFv", "FvUv", "il">;
1563
1564    // Reinterpret between different SEW under the same LMUL
1565    foreach dst_sew = ["(FixedSEW:8)", "(FixedSEW:16)", "(FixedSEW:32)",
1566                       "(FixedSEW:64)"] in {
1567      def vreinterpret_i_ # dst_sew : RVVBuiltin<"v" # dst_sew # "v", dst_sew # "vv", "csil">;
1568      def vreinterpret_u_ # dst_sew : RVVBuiltin<"Uv" # dst_sew # "Uv", dst_sew # "UvUv", "csil">;
1569    }
1570  }
1571
1572  let Name = "vundefined",
1573      ManualCodegen = [{
1574        return llvm::UndefValue::get(ResultType);
1575      }] in {
1576    def vundefined : RVVBuiltin<"v", "v", "csilfd">;
1577    def vundefined_u : RVVBuiltin<"Uv", "Uv", "csil">;
1578  }
1579
1580  // LMUL truncation
1581  // C/C++ Operand: VecTy, IR Operand: VecTy, Index
1582  let Name = "vlmul_trunc_v",
1583      ManualCodegen = [{ {
1584        ID = Intrinsic::experimental_vector_extract;
1585        IntrinsicTypes = {ResultType, Ops[0]->getType()};
1586        Ops.push_back(ConstantInt::get(Int64Ty, 0));
1587        return Builder.CreateCall(CGM.getIntrinsic(ID, IntrinsicTypes), Ops, "");
1588      } }] in {
1589    foreach dst_lmul = ["(SFixedLog2LMUL:-3)", "(SFixedLog2LMUL:-2)", "(SFixedLog2LMUL:-1)",
1590                        "(SFixedLog2LMUL:0)", "(SFixedLog2LMUL:1)", "(SFixedLog2LMUL:2)"] in {
1591      def vlmul_trunc # dst_lmul : RVVBuiltin<"v" # dst_lmul # "v", dst_lmul # "vv", "csilfd">;
1592      def vlmul_trunc_u # dst_lmul : RVVBuiltin<"Uv" # dst_lmul # "Uv", dst_lmul # "UvUv", "csil">;
1593    }
1594  }
1595
1596  // LMUL extension
1597  // C/C++ Operand: SubVecTy, IR Operand: VecTy, SubVecTy, Index
1598  let Name = "vlmul_ext_v",
1599      ManualCodegen = [{
1600        ID = Intrinsic::experimental_vector_insert;
1601        IntrinsicTypes = {ResultType, Ops[0]->getType()};
1602        Ops.push_back(llvm::UndefValue::get(ResultType));
1603        std::swap(Ops[0], Ops[1]);
1604        Ops.push_back(ConstantInt::get(Int64Ty, 0));
1605        return Builder.CreateCall(CGM.getIntrinsic(ID, IntrinsicTypes), Ops, "");
1606      }] in {
1607    foreach dst_lmul = ["(LFixedLog2LMUL:-2)", "(LFixedLog2LMUL:-1)", "(LFixedLog2LMUL:-0)",
1608                        "(LFixedLog2LMUL:1)", "(LFixedLog2LMUL:2)", "(LFixedLog2LMUL:3)"] in {
1609      def vlmul_ext # dst_lmul : RVVBuiltin<"v" # dst_lmul # "v", dst_lmul # "vv", "csilfd">;
1610      def vlmul_ext_u # dst_lmul : RVVBuiltin<"Uv" # dst_lmul # "Uv", dst_lmul # "UvUv", "csil">;
1611    }
1612  }
1613}
1614