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