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 15include "riscv_vector_common.td" 16 17defvar TypeList = ["c","s","i","l","x","f","d","y"]; 18defvar EEWList = [["8", "(Log2EEW:3)"], 19 ["16", "(Log2EEW:4)"], 20 ["32", "(Log2EEW:5)"], 21 ["64", "(Log2EEW:6)"]]; 22 23class IsFloat<string type> { 24 bit val = !or(!eq(type, "x"), !eq(type, "f"), !eq(type, "d"), !eq(type, "y")); 25} 26 27let SupportOverloading = false, 28 MaskedPolicyScheme = NonePolicy in { 29 class RVVVLEMaskBuiltin : RVVOutOp0Builtin<"m", "mPCUe", "c"> { 30 let Name = "vlm_v"; 31 let IRName = "vlm"; 32 let HasMasked = false; 33 } 34} 35 36let SupportOverloading = false, 37 UnMaskedPolicyScheme = HasPassthruOperand in { 38 multiclass RVVVLEBuiltin<list<string> types> { 39 let Name = NAME # "_v", 40 IRName = "vle", 41 MaskedIRName ="vle_mask" in { 42 foreach type = types in { 43 def : RVVOutOp0Builtin<"v", "vPCe", type>; 44 if !not(IsFloat<type>.val) then { 45 def : RVVOutOp0Builtin<"Uv", "UvPCUe", type>; 46 } 47 } 48 } 49 } 50} 51 52multiclass RVVVLEFFBuiltin<list<string> types> { 53 let Name = NAME # "_v", 54 IRName = "vleff", 55 MaskedIRName = "vleff_mask", 56 SupportOverloading = false, 57 UnMaskedPolicyScheme = HasPassthruOperand, 58 ManualCodegen = [{ 59 return emitRVVVLEFFBuiltin(this, E, ReturnValue, ResultType, ID, Ops, 60 PolicyAttrs, IsMasked, SegInstSEW); 61 }] in { 62 foreach type = types in { 63 def : RVVBuiltin<"v", "vPCePz", type>; 64 // Skip floating types for unsigned versions. 65 if !not(IsFloat<type>.val) then { 66 def : RVVBuiltin<"Uv", "UvPCUePz", type>; 67 } 68 } 69 } 70} 71 72multiclass RVVVLSEBuiltin<list<string> types> { 73 let Name = NAME # "_v", 74 IRName = "vlse", 75 MaskedIRName ="vlse_mask", 76 SupportOverloading = false, 77 UnMaskedPolicyScheme = HasPassthruOperand in { 78 foreach type = types in { 79 def : RVVOutOp0Builtin<"v", "vPCet", type>; 80 if !not(IsFloat<type>.val) then { 81 def : RVVOutOp0Builtin<"Uv", "UvPCUet", type>; 82 } 83 } 84 } 85} 86 87multiclass RVVIndexedLoad<string op> { 88 let UnMaskedPolicyScheme = HasPassthruOperand in { 89 foreach type = TypeList in { 90 foreach eew_list = EEWList[0-2] in { 91 defvar eew = eew_list[0]; 92 defvar eew_type = eew_list[1]; 93 let Name = op # eew # "_v", IRName = op, MaskedIRName = op # "_mask" in { 94 def: RVVOutOp0Op1Builtin<"v", "vPCe" # eew_type # "Uv", type>; 95 if !not(IsFloat<type>.val) then { 96 def: RVVOutOp0Op1Builtin<"Uv", "UvPCUe" # eew_type # "Uv", type>; 97 } 98 } 99 } 100 defvar eew64 = "64"; 101 defvar eew64_type = "(Log2EEW:6)"; 102 let Name = op # eew64 # "_v", IRName = op, MaskedIRName = op # "_mask", 103 RequiredFeatures = ["64bit"] in { 104 def: RVVOutOp0Op1Builtin<"v", "vPCe" # eew64_type # "Uv", type>; 105 if !not(IsFloat<type>.val) then { 106 def: RVVOutOp0Op1Builtin<"Uv", "UvPCUe" # eew64_type # "Uv", type>; 107 } 108 } 109 } 110 } 111} 112 113let HasMaskedOffOperand = false, 114 MaskedPolicyScheme = NonePolicy, 115 ManualCodegen = [{ 116 return emitRVVVSEMaskBuiltin(this, E, ReturnValue, ResultType, ID, Ops, 117 PolicyAttrs, IsMasked, SegInstSEW); 118 }] in { 119 class RVVVSEMaskBuiltin : RVVBuiltin<"m", "0PUem", "c"> { 120 let Name = "vsm_v"; 121 let IRName = "vsm"; 122 let HasMasked = false; 123 } 124 multiclass RVVVSEBuiltin<list<string> types> { 125 let Name = NAME # "_v", 126 IRName = "vse", 127 MaskedIRName = "vse_mask" in { 128 foreach type = types in { 129 def : RVVBuiltin<"v", "0Pev", type>; 130 if !not(IsFloat<type>.val) then { 131 def : RVVBuiltin<"Uv", "0PUeUv", type>; 132 } 133 } 134 } 135 } 136} 137 138multiclass RVVVSSEBuiltin<list<string> types> { 139 let Name = NAME # "_v", 140 IRName = "vsse", 141 MaskedIRName = "vsse_mask", 142 HasMaskedOffOperand = false, 143 MaskedPolicyScheme = NonePolicy, 144 ManualCodegen = [{ 145 return emitRVVVSSEBuiltin(this, E, ReturnValue, ResultType, ID, Ops, 146 PolicyAttrs, IsMasked, SegInstSEW); 147 }] in { 148 foreach type = types in { 149 def : RVVBuiltin<"v", "0Petv", type>; 150 if !not(IsFloat<type>.val) then { 151 def : RVVBuiltin<"Uv", "0PUetUv", type>; 152 } 153 } 154 } 155} 156 157multiclass RVVIndexedStore<string op> { 158 let HasMaskedOffOperand = false, 159 MaskedPolicyScheme = NonePolicy, 160 ManualCodegen = [{ 161 return emitRVVIndexedStoreBuiltin(this, E, ReturnValue, ResultType, ID, 162 Ops, PolicyAttrs, IsMasked, SegInstSEW); 163 }] in { 164 foreach type = TypeList in { 165 foreach eew_list = EEWList[0-2] in { 166 defvar eew = eew_list[0]; 167 defvar eew_type = eew_list[1]; 168 let Name = op # eew # "_v", IRName = op, MaskedIRName = op # "_mask" in { 169 def : RVVBuiltin<"v", "0Pe" # eew_type # "Uvv", type>; 170 if !not(IsFloat<type>.val) then { 171 def : RVVBuiltin<"Uv", "0PUe" # eew_type # "UvUv", type>; 172 } 173 } 174 } 175 defvar eew64 = "64"; 176 defvar eew64_type = "(Log2EEW:6)"; 177 let Name = op # eew64 # "_v", IRName = op, MaskedIRName = op # "_mask", 178 RequiredFeatures = ["64bit"] in { 179 def : RVVBuiltin<"v", "0Pe" # eew64_type # "Uvv", type>; 180 if !not(IsFloat<type>.val) then { 181 def : RVVBuiltin<"Uv", "0PUe" # eew64_type # "UvUv", type>; 182 } 183 } 184 } 185 } 186} 187 188defvar NFList = [2, 3, 4, 5, 6, 7, 8]; 189/* 190A segment load builtin has different variants. 191 192Therefore a segment unit-stride load builtin can have 4 variants, 1931. When unmasked and the policies are all specified as agnostic: 194(Address0, ..., Address{NF - 1}, Ptr, VL) 1952. When masked and the policies are all specified as agnostic: 196(Address0, ..., Address{NF - 1}, Mask, Ptr, VL) 1973. When unmasked and one of the policies is specified as undisturbed: 198(Address0, ..., Address{NF - 1}, Maskedoff0, ..., Maskedoff{NF - 1}, 199 Ptr, VL) 2004. When masked and one of the policies is specified as undisturbed: 201(Address0, ..., Address{NF - 1}, Mask, Maskedoff0, ..., Maskedoff{NF - 1}, 202 Ptr, VL) 203 204Other variants of segment load builtin share the same structure, but they 205have their own extra parameter. 206 207The segment unit-stride fault-only-first load builtin has a 'NewVL' 208operand after the 'Ptr' operand. 2091. When unmasked and the policies are all specified as agnostic: 210(Address0, ..., Address{NF - 1}, Ptr, NewVL, VL) 2112. When masked and the policies are all specified as agnostic: 212(Address0, ..., Address{NF - 1}, Mask, Ptr, NewVL, VL) 2133. When unmasked and one of the policies is specified as undisturbed: 214(Address0, ..., Address{NF - 1}, Maskedoff0, ..., Maskedoff{NF - 1}, 215 Ptr, NewVL, VL) 2164. When masked and one of the policies is specified as undisturbed: 217(Address0, ..., Address{NF - 1}, Mask, Maskedoff0, ..., Maskedoff{NF - 1}, 218 Ptr, NewVL, VL) 219 220The segment strided load builtin has a 'Stride' operand after the 'Ptr' 221operand. 2221. When unmasked and the policies are all specified as agnostic: 223(Address0, ..., Address{NF - 1}, Ptr, Stride, VL) 2242. When masked and the policies are all specified as agnostic: 225(Address0, ..., Address{NF - 1}, Mask, Ptr, Stride, VL) 2263. When unmasked and one of the policies is specified as undisturbed: 227(Address0, ..., Address{NF - 1}, Maskedoff0, ..., Maskedoff{NF - 1}, 228 Ptr, Stride, VL) 2294. When masked and one of the policies is specified as undisturbed: 230(Address0, ..., Address{NF - 1}, Mask, Maskedoff0, ..., Maskedoff{NF - 1}, 231 Ptr, Stride, VL) 232 233The segment indexed load builtin has a 'Idx' operand after the 'Ptr' operand. 2341. When unmasked and the policies are all specified as agnostic: 235(Address0, ..., Address{NF - 1}, Ptr, Idx, VL) 2362. When masked and the policies are all specified as agnostic: 237(Address0, ..., Address{NF - 1}, Mask, Ptr, Idx, VL) 2383. When unmasked and one of the policies is specified as undisturbed: 239(Address0, ..., Address{NF - 1}, Maskedoff0, ..., Maskedoff{NF - 1}, 240 Ptr, Idx, VL) 2414. When masked and one of the policies is specified as undisturbed: 242(Address0, ..., Address{NF - 1}, Mask, Maskedoff0, ..., Maskedoff{NF - 1}, 243 Ptr, Idx, VL) 244 245Segment load intrinsics has different variants similar to their builtins. 246 247Segment unit-stride load intrinsic, 248 Masked: (Vector0, ..., Vector{NF - 1}, Ptr, Mask, VL, Policy) 249 Unmasked: (Vector0, ..., Vector{NF - 1}, Ptr, VL) 250Segment unit-stride fault-only-first load intrinsic, 251 Masked: (Vector0, ..., Vector{NF - 1}, Ptr, Mask, VL, Policy) 252 Unmasked: (Vector0, ..., Vector{NF - 1}, Ptr, VL) 253Segment strided load intrinsic, 254 Masked: (Vector0, ..., Vector{NF - 1}, Ptr, Stride, Mask, VL, Policy) 255 Unmasked: (Vector0, ..., Vector{NF - 1}, Ptr, Stride, VL) 256Segment indexed load intrinsic, 257 Masked: (Vector0, ..., Vector{NF - 1}, Ptr, Index, Mask, VL, Policy) 258 Unmasked: (Vector0, ..., Vector{NF - 1}, Ptr, Index, VL) 259 260The Vector(s) is poison when the policy behavior allows us to not care 261about any masked-off elements. 262*/ 263 264class PVString<int nf, bit signed> { 265 string S = 266 !cond(!eq(nf, 2): !if(signed, "PvPv", "PUvPUv"), 267 !eq(nf, 3): !if(signed, "PvPvPv", "PUvPUvPUv"), 268 !eq(nf, 4): !if(signed, "PvPvPvPv", "PUvPUvPUvPUv"), 269 !eq(nf, 5): !if(signed, "PvPvPvPvPv", "PUvPUvPUvPUvPUv"), 270 !eq(nf, 6): !if(signed, "PvPvPvPvPvPv", "PUvPUvPUvPUvPUvPUv"), 271 !eq(nf, 7): !if(signed, "PvPvPvPvPvPvPv", "PUvPUvPUvPUvPUvPUvPUv"), 272 !eq(nf, 8): !if(signed, "PvPvPvPvPvPvPvPv", "PUvPUvPUvPUvPUvPUvPUvPUv")); 273} 274 275class VString<int nf, bit signed> { 276 string S = !cond(!eq(nf, 2): !if(signed, "vv", "UvUv"), 277 !eq(nf, 3): !if(signed, "vvv", "UvUvUv"), 278 !eq(nf, 4): !if(signed, "vvvv", "UvUvUvUv"), 279 !eq(nf, 5): !if(signed, "vvvvv", "UvUvUvUvUv"), 280 !eq(nf, 6): !if(signed, "vvvvvv", "UvUvUvUvUvUv"), 281 !eq(nf, 7): !if(signed, "vvvvvvv", "UvUvUvUvUvUvUv"), 282 !eq(nf, 8): !if(signed, "vvvvvvvv", "UvUvUvUvUvUvUvUv")); 283} 284 285 286class FixedVString<int fixed_lmul, int num, string vec> { 287 string V = "(LFixedLog2LMUL:" # fixed_lmul # ")" # vec; 288 string S = !interleave(!listsplat(V, num), ""); 289} 290 291multiclass RVVNonTupleVCreateBuiltin<int dst_lmul, list<int> src_lmul_list> { 292 defvar dst_v = FixedVString<dst_lmul, 1, "v">.V; 293 defvar dst_uv = FixedVString<dst_lmul, 1, "Uv">.V; 294 foreach src_lmul = src_lmul_list in { 295 defvar num = !shl(1, !sub(dst_lmul, src_lmul)); 296 297 defvar src_v = FixedVString<src_lmul, num, "v">.V; 298 defvar src_s = FixedVString<src_lmul, num, "v">.S; 299 def vcreate # src_v # dst_v : RVVBuiltin<src_v # dst_v, 300 dst_v # src_s, 301 "csilxfdy">; 302 303 defvar src_uv = FixedVString<src_lmul, num, "Uv">.V; 304 defvar src_us = FixedVString<src_lmul, num, "Uv">.S; 305 def vcreate_u # src_uv # dst_uv : RVVBuiltin<src_uv # dst_uv, 306 dst_uv # src_us, 307 "csil">; 308 } 309} 310 311multiclass RVVPseudoUnaryBuiltin<string IR, string type_range> { 312 let Name = NAME, 313 IRName = IR, 314 MaskedIRName = IR # "_mask", 315 UnMaskedPolicyScheme = HasPassthruOperand, 316 ManualCodegen = [{ 317 return emitRVVPseudoUnaryBuiltin(this, E, ReturnValue, ResultType, ID, 318 Ops, PolicyAttrs, IsMasked, SegInstSEW); 319 }] in { 320 def : RVVBuiltin<"v", "vv", type_range>; 321 } 322} 323 324multiclass RVVPseudoVNotBuiltin<string IR, string type_range> { 325 let Name = NAME, 326 IRName = IR, 327 MaskedIRName = IR # "_mask", 328 UnMaskedPolicyScheme = HasPassthruOperand, 329 ManualCodegen = [{ 330 return emitRVVPseudoVNotBuiltin(this, E, ReturnValue, ResultType, ID, 331 Ops, PolicyAttrs, IsMasked, SegInstSEW); 332 }] in { 333 def : RVVBuiltin<"v", "vv", type_range>; 334 def : RVVBuiltin<"Uv", "UvUv", type_range>; 335 } 336} 337 338multiclass RVVPseudoMaskBuiltin<string IR, string type_range> { 339 let Name = NAME, 340 IRName = IR, 341 HasMasked = false, 342 ManualCodegen = [{ 343 return emitRVVPseudoMaskBuiltin(this, E, ReturnValue, ResultType, ID, 344 Ops, PolicyAttrs, IsMasked, SegInstSEW); 345 }] in { 346 def : RVVBuiltin<"m", "mm", type_range>; 347 } 348} 349 350multiclass RVVPseudoVFUnaryBuiltin<string IR, string type_range> { 351 let Name = NAME, 352 IRName = IR, 353 MaskedIRName = IR # "_mask", 354 UnMaskedPolicyScheme = HasPassthruOperand, 355 ManualCodegen = [{ 356 return emitRVVPseudoVFUnaryBuiltin(this, E, ReturnValue, ResultType, ID, 357 Ops, PolicyAttrs, IsMasked, SegInstSEW); 358 }] in { 359 def : RVVBuiltin<"v", "vv", type_range>; 360 } 361} 362 363multiclass RVVPseudoVWCVTBuiltin<string IR, string MName, string type_range, 364 list<list<string>> suffixes_prototypes> { 365 let Name = NAME, 366 OverloadedName = MName, 367 IRName = IR, 368 MaskedIRName = IR # "_mask", 369 UnMaskedPolicyScheme = HasPassthruOperand, 370 ManualCodegen = [{ 371 return emitRVVPseudoVWCVTBuiltin(this, E, ReturnValue, ResultType, ID, 372 Ops, PolicyAttrs, IsMasked, SegInstSEW); 373 }] in { 374 foreach s_p = suffixes_prototypes in { 375 def : RVVBuiltin<s_p[0], s_p[1], type_range>; 376 } 377 } 378} 379 380multiclass RVVPseudoVNCVTBuiltin<string IR, string MName, string type_range, 381 list<list<string>> suffixes_prototypes> { 382 let Name = NAME, 383 OverloadedName = MName, 384 IRName = IR, 385 MaskedIRName = IR # "_mask", 386 UnMaskedPolicyScheme = HasPassthruOperand, 387 ManualCodegen = [{ 388 return emitRVVPseudoVNCVTBuiltin(this, E, ReturnValue, ResultType, ID, 389 Ops, PolicyAttrs, IsMasked, SegInstSEW); 390 }] in { 391 foreach s_p = suffixes_prototypes in { 392 def : RVVBuiltin<s_p[0], s_p[1], type_range>; 393 } 394 } 395} 396 397let HeaderCode = 398[{ 399#define __riscv_vlenb() __builtin_rvv_vlenb() 400}] in 401def vlenb_macro: RVVHeader; 402 403let HasBuiltinAlias = false, HasVL = false, HasMasked = false, 404 UnMaskedPolicyScheme = NonePolicy, MaskedPolicyScheme = NonePolicy, 405 Log2LMUL = [0], IRName = "", 406 ManualCodegen = [{ 407 return emitRVVVlenbBuiltin(this, E, ReturnValue, ResultType, ID, Ops, 408 PolicyAttrs, IsMasked, SegInstSEW); 409 }] in 410{ 411 def vlenb : RVVBuiltin<"", "u", "i">; 412} 413 414// 6. Configuration-Setting Instructions 415// 6.1. vsetvli/vsetvl instructions 416 417// vsetvl/vsetvlmax are a macro because they require constant integers in SEW 418// and LMUL. 419let HeaderCode = 420[{ 421#define __riscv_vsetvl_e8mf4(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 6) 422#define __riscv_vsetvl_e8mf2(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 7) 423#define __riscv_vsetvl_e8m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 0) 424#define __riscv_vsetvl_e8m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 1) 425#define __riscv_vsetvl_e8m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 2) 426#define __riscv_vsetvl_e8m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 3) 427 428#define __riscv_vsetvl_e16mf2(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 7) 429#define __riscv_vsetvl_e16m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 0) 430#define __riscv_vsetvl_e16m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 1) 431#define __riscv_vsetvl_e16m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 2) 432#define __riscv_vsetvl_e16m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 3) 433 434#define __riscv_vsetvl_e32m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 0) 435#define __riscv_vsetvl_e32m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 1) 436#define __riscv_vsetvl_e32m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 2) 437#define __riscv_vsetvl_e32m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 3) 438 439#define __riscv_vsetvl_e8mf8(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 5) 440#define __riscv_vsetvl_e16mf4(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 6) 441#define __riscv_vsetvl_e32mf2(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 7) 442 443#define __riscv_vsetvl_e64m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 0) 444#define __riscv_vsetvl_e64m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 1) 445#define __riscv_vsetvl_e64m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 2) 446#define __riscv_vsetvl_e64m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 3) 447 448#define __riscv_vsetvlmax_e8mf4() __builtin_rvv_vsetvlimax(0, 6) 449#define __riscv_vsetvlmax_e8mf2() __builtin_rvv_vsetvlimax(0, 7) 450#define __riscv_vsetvlmax_e8m1() __builtin_rvv_vsetvlimax(0, 0) 451#define __riscv_vsetvlmax_e8m2() __builtin_rvv_vsetvlimax(0, 1) 452#define __riscv_vsetvlmax_e8m4() __builtin_rvv_vsetvlimax(0, 2) 453#define __riscv_vsetvlmax_e8m8() __builtin_rvv_vsetvlimax(0, 3) 454 455#define __riscv_vsetvlmax_e16mf2() __builtin_rvv_vsetvlimax(1, 7) 456#define __riscv_vsetvlmax_e16m1() __builtin_rvv_vsetvlimax(1, 0) 457#define __riscv_vsetvlmax_e16m2() __builtin_rvv_vsetvlimax(1, 1) 458#define __riscv_vsetvlmax_e16m4() __builtin_rvv_vsetvlimax(1, 2) 459#define __riscv_vsetvlmax_e16m8() __builtin_rvv_vsetvlimax(1, 3) 460 461#define __riscv_vsetvlmax_e32m1() __builtin_rvv_vsetvlimax(2, 0) 462#define __riscv_vsetvlmax_e32m2() __builtin_rvv_vsetvlimax(2, 1) 463#define __riscv_vsetvlmax_e32m4() __builtin_rvv_vsetvlimax(2, 2) 464#define __riscv_vsetvlmax_e32m8() __builtin_rvv_vsetvlimax(2, 3) 465 466#define __riscv_vsetvlmax_e8mf8() __builtin_rvv_vsetvlimax(0, 5) 467#define __riscv_vsetvlmax_e16mf4() __builtin_rvv_vsetvlimax(1, 6) 468#define __riscv_vsetvlmax_e32mf2() __builtin_rvv_vsetvlimax(2, 7) 469 470#define __riscv_vsetvlmax_e64m1() __builtin_rvv_vsetvlimax(3, 0) 471#define __riscv_vsetvlmax_e64m2() __builtin_rvv_vsetvlimax(3, 1) 472#define __riscv_vsetvlmax_e64m4() __builtin_rvv_vsetvlimax(3, 2) 473#define __riscv_vsetvlmax_e64m8() __builtin_rvv_vsetvlimax(3, 3) 474 475}] in 476def vsetvl_macro: RVVHeader; 477 478let HasBuiltinAlias = false, 479 HasVL = false, 480 HasMasked = false, 481 MaskedPolicyScheme = NonePolicy, 482 Log2LMUL = [0], 483 ManualCodegen = [{ 484 return emitRVVVsetvliBuiltin(this, E, ReturnValue, ResultType, ID, Ops, 485 PolicyAttrs, IsMasked, SegInstSEW); 486 }] in // Set XLEN type 487{ 488 def vsetvli : RVVBuiltin<"", "zzKzKz", "i">; 489 def vsetvlimax : RVVBuiltin<"", "zKzKz", "i">; 490} 491 492// 7. Vector Loads and Stores 493// 7.4. Vector Unit-Stride Instructions 494def vlm: RVVVLEMaskBuiltin; 495defm vle8: RVVVLEBuiltin<["c"]>; 496defm vle16: RVVVLEBuiltin<["s","x","y"]>; 497defm vle32: RVVVLEBuiltin<["i","f"]>; 498defm vle64: RVVVLEBuiltin<["l","d"]>; 499 500def vsm : RVVVSEMaskBuiltin; 501defm vse8 : RVVVSEBuiltin<["c"]>; 502defm vse16: RVVVSEBuiltin<["s","x","y"]>; 503defm vse32: RVVVSEBuiltin<["i","f"]>; 504defm vse64: RVVVSEBuiltin<["l","d"]>; 505 506// 7.5. Vector Strided Instructions 507defm vlse8: RVVVLSEBuiltin<["c"]>; 508defm vlse16: RVVVLSEBuiltin<["s","x","y"]>; 509defm vlse32: RVVVLSEBuiltin<["i","f"]>; 510defm vlse64: RVVVLSEBuiltin<["l","d"]>; 511 512defm vsse8 : RVVVSSEBuiltin<["c"]>; 513defm vsse16: RVVVSSEBuiltin<["s","x","y"]>; 514defm vsse32: RVVVSSEBuiltin<["i","f"]>; 515defm vsse64: RVVVSSEBuiltin<["l","d"]>; 516 517// 7.6. Vector Indexed Instructions 518defm : RVVIndexedLoad<"vluxei">; 519defm : RVVIndexedLoad<"vloxei">; 520 521defm : RVVIndexedStore<"vsuxei">; 522defm : RVVIndexedStore<"vsoxei">; 523 524// 7.7. Unit-stride Fault-Only-First Loads 525defm vle8ff: RVVVLEFFBuiltin<["c"]>; 526defm vle16ff: RVVVLEFFBuiltin<["s","x","y"]>; 527defm vle32ff: RVVVLEFFBuiltin<["i", "f"]>; 528defm vle64ff: RVVVLEFFBuiltin<["l", "d"]>; 529 530multiclass RVVUnitStridedSegLoadTuple<string op> { 531 foreach type = TypeList in { 532 defvar eew = !cond(!eq(type, "c") : "8", 533 !eq(type, "s") : "16", 534 !eq(type, "i") : "32", 535 !eq(type, "l") : "64", 536 !eq(type, "x") : "16", 537 !eq(type, "f") : "32", 538 !eq(type, "d") : "64", 539 !eq(type, "y") : "16"); 540 foreach nf = NFList in { 541 let Name = op # nf # "e" # eew # "_v", 542 IRName = op # nf, 543 MaskedIRName = op # nf # "_mask", 544 NF = nf, 545 ManualCodegen = [{ 546 return emitRVVUnitStridedSegLoadTupleBuiltin( 547 this, E, ReturnValue, ResultType, ID, Ops, PolicyAttrs, 548 IsMasked, SegInstSEW); 549 }] in { 550 defvar T = "(Tuple:" # nf # ")"; 551 def : RVVBuiltin<T # "v", T # "vPCe", type>; 552 if !not(IsFloat<type>.val) then { 553 def : RVVBuiltin<T # "Uv", T # "UvPCUe", type>; 554 } 555 } 556 } 557 } 558} 559 560multiclass RVVUnitStridedSegStoreTuple<string op> { 561 foreach type = TypeList in { 562 defvar eew = !cond(!eq(type, "c") : "8", 563 !eq(type, "s") : "16", 564 !eq(type, "i") : "32", 565 !eq(type, "l") : "64", 566 !eq(type, "x") : "16", 567 !eq(type, "f") : "32", 568 !eq(type, "d") : "64", 569 !eq(type, "y") : "16"); 570 foreach nf = NFList in { 571 let Name = op # nf # "e" # eew # "_v", 572 IRName = op # nf, 573 MaskedIRName = op # nf # "_mask", 574 NF = nf, 575 HasMaskedOffOperand = false, 576 ManualCodegen = [{ 577 return emitRVVUnitStridedSegStoreTupleBuiltin( 578 this, E, ReturnValue, ResultType, ID, Ops, PolicyAttrs, 579 IsMasked, SegInstSEW); 580 }] in { 581 defvar T = "(Tuple:" # nf # ")"; 582 def : RVVBuiltin<T # "v", "0Pe" # T # "v", type>; 583 if !not(IsFloat<type>.val) then { 584 def : RVVBuiltin<T # "Uv", "0PUe" # T # "Uv", type>; 585 } 586 } 587 } 588 } 589} 590 591multiclass RVVUnitStridedSegLoadFFTuple<string op> { 592 foreach type = TypeList in { 593 defvar eew = !cond(!eq(type, "c") : "8", 594 !eq(type, "s") : "16", 595 !eq(type, "i") : "32", 596 !eq(type, "l") : "64", 597 !eq(type, "x") : "16", 598 !eq(type, "f") : "32", 599 !eq(type, "d") : "64", 600 !eq(type, "y") : "16"); 601 foreach nf = NFList in { 602 let Name = op # nf # "e" # eew # "ff_v", 603 IRName = op # nf # "ff", 604 MaskedIRName = op # nf # "ff_mask", 605 NF = nf, 606 ManualCodegen = [{ 607 return emitRVVUnitStridedSegLoadFFTupleBuiltin( 608 this, E, ReturnValue, ResultType, ID, Ops, PolicyAttrs, IsMasked, 609 SegInstSEW); 610 }] in { 611 defvar T = "(Tuple:" # nf # ")"; 612 def : RVVBuiltin<T # "v", T # "vPCePz", type>; 613 if !not(IsFloat<type>.val) then { 614 def : RVVBuiltin<T # "Uv", T # "UvPCUePz", type>; 615 } 616 } 617 } 618 } 619} 620 621multiclass RVVStridedSegLoadTuple<string op> { 622 foreach type = TypeList in { 623 defvar eew = !cond(!eq(type, "c") : "8", 624 !eq(type, "s") : "16", 625 !eq(type, "i") : "32", 626 !eq(type, "l") : "64", 627 !eq(type, "x") : "16", 628 !eq(type, "f") : "32", 629 !eq(type, "d") : "64", 630 !eq(type, "y") : "16"); 631 foreach nf = NFList in { 632 let Name = op # nf # "e" # eew # "_v", 633 IRName = op # nf, 634 MaskedIRName = op # nf # "_mask", 635 NF = nf, 636 ManualCodegen = [{ 637 return emitRVVStridedSegLoadTupleBuiltin( 638 this, E, ReturnValue, ResultType, ID, Ops, PolicyAttrs, IsMasked, 639 SegInstSEW); 640 }] in { 641 defvar T = "(Tuple:" # nf # ")"; 642 def : RVVBuiltin<T # "v", T # "vPCet", type>; 643 if !not(IsFloat<type>.val) then { 644 def : RVVBuiltin<T # "Uv", T # "UvPCUet", type>; 645 } 646 } 647 } 648 } 649} 650 651multiclass RVVStridedSegStoreTuple<string op> { 652 foreach type = TypeList in { 653 defvar eew = !cond(!eq(type, "c") : "8", 654 !eq(type, "s") : "16", 655 !eq(type, "i") : "32", 656 !eq(type, "l") : "64", 657 !eq(type, "x") : "16", 658 !eq(type, "f") : "32", 659 !eq(type, "d") : "64", 660 !eq(type, "y") : "16"); 661 foreach nf = NFList in { 662 let Name = op # nf # "e" # eew # "_v", 663 IRName = op # nf, 664 MaskedIRName = op # nf # "_mask", 665 NF = nf, 666 HasMaskedOffOperand = false, 667 MaskedPolicyScheme = NonePolicy, 668 ManualCodegen = [{ 669 return emitRVVStridedSegStoreTupleBuiltin( 670 this, E, ReturnValue, ResultType, ID, Ops, PolicyAttrs, IsMasked, 671 SegInstSEW); 672 }] in { 673 defvar T = "(Tuple:" # nf # ")"; 674 def : RVVBuiltin<T # "v", "0Pet" # T # "v", type>; 675 if !not(IsFloat<type>.val) then { 676 def : RVVBuiltin<T # "Uv", "0PUet" # T # "Uv", type>; 677 } 678 } 679 } 680 } 681} 682 683multiclass RVVIndexedSegLoadTuple<string op> { 684 foreach type = TypeList in { 685 foreach eew_info = EEWList in { 686 defvar eew = eew_info[0]; 687 defvar eew_type = eew_info[1]; 688 foreach nf = NFList in { 689 let Name = op # nf # "ei" # eew # "_v", 690 IRName = op # nf, 691 MaskedIRName = op # nf # "_mask", 692 NF = nf, 693 ManualCodegen = [{ 694 return emitRVVIndexedSegLoadTupleBuiltin( 695 this, E, ReturnValue, ResultType, ID, Ops, PolicyAttrs, IsMasked, 696 SegInstSEW); 697 }] in { 698 defvar T = "(Tuple:" # nf # ")"; 699 def : RVVBuiltin<T # "v", T # "vPCe" # eew_type # "Uv", type>; 700 if !not(IsFloat<type>.val) then { 701 def : RVVBuiltin<T # "Uv", T # "UvPCUe" # eew_type # "Uv", type>; 702 } 703 } 704 } 705 } 706 } 707} 708 709multiclass RVVIndexedSegStoreTuple<string op> { 710 foreach type = TypeList in { 711 foreach eew_info = EEWList in { 712 defvar eew = eew_info[0]; 713 defvar eew_type = eew_info[1]; 714 foreach nf = NFList in { 715 let Name = op # nf # "ei" # eew # "_v", 716 IRName = op # nf, 717 MaskedIRName = op # nf # "_mask", 718 NF = nf, 719 HasMaskedOffOperand = false, 720 MaskedPolicyScheme = NonePolicy, 721 ManualCodegen = [{ 722 return emitRVVIndexedSegStoreTupleBuiltin( 723 this, E, ReturnValue, ResultType, ID, Ops, PolicyAttrs, IsMasked, 724 SegInstSEW); 725 }] in { 726 defvar T = "(Tuple:" # nf # ")"; 727 def : RVVBuiltin<T # "v", "0Pe" # eew_type # "Uv" # T # "v", type>; 728 if !not(IsFloat<type>.val) then { 729 def : RVVBuiltin<T # "Uv", "0PUe" # eew_type # "Uv" # T # "Uv", type>; 730 } 731 } 732 } 733 } 734 } 735} 736 737// 7.8 Vector Load/Store Segment Instructions 738let UnMaskedPolicyScheme = HasPassthruOperand, 739 IsTuple = true in { 740 defm : RVVUnitStridedSegLoadTuple<"vlseg">; 741 defm : RVVUnitStridedSegLoadFFTuple<"vlseg">; 742 defm : RVVStridedSegLoadTuple<"vlsseg">; 743 defm : RVVIndexedSegLoadTuple<"vluxseg">; 744 defm : RVVIndexedSegLoadTuple<"vloxseg">; 745} 746 747let UnMaskedPolicyScheme = NonePolicy, 748 MaskedPolicyScheme = NonePolicy, 749 IsTuple = true in { 750defm : RVVUnitStridedSegStoreTuple<"vsseg">; 751defm : RVVStridedSegStoreTuple<"vssseg">; 752defm : RVVIndexedSegStoreTuple<"vsuxseg">; 753defm : RVVIndexedSegStoreTuple<"vsoxseg">; 754} 755 756// 11. Vector Integer Arithmetic Instructions 757// 11.1. Vector Single-Width Integer Add and Subtract 758let UnMaskedPolicyScheme = HasPassthruOperand in { 759defm vadd : RVVIntBinBuiltinSet; 760defm vsub : RVVIntBinBuiltinSet; 761defm vrsub : RVVOutOp1BuiltinSet<"vrsub", "csil", 762 [["vx", "v", "vve"], 763 ["vx", "Uv", "UvUvUe"]]>; 764} 765defm vneg_v : RVVPseudoUnaryBuiltin<"vrsub", "csil">; 766 767// 11.2. Vector Widening Integer Add/Subtract 768// Widening unsigned integer add/subtract, 2*SEW = SEW +/- SEW 769let UnMaskedPolicyScheme = HasPassthruOperand in { 770defm vwaddu : RVVUnsignedWidenBinBuiltinSet; 771defm vwsubu : RVVUnsignedWidenBinBuiltinSet; 772// Widening signed integer add/subtract, 2*SEW = SEW +/- SEW 773defm vwadd : RVVSignedWidenBinBuiltinSet; 774defm vwsub : RVVSignedWidenBinBuiltinSet; 775// Widening unsigned integer add/subtract, 2*SEW = 2*SEW +/- SEW 776defm vwaddu : RVVUnsignedWidenOp0BinBuiltinSet; 777defm vwsubu : RVVUnsignedWidenOp0BinBuiltinSet; 778// Widening signed integer add/subtract, 2*SEW = 2*SEW +/- SEW 779defm vwadd : RVVSignedWidenOp0BinBuiltinSet; 780defm vwsub : RVVSignedWidenOp0BinBuiltinSet; 781} 782defm vwcvtu_x_x_v : RVVPseudoVWCVTBuiltin<"vwaddu", "vwcvtu_x", "csi", 783 [["Uw", "UwUv"]]>; 784defm vwcvt_x_x_v : RVVPseudoVWCVTBuiltin<"vwadd", "vwcvt_x", "csi", 785 [["w", "wv"]]>; 786 787// 11.3. Vector Integer Extension 788let UnMaskedPolicyScheme = HasPassthruOperand in { 789let Log2LMUL = [-3, -2, -1, 0, 1, 2] in { 790 def vsext_vf2 : RVVIntExt<"vsext", "w", "wv", "csi">; 791 def vzext_vf2 : RVVIntExt<"vzext", "Uw", "UwUv", "csi">; 792} 793let Log2LMUL = [-3, -2, -1, 0, 1] in { 794 def vsext_vf4 : RVVIntExt<"vsext", "q", "qv", "cs">; 795 def vzext_vf4 : RVVIntExt<"vzext", "Uq", "UqUv", "cs">; 796} 797let Log2LMUL = [-3, -2, -1, 0] in { 798 def vsext_vf8 : RVVIntExt<"vsext", "o", "ov", "c">; 799 def vzext_vf8 : RVVIntExt<"vzext", "Uo", "UoUv", "c">; 800} 801} 802 803// 11.4. Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions 804let HasMasked = false, MaskedPolicyScheme = NonePolicy in { 805 let UnMaskedPolicyScheme = HasPassthruOperand in { 806 defm vadc : RVVCarryinBuiltinSet; 807 defm vsbc : RVVCarryinBuiltinSet; 808 } 809 defm vmadc : RVVCarryOutInBuiltinSet<"vmadc_carry_in">; 810 defm vmadc : RVVIntMaskOutBuiltinSet; 811 defm vmsbc : RVVCarryOutInBuiltinSet<"vmsbc_borrow_in">; 812 defm vmsbc : RVVIntMaskOutBuiltinSet; 813} 814 815// 11.5. Vector Bitwise Logical Instructions 816let UnMaskedPolicyScheme = HasPassthruOperand in { 817defm vand : RVVIntBinBuiltinSet; 818defm vxor : RVVIntBinBuiltinSet; 819defm vor : RVVIntBinBuiltinSet; 820} 821defm vnot_v : RVVPseudoVNotBuiltin<"vxor", "csil">; 822 823// 11.6. Vector Single-Width Shift Instructions 824let UnMaskedPolicyScheme = HasPassthruOperand in { 825defm vsll : RVVShiftBuiltinSet; 826defm vsrl : RVVUnsignedShiftBuiltinSet; 827defm vsra : RVVSignedShiftBuiltinSet; 828 829// 11.7. Vector Narrowing Integer Right Shift Instructions 830defm vnsrl : RVVUnsignedNShiftBuiltinSet; 831defm vnsra : RVVSignedNShiftBuiltinSet; 832} 833defm vncvt_x_x_w : RVVPseudoVNCVTBuiltin<"vnsrl", "vncvt_x", "csi", 834 [["v", "vw"], 835 ["Uv", "UvUw"]]>; 836 837// 11.8. Vector Integer Compare Instructions 838let MaskedPolicyScheme = HasPassthruOperand, 839 HasTailPolicy = false in { 840defm vmseq : RVVIntMaskOutBuiltinSet; 841defm vmsne : RVVIntMaskOutBuiltinSet; 842defm vmsltu : RVVUnsignedMaskOutBuiltinSet; 843defm vmslt : RVVSignedMaskOutBuiltinSet; 844defm vmsleu : RVVUnsignedMaskOutBuiltinSet; 845defm vmsle : RVVSignedMaskOutBuiltinSet; 846defm vmsgtu : RVVUnsignedMaskOutBuiltinSet; 847defm vmsgt : RVVSignedMaskOutBuiltinSet; 848defm vmsgeu : RVVUnsignedMaskOutBuiltinSet; 849defm vmsge : RVVSignedMaskOutBuiltinSet; 850} 851 852// 11.9. Vector Integer Min/Max Instructions 853let UnMaskedPolicyScheme = HasPassthruOperand in { 854defm vminu : RVVUnsignedBinBuiltinSet; 855defm vmin : RVVSignedBinBuiltinSet; 856defm vmaxu : RVVUnsignedBinBuiltinSet; 857defm vmax : RVVSignedBinBuiltinSet; 858 859// 11.10. Vector Single-Width Integer Multiply Instructions 860defm vmul : RVVIntBinBuiltinSet; 861defm vmulh : RVVSignedBinBuiltinSet; 862defm vmulhu : RVVUnsignedBinBuiltinSet; 863defm vmulhsu : RVVOutOp1BuiltinSet<"vmulhsu", "csil", 864 [["vv", "v", "vvUv"], 865 ["vx", "v", "vvUe"]]>; 866 867// 11.11. Vector Integer Divide Instructions 868defm vdivu : RVVUnsignedBinBuiltinSet; 869defm vdiv : RVVSignedBinBuiltinSet; 870defm vremu : RVVUnsignedBinBuiltinSet; 871defm vrem : RVVSignedBinBuiltinSet; 872} 873 874// 11.12. Vector Widening Integer Multiply Instructions 875let Log2LMUL = [-3, -2, -1, 0, 1, 2], UnMaskedPolicyScheme = HasPassthruOperand in { 876defm vwmul : RVVOutOp0Op1BuiltinSet<"vwmul", "csi", 877 [["vv", "w", "wvv"], 878 ["vx", "w", "wve"]]>; 879defm vwmulu : RVVOutOp0Op1BuiltinSet<"vwmulu", "csi", 880 [["vv", "Uw", "UwUvUv"], 881 ["vx", "Uw", "UwUvUe"]]>; 882defm vwmulsu : RVVOutOp0Op1BuiltinSet<"vwmulsu", "csi", 883 [["vv", "w", "wvUv"], 884 ["vx", "w", "wvUe"]]>; 885} 886 887// 11.13. Vector Single-Width Integer Multiply-Add Instructions 888let UnMaskedPolicyScheme = HasPolicyOperand in { 889defm vmacc : RVVIntTerBuiltinSet; 890defm vnmsac : RVVIntTerBuiltinSet; 891defm vmadd : RVVIntTerBuiltinSet; 892defm vnmsub : RVVIntTerBuiltinSet; 893 894// 11.14. Vector Widening Integer Multiply-Add Instructions 895let HasMaskedOffOperand = false, 896 Log2LMUL = [-3, -2, -1, 0, 1, 2] in { 897defm vwmaccu : RVVOutOp1Op2BuiltinSet<"vwmaccu", "csi", 898 [["vv", "Uw", "UwUwUvUv"], 899 ["vx", "Uw", "UwUwUeUv"]]>; 900defm vwmacc : RVVOutOp1Op2BuiltinSet<"vwmacc", "csi", 901 [["vv", "w", "wwvv"], 902 ["vx", "w", "wwev"]]>; 903defm vwmaccsu : RVVOutOp1Op2BuiltinSet<"vwmaccsu", "csi", 904 [["vv", "w", "wwvUv"], 905 ["vx", "w", "wweUv"]]>; 906defm vwmaccus : RVVOutOp1Op2BuiltinSet<"vwmaccus", "csi", 907 [["vx", "w", "wwUev"]]>; 908} 909} 910 911// 11.15. Vector Integer Merge Instructions 912// C/C++ Operand: (mask, op1, op2, vl), Intrinsic: (passthru, op1, op2, mask, vl) 913let HasMasked = false, 914 UnMaskedPolicyScheme = HasPassthruOperand, 915 MaskedPolicyScheme = NonePolicy, 916 ManualCodegen = [{ 917 // insert poison passthru 918 if (PolicyAttrs & RVV_VTA) 919 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType)); 920 IntrinsicTypes = {ResultType, Ops[2]->getType(), Ops.back()->getType()}; 921 }] in { 922 defm vmerge : RVVOutOp1BuiltinSet<"vmerge", "csil", 923 [["vvm", "v", "vvvm"], 924 ["vxm", "v", "vvem"], 925 ["vvm", "Uv", "UvUvUvm"], 926 ["vxm", "Uv", "UvUvUem"]]>; 927} 928 929// 11.16. Vector Integer Move Instructions 930let HasMasked = false, 931 UnMaskedPolicyScheme = HasPassthruOperand, 932 MaskedPolicyScheme = NonePolicy, 933 OverloadedName = "vmv_v" in { 934 defm vmv_v : RVVOutBuiltinSet<"vmv_v_v", "csil", 935 [["v", "Uv", "UvUv"]]>; 936 defm vmv_v : RVVOutBuiltinSet<"vmv_v_v", "csilxfdy", 937 [["v", "v", "vv"]]>; 938 let SupportOverloading = false in 939 defm vmv_v : RVVOutBuiltinSet<"vmv_v_x", "csil", 940 [["x", "v", "ve"], 941 ["x", "Uv", "UvUe"]]>; 942} 943 944// 12. Vector Fixed-Point Arithmetic Instructions 945let HeaderCode = 946[{ 947enum __RISCV_VXRM { 948 __RISCV_VXRM_RNU = 0, 949 __RISCV_VXRM_RNE = 1, 950 __RISCV_VXRM_RDN = 2, 951 __RISCV_VXRM_ROD = 3, 952}; 953}] in 954def vxrm_enum : RVVHeader; 955 956// 12.1. Vector Single-Width Saturating Add and Subtract 957let UnMaskedPolicyScheme = HasPassthruOperand in { 958defm vsaddu : RVVUnsignedBinBuiltinSet; 959defm vsadd : RVVSignedBinBuiltinSet; 960defm vssubu : RVVUnsignedBinBuiltinSet; 961defm vssub : RVVSignedBinBuiltinSet; 962 963let ManualCodegen = [{ 964 { 965 return emitRVVAveragingBuiltin(this, E, ReturnValue, ResultType, ID, Ops, 966 PolicyAttrs, IsMasked, SegInstSEW); 967 } 968}] in { 969 // 12.2. Vector Single-Width Averaging Add and Subtract 970 defm vaaddu : RVVUnsignedBinBuiltinSetRoundingMode; 971 defm vaadd : RVVSignedBinBuiltinSetRoundingMode; 972 defm vasubu : RVVUnsignedBinBuiltinSetRoundingMode; 973 defm vasub : RVVSignedBinBuiltinSetRoundingMode; 974 975 // 12.3. Vector Single-Width Fractional Multiply with Rounding and Saturation 976 defm vsmul : RVVSignedBinBuiltinSetRoundingMode; 977 978 // 12.4. Vector Single-Width Scaling Shift Instructions 979 defm vssrl : RVVUnsignedShiftBuiltinSetRoundingMode; 980 defm vssra : RVVSignedShiftBuiltinSetRoundingMode; 981} 982 983let ManualCodegen = [{ 984 { 985 return emitRVVNarrowingClipBuiltin(this, E, ReturnValue, ResultType, ID, 986 Ops, PolicyAttrs, IsMasked, SegInstSEW); 987 } 988}] in { 989 // 12.5. Vector Narrowing Fixed-Point Clip Instructions 990 defm vnclipu : RVVUnsignedNShiftBuiltinSetRoundingMode; 991 defm vnclip : RVVSignedNShiftBuiltinSetRoundingMode; 992} 993} 994 995// 13. Vector Floating-Point Instructions 996let HeaderCode = 997[{ 998enum __RISCV_FRM { 999 __RISCV_FRM_RNE = 0, 1000 __RISCV_FRM_RTZ = 1, 1001 __RISCV_FRM_RDN = 2, 1002 __RISCV_FRM_RUP = 3, 1003 __RISCV_FRM_RMM = 4, 1004}; 1005}] in def frm_enum : RVVHeader; 1006 1007let UnMaskedPolicyScheme = HasPassthruOperand in { 1008let ManualCodegen = [{ 1009 { 1010 return emitRVVFloatingPointBuiltin(this, E, ReturnValue, ResultType, ID, 1011 Ops, PolicyAttrs, IsMasked, SegInstSEW); 1012 } 1013}] in { 1014 let HasFRMRoundModeOp = true in { 1015 // 13.2. Vector Single-Width Floating-Point Add/Subtract Instructions 1016 defm vfadd : RVVFloatingBinBuiltinSetRoundingMode; 1017 defm vfsub : RVVFloatingBinBuiltinSetRoundingMode; 1018 defm vfrsub : RVVFloatingBinVFBuiltinSetRoundingMode; 1019 1020 // 13.3. Vector Widening Floating-Point Add/Subtract Instructions 1021 // Widening FP add/subtract, 2*SEW = 2*SEW +/- SEW 1022 defm vfwadd : RVVFloatingWidenOp0BinBuiltinSetRoundingMode; 1023 defm vfwsub : RVVFloatingWidenOp0BinBuiltinSetRoundingMode; 1024 1025 // 13.4. Vector Single-Width Floating-Point Multiply/Divide Instructions 1026 defm vfmul : RVVFloatingBinBuiltinSetRoundingMode; 1027 defm vfdiv : RVVFloatingBinBuiltinSetRoundingMode; 1028 defm vfrdiv : RVVFloatingBinVFBuiltinSetRoundingMode; 1029 } 1030 // 13.2. Vector Single-Width Floating-Point Add/Subtract Instructions 1031 defm vfadd : RVVFloatingBinBuiltinSet; 1032 defm vfsub : RVVFloatingBinBuiltinSet; 1033 defm vfrsub : RVVFloatingBinVFBuiltinSet; 1034 1035 // 13.3. Vector Widening Floating-Point Add/Subtract Instructions 1036 // Widening FP add/subtract, 2*SEW = 2*SEW +/- SEW 1037 defm vfwadd : RVVFloatingWidenOp0BinBuiltinSet; 1038 defm vfwsub : RVVFloatingWidenOp0BinBuiltinSet; 1039 1040 // 13.4. Vector Single-Width Floating-Point Multiply/Divide Instructions 1041 defm vfmul : RVVFloatingBinBuiltinSet; 1042 defm vfdiv : RVVFloatingBinBuiltinSet; 1043 defm vfrdiv : RVVFloatingBinVFBuiltinSet; 1044} 1045 1046let ManualCodegen = [{ 1047 { 1048 return emitRVVWideningFloatingPointBuiltin( 1049 this, E, ReturnValue, ResultType, ID, Ops, PolicyAttrs, IsMasked, 1050 SegInstSEW); 1051 } 1052}] in { 1053 let HasFRMRoundModeOp = true in { 1054 // 13.3. Vector Widening Floating-Point Add/Subtract Instructions 1055 // Widening FP add/subtract, 2*SEW = SEW +/- SEW 1056 defm vfwadd : RVVFloatingWidenBinBuiltinSetRoundingMode; 1057 defm vfwsub : RVVFloatingWidenBinBuiltinSetRoundingMode; 1058 1059 // 13.5. Vector Widening Floating-Point Multiply 1060 let Log2LMUL = [-2, -1, 0, 1, 2] in { 1061 defm vfwmul : RVVOutOp0Op1BuiltinSet<"vfwmul", "f", 1062 [["vv", "w", "wvvu"], 1063 ["vf", "w", "wveu"]]>; 1064 let RequiredFeatures = ["zvfh"] in 1065 defm vfwmul : RVVOutOp0Op1BuiltinSet<"vfwmul", "x", 1066 [["vv", "w", "wvvu"], 1067 ["vf", "w", "wveu"]]>; 1068 } 1069 } 1070 // 13.3. Vector Widening Floating-Point Add/Subtract Instructions 1071 // Widening FP add/subtract, 2*SEW = SEW +/- SEW 1072 defm vfwadd : RVVFloatingWidenBinBuiltinSet; 1073 defm vfwsub : RVVFloatingWidenBinBuiltinSet; 1074 1075 // 13.5. Vector Widening Floating-Point Multiply 1076 let Log2LMUL = [-2, -1, 0, 1, 2] in { 1077 defm vfwmul : RVVOutOp0Op1BuiltinSet<"vfwmul", "f", 1078 [["vv", "w", "wvv"], 1079 ["vf", "w", "wve"]]>; 1080 let RequiredFeatures = ["zvfh"] in 1081 defm vfwmul : RVVOutOp0Op1BuiltinSet<"vfwmul", "x", 1082 [["vv", "w", "wvv"], 1083 ["vf", "w", "wve"]]>; 1084 } 1085} 1086} 1087 1088 1089let UnMaskedPolicyScheme = HasPolicyOperand in { 1090let ManualCodegen = [{ 1091 { 1092 return emitRVVFMABuiltin(this, E, ReturnValue, ResultType, ID, Ops, 1093 PolicyAttrs, IsMasked, SegInstSEW); 1094 } 1095}] in { 1096 let HasFRMRoundModeOp = 1 in { 1097 // 13.6. Vector Single-Width Floating-Point Fused Multiply-Add Instructions 1098 defm vfmacc : RVVFloatingTerBuiltinSetRoundingMode; 1099 defm vfnmacc : RVVFloatingTerBuiltinSetRoundingMode; 1100 defm vfmsac : RVVFloatingTerBuiltinSetRoundingMode; 1101 defm vfnmsac : RVVFloatingTerBuiltinSetRoundingMode; 1102 defm vfmadd : RVVFloatingTerBuiltinSetRoundingMode; 1103 defm vfnmadd : RVVFloatingTerBuiltinSetRoundingMode; 1104 defm vfmsub : RVVFloatingTerBuiltinSetRoundingMode; 1105 defm vfnmsub : RVVFloatingTerBuiltinSetRoundingMode; 1106 } 1107 // 13.6. Vector Single-Width Floating-Point Fused Multiply-Add Instructions 1108 defm vfmacc : RVVFloatingTerBuiltinSet; 1109 defm vfnmacc : RVVFloatingTerBuiltinSet; 1110 defm vfmsac : RVVFloatingTerBuiltinSet; 1111 defm vfnmsac : RVVFloatingTerBuiltinSet; 1112 defm vfmadd : RVVFloatingTerBuiltinSet; 1113 defm vfnmadd : RVVFloatingTerBuiltinSet; 1114 defm vfmsub : RVVFloatingTerBuiltinSet; 1115 defm vfnmsub : RVVFloatingTerBuiltinSet; 1116} 1117 1118let ManualCodegen = [{ 1119 { 1120 return emitRVVWideningFMABuiltin(this, E, ReturnValue, ResultType, ID, 1121 Ops, PolicyAttrs, IsMasked, SegInstSEW); 1122 } 1123}] in { 1124 let HasFRMRoundModeOp = 1 in { 1125 // 13.7. Vector Widening Floating-Point Fused Multiply-Add Instructions 1126 defm vfwmacc : RVVFloatingWidenTerBuiltinSetRoundingMode; 1127 defm vfwnmacc : RVVFloatingWidenTerBuiltinSetRoundingMode; 1128 defm vfwmsac : RVVFloatingWidenTerBuiltinSetRoundingMode; 1129 defm vfwnmsac : RVVFloatingWidenTerBuiltinSetRoundingMode; 1130 1131 // Vector BF16 widening multiply-accumulate 1132 let Log2LMUL = [-2, -1, 0, 1, 2], 1133 RequiredFeatures = ["zvfbfwma"], 1134 HasMaskedOffOperand = false in 1135 defm vfwmaccbf16 : RVVOutOp1Op2BuiltinSet<"vfwmaccbf16", "y", 1136 [["vv", "Fw", "FwFwvvu"], 1137 ["vf", "Fw", "FwFwevu"]]>; 1138 } 1139 // 13.7. Vector Widening Floating-Point Fused Multiply-Add Instructions 1140 defm vfwmacc : RVVFloatingWidenTerBuiltinSet; 1141 defm vfwnmacc : RVVFloatingWidenTerBuiltinSet; 1142 defm vfwmsac : RVVFloatingWidenTerBuiltinSet; 1143 defm vfwnmsac : RVVFloatingWidenTerBuiltinSet; 1144 1145 // Vector BF16 widening multiply-accumulate 1146 let Log2LMUL = [-2, -1, 0, 1, 2], 1147 RequiredFeatures = ["zvfbfwma"], 1148 HasMaskedOffOperand = false in 1149 defm vfwmaccbf16 : RVVOutOp1Op2BuiltinSet<"vfwmaccbf16", "y", 1150 [["vv", "Fw", "FwFwvv"], 1151 ["vf", "Fw", "FwFwev"]]>; 1152} 1153 1154} 1155 1156let UnMaskedPolicyScheme = HasPassthruOperand in { 1157let ManualCodegen = [{ 1158 { 1159 return emitRVVFloatingUnaryBuiltin(this, E, ReturnValue, ResultType, ID, 1160 Ops, PolicyAttrs, IsMasked, SegInstSEW); 1161 } 1162}] in { 1163 let HasFRMRoundModeOp = 1 in { 1164 // 13.8. Vector Floating-Point Square-Root Instruction 1165 defm vfsqrt : RVVOutBuiltinSet<"vfsqrt", "fd", [["v", "v", "vvu"]]>; 1166 let RequiredFeatures = ["zvfh"] in 1167 defm vfsqrt : RVVOutBuiltinSet<"vfsqrt", "x", [["v", "v", "vvu"]]>; 1168 1169 // 13.10. Vector Floating-Point Reciprocal Estimate Instruction 1170 defm vfrec7 : RVVOutBuiltinSet<"vfrec7", "fd", [["v", "v", "vvu"]]>; 1171 let RequiredFeatures = ["zvfh"] in 1172 defm vfrec7 : RVVOutBuiltinSet<"vfrec7", "x", [["v", "v", "vvu"]]>; 1173 } 1174 // 13.8. Vector Floating-Point Square-Root Instruction 1175 defm vfsqrt : RVVOutBuiltinSet<"vfsqrt", "fd", [["v", "v", "vv"]]>; 1176 let RequiredFeatures = ["zvfh"] in 1177 defm vfsqrt : RVVOutBuiltinSet<"vfsqrt", "x", [["v", "v", "vv"]]>; 1178 1179 // 13.10. Vector Floating-Point Reciprocal Estimate Instruction 1180 defm vfrec7 : RVVOutBuiltinSet<"vfrec7", "fd", [["v", "v", "vv"]]>; 1181 let RequiredFeatures = ["zvfh"] in 1182 defm vfrec7 : RVVOutBuiltinSet<"vfrec7", "x", [["v", "v", "vv"]]>; 1183} 1184 1185// 13.9. Vector Floating-Point Reciprocal Square-Root Estimate Instruction 1186defm vfrsqrt7 : RVVOutBuiltinSet<"vfrsqrt7", "fd", [["v", "v", "vv"]]>; 1187let RequiredFeatures = ["zvfh"] in 1188 defm vfrsqrt7 : RVVOutBuiltinSet<"vfrsqrt7", "x", [["v", "v", "vv"]]>; 1189 1190// 13.11. Vector Floating-Point MIN/MAX Instructions 1191defm vfmin : RVVFloatingBinBuiltinSet; 1192defm vfmax : RVVFloatingBinBuiltinSet; 1193 1194// 13.12. Vector Floating-Point Sign-Injection Instructions 1195defm vfsgnj : RVVFloatingBinBuiltinSet; 1196defm vfsgnjn : RVVFloatingBinBuiltinSet; 1197defm vfsgnjx : RVVFloatingBinBuiltinSet; 1198} 1199defm vfneg_v : RVVPseudoVFUnaryBuiltin<"vfsgnjn", "fd">; 1200let RequiredFeatures = ["zvfh"] in 1201 defm vfneg_v : RVVPseudoVFUnaryBuiltin<"vfsgnjn", "x">; 1202defm vfabs_v : RVVPseudoVFUnaryBuiltin<"vfsgnjx", "fd">; 1203let RequiredFeatures = ["zvfh"] in 1204 defm vfabs_v : RVVPseudoVFUnaryBuiltin<"vfsgnjx", "x">; 1205 1206// 13.13. Vector Floating-Point Compare Instructions 1207let MaskedPolicyScheme = HasPassthruOperand, 1208 HasTailPolicy = false in { 1209defm vmfeq : RVVFloatingMaskOutBuiltinSet; 1210defm vmfne : RVVFloatingMaskOutBuiltinSet; 1211defm vmflt : RVVFloatingMaskOutBuiltinSet; 1212defm vmfle : RVVFloatingMaskOutBuiltinSet; 1213defm vmfgt : RVVFloatingMaskOutBuiltinSet; 1214defm vmfge : RVVFloatingMaskOutBuiltinSet; 1215} 1216 1217// 13.14. Vector Floating-Point Classify Instruction 1218let UnMaskedPolicyScheme = HasPassthruOperand in { 1219defm vfclass : RVVOp0BuiltinSet<"vfclass", "fd", [["v", "Uv", "Uvv"]]>; 1220let RequiredFeatures = ["zvfh"] in 1221 defm vfclass : RVVOp0BuiltinSet<"vfclass", "x", [["v", "Uv", "Uvv"]]>; 1222} 1223 1224// 13.15. Vector Floating-Point Merge Instruction 1225// C/C++ Operand: (mask, op1, op2, vl), Builtin: (op1, op2, mask, vl) 1226let HasMasked = false, 1227 UnMaskedPolicyScheme = HasPassthruOperand, 1228 MaskedPolicyScheme = NonePolicy, 1229 ManualCodegen = [{ 1230 // insert poison passthru 1231 if (PolicyAttrs & RVV_VTA) 1232 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType)); 1233 IntrinsicTypes = {ResultType, Ops[2]->getType(), Ops.back()->getType()}; 1234 }] in { 1235 defm vmerge : RVVOutOp1BuiltinSet<"vmerge", "xfdy", 1236 [["vvm", "v", "vvvm"]]>; 1237 defm vfmerge : RVVOutOp1BuiltinSet<"vfmerge", "fd", 1238 [["vfm", "v", "vvem"]]>; 1239 let RequiredFeatures = ["zvfh"] in 1240 defm vfmerge : RVVOutOp1BuiltinSet<"vfmerge", "x", 1241 [["vfm", "v", "vvem"]]>; 1242} 1243 1244// 13.16. Vector Floating-Point Move Instruction 1245let HasMasked = false, 1246 UnMaskedPolicyScheme = HasPassthruOperand, 1247 SupportOverloading = false, 1248 MaskedPolicyScheme = NonePolicy, 1249 OverloadedName = "vfmv_v" in { 1250 defm vfmv_v : RVVOutBuiltinSet<"vfmv_v_f", "fd", 1251 [["f", "v", "ve"]]>; 1252 let RequiredFeatures = ["zvfh"] in 1253 defm vfmv_v : RVVOutBuiltinSet<"vfmv_v_f", "x", 1254 [["f", "v", "ve"]]>; 1255} 1256 1257// 13.17. Single-Width Floating-Point/Integer Type-Convert Instructions 1258let UnMaskedPolicyScheme = HasPassthruOperand in { 1259let OverloadedName = "vfcvt_rtz_xu" in { 1260 defm : RVVConvBuiltinSet<"vfcvt_rtz_xu_f_v", "fd", [["Uv", "Uvv"]]>; 1261 let RequiredFeatures = ["zvfh"] in 1262 defm : RVVConvBuiltinSet<"vfcvt_rtz_xu_f_v", "x", [["Uv", "Uvv"]]>; 1263} 1264let OverloadedName = "vfcvt_rtz_x" in { 1265 defm : RVVConvBuiltinSet<"vfcvt_rtz_x_f_v", "fd", [["Iv", "Ivv"]]>; 1266 let RequiredFeatures = ["zvfh"] in 1267 defm : RVVConvBuiltinSet<"vfcvt_rtz_x_f_v", "x", [["Iv", "Ivv"]]>; 1268} 1269 1270// 13.18. Widening Floating-Point/Integer Type-Convert Instructions 1271let Log2LMUL = [-3, -2, -1, 0, 1, 2] in { 1272 let OverloadedName = "vfwcvt_rtz_xu" in { 1273 defm : RVVConvBuiltinSet<"vfwcvt_rtz_xu_f_v", "f", [["Uw", "Uwv"]]>; 1274 let RequiredFeatures = ["zvfh"] in 1275 defm : RVVConvBuiltinSet<"vfwcvt_rtz_xu_f_v", "x", [["Uw", "Uwv"]]>; 1276 } 1277 let OverloadedName = "vfwcvt_rtz_x" in { 1278 defm : RVVConvBuiltinSet<"vfwcvt_rtz_x_f_v", "f", [["Iw", "Iwv"]]>; 1279 let RequiredFeatures = ["zvfh"] in 1280 defm : RVVConvBuiltinSet<"vfwcvt_rtz_x_f_v", "x", [["Iw", "Iwv"]]>; 1281 } 1282 let OverloadedName = "vfwcvt_f" in { 1283 defm : RVVConvBuiltinSet<"vfwcvt_f_xu_v", "si", [["Fw", "FwUv"]]>; 1284 defm : RVVConvBuiltinSet<"vfwcvt_f_x_v", "si", [["Fw", "Fwv"]]>; 1285 let RequiredFeatures = ["zvfh"] in { 1286 defm : RVVConvBuiltinSet<"vfwcvt_f_xu_v", "c", [["Fw", "FwUv"]]>; 1287 defm : RVVConvBuiltinSet<"vfwcvt_f_x_v", "c", [["Fw", "Fwv"]]>; 1288 } 1289 } 1290 let OverloadedName = "vfwcvt_f" in { 1291 defm : RVVConvBuiltinSet<"vfwcvt_f_f_v", "f", [["w", "wv"]]>; 1292 let RequiredFeatures = ["zvfhmin"] in 1293 defm : RVVConvBuiltinSet<"vfwcvt_f_f_v", "x", [["w", "wv"]]>; 1294 } 1295} 1296 1297// 13.19. Narrowing Floating-Point/Integer Type-Convert Instructions 1298let Log2LMUL = [-3, -2, -1, 0, 1, 2] in { 1299 let OverloadedName = "vfncvt_rtz_xu" in { 1300 defm : RVVConvBuiltinSet<"vfncvt_rtz_xu_f_w", "si", [["Uv", "UvFw"]]>; 1301 let RequiredFeatures = ["zvfh"] in 1302 defm : RVVConvBuiltinSet<"vfncvt_rtz_xu_f_w", "c", [["Uv", "UvFw"]]>; 1303 } 1304 let OverloadedName = "vfncvt_rtz_x" in { 1305 defm : RVVConvBuiltinSet<"vfncvt_rtz_x_f_w", "si", [["Iv", "IvFw"]]>; 1306 let RequiredFeatures = ["zvfh"] in 1307 defm : RVVConvBuiltinSet<"vfncvt_rtz_x_f_w", "c", [["Iv", "IvFw"]]>; 1308 } 1309 let OverloadedName = "vfncvt_rod_f" in { 1310 defm : RVVConvBuiltinSet<"vfncvt_rod_f_f_w", "f", [["v", "vw"]]>; 1311 let RequiredFeatures = ["zvfh"] in 1312 defm : RVVConvBuiltinSet<"vfncvt_rod_f_f_w", "x", [["v", "vw"]]>; 1313 } 1314} 1315 1316// Zvfbfmin - Vector convert BF16 to FP32 1317let RequiredFeatures = ["zvfbfmin"], Log2LMUL = [-2, -1, 0, 1, 2] in 1318def vfwcvtbf16_f_f_v : RVVConvBuiltin<"Fw", "Fwv", "y", "vfwcvtbf16_f">; 1319 1320let ManualCodegen = [{ 1321 { 1322 return emitRVVFloatingConvBuiltin(this, E, ReturnValue, ResultType, ID, 1323 Ops, PolicyAttrs, IsMasked, SegInstSEW); 1324 } 1325}] in { 1326 let HasFRMRoundModeOp = 1 in { 1327 // 14.17. Single-Width Floating-Point/Integer Type-Convert Instructions 1328 let OverloadedName = "vfcvt_x" in { 1329 defm : RVVConvBuiltinSet<"vfcvt_x_f_v", "fd", [["Iv", "Ivvu"]]>; 1330 let RequiredFeatures = ["zvfh"] in 1331 defm : RVVConvBuiltinSet<"vfcvt_x_f_v", "x", [["Iv", "Ivvu"]]>; 1332 } 1333 let OverloadedName = "vfcvt_xu" in { 1334 defm : RVVConvBuiltinSet<"vfcvt_xu_f_v", "fd", [["Uv", "Uvvu"]]>; 1335 let RequiredFeatures = ["zvfh"] in 1336 defm : RVVConvBuiltinSet<"vfcvt_xu_f_v", "x", [["Uv", "Uvvu"]]>; 1337 } 1338 let OverloadedName = "vfcvt_f" in { 1339 defm : RVVConvBuiltinSet<"vfcvt_f_x_v", "fd", [["v", "vIvu"]]>; 1340 defm : RVVConvBuiltinSet<"vfcvt_f_xu_v", "fd", [["v", "vUvu"]]>; 1341 let RequiredFeatures = ["zvfh"] in { 1342 defm : RVVConvBuiltinSet<"vfcvt_f_x_v", "x", [["v", "vIvu"]]>; 1343 defm : RVVConvBuiltinSet<"vfcvt_f_xu_v", "x", [["v", "vUvu"]]>; 1344 } 1345 } 1346 1347 // 13.18. Widening Floating-Point/Integer Type-Convert Instructions 1348 let Log2LMUL = [-3, -2, -1, 0, 1, 2] in { 1349 let OverloadedName = "vfwcvt_x" in { 1350 defm : RVVConvBuiltinSet<"vfwcvt_x_f_v", "f", [["Iw", "Iwvu"]]>; 1351 let RequiredFeatures = ["zvfh"] in 1352 defm : RVVConvBuiltinSet<"vfwcvt_x_f_v", "x", [["Iw", "Iwvu"]]>; 1353 } 1354 let OverloadedName = "vfwcvt_xu" in { 1355 defm : RVVConvBuiltinSet<"vfwcvt_xu_f_v", "f", [["Uw", "Uwvu"]]>; 1356 let RequiredFeatures = ["zvfh"] in 1357 defm : RVVConvBuiltinSet<"vfwcvt_xu_f_v", "x", [["Uw", "Uwvu"]]>; 1358 } 1359 } 1360 // 13.19. Narrowing Floating-Point/Integer Type-Convert Instructions 1361 let Log2LMUL = [-3, -2, -1, 0, 1, 2] in { 1362 let OverloadedName = "vfncvt_x" in { 1363 defm : RVVConvBuiltinSet<"vfncvt_x_f_w", "si", [["Iv", "IvFwu"]]>; 1364 let RequiredFeatures = ["zvfh"] in 1365 defm : RVVConvBuiltinSet<"vfncvt_x_f_w", "c", [["Iv", "IvFwu"]]>; 1366 } 1367 let OverloadedName = "vfncvt_xu" in { 1368 defm : RVVConvBuiltinSet<"vfncvt_xu_f_w", "si", [["Uv", "UvFwu"]]>; 1369 let RequiredFeatures = ["zvfh"] in 1370 defm : RVVConvBuiltinSet<"vfncvt_xu_f_w", "c", [["Uv", "UvFwu"]]>; 1371 } 1372 let OverloadedName = "vfncvt_f" in { 1373 defm : RVVConvBuiltinSet<"vfncvt_f_x_w", "f", [["v", "vIwu"]]>; 1374 defm : RVVConvBuiltinSet<"vfncvt_f_xu_w", "f", [["v", "vUwu"]]>; 1375 let RequiredFeatures = ["zvfh"] in { 1376 defm : RVVConvBuiltinSet<"vfncvt_f_x_w", "x", [["v", "vIwu"]]>; 1377 defm : RVVConvBuiltinSet<"vfncvt_f_xu_w", "x", [["v", "vUwu"]]>; 1378 } 1379 } 1380 let OverloadedName = "vfncvt_f" in { 1381 defm : RVVConvBuiltinSet<"vfncvt_f_f_w", "f", [["v", "vwu"]]>; 1382 let RequiredFeatures = ["zvfhmin"] in 1383 defm : RVVConvBuiltinSet<"vfncvt_f_f_w", "x", [["v", "vwu"]]>; 1384 } 1385 } 1386 1387 // Zvfbfmin - Vector convert FP32 to BF16 1388 let RequiredFeatures = ["zvfbfmin"], 1389 Log2LMUL = [-2, -1, 0, 1, 2], 1390 OverloadedName = "vfncvtbf16_f" in 1391 defm : RVVConvBuiltinSet<"vfncvtbf16_f_f_w", "y", [["v", "vFwu"]]>; 1392 } 1393 1394 // 13.17. Single-Width Floating-Point/Integer Type-Convert Instructions 1395 let OverloadedName = "vfcvt_x" in { 1396 defm : RVVConvBuiltinSet<"vfcvt_x_f_v", "fd", [["Iv", "Ivv"]]>; 1397 let RequiredFeatures = ["zvfh"] in 1398 defm : RVVConvBuiltinSet<"vfcvt_x_f_v", "x", [["Iv", "Ivv"]]>; 1399 } 1400 let OverloadedName = "vfcvt_xu" in { 1401 defm : RVVConvBuiltinSet<"vfcvt_xu_f_v", "fd", [["Uv", "Uvv"]]>; 1402 let RequiredFeatures = ["zvfh"] in 1403 defm : RVVConvBuiltinSet<"vfcvt_xu_f_v", "x", [["Uv", "Uvv"]]>; 1404 } 1405 let OverloadedName = "vfcvt_f" in { 1406 defm : RVVConvBuiltinSet<"vfcvt_f_x_v", "fd", [["v", "vIv"]]>; 1407 defm : RVVConvBuiltinSet<"vfcvt_f_xu_v", "fd", [["v", "vUv"]]>; 1408 let RequiredFeatures = ["zvfh"] in { 1409 defm : RVVConvBuiltinSet<"vfcvt_f_x_v", "x", [["v", "vIv"]]>; 1410 defm : RVVConvBuiltinSet<"vfcvt_f_xu_v", "x", [["v", "vUv"]]>; 1411 } 1412 } 1413 1414 // 13.18. Widening Floating-Point/Integer Type-Convert Instructions 1415 let Log2LMUL = [-3, -2, -1, 0, 1, 2] in { 1416 let OverloadedName = "vfwcvt_x" in { 1417 defm : RVVConvBuiltinSet<"vfwcvt_x_f_v", "f", [["Iw", "Iwv"]]>; 1418 let RequiredFeatures = ["zvfh"] in 1419 defm : RVVConvBuiltinSet<"vfwcvt_x_f_v", "x", [["Iw", "Iwv"]]>; 1420 } 1421 let OverloadedName = "vfwcvt_xu" in { 1422 defm : RVVConvBuiltinSet<"vfwcvt_xu_f_v", "f", [["Uw", "Uwv"]]>; 1423 let RequiredFeatures = ["zvfh"] in 1424 defm : RVVConvBuiltinSet<"vfwcvt_xu_f_v", "x", [["Uw", "Uwv"]]>; 1425 } 1426 } 1427 // 13.19. Narrowing Floating-Point/Integer Type-Convert Instructions 1428 let Log2LMUL = [-3, -2, -1, 0, 1, 2] in { 1429 let OverloadedName = "vfncvt_x" in { 1430 defm : RVVConvBuiltinSet<"vfncvt_x_f_w", "si", [["Iv", "IvFw"]]>; 1431 let RequiredFeatures = ["zvfh"] in 1432 defm : RVVConvBuiltinSet<"vfncvt_x_f_w", "c", [["Iv", "IvFw"]]>; 1433 } 1434 let OverloadedName = "vfncvt_xu" in { 1435 defm : RVVConvBuiltinSet<"vfncvt_xu_f_w", "si", [["Uv", "UvFw"]]>; 1436 let RequiredFeatures = ["zvfh"] in 1437 defm : RVVConvBuiltinSet<"vfncvt_xu_f_w", "c", [["Uv", "UvFw"]]>; 1438 } 1439 let OverloadedName = "vfncvt_f" in { 1440 defm : RVVConvBuiltinSet<"vfncvt_f_x_w", "f", [["v", "vIw"]]>; 1441 defm : RVVConvBuiltinSet<"vfncvt_f_xu_w", "f", [["v", "vUw"]]>; 1442 let RequiredFeatures = ["zvfh"] in { 1443 defm : RVVConvBuiltinSet<"vfncvt_f_x_w", "x", [["v", "vIw"]]>; 1444 defm : RVVConvBuiltinSet<"vfncvt_f_xu_w", "x", [["v", "vUw"]]>; 1445 } 1446 } 1447 let OverloadedName = "vfncvt_f" in { 1448 defm : RVVConvBuiltinSet<"vfncvt_f_f_w", "f", [["v", "vw"]]>; 1449 let RequiredFeatures = ["zvfhmin"] in 1450 defm : RVVConvBuiltinSet<"vfncvt_f_f_w", "x", [["v", "vw"]]>; 1451 } 1452 } 1453 1454 // Zvfbfmin - Vector convert FP32 to BF16 1455 let Log2LMUL = [-2, -1, 0, 1, 2], 1456 OverloadedName = "vfncvtbf16_f" in 1457 defm : RVVConvBuiltinSet<"vfncvtbf16_f_f_w", "y", [["v", "vFw"]]>; 1458} 1459} 1460 1461// 14. Vector Reduction Operations 1462// 14.1. Vector Single-Width Integer Reduction Instructions 1463let UnMaskedPolicyScheme = HasPassthruOperand, 1464 MaskedPolicyScheme = HasPassthruOperand, 1465 HasMaskPolicy = false in { 1466defm vredsum : RVVIntReductionBuiltinSet; 1467defm vredmaxu : RVVUnsignedReductionBuiltin; 1468defm vredmax : RVVSignedReductionBuiltin; 1469defm vredminu : RVVUnsignedReductionBuiltin; 1470defm vredmin : RVVSignedReductionBuiltin; 1471defm vredand : RVVIntReductionBuiltinSet; 1472defm vredor : RVVIntReductionBuiltinSet; 1473defm vredxor : RVVIntReductionBuiltinSet; 1474 1475// 14.2. Vector Widening Integer Reduction Instructions 1476// Vector Widening Integer Reduction Operations 1477let HasMaskedOffOperand = true in { 1478 defm vwredsum : RVVOutOp0BuiltinSet<"vwredsum", "csi", 1479 [["vs", "vSw", "SwvSw"]]>; 1480 defm vwredsumu : RVVOutOp0BuiltinSet<"vwredsumu", "csi", 1481 [["vs", "UvUSw", "USwUvUSw"]]>; 1482} 1483 1484// 14.3. Vector Single-Width Floating-Point Reduction Instructions 1485defm vfredmax : RVVFloatingReductionBuiltin; 1486defm vfredmin : RVVFloatingReductionBuiltin; 1487let ManualCodegen = [{ 1488 { 1489 return emitRVVFloatingReductionBuiltin( 1490 this, E, ReturnValue, ResultType, ID, Ops, PolicyAttrs, IsMasked, 1491 SegInstSEW); 1492 } 1493}] in { 1494 let HasFRMRoundModeOp = 1 in { 1495 // 14.3. Vector Single-Width Floating-Point Reduction Instructions 1496 defm vfredusum : RVVFloatingReductionBuiltinRoundingMode; 1497 defm vfredosum : RVVFloatingReductionBuiltinRoundingMode; 1498 1499 // 14.4. Vector Widening Floating-Point Reduction Instructions 1500 defm vfwredusum : RVVFloatingWidenReductionBuiltinRoundingMode; 1501 defm vfwredosum : RVVFloatingWidenReductionBuiltinRoundingMode; 1502 } 1503 // 14.3. Vector Single-Width Floating-Point Reduction Instructions 1504 defm vfredusum : RVVFloatingReductionBuiltin; 1505 defm vfredosum : RVVFloatingReductionBuiltin; 1506 1507 // 14.4. Vector Widening Floating-Point Reduction Instructions 1508 defm vfwredusum : RVVFloatingWidenReductionBuiltin; 1509 defm vfwredosum : RVVFloatingWidenReductionBuiltin; 1510} 1511} 1512 1513// 15. Vector Mask Instructions 1514// 15.1. Vector Mask-Register Logical Instructions 1515def vmand : RVVMaskBinBuiltin; 1516def vmnand : RVVMaskBinBuiltin; 1517def vmandn : RVVMaskBinBuiltin; 1518def vmxor : RVVMaskBinBuiltin; 1519def vmor : RVVMaskBinBuiltin; 1520def vmnor : RVVMaskBinBuiltin; 1521def vmorn : RVVMaskBinBuiltin; 1522def vmxnor : RVVMaskBinBuiltin; 1523// pseudoinstructions 1524def vmclr : RVVMaskNullaryBuiltin; 1525def vmset : RVVMaskNullaryBuiltin; 1526defm vmmv_m : RVVPseudoMaskBuiltin<"vmand", "c">; 1527defm vmnot_m : RVVPseudoMaskBuiltin<"vmnand", "c">; 1528 1529let MaskedPolicyScheme = NonePolicy in { 1530// 15.2. Vector count population in mask vcpop.m 1531def vcpop : RVVMaskOp0Builtin<"um">; 1532 1533// 15.3. vfirst find-first-set mask bit 1534def vfirst : RVVMaskOp0Builtin<"lm">; 1535} 1536 1537let MaskedPolicyScheme = HasPassthruOperand, 1538 HasTailPolicy = false in { 1539// 15.4. vmsbf.m set-before-first mask bit 1540def vmsbf : RVVMaskUnaryBuiltin; 1541 1542// 15.5. vmsif.m set-including-first mask bit 1543def vmsif : RVVMaskUnaryBuiltin; 1544 1545// 15.6. vmsof.m set-only-first mask bit 1546def vmsof : RVVMaskUnaryBuiltin; 1547} 1548 1549let UnMaskedPolicyScheme = HasPassthruOperand, SupportOverloading = false in { 1550 // 15.8. Vector Iota Instruction 1551 defm viota : RVVOutBuiltinSet<"viota", "csil", [["m", "Uv", "Uvm"]]>; 1552 1553 // 15.9. Vector Element Index Instruction 1554 defm vid : RVVOutBuiltinSet<"vid", "csil", [["v", "v", "v"], 1555 ["v", "Uv", "Uv"]]>; 1556} 1557 1558// 16. Vector Permutation Instructions 1559// 16.1. Integer Scalar Move Instructions 1560let HasMasked = false, MaskedPolicyScheme = NonePolicy in { 1561 let HasVL = false, OverloadedName = "vmv_x" in 1562 defm vmv_x : RVVOp0BuiltinSet<"vmv_x_s", "csil", 1563 [["s", "ve", "ev"], 1564 ["s", "UvUe", "UeUv"]]>; 1565 let OverloadedName = "vmv_s", 1566 UnMaskedPolicyScheme = HasPassthruOperand, 1567 SupportOverloading = false in 1568 defm vmv_s : RVVOutBuiltinSet<"vmv_s_x", "csil", 1569 [["x", "v", "ve"], 1570 ["x", "Uv", "UvUe"]]>; 1571} 1572 1573// 16.2. Floating-Point Scalar Move Instructions 1574let HasMasked = false, MaskedPolicyScheme = NonePolicy in { 1575 let HasVL = false, OverloadedName = "vfmv_f" in { 1576 defm vfmv_f : RVVOp0BuiltinSet<"vfmv_f_s", "fd", 1577 [["s", "ve", "ev"]]>; 1578 let RequiredFeatures = ["zvfh"] in 1579 defm vfmv_f : RVVOp0BuiltinSet<"vfmv_f_s", "x", 1580 [["s", "ve", "ev"]]>; 1581 } 1582 let OverloadedName = "vfmv_s", 1583 UnMaskedPolicyScheme = HasPassthruOperand, 1584 SupportOverloading = false in { 1585 defm vfmv_s : RVVOutBuiltinSet<"vfmv_s_f", "fd", 1586 [["f", "v", "ve"], 1587 ["x", "Uv", "UvUe"]]>; 1588 let RequiredFeatures = ["zvfh"] in 1589 defm vfmv_s : RVVOutBuiltinSet<"vfmv_s_f", "x", 1590 [["f", "v", "ve"], 1591 ["x", "Uv", "UvUe"]]>; 1592 } 1593} 1594 1595// 16.3. Vector Slide Instructions 1596// 16.3.1. Vector Slideup Instructions 1597defm vslideup : RVVSlideUpBuiltinSet; 1598// 16.3.2. Vector Slidedown Instructions 1599defm vslidedown : RVVSlideDownBuiltinSet; 1600 1601// 16.3.3. Vector Slide1up Instructions 1602let UnMaskedPolicyScheme = HasPassthruOperand in { 1603defm vslide1up : RVVSlideOneBuiltinSet; 1604defm vfslide1up : RVVFloatingBinVFBuiltinSet; 1605 1606// 16.3.4. Vector Slide1down Instruction 1607defm vslide1down : RVVSlideOneBuiltinSet; 1608defm vfslide1down : RVVFloatingBinVFBuiltinSet; 1609 1610// 16.4. Vector Register Gather Instructions 1611// signed and floating type 1612defm vrgather : RVVOutBuiltinSet<"vrgather_vv", "csilxfdy", 1613 [["vv", "v", "vvUv"]]>; 1614defm vrgather : RVVOutBuiltinSet<"vrgather_vx", "csilxfdy", 1615 [["vx", "v", "vvz"]]>; 1616defm vrgatherei16 : RVVOutBuiltinSet<"vrgatherei16_vv", "csilxfdy", 1617 [["vv", "v", "vv(Log2EEW:4)Uv"]]>; 1618// unsigned type 1619defm vrgather : RVVOutBuiltinSet<"vrgather_vv", "csil", 1620 [["vv", "Uv", "UvUvUv"]]>; 1621defm vrgather : RVVOutBuiltinSet<"vrgather_vx", "csil", 1622 [["vx", "Uv", "UvUvz"]]>; 1623defm vrgatherei16 : RVVOutBuiltinSet<"vrgatherei16_vv", "csil", 1624 [["vv", "Uv", "UvUv(Log2EEW:4)Uv"]]>; 1625} 1626 1627// 16.5. Vector Compress Instruction 1628let HasMasked = false, 1629 UnMaskedPolicyScheme = HasPassthruOperand, 1630 MaskedPolicyScheme = NonePolicy, 1631 ManualCodegen = [{ 1632 // insert poison passthru 1633 if (PolicyAttrs & RVV_VTA) 1634 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType)); 1635 IntrinsicTypes = {ResultType, Ops.back()->getType()}; 1636 }] in { 1637 // signed and floating type 1638 defm vcompress : RVVOutBuiltinSet<"vcompress", "csilxfdy", 1639 [["vm", "v", "vvm"]]>; 1640 // unsigned type 1641 defm vcompress : RVVOutBuiltinSet<"vcompress", "csil", 1642 [["vm", "Uv", "UvUvm"]]>; 1643} 1644 1645// Miscellaneous 1646let HasMasked = false, HasVL = false, IRName = "" in { 1647 let Name = "vreinterpret_v", MaskedPolicyScheme = NonePolicy, 1648 ManualCodegen = [{ 1649 return emitRVVReinterpretBuiltin(this, E, ReturnValue, ResultType, ID, 1650 Ops, PolicyAttrs, IsMasked, SegInstSEW); 1651 }] in { 1652 // Reinterpret between different type under the same SEW and LMUL 1653 def vreinterpret_i_u : RVVBuiltin<"Uvv", "vUv", "csil", "v">; 1654 def vreinterpret_i_f : RVVBuiltin<"Fvv", "vFv", "sil", "v">; 1655 def vreinterpret_u_i : RVVBuiltin<"vUv", "Uvv", "csil", "Uv">; 1656 def vreinterpret_u_f : RVVBuiltin<"FvUv", "UvFv", "sil", "Uv">; 1657 def vreinterpret_f_i : RVVBuiltin<"vFv", "Fvv", "sil", "Fv">; 1658 def vreinterpret_f_u : RVVBuiltin<"UvFv", "FvUv", "sil", "Fv">; 1659 def vreinterpret_i_bf16 : RVVBuiltin<"vIv", "Ivv", "y", "Iv">; 1660 def vreinterpret_u_bf16 : RVVBuiltin<"vUv", "Uvv", "y", "Uv">; 1661 def vreinterpret_bf16_i : RVVBuiltin<"Ivv", "vIv", "y", "v">; 1662 def vreinterpret_bf16_u : RVVBuiltin<"Uvv", "vUv", "y", "v">; 1663 1664 // Reinterpret between different SEW under the same LMUL 1665 foreach dst_sew = ["(FixedSEW:8)", "(FixedSEW:16)", "(FixedSEW:32)", 1666 "(FixedSEW:64)"] in { 1667 def vreinterpret_i_ # dst_sew : RVVBuiltin<"v" # dst_sew # "v", 1668 dst_sew # "vv", "csil", dst_sew # "v">; 1669 def vreinterpret_u_ # dst_sew : RVVBuiltin<"Uv" # dst_sew # "Uv", 1670 dst_sew # "UvUv", "csil", dst_sew # "Uv">; 1671 } 1672 1673 // Existing users of FixedSEW - the reinterpretation between different SEW 1674 // and same LMUL has the implicit assumption that if FixedSEW is set to the 1675 // given element width, then the type will be identified as invalid, thus 1676 // skipping definition of reinterpret of SEW=8 to SEW=8. However this blocks 1677 // our usage here of defining all possible combinations of a fixed SEW to 1678 // any boolean. So we need to separately define SEW=8 here. 1679 // Reinterpret from LMUL=1 integer type to vector boolean type 1680 def vreintrepret_m1_b8_signed : 1681 RVVBuiltin<"Svm", 1682 "mSv", 1683 "c", "m">; 1684 def vreintrepret_m1_b8_usigned : 1685 RVVBuiltin<"USvm", 1686 "mUSv", 1687 "c", "m">; 1688 1689 // Reinterpret from vector boolean type to LMUL=1 integer type 1690 def vreintrepret_b8_m1_signed : 1691 RVVBuiltin<"mSv", 1692 "Svm", 1693 "c", "Sv">; 1694 def vreintrepret_b8_m1_usigned : 1695 RVVBuiltin<"mUSv", 1696 "USvm", 1697 "c", "USv">; 1698 1699 foreach dst_sew = ["16", "32", "64"] in { 1700 // Reinterpret from LMUL=1 integer type to vector boolean type 1701 def vreinterpret_m1_b # dst_sew # _signed: 1702 RVVBuiltin<"(FixedSEW:" # dst_sew # ")Svm", 1703 "m(FixedSEW:" # dst_sew # ")Sv", 1704 "c", "m">; 1705 def vreinterpret_m1_b # dst_sew # _unsigned: 1706 RVVBuiltin<"(FixedSEW:" # dst_sew # ")USvm", 1707 "m(FixedSEW:" # dst_sew # ")USv", 1708 "c", "m">; 1709 // Reinterpret from vector boolean type to LMUL=1 integer type 1710 def vreinterpret_b # dst_sew # _m1_signed: 1711 RVVBuiltin<"m(FixedSEW:" # dst_sew # ")Sv", 1712 "(FixedSEW:" # dst_sew # ")Svm", 1713 "c", "(FixedSEW:" # dst_sew # ")Sv">; 1714 def vreinterpret_b # dst_sew # _m1_unsigned: 1715 RVVBuiltin<"m(FixedSEW:" # dst_sew # ")USv", 1716 "(FixedSEW:" # dst_sew # ")USvm", 1717 "c", "(FixedSEW:" # dst_sew # ")USv">; 1718 } 1719 } 1720 1721 let Name = "vundefined", SupportOverloading = false, 1722 MaskedPolicyScheme = NonePolicy, 1723 ManualCodegen = [{ 1724 return llvm::PoisonValue::get(ResultType); 1725 }] in { 1726 def vundefined : RVVBuiltin<"v", "v", "csilxfdy">; 1727 def vundefined_u : RVVBuiltin<"Uv", "Uv", "csil">; 1728 1729 foreach nf = NFList in { 1730 let NF = nf in { 1731 defvar T = "(Tuple:" # nf # ")"; 1732 def : RVVBuiltin<T # "v", T # "v", "csilxfdy">; 1733 def : RVVBuiltin<T # "Uv", T # "Uv", "csil">; 1734 } 1735 } 1736 1737 } 1738 1739 // LMUL truncation 1740 // C/C++ Operand: VecTy, IR Operand: VecTy, Index 1741 let Name = "vlmul_trunc_v", OverloadedName = "vlmul_trunc", 1742 MaskedPolicyScheme = NonePolicy, 1743 ManualCodegen = [{ { 1744 return Builder.CreateExtractVector(ResultType, Ops[0], 1745 ConstantInt::get(Int64Ty, 0)); 1746 } }] in { 1747 foreach dst_lmul = ["(SFixedLog2LMUL:-3)", "(SFixedLog2LMUL:-2)", "(SFixedLog2LMUL:-1)", 1748 "(SFixedLog2LMUL:0)", "(SFixedLog2LMUL:1)", "(SFixedLog2LMUL:2)"] in { 1749 def vlmul_trunc # dst_lmul : RVVBuiltin<"v" # dst_lmul # "v", 1750 dst_lmul # "vv", "csilxfdy", dst_lmul # "v">; 1751 def vlmul_trunc_u # dst_lmul : RVVBuiltin<"Uv" # dst_lmul # "Uv", 1752 dst_lmul # "UvUv", "csil", dst_lmul # "Uv">; 1753 } 1754 } 1755 1756 // LMUL extension 1757 // C/C++ Operand: SubVecTy, IR Operand: VecTy, SubVecTy, Index 1758 let Name = "vlmul_ext_v", OverloadedName = "vlmul_ext", 1759 MaskedPolicyScheme = NonePolicy, 1760 ManualCodegen = [{ 1761 return Builder.CreateInsertVector(ResultType, 1762 llvm::PoisonValue::get(ResultType), 1763 Ops[0], ConstantInt::get(Int64Ty, 0)); 1764 }] in { 1765 foreach dst_lmul = ["(LFixedLog2LMUL:-2)", "(LFixedLog2LMUL:-1)", "(LFixedLog2LMUL:-0)", 1766 "(LFixedLog2LMUL:1)", "(LFixedLog2LMUL:2)", "(LFixedLog2LMUL:3)"] in { 1767 def vlmul_ext # dst_lmul : RVVBuiltin<"v" # dst_lmul # "v", 1768 dst_lmul # "vv", "csilxfdy", dst_lmul # "v">; 1769 def vlmul_ext_u # dst_lmul : RVVBuiltin<"Uv" # dst_lmul # "Uv", 1770 dst_lmul # "UvUv", "csil", dst_lmul # "Uv">; 1771 } 1772 } 1773 1774 let Name = "vget_v", MaskedPolicyScheme = NonePolicy, 1775 ManualCodegen = [{ 1776 return emitRVVGetBuiltin(this, E, ReturnValue, ResultType, ID, Ops, 1777 PolicyAttrs, IsMasked, SegInstSEW); 1778 }] in { 1779 foreach dst_lmul = ["(SFixedLog2LMUL:0)", "(SFixedLog2LMUL:1)", "(SFixedLog2LMUL:2)"] in { 1780 def : RVVBuiltin<"v" # dst_lmul # "v", dst_lmul # "vvKz", "csilxfdy", dst_lmul # "v">; 1781 def : RVVBuiltin<"Uv" # dst_lmul # "Uv", dst_lmul # "UvUvKz", "csil", dst_lmul # "Uv">; 1782 } 1783 foreach nf = NFList in { 1784 defvar T = "(Tuple:" # nf # ")"; 1785 def : RVVBuiltin<T # "vv", "v" # T # "vKz", "csilxfdy", "v">; 1786 def : RVVBuiltin<T # "UvUv", "Uv" # T # "UvKz", "csil", "Uv">; 1787 } 1788 } 1789 1790 let Name = "vset_v", MaskedPolicyScheme = NonePolicy, 1791 ManualCodegen = [{ 1792 return emitRVVSetBuiltin(this, E, ReturnValue, ResultType, ID, Ops, 1793 PolicyAttrs, IsMasked, SegInstSEW); 1794 }] in { 1795 foreach dst_lmul = ["(LFixedLog2LMUL:1)", "(LFixedLog2LMUL:2)", "(LFixedLog2LMUL:3)"] in { 1796 def : RVVBuiltin<"v" # dst_lmul # "v", dst_lmul # "v" # dst_lmul # "vKzv", "csilxfdy">; 1797 def : RVVBuiltin<"Uv" # dst_lmul # "Uv", dst_lmul # "Uv" # dst_lmul #"UvKzUv", "csil">; 1798 } 1799 foreach nf = NFList in { 1800 defvar T = "(Tuple:" # nf # ")"; 1801 def : RVVBuiltin<"v" # T # "v", T # "v" # T # "vKzv", "csilxfdy">; 1802 def : RVVBuiltin<"Uv" # T # "Uv", T # "Uv" # T # "UvKzUv", "csil">; 1803 } 1804 } 1805 1806 let Name = "vcreate_v", 1807 UnMaskedPolicyScheme = NonePolicy, 1808 MaskedPolicyScheme = NonePolicy, 1809 SupportOverloading = false, 1810 ManualCodegen = [{ 1811 return emitRVVCreateBuiltin(this, E, ReturnValue, ResultType, ID, Ops, 1812 PolicyAttrs, IsMasked, SegInstSEW); 1813 }] in { 1814 1815 // Since the vcreate_v uses LFixedLog2LMUL, setting the Log2LMUL to [-3] can 1816 // avoid creating the intrinsics which contain the same name and prototype. 1817 let Log2LMUL = [-3] in { 1818 defm : RVVNonTupleVCreateBuiltin<1, [0]>; 1819 defm : RVVNonTupleVCreateBuiltin<2, [0, 1]>; 1820 defm : RVVNonTupleVCreateBuiltin<3, [0, 1, 2]>; 1821 } 1822 1823 foreach nf = NFList in { 1824 let NF = nf in { 1825 defvar T = "(Tuple:" # nf # ")"; 1826 defvar V = VString<nf, /*signed=*/true>.S; 1827 defvar UV = VString<nf, /*signed=*/false>.S; 1828 def : RVVBuiltin<T # "v", T # "v" # V, "csilxfdy">; 1829 def : RVVBuiltin<T # "Uv", T # "Uv" # UV, "csil">; 1830 } 1831 } 1832 } 1833} 1834 1835multiclass RVVOutBuiltinSetZvbb { 1836 let OverloadedName = NAME in 1837 defm "" : RVVOutBuiltinSet<NAME, "csil", [["v", "v", "vv"], 1838 ["v", "Uv", "UvUv"]]>; 1839} 1840 1841multiclass RVVOutBuiltinSetZvk<bit HasVV = 1, bit HasVS = 1> { 1842 // vaesz only has 'vs' and vgmul only has 'vv' and they do not have ambiguous 1843 // prototypes like other zvkned instructions (e.g. vaesdf), so we don't 1844 // need to encode the operand mnemonics into its intrinsic function name. 1845 if HasVV then { 1846 defvar name = NAME # !if(!eq(NAME, "vgmul"), "", "_vv"); 1847 let OverloadedName = name in 1848 defm "" : RVVOutBuiltinSet<NAME # "_vv", "i", 1849 [["vv", "Uv", "UvUvUv"]]>; 1850 } 1851 1852 if HasVS then { 1853 foreach vs2_lmul = ["(SEFixedLog2LMUL:-1)", "(SEFixedLog2LMUL:0)", 1854 "(SEFixedLog2LMUL:1)", "(SEFixedLog2LMUL:2)"] in { 1855 defvar name = NAME # !if(!eq(NAME, "vaesz"), "", "_vs"); 1856 let OverloadedName = name, IRName = NAME # "_vs", Name = NAME # "_vs", 1857 IntrinsicTypes = [-1, 1] in 1858 def NAME # vs2_lmul 1859 : RVVBuiltin<vs2_lmul # "UvUv", "UvUv" # vs2_lmul # "Uv", "i">; 1860 } 1861 } 1862} 1863 1864multiclass RVVOutOp2BuiltinSetVVZvk<string type_range = "i"> 1865 : RVVOutOp2BuiltinSet<NAME, type_range, [["vv", "Uv", "UvUvUvUv"]]>; 1866 1867multiclass RVVOutOp2BuiltinSetVIZvk<string type_range = "i"> 1868 : RVVOutOp2BuiltinSet<NAME, type_range, [["vi", "Uv", "UvUvUvKz"]]>; 1869 1870multiclass RVVSignedWidenBinBuiltinSetVwsll 1871 : RVVWidenBuiltinSet<NAME, "csi", 1872 [["vv", "Uw", "UwUvUv"], 1873 ["vx", "Uw", "UwUvz"]]>; 1874 1875let UnMaskedPolicyScheme = HasPassthruOperand in { 1876 // zvkb 1877 let RequiredFeatures = ["zvkb"] in { 1878 defm vandn : RVVUnsignedBinBuiltinSet; 1879 defm vbrev8 : RVVOutBuiltinSetZvbb; 1880 defm vrev8 : RVVOutBuiltinSetZvbb; 1881 defm vrol : RVVUnsignedShiftBuiltinSet; 1882 defm vror : RVVUnsignedShiftBuiltinSet; 1883 } 1884 1885 // zvbb 1886 let RequiredFeatures = ["zvbb"] in { 1887 defm vbrev : RVVOutBuiltinSetZvbb; 1888 defm vclz : RVVOutBuiltinSetZvbb; 1889 defm vctz : RVVOutBuiltinSetZvbb; 1890 let IRName = "vcpopv", MaskedIRName = "vcpopv_mask" in 1891 defm vcpop : RVVOutBuiltinSetZvbb; 1892 let OverloadedName = "vwsll" in 1893 defm vwsll : RVVSignedWidenBinBuiltinSetVwsll; 1894 } 1895 1896 // zvbc 1897 let RequiredFeatures = ["zvbc"] in { 1898 defm vclmul : RVVInt64BinBuiltinSet; 1899 defm vclmulh : RVVInt64BinBuiltinSet; 1900 } 1901} 1902 1903let UnMaskedPolicyScheme = HasPolicyOperand, HasMasked = false in { 1904 // zvkg 1905 let RequiredFeatures = ["zvkg"] in { 1906 defm vghsh : RVVOutOp2BuiltinSetVVZvk; 1907 defm vgmul : RVVOutBuiltinSetZvk<HasVV=1, HasVS=0>; 1908 } 1909 1910 // zvkned 1911 let RequiredFeatures = ["zvkned"] in { 1912 defm vaesdf : RVVOutBuiltinSetZvk; 1913 defm vaesdm : RVVOutBuiltinSetZvk; 1914 defm vaesef : RVVOutBuiltinSetZvk; 1915 defm vaesem : RVVOutBuiltinSetZvk; 1916 let UnMaskedPolicyScheme = HasPassthruOperand in 1917 defm vaeskf1 : RVVOutOp1BuiltinSet<"vaeskf1", "i", [["vi", "Uv", "UvUvKz"]]>; 1918 defm vaeskf2 : RVVOutOp2BuiltinSetVIZvk; 1919 defm vaesz : RVVOutBuiltinSetZvk<HasVV=0>; 1920 } 1921 1922 // zvknha and zvknhb has duplicated intrinsic but they don't imply each other, 1923 // so we need to handle it manually in SemaRISCV.cpp. 1924 defm vsha2ch : RVVOutOp2BuiltinSetVVZvk<"il">; 1925 defm vsha2cl : RVVOutOp2BuiltinSetVVZvk<"il">; 1926 defm vsha2ms : RVVOutOp2BuiltinSetVVZvk<"il">; 1927 1928 // zvksed 1929 let RequiredFeatures = ["zvksed"] in { 1930 let UnMaskedPolicyScheme = HasPassthruOperand in 1931 defm vsm4k : RVVOutOp1BuiltinSet<"vsm4k", "i", [["vi", "Uv", "UvUvKz"]]>; 1932 defm vsm4r : RVVOutBuiltinSetZvk; 1933 } 1934 1935 // zvksh 1936 let RequiredFeatures = ["zvksh"] in { 1937 defm vsm3c : RVVOutOp2BuiltinSetVIZvk; 1938 let UnMaskedPolicyScheme = HasPassthruOperand in 1939 defm vsm3me : RVVOutOp1BuiltinSet<"vsm3me", "i", [["vv", "Uv", "UvUvUv"]]>; 1940 } 1941} 1942