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