106c3fb27SDimitry Andric//==------ riscv_vector_common.td - RISC-V V-ext builtin class ------------===//
206c3fb27SDimitry Andric//
306c3fb27SDimitry Andric//  Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406c3fb27SDimitry Andric//  See https://llvm.org/LICENSE.txt for license information.
506c3fb27SDimitry Andric//  SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606c3fb27SDimitry Andric//
706c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
806c3fb27SDimitry Andric//
906c3fb27SDimitry Andric// This file defines RVV builtin base class for RISC-V V-extension.
1006c3fb27SDimitry Andric//
1106c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
1206c3fb27SDimitry Andric
1306c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
1406c3fb27SDimitry Andric// Instruction definitions
1506c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
1606c3fb27SDimitry Andric// Each record of the class RVVBuiltin defines a collection of builtins (i.e.
1706c3fb27SDimitry Andric// "def vadd : RVVBuiltin" will be used to define things like "vadd_vv_i32m1",
1806c3fb27SDimitry Andric// "vadd_vv_i32m2", etc).
1906c3fb27SDimitry Andric//
2006c3fb27SDimitry Andric// The elements of this collection are defined by an instantiation process the
2106c3fb27SDimitry Andric// range of which is specified by the cross product of the LMUL attribute and
2206c3fb27SDimitry Andric// every element in the attribute TypeRange. By default builtins have LMUL = [1,
2306c3fb27SDimitry Andric// 2, 4, 8, 1/2, 1/4, 1/8] so the process is repeated 7 times. In tablegen we
2406c3fb27SDimitry Andric// use the Log2LMUL [0, 1, 2, 3, -1, -2, -3] to represent the LMUL.
2506c3fb27SDimitry Andric//
2606c3fb27SDimitry Andric// LMUL represents the fact that the types of values used by that builtin are
2706c3fb27SDimitry Andric// values generated by instructions that are executed under that LMUL. However,
2806c3fb27SDimitry Andric// this does not mean the builtin is necessarily lowered into an instruction
2906c3fb27SDimitry Andric// that executes under the specified LMUL. An example where this happens are
3006c3fb27SDimitry Andric// loads and stores of masks. A mask like `vbool8_t` can be generated, for
3106c3fb27SDimitry Andric// instance, by comparing two `__rvv_int8m1_t` (this is LMUL=1) or comparing two
3206c3fb27SDimitry Andric// `__rvv_int16m2_t` (this is LMUL=2). The actual load or store, however, will
3306c3fb27SDimitry Andric// be performed under LMUL=1 because mask registers are not grouped.
3406c3fb27SDimitry Andric//
3506c3fb27SDimitry Andric// TypeRange is a non-empty sequence of basic types:
3606c3fb27SDimitry Andric//
3706c3fb27SDimitry Andric//   c: int8_t (i8)
3806c3fb27SDimitry Andric//   s: int16_t (i16)
3906c3fb27SDimitry Andric//   i: int32_t (i32)
4006c3fb27SDimitry Andric//   l: int64_t (i64)
4106c3fb27SDimitry Andric//   x: float16_t (half)
4206c3fb27SDimitry Andric//   f: float32_t (float)
4306c3fb27SDimitry Andric//   d: float64_t (double)
44*647cbc5dSDimitry Andric//   y: bfloat16_t (bfloat16)
4506c3fb27SDimitry Andric//
4606c3fb27SDimitry Andric// This way, given an LMUL, a record with a TypeRange "sil" will cause the
4706c3fb27SDimitry Andric// definition of 3 builtins. Each type "t" in the TypeRange (in this example
4806c3fb27SDimitry Andric// they are int16_t, int32_t, int64_t) is used as a parameter that drives the
4906c3fb27SDimitry Andric// definition of that particular builtin (for the given LMUL).
5006c3fb27SDimitry Andric//
5106c3fb27SDimitry Andric// During the instantiation, types can be transformed or modified using type
5206c3fb27SDimitry Andric// transformers. Given a type "t" the following primitive type transformers can
5306c3fb27SDimitry Andric// be applied to it to yield another type.
5406c3fb27SDimitry Andric//
5506c3fb27SDimitry Andric//   e: type of "t" as is (identity)
5606c3fb27SDimitry Andric//   v: computes a vector type whose element type is "t" for the current LMUL
5706c3fb27SDimitry Andric//   w: computes a vector type identical to what 'v' computes except for the
5806c3fb27SDimitry Andric//      element type which is twice as wide as the element type of 'v'
5906c3fb27SDimitry Andric//   q: computes a vector type identical to what 'v' computes except for the
6006c3fb27SDimitry Andric//      element type which is four times as wide as the element type of 'v'
6106c3fb27SDimitry Andric//   o: computes a vector type identical to what 'v' computes except for the
6206c3fb27SDimitry Andric//      element type which is eight times as wide as the element type of 'v'
6306c3fb27SDimitry Andric//   m: computes a vector type identical to what 'v' computes except for the
6406c3fb27SDimitry Andric//      element type which is bool
6506c3fb27SDimitry Andric//   0: void type, ignores "t"
6606c3fb27SDimitry Andric//   z: size_t, ignores "t"
6706c3fb27SDimitry Andric//   t: ptrdiff_t, ignores "t"
6806c3fb27SDimitry Andric//   u: unsigned long, ignores "t"
6906c3fb27SDimitry Andric//   l: long, ignores "t"
705f757f3fSDimitry Andric//   f: float32, ignores "t"
7106c3fb27SDimitry Andric//
7206c3fb27SDimitry Andric// So for instance if t is "i", i.e. int, then "e" will yield int again. "v"
7306c3fb27SDimitry Andric// will yield an RVV vector type (assume LMUL=1), so __rvv_int32m1_t.
7406c3fb27SDimitry Andric// Accordingly "w" would yield __rvv_int64m2_t.
7506c3fb27SDimitry Andric//
7606c3fb27SDimitry Andric// A type transformer can be prefixed by other non-primitive type transformers.
7706c3fb27SDimitry Andric//
7806c3fb27SDimitry Andric//   P: constructs a pointer to the current type
7906c3fb27SDimitry Andric//   C: adds const to the type
8006c3fb27SDimitry Andric//   K: requires the integer type to be a constant expression
8106c3fb27SDimitry Andric//   U: given an integer type or vector type, computes its unsigned variant
8206c3fb27SDimitry Andric//   I: given a vector type, compute the vector type with integer type
8306c3fb27SDimitry Andric//      elements of the same width
8406c3fb27SDimitry Andric//   F: given a vector type, compute the vector type with floating-point type
8506c3fb27SDimitry Andric//      elements of the same width
8606c3fb27SDimitry Andric//   S: given a vector type, computes its equivalent one for LMUL=1. This is a
8706c3fb27SDimitry Andric//      no-op if the vector was already LMUL=1
8806c3fb27SDimitry Andric//   (Log2EEW:Value): Log2EEW value could be 3/4/5/6 (8/16/32/64), given a
8906c3fb27SDimitry Andric//      vector type (SEW and LMUL) and EEW (8/16/32/64), computes its
9006c3fb27SDimitry Andric//      equivalent integer vector type with EEW and corresponding ELMUL (elmul =
9106c3fb27SDimitry Andric//      (eew/sew) * lmul). For example, vector type is __rvv_float16m4
9206c3fb27SDimitry Andric//      (SEW=16, LMUL=4) and Log2EEW is 3 (EEW=8), and then equivalent vector
9306c3fb27SDimitry Andric//      type is __rvv_uint8m2_t (elmul=(8/16)*4 = 2). Ignore to define a new
9406c3fb27SDimitry Andric//      builtins if its equivalent type has illegal lmul.
9506c3fb27SDimitry Andric//   (FixedSEW:Value): Given a vector type (SEW and LMUL), and computes another
9606c3fb27SDimitry Andric//      vector type which only changed SEW as given value. Ignore to define a new
9706c3fb27SDimitry Andric//      builtin if its equivalent type has illegal lmul or the SEW does not changed.
9806c3fb27SDimitry Andric//   (SFixedLog2LMUL:Value): Smaller Fixed Log2LMUL. Given a vector type (SEW
9906c3fb27SDimitry Andric//      and LMUL), and computes another vector type which only changed LMUL as
10006c3fb27SDimitry Andric//      given value. The new LMUL should be smaller than the old one. Ignore to
10106c3fb27SDimitry Andric//      define a new builtin if its equivalent type has illegal lmul.
1025f757f3fSDimitry Andric//   (SEFixedLog2LMUL:Value): Smaller or Equal Fixed Log2LMUL. Given a vector
1035f757f3fSDimitry Andric//      type (SEW and LMUL), and computes another vector type which only
1045f757f3fSDimitry Andric//      changed LMUL as given value. The new LMUL should be smaller than or
1055f757f3fSDimitry Andric//      equal to the old one. Ignore to define a new builtin if its equivalent
1065f757f3fSDimitry Andric//      type has illegal lmul.
10706c3fb27SDimitry Andric//   (LFixedLog2LMUL:Value): Larger Fixed Log2LMUL. Given a vector type (SEW
10806c3fb27SDimitry Andric//      and LMUL), and computes another vector type which only changed LMUL as
10906c3fb27SDimitry Andric//      given value. The new LMUL should be larger than the old one. Ignore to
11006c3fb27SDimitry Andric//      define a new builtin if its equivalent type has illegal lmul.
11106c3fb27SDimitry Andric//
11206c3fb27SDimitry Andric// Following with the example above, if t is "i", then "Ue" will yield unsigned
11306c3fb27SDimitry Andric// int and "Fv" will yield __rvv_float32m1_t (again assuming LMUL=1), Fw would
11406c3fb27SDimitry Andric// yield __rvv_float64m2_t, etc.
11506c3fb27SDimitry Andric//
11606c3fb27SDimitry Andric// Each builtin is then defined by applying each type in TypeRange against the
11706c3fb27SDimitry Andric// sequence of type transformers described in Suffix and Prototype.
11806c3fb27SDimitry Andric//
11906c3fb27SDimitry Andric// The name of the builtin is defined by the Name attribute (which defaults to
12006c3fb27SDimitry Andric// the name of the class) appended (separated with an underscore) the Suffix
12106c3fb27SDimitry Andric// attribute. For instance with Name="foo", Suffix = "v" and TypeRange = "il",
12206c3fb27SDimitry Andric// the builtin generated will be __builtin_rvv_foo_i32m1 and
12306c3fb27SDimitry Andric// __builtin_rvv_foo_i64m1 (under LMUL=1). If Suffix contains more than one
12406c3fb27SDimitry Andric// type transformer (say "vv") each of the types is separated with an
12506c3fb27SDimitry Andric// underscore as in "__builtin_rvv_foo_i32m1_i32m1".
12606c3fb27SDimitry Andric//
12706c3fb27SDimitry Andric// The C/C++ prototype of the builtin is defined by the Prototype attribute.
12806c3fb27SDimitry Andric// Prototype is a non-empty sequence of type transformers, the first of which
12906c3fb27SDimitry Andric// is the return type of the builtin and the rest are the parameters of the
13006c3fb27SDimitry Andric// builtin, in order. For instance if Prototype is "wvv" and TypeRange is "si"
13106c3fb27SDimitry Andric// a first builtin will have type
13206c3fb27SDimitry Andric// __rvv_int32m2_t (__rvv_int16m1_t, __rvv_int16m1_t) and the second builtin
13306c3fb27SDimitry Andric// will have type __rvv_int64m2_t (__rvv_int32m1_t, __rvv_int32m1_t) (again
13406c3fb27SDimitry Andric// under LMUL=1).
13506c3fb27SDimitry Andric//
13606c3fb27SDimitry Andric// There are a number of attributes that are used to constraint the number and
13706c3fb27SDimitry Andric// shape of the builtins generated. Refer to the comments below for them.
13806c3fb27SDimitry Andric
13906c3fb27SDimitry Andricclass PolicyScheme<int val>{
14006c3fb27SDimitry Andric  int Value = val;
14106c3fb27SDimitry Andric}
14206c3fb27SDimitry Andricdef NonePolicy : PolicyScheme<0>;
14306c3fb27SDimitry Andricdef HasPassthruOperand : PolicyScheme<1>;
14406c3fb27SDimitry Andricdef HasPolicyOperand : PolicyScheme<2>;
14506c3fb27SDimitry Andric
14606c3fb27SDimitry Andricclass RVVBuiltin<string suffix, string prototype, string type_range,
14706c3fb27SDimitry Andric                 string overloaded_suffix = ""> {
14806c3fb27SDimitry Andric  // Base name that will be prepended in __builtin_rvv_ and appended the
14906c3fb27SDimitry Andric  // computed Suffix.
15006c3fb27SDimitry Andric  string Name = NAME;
15106c3fb27SDimitry Andric
15206c3fb27SDimitry Andric  // If not empty, each instantiated builtin will have this appended after an
15306c3fb27SDimitry Andric  // underscore (_). It is instantiated like Prototype.
15406c3fb27SDimitry Andric  string Suffix = suffix;
15506c3fb27SDimitry Andric
15606c3fb27SDimitry Andric  // If empty, default OverloadedName is sub string of `Name` which end of first
15706c3fb27SDimitry Andric  // '_'. For example, the default overloaded name  is `vadd` for Name `vadd_vv`.
15806c3fb27SDimitry Andric  // It's used for describe some special naming cases.
15906c3fb27SDimitry Andric  string OverloadedName = "";
16006c3fb27SDimitry Andric
16106c3fb27SDimitry Andric  // If not empty, each OverloadedName will have this appended after an
16206c3fb27SDimitry Andric  // underscore (_). It is instantiated like Prototype.
16306c3fb27SDimitry Andric  string OverloadedSuffix = overloaded_suffix;
16406c3fb27SDimitry Andric
16506c3fb27SDimitry Andric  // The different variants of the builtin, parameterised with a type.
16606c3fb27SDimitry Andric  string TypeRange = type_range;
16706c3fb27SDimitry Andric
16806c3fb27SDimitry Andric  // We use each type described in TypeRange and LMUL with prototype to
16906c3fb27SDimitry Andric  // instantiate a specific element of the set of builtins being defined.
17006c3fb27SDimitry Andric  // Prototype attribute defines the C/C++ prototype of the builtin. It is a
17106c3fb27SDimitry Andric  // non-empty sequence of type transformers, the first of which is the return
17206c3fb27SDimitry Andric  // type of the builtin and the rest are the parameters of the builtin, in
17306c3fb27SDimitry Andric  // order. For instance if Prototype is "wvv", TypeRange is "si" and LMUL=1, a
17406c3fb27SDimitry Andric  // first builtin will have type
17506c3fb27SDimitry Andric  // __rvv_int32m2_t (__rvv_int16m1_t, __rvv_int16m1_t), and the second builtin
17606c3fb27SDimitry Andric  // will have type __rvv_int64m2_t (__rvv_int32m1_t, __rvv_int32m1_t).
17706c3fb27SDimitry Andric  string Prototype = prototype;
17806c3fb27SDimitry Andric
17906c3fb27SDimitry Andric  // This builtin has a masked form.
18006c3fb27SDimitry Andric  bit HasMasked = true;
18106c3fb27SDimitry Andric
18206c3fb27SDimitry Andric  // If HasMasked, this flag states that this builtin has a maskedoff operand. It
18306c3fb27SDimitry Andric  // is always the first operand in builtin and IR intrinsic.
18406c3fb27SDimitry Andric  bit HasMaskedOffOperand = true;
18506c3fb27SDimitry Andric
18606c3fb27SDimitry Andric  // This builtin has a granted vector length parameter.
18706c3fb27SDimitry Andric  bit HasVL = true;
18806c3fb27SDimitry Andric
18906c3fb27SDimitry Andric  // The policy scheme for masked intrinsic IR.
19006c3fb27SDimitry Andric  // It could be NonePolicy or HasPolicyOperand.
19106c3fb27SDimitry Andric  // HasPolicyOperand: Has a policy operand. 0 is tail and mask undisturbed, 1 is
19206c3fb27SDimitry Andric  // tail agnostic, 2 is mask undisturbed, and 3 is tail and mask agnostic. The
19306c3fb27SDimitry Andric  // policy operand is located at the last position.
19406c3fb27SDimitry Andric  PolicyScheme MaskedPolicyScheme = HasPolicyOperand;
19506c3fb27SDimitry Andric
19606c3fb27SDimitry Andric  // The policy scheme for unmasked intrinsic IR.
19706c3fb27SDimitry Andric  // It could be NonePolicy, HasPassthruOperand or HasPolicyOperand.
19806c3fb27SDimitry Andric  // HasPassthruOperand: Has a passthru operand to decide tail policy. If it is
19906c3fb27SDimitry Andric  // poison, tail policy is tail agnostic, otherwise policy is tail undisturbed.
20006c3fb27SDimitry Andric  // HasPolicyOperand: Has a policy operand. 1 is tail agnostic and 0 is tail
20106c3fb27SDimitry Andric  // undisturbed.
20206c3fb27SDimitry Andric  PolicyScheme UnMaskedPolicyScheme = NonePolicy;
20306c3fb27SDimitry Andric
20406c3fb27SDimitry Andric  // This builtin support tail agnostic and undisturbed policy.
20506c3fb27SDimitry Andric  bit HasTailPolicy = true;
20606c3fb27SDimitry Andric  // This builtin support mask agnostic and undisturbed policy.
20706c3fb27SDimitry Andric  bit HasMaskPolicy = true;
20806c3fb27SDimitry Andric
20906c3fb27SDimitry Andric  // This builtin prototype with TA or TAMA policy could not support overloading
21006c3fb27SDimitry Andric  // API. Other policy intrinsic functions would support overloading API with
21106c3fb27SDimitry Andric  // suffix `_tu`, `tumu`, `tuma`, `tamu` and `tama`.
21206c3fb27SDimitry Andric  bit SupportOverloading = true;
21306c3fb27SDimitry Andric
21406c3fb27SDimitry Andric  // This builtin is valid for the given Log2LMULs.
21506c3fb27SDimitry Andric  list<int> Log2LMUL = [0, 1, 2, 3, -1, -2, -3];
21606c3fb27SDimitry Andric
21706c3fb27SDimitry Andric  // Manual code in clang codegen riscv_vector_builtin_cg.inc
21806c3fb27SDimitry Andric  code ManualCodegen = [{}];
21906c3fb27SDimitry Andric
22006c3fb27SDimitry Andric  // When emit the automatic clang codegen, it describes what types we have to use
22106c3fb27SDimitry Andric  // to obtain the specific LLVM intrinsic. -1 means the return type, otherwise,
22206c3fb27SDimitry Andric  // k >= 0 meaning the k-th operand (counting from zero) of the codegen'd
22306c3fb27SDimitry Andric  // parameter of the unmasked version. k can't be the mask operand's position.
22406c3fb27SDimitry Andric  list<int> IntrinsicTypes = [];
22506c3fb27SDimitry Andric
22606c3fb27SDimitry Andric  // If these names are not empty, this is the ID of the LLVM intrinsic
22706c3fb27SDimitry Andric  // we want to lower to.
22806c3fb27SDimitry Andric  string IRName = NAME;
22906c3fb27SDimitry Andric
23006c3fb27SDimitry Andric  // If HasMasked, this is the ID of the LLVM intrinsic we want to lower to.
23106c3fb27SDimitry Andric  string MaskedIRName = NAME #"_mask";
23206c3fb27SDimitry Andric
23306c3fb27SDimitry Andric  // Use clang_builtin_alias to save the number of builtins.
23406c3fb27SDimitry Andric  bit HasBuiltinAlias = true;
23506c3fb27SDimitry Andric
23606c3fb27SDimitry Andric  // Features required to enable for this builtin.
23706c3fb27SDimitry Andric  list<string> RequiredFeatures = [];
23806c3fb27SDimitry Andric
23906c3fb27SDimitry Andric  // Number of fields for Load/Store Segment instructions.
24006c3fb27SDimitry Andric  int NF = 1;
24106c3fb27SDimitry Andric
24206c3fb27SDimitry Andric  // Set to true if the builtin is associated with tuple types.
24306c3fb27SDimitry Andric  bit IsTuple = false;
24406c3fb27SDimitry Andric
24506c3fb27SDimitry Andric  // Set to true if the builtin has a parameter that models floating-point
24606c3fb27SDimitry Andric  // rounding mode control
24706c3fb27SDimitry Andric  bit HasFRMRoundModeOp = false;
24806c3fb27SDimitry Andric}
24906c3fb27SDimitry Andric
25006c3fb27SDimitry Andric// This is the code emitted in the header.
25106c3fb27SDimitry Andricclass RVVHeader {
25206c3fb27SDimitry Andric  code HeaderCode;
25306c3fb27SDimitry Andric}
2545f757f3fSDimitry Andric
2555f757f3fSDimitry Andric//===----------------------------------------------------------------------===//
2565f757f3fSDimitry Andric// Basic classes with automatic codegen.
2575f757f3fSDimitry Andric//===----------------------------------------------------------------------===//
2585f757f3fSDimitry Andric
2595f757f3fSDimitry Andricclass RVVOutBuiltin<string suffix, string prototype, string type_range>
2605f757f3fSDimitry Andric    : RVVBuiltin<suffix, prototype, type_range> {
2615f757f3fSDimitry Andric  let IntrinsicTypes = [-1];
2625f757f3fSDimitry Andric}
2635f757f3fSDimitry Andric
2645f757f3fSDimitry Andricclass RVVOp0Builtin<string suffix, string prototype, string type_range>
2655f757f3fSDimitry Andric    : RVVBuiltin<suffix, prototype, type_range> {
2665f757f3fSDimitry Andric  let IntrinsicTypes = [0];
2675f757f3fSDimitry Andric}
2685f757f3fSDimitry Andric
2695f757f3fSDimitry Andricclass RVVOutOp1Builtin<string suffix, string prototype, string type_range>
2705f757f3fSDimitry Andric    : RVVBuiltin<suffix, prototype, type_range> {
2715f757f3fSDimitry Andric  let IntrinsicTypes = [-1, 1];
2725f757f3fSDimitry Andric}
2735f757f3fSDimitry Andric
2745f757f3fSDimitry Andricclass RVVOutOp0Op1Builtin<string suffix, string prototype, string type_range>
2755f757f3fSDimitry Andric    : RVVBuiltin<suffix, prototype, type_range> {
2765f757f3fSDimitry Andric  let IntrinsicTypes = [-1, 0, 1];
2775f757f3fSDimitry Andric}
2785f757f3fSDimitry Andric
2795f757f3fSDimitry Andricmulticlass RVVBuiltinSet<string intrinsic_name, string type_range,
2805f757f3fSDimitry Andric                         list<list<string>> suffixes_prototypes,
2815f757f3fSDimitry Andric                         list<int> intrinsic_types> {
2825f757f3fSDimitry Andric  let IRName = intrinsic_name, MaskedIRName = intrinsic_name # "_mask",
2835f757f3fSDimitry Andric      IntrinsicTypes = intrinsic_types in {
2845f757f3fSDimitry Andric    foreach s_p = suffixes_prototypes in {
2855f757f3fSDimitry Andric      let Name = NAME # "_" # s_p[0] in {
2865f757f3fSDimitry Andric        defvar suffix = s_p[1];
2875f757f3fSDimitry Andric        defvar prototype = s_p[2];
2885f757f3fSDimitry Andric        def : RVVBuiltin<suffix, prototype, type_range>;
2895f757f3fSDimitry Andric      }
2905f757f3fSDimitry Andric    }
2915f757f3fSDimitry Andric  }
2925f757f3fSDimitry Andric}
2935f757f3fSDimitry Andric
2945f757f3fSDimitry Andric// IntrinsicTypes is output, op0, op1 [-1, 0, 1]
2955f757f3fSDimitry Andricmulticlass RVVOutOp0Op1BuiltinSet<string intrinsic_name, string type_range,
2965f757f3fSDimitry Andric                                  list<list<string>> suffixes_prototypes>
2975f757f3fSDimitry Andric    : RVVBuiltinSet<intrinsic_name, type_range, suffixes_prototypes,
2985f757f3fSDimitry Andric                            [-1, 0, 1]>;
2995f757f3fSDimitry Andric
3005f757f3fSDimitry Andricmulticlass RVVOutBuiltinSet<string intrinsic_name, string type_range,
3015f757f3fSDimitry Andric                            list<list<string>> suffixes_prototypes>
3025f757f3fSDimitry Andric    : RVVBuiltinSet<intrinsic_name, type_range, suffixes_prototypes, [-1]>;
3035f757f3fSDimitry Andric
3045f757f3fSDimitry Andricmulticlass RVVOp0BuiltinSet<string intrinsic_name, string type_range,
3055f757f3fSDimitry Andric                            list<list<string>> suffixes_prototypes>
3065f757f3fSDimitry Andric    : RVVBuiltinSet<intrinsic_name, type_range, suffixes_prototypes, [0]>;
3075f757f3fSDimitry Andric
3085f757f3fSDimitry Andric// IntrinsicTypes is output, op1 [-1, 0]
3095f757f3fSDimitry Andricmulticlass RVVOutOp0BuiltinSet<string intrinsic_name, string type_range,
3105f757f3fSDimitry Andric                               list<list<string>> suffixes_prototypes>
3115f757f3fSDimitry Andric    : RVVBuiltinSet<intrinsic_name, type_range, suffixes_prototypes, [-1, 0]>;
3125f757f3fSDimitry Andric
3135f757f3fSDimitry Andric// IntrinsicTypes is output, op1 [-1, 1]
3145f757f3fSDimitry Andricmulticlass RVVOutOp1BuiltinSet<string intrinsic_name, string type_range,
3155f757f3fSDimitry Andric                               list<list<string>> suffixes_prototypes>
3165f757f3fSDimitry Andric    : RVVBuiltinSet<intrinsic_name, type_range, suffixes_prototypes, [-1, 1]>;
3175f757f3fSDimitry Andric
3185f757f3fSDimitry Andricmulticlass RVVOp0Op1BuiltinSet<string intrinsic_name, string type_range,
3195f757f3fSDimitry Andric                               list<list<string>> suffixes_prototypes>
3205f757f3fSDimitry Andric    : RVVBuiltinSet<intrinsic_name, type_range, suffixes_prototypes, [0, 1]>;
3215f757f3fSDimitry Andric
3225f757f3fSDimitry Andricmulticlass RVVOutOp1Op2BuiltinSet<string intrinsic_name, string type_range,
3235f757f3fSDimitry Andric                                  list<list<string>> suffixes_prototypes>
3245f757f3fSDimitry Andric    : RVVBuiltinSet<intrinsic_name, type_range, suffixes_prototypes, [-1, 1, 2]>;
3255f757f3fSDimitry Andric
3265f757f3fSDimitry Andric// IntrinsicTypes is output, op2 [-1, 2]
3275f757f3fSDimitry Andricmulticlass RVVOutOp2BuiltinSet<string intrinsic_name, string type_range,
3285f757f3fSDimitry Andric                               list<list<string>> suffixes_prototypes>
3295f757f3fSDimitry Andric    : RVVBuiltinSet<intrinsic_name, type_range, suffixes_prototypes, [-1, 2]>;
3305f757f3fSDimitry Andric
3315f757f3fSDimitry Andricmulticlass RVVSignedBinBuiltinSet
3325f757f3fSDimitry Andric    : RVVOutOp1BuiltinSet<NAME, "csil",
3335f757f3fSDimitry Andric                          [["vv", "v", "vvv"],
3345f757f3fSDimitry Andric                           ["vx", "v", "vve"]]>;
3355f757f3fSDimitry Andric
3365f757f3fSDimitry Andricmulticlass RVVSignedBinBuiltinSetRoundingMode
3375f757f3fSDimitry Andric    : RVVOutOp1BuiltinSet<NAME, "csil",
3385f757f3fSDimitry Andric                          [["vv", "v", "vvvu"],
3395f757f3fSDimitry Andric                           ["vx", "v", "vveu"]]>;
3405f757f3fSDimitry Andric
3415f757f3fSDimitry Andricmulticlass RVVUnsignedBinBuiltinSet
3425f757f3fSDimitry Andric    : RVVOutOp1BuiltinSet<NAME, "csil",
3435f757f3fSDimitry Andric                          [["vv", "Uv", "UvUvUv"],
3445f757f3fSDimitry Andric                           ["vx", "Uv", "UvUvUe"]]>;
3455f757f3fSDimitry Andric
3465f757f3fSDimitry Andricmulticlass RVVUnsignedBinBuiltinSetRoundingMode
3475f757f3fSDimitry Andric    : RVVOutOp1BuiltinSet<NAME, "csil",
3485f757f3fSDimitry Andric                          [["vv", "Uv", "UvUvUvu"],
3495f757f3fSDimitry Andric                           ["vx", "Uv", "UvUvUeu"]]>;
3505f757f3fSDimitry Andric
3515f757f3fSDimitry Andricmulticlass RVVIntBinBuiltinSet
3525f757f3fSDimitry Andric    : RVVSignedBinBuiltinSet,
3535f757f3fSDimitry Andric      RVVUnsignedBinBuiltinSet;
3545f757f3fSDimitry Andric
3555f757f3fSDimitry Andricmulticlass RVVInt64BinBuiltinSet
3565f757f3fSDimitry Andric    : RVVOutOp1BuiltinSet<NAME, "l",
3575f757f3fSDimitry Andric                          [["vv", "v", "vvv"],
3585f757f3fSDimitry Andric                           ["vx", "v", "vve"]]>,
3595f757f3fSDimitry Andric      RVVOutOp1BuiltinSet<NAME, "l",
3605f757f3fSDimitry Andric                          [["vv", "Uv", "UvUvUv"],
3615f757f3fSDimitry Andric                           ["vx", "Uv", "UvUvUe"]]>;
3625f757f3fSDimitry Andric
3635f757f3fSDimitry Andricmulticlass RVVSlideOneBuiltinSet
3645f757f3fSDimitry Andric    : RVVOutOp1BuiltinSet<NAME, "csil",
3655f757f3fSDimitry Andric                          [["vx", "v", "vve"],
3665f757f3fSDimitry Andric                           ["vx", "Uv", "UvUvUe"]]>;
3675f757f3fSDimitry Andric
3685f757f3fSDimitry Andricmulticlass RVVSignedShiftBuiltinSet
3695f757f3fSDimitry Andric    : RVVOutOp1BuiltinSet<NAME, "csil",
3705f757f3fSDimitry Andric                          [["vv", "v", "vvUv"],
3715f757f3fSDimitry Andric                           ["vx", "v", "vvz"]]>;
3725f757f3fSDimitry Andric
3735f757f3fSDimitry Andricmulticlass RVVSignedShiftBuiltinSetRoundingMode
3745f757f3fSDimitry Andric    : RVVOutOp1BuiltinSet<NAME, "csil",
3755f757f3fSDimitry Andric                          [["vv", "v", "vvUvu"],
3765f757f3fSDimitry Andric                           ["vx", "v", "vvzu"]]>;
3775f757f3fSDimitry Andric
3785f757f3fSDimitry Andricmulticlass RVVUnsignedShiftBuiltinSet
3795f757f3fSDimitry Andric    : RVVOutOp1BuiltinSet<NAME, "csil",
3805f757f3fSDimitry Andric                          [["vv", "Uv", "UvUvUv"],
3815f757f3fSDimitry Andric                           ["vx", "Uv", "UvUvz"]]>;
3825f757f3fSDimitry Andric
3835f757f3fSDimitry Andricmulticlass RVVUnsignedShiftBuiltinSetRoundingMode
3845f757f3fSDimitry Andric    : RVVOutOp1BuiltinSet<NAME, "csil",
3855f757f3fSDimitry Andric                          [["vv", "Uv", "UvUvUvu"],
3865f757f3fSDimitry Andric                           ["vx", "Uv", "UvUvzu"]]>;
3875f757f3fSDimitry Andric
3885f757f3fSDimitry Andricmulticlass RVVShiftBuiltinSet
3895f757f3fSDimitry Andric    : RVVSignedShiftBuiltinSet,
3905f757f3fSDimitry Andric      RVVUnsignedShiftBuiltinSet;
3915f757f3fSDimitry Andric
3925f757f3fSDimitry Andriclet Log2LMUL = [-3, -2, -1, 0, 1, 2] in {
3935f757f3fSDimitry Andric  multiclass RVVSignedNShiftBuiltinSet
3945f757f3fSDimitry Andric      : RVVOutOp0Op1BuiltinSet<NAME, "csil",
3955f757f3fSDimitry Andric                                     [["wv", "v", "vwUv"],
3965f757f3fSDimitry Andric                                      ["wx", "v", "vwz"]]>;
3975f757f3fSDimitry Andric
3985f757f3fSDimitry Andric  multiclass RVVSignedNShiftBuiltinSetRoundingMode
3995f757f3fSDimitry Andric      : RVVOutOp0Op1BuiltinSet<NAME, "csil",
4005f757f3fSDimitry Andric                                     [["wv", "v", "vwUvu"],
4015f757f3fSDimitry Andric                                      ["wx", "v", "vwzu"]]>;
4025f757f3fSDimitry Andric
4035f757f3fSDimitry Andric  multiclass RVVUnsignedNShiftBuiltinSet
4045f757f3fSDimitry Andric      : RVVOutOp0Op1BuiltinSet<NAME, "csil",
4055f757f3fSDimitry Andric                                     [["wv", "Uv", "UvUwUv"],
4065f757f3fSDimitry Andric                                      ["wx", "Uv", "UvUwz"]]>;
4075f757f3fSDimitry Andric
4085f757f3fSDimitry Andric  multiclass RVVUnsignedNShiftBuiltinSetRoundingMode
4095f757f3fSDimitry Andric      : RVVOutOp0Op1BuiltinSet<NAME, "csil",
4105f757f3fSDimitry Andric                                     [["wv", "Uv", "UvUwUvu"],
4115f757f3fSDimitry Andric                                      ["wx", "Uv", "UvUwzu"]]>;
4125f757f3fSDimitry Andric
4135f757f3fSDimitry Andric}
4145f757f3fSDimitry Andric
4155f757f3fSDimitry Andricmulticlass RVVCarryinBuiltinSet
4165f757f3fSDimitry Andric    : RVVOutOp1BuiltinSet<NAME, "csil",
4175f757f3fSDimitry Andric                          [["vvm", "v", "vvvm"],
4185f757f3fSDimitry Andric                           ["vxm", "v", "vvem"],
4195f757f3fSDimitry Andric                           ["vvm", "Uv", "UvUvUvm"],
4205f757f3fSDimitry Andric                           ["vxm", "Uv", "UvUvUem"]]>;
4215f757f3fSDimitry Andric
4225f757f3fSDimitry Andricmulticlass RVVCarryOutInBuiltinSet<string intrinsic_name>
4235f757f3fSDimitry Andric    : RVVOp0Op1BuiltinSet<intrinsic_name, "csil",
4245f757f3fSDimitry Andric                          [["vvm", "vm", "mvvm"],
4255f757f3fSDimitry Andric                           ["vxm", "vm", "mvem"],
4265f757f3fSDimitry Andric                           ["vvm", "Uvm", "mUvUvm"],
4275f757f3fSDimitry Andric                           ["vxm", "Uvm", "mUvUem"]]>;
4285f757f3fSDimitry Andric
4295f757f3fSDimitry Andricmulticlass RVVSignedMaskOutBuiltinSet
4305f757f3fSDimitry Andric    : RVVOp0Op1BuiltinSet<NAME, "csil",
4315f757f3fSDimitry Andric                          [["vv", "vm", "mvv"],
4325f757f3fSDimitry Andric                           ["vx", "vm", "mve"]]>;
4335f757f3fSDimitry Andric
4345f757f3fSDimitry Andricmulticlass RVVUnsignedMaskOutBuiltinSet
4355f757f3fSDimitry Andric    : RVVOp0Op1BuiltinSet<NAME, "csil",
4365f757f3fSDimitry Andric                          [["vv", "Uvm", "mUvUv"],
4375f757f3fSDimitry Andric                           ["vx", "Uvm", "mUvUe"]]>;
4385f757f3fSDimitry Andric
4395f757f3fSDimitry Andricmulticlass RVVIntMaskOutBuiltinSet
4405f757f3fSDimitry Andric    : RVVSignedMaskOutBuiltinSet,
4415f757f3fSDimitry Andric      RVVUnsignedMaskOutBuiltinSet;
4425f757f3fSDimitry Andric
4435f757f3fSDimitry Andricclass RVVIntExt<string intrinsic_name, string suffix, string prototype,
4445f757f3fSDimitry Andric                string type_range>
4455f757f3fSDimitry Andric    : RVVBuiltin<suffix, prototype, type_range> {
4465f757f3fSDimitry Andric  let IRName = intrinsic_name;
4475f757f3fSDimitry Andric  let MaskedIRName = intrinsic_name # "_mask";
4485f757f3fSDimitry Andric  let OverloadedName = NAME;
4495f757f3fSDimitry Andric  let IntrinsicTypes = [-1, 0];
4505f757f3fSDimitry Andric}
4515f757f3fSDimitry Andric
4525f757f3fSDimitry Andriclet HasMaskedOffOperand = false in {
4535f757f3fSDimitry Andric  multiclass RVVIntTerBuiltinSet {
4545f757f3fSDimitry Andric    defm "" : RVVOutOp1BuiltinSet<NAME, "csil",
4555f757f3fSDimitry Andric                                  [["vv", "v", "vvvv"],
4565f757f3fSDimitry Andric                                   ["vx", "v", "vvev"],
4575f757f3fSDimitry Andric                                   ["vv", "Uv", "UvUvUvUv"],
4585f757f3fSDimitry Andric                                   ["vx", "Uv", "UvUvUeUv"]]>;
4595f757f3fSDimitry Andric  }
4605f757f3fSDimitry Andric  multiclass RVVFloatingTerBuiltinSet {
4615f757f3fSDimitry Andric    defm "" : RVVOutOp1BuiltinSet<NAME, "xfd",
4625f757f3fSDimitry Andric                                  [["vv", "v", "vvvv"],
4635f757f3fSDimitry Andric                                   ["vf", "v", "vvev"]]>;
4645f757f3fSDimitry Andric  }
4655f757f3fSDimitry Andric  multiclass RVVFloatingTerBuiltinSetRoundingMode {
4665f757f3fSDimitry Andric    defm "" : RVVOutOp1BuiltinSet<NAME, "xfd",
4675f757f3fSDimitry Andric                                  [["vv", "v", "vvvvu"],
4685f757f3fSDimitry Andric                                   ["vf", "v", "vvevu"]]>;
4695f757f3fSDimitry Andric  }
4705f757f3fSDimitry Andric}
4715f757f3fSDimitry Andric
4725f757f3fSDimitry Andriclet HasMaskedOffOperand = false, Log2LMUL = [-2, -1, 0, 1, 2] in {
4735f757f3fSDimitry Andric  multiclass RVVFloatingWidenTerBuiltinSet {
4745f757f3fSDimitry Andric    defm ""  : RVVOutOp1Op2BuiltinSet<NAME, "xf",
4755f757f3fSDimitry Andric                                      [["vv", "w", "wwvv"],
4765f757f3fSDimitry Andric                                       ["vf", "w", "wwev"]]>;
4775f757f3fSDimitry Andric  }
4785f757f3fSDimitry Andric  multiclass RVVFloatingWidenTerBuiltinSetRoundingMode {
4795f757f3fSDimitry Andric    defm ""  : RVVOutOp1Op2BuiltinSet<NAME, "xf",
4805f757f3fSDimitry Andric                                      [["vv", "w", "wwvvu"],
4815f757f3fSDimitry Andric                                       ["vf", "w", "wwevu"]]>;
4825f757f3fSDimitry Andric  }
4835f757f3fSDimitry Andric}
4845f757f3fSDimitry Andric
4855f757f3fSDimitry Andricmulticlass RVVFloatingBinBuiltinSet
4865f757f3fSDimitry Andric    : RVVOutOp1BuiltinSet<NAME, "xfd",
4875f757f3fSDimitry Andric                          [["vv", "v", "vvv"],
4885f757f3fSDimitry Andric                           ["vf", "v", "vve"]]>;
4895f757f3fSDimitry Andric
4905f757f3fSDimitry Andricmulticlass RVVFloatingBinBuiltinSetRoundingMode
4915f757f3fSDimitry Andric    : RVVOutOp1BuiltinSet<NAME, "xfd",
4925f757f3fSDimitry Andric                          [["vv", "v", "vvvu"],
4935f757f3fSDimitry Andric                           ["vf", "v", "vveu"]]>;
4945f757f3fSDimitry Andric
4955f757f3fSDimitry Andricmulticlass RVVFloatingBinVFBuiltinSet
4965f757f3fSDimitry Andric    : RVVOutOp1BuiltinSet<NAME, "xfd",
4975f757f3fSDimitry Andric                          [["vf", "v", "vve"]]>;
4985f757f3fSDimitry Andric
4995f757f3fSDimitry Andricmulticlass RVVFloatingBinVFBuiltinSetRoundingMode
5005f757f3fSDimitry Andric    : RVVOutOp1BuiltinSet<NAME, "xfd",
5015f757f3fSDimitry Andric                          [["vf", "v", "vveu"]]>;
5025f757f3fSDimitry Andric
5035f757f3fSDimitry Andricmulticlass RVVFloatingMaskOutBuiltinSet
5045f757f3fSDimitry Andric    : RVVOp0Op1BuiltinSet<NAME, "xfd",
5055f757f3fSDimitry Andric                          [["vv", "vm", "mvv"],
5065f757f3fSDimitry Andric                           ["vf", "vm", "mve"]]>;
5075f757f3fSDimitry Andric
5085f757f3fSDimitry Andricmulticlass RVVFloatingMaskOutVFBuiltinSet
5095f757f3fSDimitry Andric    : RVVOp0Op1BuiltinSet<NAME, "fd",
5105f757f3fSDimitry Andric                          [["vf", "vm", "mve"]]>;
5115f757f3fSDimitry Andric
5125f757f3fSDimitry Andricmulticlass RVVConvBuiltinSet<string intrinsic_name, string type_range,
5135f757f3fSDimitry Andric                         list<list<string>> suffixes_prototypes> {
5145f757f3fSDimitry Andriclet Name = intrinsic_name,
5155f757f3fSDimitry Andric    IRName = intrinsic_name,
5165f757f3fSDimitry Andric    MaskedIRName = intrinsic_name # "_mask",
5175f757f3fSDimitry Andric    IntrinsicTypes = [-1, 0] in {
5185f757f3fSDimitry Andric  foreach s_p = suffixes_prototypes in {
5195f757f3fSDimitry Andric      defvar suffix = s_p[0];
5205f757f3fSDimitry Andric      defvar prototype = s_p[1];
5215f757f3fSDimitry Andric      def : RVVBuiltin<suffix, prototype, type_range>;
5225f757f3fSDimitry Andric    }
5235f757f3fSDimitry Andric  }
5245f757f3fSDimitry Andric}
5255f757f3fSDimitry Andric
5265f757f3fSDimitry Andric
5275f757f3fSDimitry Andricclass RVVMaskBinBuiltin : RVVOutBuiltin<"m", "mmm", "c"> {
5285f757f3fSDimitry Andric  let Name = NAME # "_mm";
5295f757f3fSDimitry Andric  let HasMasked = false;
5305f757f3fSDimitry Andric}
5315f757f3fSDimitry Andric
5325f757f3fSDimitry Andricclass RVVMaskUnaryBuiltin : RVVOutBuiltin<"m", "mm", "c"> {
5335f757f3fSDimitry Andric  let Name = NAME # "_m";
5345f757f3fSDimitry Andric}
5355f757f3fSDimitry Andric
5365f757f3fSDimitry Andricclass RVVMaskNullaryBuiltin : RVVOutBuiltin<"m", "m", "c"> {
5375f757f3fSDimitry Andric  let Name = NAME # "_m";
5385f757f3fSDimitry Andric  let HasMasked = false;
5395f757f3fSDimitry Andric  let SupportOverloading = false;
5405f757f3fSDimitry Andric}
5415f757f3fSDimitry Andric
5425f757f3fSDimitry Andricclass RVVMaskOp0Builtin<string prototype> : RVVOp0Builtin<"m", prototype, "c"> {
5435f757f3fSDimitry Andric  let Name = NAME # "_m";
5445f757f3fSDimitry Andric  let HasMaskedOffOperand = false;
5455f757f3fSDimitry Andric}
5465f757f3fSDimitry Andric
5475f757f3fSDimitry Andriclet UnMaskedPolicyScheme = HasPolicyOperand,
5485f757f3fSDimitry Andric    HasMaskedOffOperand = false in {
5495f757f3fSDimitry Andric  multiclass RVVSlideUpBuiltinSet {
5505f757f3fSDimitry Andric    defm "" : RVVOutBuiltinSet<NAME, "csilxfd",
5515f757f3fSDimitry Andric                               [["vx","v", "vvvz"]]>;
5525f757f3fSDimitry Andric    defm "" : RVVOutBuiltinSet<NAME, "csil",
5535f757f3fSDimitry Andric                               [["vx","Uv", "UvUvUvz"]]>;
5545f757f3fSDimitry Andric  }
5555f757f3fSDimitry Andric}
5565f757f3fSDimitry Andric
5575f757f3fSDimitry Andriclet UnMaskedPolicyScheme = HasPassthruOperand,
5585f757f3fSDimitry Andric    ManualCodegen = [{
5595f757f3fSDimitry Andric      if (IsMasked) {
5605f757f3fSDimitry Andric        std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
5615f757f3fSDimitry Andric        if ((PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA))
5625f757f3fSDimitry Andric          Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
5635f757f3fSDimitry Andric      } else {
5645f757f3fSDimitry Andric        if (PolicyAttrs & RVV_VTA)
5655f757f3fSDimitry Andric          Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
5665f757f3fSDimitry Andric      }
5675f757f3fSDimitry Andric
5685f757f3fSDimitry Andric      Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
5695f757f3fSDimitry Andric      IntrinsicTypes = {ResultType, Ops.back()->getType()};
5705f757f3fSDimitry Andric    }] in {
5715f757f3fSDimitry Andric  multiclass RVVSlideDownBuiltinSet {
5725f757f3fSDimitry Andric    defm "" : RVVOutBuiltinSet<NAME, "csilxfd",
5735f757f3fSDimitry Andric                               [["vx","v", "vvz"]]>;
5745f757f3fSDimitry Andric    defm "" : RVVOutBuiltinSet<NAME, "csil",
5755f757f3fSDimitry Andric                               [["vx","Uv", "UvUvz"]]>;
5765f757f3fSDimitry Andric  }
5775f757f3fSDimitry Andric}
5785f757f3fSDimitry Andric
5795f757f3fSDimitry Andricclass RVVFloatingUnaryBuiltin<string builtin_suffix, string ir_suffix,
5805f757f3fSDimitry Andric                              string prototype>
5815f757f3fSDimitry Andric    : RVVOutBuiltin<ir_suffix, prototype, "xfd"> {
5825f757f3fSDimitry Andric  let Name = NAME # "_" # builtin_suffix;
5835f757f3fSDimitry Andric}
5845f757f3fSDimitry Andric
5855f757f3fSDimitry Andricclass RVVFloatingUnaryVVBuiltin : RVVFloatingUnaryBuiltin<"v", "v", "vv">;
5865f757f3fSDimitry Andric
5875f757f3fSDimitry Andricclass RVVConvBuiltin<string suffix, string prototype, string type_range,
5885f757f3fSDimitry Andric                     string overloaded_name>
5895f757f3fSDimitry Andric    : RVVBuiltin<suffix, prototype, type_range> {
5905f757f3fSDimitry Andric  let IntrinsicTypes = [-1, 0];
5915f757f3fSDimitry Andric  let OverloadedName = overloaded_name;
5925f757f3fSDimitry Andric}
5935f757f3fSDimitry Andric
5945f757f3fSDimitry Andricclass RVVConvToSignedBuiltin<string overloaded_name>
5955f757f3fSDimitry Andric    : RVVConvBuiltin<"Iv", "Ivv", "xfd", overloaded_name>;
5965f757f3fSDimitry Andric
5975f757f3fSDimitry Andricclass RVVConvToUnsignedBuiltin<string overloaded_name>
5985f757f3fSDimitry Andric    : RVVConvBuiltin<"Uv", "Uvv", "xfd", overloaded_name>;
5995f757f3fSDimitry Andric
6005f757f3fSDimitry Andricclass RVVConvToWidenSignedBuiltin<string overloaded_name>
6015f757f3fSDimitry Andric    : RVVConvBuiltin<"Iw", "Iwv", "xf", overloaded_name>;
6025f757f3fSDimitry Andric
6035f757f3fSDimitry Andricclass RVVConvToWidenUnsignedBuiltin<string overloaded_name>
6045f757f3fSDimitry Andric    : RVVConvBuiltin<"Uw", "Uwv", "xf", overloaded_name>;
6055f757f3fSDimitry Andric
6065f757f3fSDimitry Andricclass RVVConvToNarrowingSignedBuiltin<string overloaded_name>
6075f757f3fSDimitry Andric    : RVVConvBuiltin<"Iv", "IvFw", "csi", overloaded_name>;
6085f757f3fSDimitry Andric
6095f757f3fSDimitry Andricclass RVVConvToNarrowingUnsignedBuiltin<string overloaded_name>
6105f757f3fSDimitry Andric    : RVVConvBuiltin<"Uv", "UvFw", "csi", overloaded_name>;
6115f757f3fSDimitry Andric
6125f757f3fSDimitry Andriclet HasMaskedOffOperand = true in {
6135f757f3fSDimitry Andric  multiclass RVVSignedReductionBuiltin {
6145f757f3fSDimitry Andric    defm "" : RVVOutOp0BuiltinSet<NAME, "csil",
6155f757f3fSDimitry Andric                                  [["vs", "vSv", "SvvSv"]]>;
6165f757f3fSDimitry Andric  }
6175f757f3fSDimitry Andric  multiclass RVVUnsignedReductionBuiltin {
6185f757f3fSDimitry Andric    defm "" : RVVOutOp0BuiltinSet<NAME, "csil",
6195f757f3fSDimitry Andric                                  [["vs", "UvUSv", "USvUvUSv"]]>;
6205f757f3fSDimitry Andric  }
6215f757f3fSDimitry Andric  multiclass RVVFloatingReductionBuiltin {
6225f757f3fSDimitry Andric    defm "" : RVVOutOp0BuiltinSet<NAME, "xfd",
6235f757f3fSDimitry Andric                                  [["vs", "vSv", "SvvSv"]]>;
6245f757f3fSDimitry Andric  }
6255f757f3fSDimitry Andric  multiclass RVVFloatingReductionBuiltinRoundingMode {
6265f757f3fSDimitry Andric    defm "" : RVVOutOp0BuiltinSet<NAME, "xfd",
6275f757f3fSDimitry Andric                                  [["vs", "vSv", "SvvSvu"]]>;
6285f757f3fSDimitry Andric  }
6295f757f3fSDimitry Andric  multiclass RVVFloatingWidenReductionBuiltin {
6305f757f3fSDimitry Andric    defm "" : RVVOutOp0BuiltinSet<NAME, "xf",
6315f757f3fSDimitry Andric                                  [["vs", "vSw", "SwvSw"]]>;
6325f757f3fSDimitry Andric  }
6335f757f3fSDimitry Andric  multiclass RVVFloatingWidenReductionBuiltinRoundingMode {
6345f757f3fSDimitry Andric    defm "" : RVVOutOp0BuiltinSet<NAME, "xf",
6355f757f3fSDimitry Andric                                  [["vs", "vSw", "SwvSwu"]]>;
6365f757f3fSDimitry Andric  }
6375f757f3fSDimitry Andric}
6385f757f3fSDimitry Andric
6395f757f3fSDimitry Andricmulticlass RVVIntReductionBuiltinSet
6405f757f3fSDimitry Andric    : RVVSignedReductionBuiltin,
6415f757f3fSDimitry Andric      RVVUnsignedReductionBuiltin;
6425f757f3fSDimitry Andric
6435f757f3fSDimitry Andric// For widen operation which has different mangling name.
6445f757f3fSDimitry Andricmulticlass RVVWidenBuiltinSet<string intrinsic_name, string type_range,
6455f757f3fSDimitry Andric                              list<list<string>> suffixes_prototypes> {
6465f757f3fSDimitry Andric  let Log2LMUL = [-3, -2, -1, 0, 1, 2],
6475f757f3fSDimitry Andric      IRName = intrinsic_name, MaskedIRName = intrinsic_name # "_mask" in {
6485f757f3fSDimitry Andric    foreach s_p = suffixes_prototypes in {
6495f757f3fSDimitry Andric      let Name = NAME # "_" # s_p[0],
6505f757f3fSDimitry Andric          OverloadedName = NAME # "_" # s_p[0] in {
6515f757f3fSDimitry Andric        defvar suffix = s_p[1];
6525f757f3fSDimitry Andric        defvar prototype = s_p[2];
6535f757f3fSDimitry Andric        def : RVVOutOp0Op1Builtin<suffix, prototype, type_range>;
6545f757f3fSDimitry Andric      }
6555f757f3fSDimitry Andric    }
6565f757f3fSDimitry Andric  }
6575f757f3fSDimitry Andric}
6585f757f3fSDimitry Andric
6595f757f3fSDimitry Andric// For widen operation with widen operand which has different mangling name.
6605f757f3fSDimitry Andricmulticlass RVVWidenWOp0BuiltinSet<string intrinsic_name, string type_range,
6615f757f3fSDimitry Andric                                  list<list<string>> suffixes_prototypes> {
6625f757f3fSDimitry Andric  let Log2LMUL = [-3, -2, -1, 0, 1, 2],
6635f757f3fSDimitry Andric      IRName = intrinsic_name, MaskedIRName = intrinsic_name # "_mask" in {
6645f757f3fSDimitry Andric    foreach s_p = suffixes_prototypes in {
6655f757f3fSDimitry Andric      let Name = NAME # "_" # s_p[0],
6665f757f3fSDimitry Andric          OverloadedName = NAME # "_" # s_p[0] in {
6675f757f3fSDimitry Andric        defvar suffix = s_p[1];
6685f757f3fSDimitry Andric        defvar prototype = s_p[2];
6695f757f3fSDimitry Andric        def : RVVOutOp1Builtin<suffix, prototype, type_range>;
6705f757f3fSDimitry Andric      }
6715f757f3fSDimitry Andric    }
6725f757f3fSDimitry Andric  }
6735f757f3fSDimitry Andric}
6745f757f3fSDimitry Andric
6755f757f3fSDimitry Andricmulticlass RVVSignedWidenBinBuiltinSet
6765f757f3fSDimitry Andric    : RVVWidenBuiltinSet<NAME, "csi",
6775f757f3fSDimitry Andric                         [["vv", "w", "wvv"],
6785f757f3fSDimitry Andric                          ["vx", "w", "wve"]]>;
6795f757f3fSDimitry Andric
6805f757f3fSDimitry Andricmulticlass RVVSignedWidenOp0BinBuiltinSet
6815f757f3fSDimitry Andric    : RVVWidenWOp0BuiltinSet<NAME # "_w", "csi",
6825f757f3fSDimitry Andric                             [["wv", "w", "wwv"],
6835f757f3fSDimitry Andric                              ["wx", "w", "wwe"]]>;
6845f757f3fSDimitry Andric
6855f757f3fSDimitry Andricmulticlass RVVUnsignedWidenBinBuiltinSet
6865f757f3fSDimitry Andric    : RVVWidenBuiltinSet<NAME, "csi",
6875f757f3fSDimitry Andric                         [["vv", "Uw", "UwUvUv"],
6885f757f3fSDimitry Andric                          ["vx", "Uw", "UwUvUe"]]>;
6895f757f3fSDimitry Andric
6905f757f3fSDimitry Andricmulticlass RVVUnsignedWidenOp0BinBuiltinSet
6915f757f3fSDimitry Andric    : RVVWidenWOp0BuiltinSet<NAME # "_w", "csi",
6925f757f3fSDimitry Andric                             [["wv", "Uw", "UwUwUv"],
6935f757f3fSDimitry Andric                              ["wx", "Uw", "UwUwUe"]]>;
6945f757f3fSDimitry Andric
6955f757f3fSDimitry Andricmulticlass RVVFloatingWidenBinBuiltinSet
6965f757f3fSDimitry Andric    : RVVWidenBuiltinSet<NAME, "xf",
6975f757f3fSDimitry Andric                         [["vv", "w", "wvv"],
6985f757f3fSDimitry Andric                          ["vf", "w", "wve"]]>;
6995f757f3fSDimitry Andric
7005f757f3fSDimitry Andricmulticlass RVVFloatingWidenBinBuiltinSetRoundingMode
7015f757f3fSDimitry Andric    : RVVWidenBuiltinSet<NAME, "xf",
7025f757f3fSDimitry Andric                         [["vv", "w", "wvvu"],
7035f757f3fSDimitry Andric                          ["vf", "w", "wveu"]]>;
7045f757f3fSDimitry Andric
7055f757f3fSDimitry Andricmulticlass RVVFloatingWidenOp0BinBuiltinSet
7065f757f3fSDimitry Andric    : RVVWidenWOp0BuiltinSet<NAME # "_w", "xf",
7075f757f3fSDimitry Andric                             [["wv", "w", "wwv"],
7085f757f3fSDimitry Andric                              ["wf", "w", "wwe"]]>;
7095f757f3fSDimitry Andric
7105f757f3fSDimitry Andricmulticlass RVVFloatingWidenOp0BinBuiltinSetRoundingMode
7115f757f3fSDimitry Andric    : RVVWidenWOp0BuiltinSet<NAME # "_w", "xf",
7125f757f3fSDimitry Andric                             [["wv", "w", "wwvu"],
7135f757f3fSDimitry Andric                              ["wf", "w", "wweu"]]>;
714