1//===-- GenericOpcodes.td - Opcodes used with GlobalISel ---*- tablegen -*-===// 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 generic opcodes used with GlobalISel. 10// After instruction selection, these opcodes should not appear. 11// 12//===----------------------------------------------------------------------===// 13 14//------------------------------------------------------------------------------ 15// Unary ops. 16//------------------------------------------------------------------------------ 17 18class GenericInstruction : StandardPseudoInstruction { 19 let isPreISelOpcode = true; 20} 21 22// Provide a variant of an instruction with the same operands, but 23// different instruction flags. This is intended to provide a 24// convenient way to define strict floating point variants of ordinary 25// floating point instructions. 26class ConstrainedIntruction<GenericInstruction baseInst> : 27 GenericInstruction { 28 let OutOperandList = baseInst.OutOperandList; 29 let InOperandList = baseInst.InOperandList; 30 let isCommutable = baseInst.isCommutable; 31 32 // TODO: Do we need a better way to mark reads from FP mode than 33 // hasSideEffects? 34 let hasSideEffects = true; 35 let mayRaiseFPException = true; 36} 37 38// Extend the underlying scalar type of an operation, leaving the high bits 39// unspecified. 40def G_ANYEXT : GenericInstruction { 41 let OutOperandList = (outs type0:$dst); 42 let InOperandList = (ins type1:$src); 43 let hasSideEffects = false; 44} 45 46// Sign extend the underlying scalar type of an operation, copying the sign bit 47// into the newly-created space. 48def G_SEXT : GenericInstruction { 49 let OutOperandList = (outs type0:$dst); 50 let InOperandList = (ins type1:$src); 51 let hasSideEffects = false; 52} 53 54// Sign extend the a value from an arbitrary bit position, copying the sign bit 55// into all bits above it. This is equivalent to a shl + ashr pair with an 56// appropriate shift amount. $sz is an immediate (MachineOperand::isImm() 57// returns true) to allow targets to have some bitwidths legal and others 58// lowered. This opcode is particularly useful if the target has sign-extension 59// instructions that are cheaper than the constituent shifts as the optimizer is 60// able to make decisions on whether it's better to hang on to the G_SEXT_INREG 61// or to lower it and optimize the individual shifts. 62def G_SEXT_INREG : GenericInstruction { 63 let OutOperandList = (outs type0:$dst); 64 let InOperandList = (ins type0:$src, untyped_imm_0:$sz); 65 let hasSideEffects = false; 66} 67 68// Zero extend the underlying scalar type of an operation, putting zero bits 69// into the newly-created space. 70def G_ZEXT : GenericInstruction { 71 let OutOperandList = (outs type0:$dst); 72 let InOperandList = (ins type1:$src); 73 let hasSideEffects = false; 74} 75 76 77// Truncate the underlying scalar type of an operation. This is equivalent to 78// G_EXTRACT for scalar types, but acts elementwise on vectors. 79def G_TRUNC : GenericInstruction { 80 let OutOperandList = (outs type0:$dst); 81 let InOperandList = (ins type1:$src); 82 let hasSideEffects = false; 83} 84 85def G_IMPLICIT_DEF : GenericInstruction { 86 let OutOperandList = (outs type0:$dst); 87 let InOperandList = (ins); 88 let hasSideEffects = false; 89} 90 91def G_PHI : GenericInstruction { 92 let OutOperandList = (outs type0:$dst); 93 let InOperandList = (ins variable_ops); 94 let hasSideEffects = false; 95} 96 97def G_FRAME_INDEX : GenericInstruction { 98 let OutOperandList = (outs type0:$dst); 99 let InOperandList = (ins unknown:$src2); 100 let hasSideEffects = false; 101} 102 103def G_GLOBAL_VALUE : GenericInstruction { 104 let OutOperandList = (outs type0:$dst); 105 let InOperandList = (ins unknown:$src); 106 let hasSideEffects = false; 107} 108 109def G_INTTOPTR : GenericInstruction { 110 let OutOperandList = (outs type0:$dst); 111 let InOperandList = (ins type1:$src); 112 let hasSideEffects = false; 113} 114 115def G_PTRTOINT : GenericInstruction { 116 let OutOperandList = (outs type0:$dst); 117 let InOperandList = (ins type1:$src); 118 let hasSideEffects = false; 119} 120 121def G_BITCAST : GenericInstruction { 122 let OutOperandList = (outs type0:$dst); 123 let InOperandList = (ins type1:$src); 124 let hasSideEffects = false; 125} 126 127// Only supports scalar result types 128def G_CONSTANT : GenericInstruction { 129 let OutOperandList = (outs type0:$dst); 130 let InOperandList = (ins unknown:$imm); 131 let hasSideEffects = false; 132} 133 134// Only supports scalar result types 135def G_FCONSTANT : GenericInstruction { 136 let OutOperandList = (outs type0:$dst); 137 let InOperandList = (ins unknown:$imm); 138 let hasSideEffects = false; 139} 140 141def G_VASTART : GenericInstruction { 142 let OutOperandList = (outs); 143 let InOperandList = (ins type0:$list); 144 let hasSideEffects = false; 145 let mayStore = true; 146} 147 148def G_VAARG : GenericInstruction { 149 let OutOperandList = (outs type0:$val); 150 let InOperandList = (ins type1:$list, unknown:$align); 151 let hasSideEffects = false; 152 let mayLoad = true; 153 let mayStore = true; 154} 155 156def G_CTLZ : GenericInstruction { 157 let OutOperandList = (outs type0:$dst); 158 let InOperandList = (ins type1:$src); 159 let hasSideEffects = false; 160} 161 162def G_CTLZ_ZERO_UNDEF : GenericInstruction { 163 let OutOperandList = (outs type0:$dst); 164 let InOperandList = (ins type1:$src); 165 let hasSideEffects = false; 166} 167 168def G_CTTZ : GenericInstruction { 169 let OutOperandList = (outs type0:$dst); 170 let InOperandList = (ins type1:$src); 171 let hasSideEffects = false; 172} 173 174def G_CTTZ_ZERO_UNDEF : GenericInstruction { 175 let OutOperandList = (outs type0:$dst); 176 let InOperandList = (ins type1:$src); 177 let hasSideEffects = false; 178} 179 180def G_CTPOP : GenericInstruction { 181 let OutOperandList = (outs type0:$dst); 182 let InOperandList = (ins type1:$src); 183 let hasSideEffects = false; 184} 185 186def G_BSWAP : GenericInstruction { 187 let OutOperandList = (outs type0:$dst); 188 let InOperandList = (ins type0:$src); 189 let hasSideEffects = false; 190} 191 192def G_BITREVERSE : GenericInstruction { 193 let OutOperandList = (outs type0:$dst); 194 let InOperandList = (ins type0:$src); 195 let hasSideEffects = false; 196} 197 198def G_ADDRSPACE_CAST : GenericInstruction { 199 let OutOperandList = (outs type0:$dst); 200 let InOperandList = (ins type1:$src); 201 let hasSideEffects = false; 202} 203 204def G_BLOCK_ADDR : GenericInstruction { 205 let OutOperandList = (outs type0:$dst); 206 let InOperandList = (ins unknown:$ba); 207 let hasSideEffects = false; 208} 209 210def G_JUMP_TABLE : GenericInstruction { 211 let OutOperandList = (outs type0:$dst); 212 let InOperandList = (ins unknown:$jti); 213 let hasSideEffects = false; 214} 215 216def G_DYN_STACKALLOC : GenericInstruction { 217 let OutOperandList = (outs ptype0:$dst); 218 let InOperandList = (ins type1:$size, i32imm:$align); 219 let hasSideEffects = true; 220} 221 222def G_FREEZE : GenericInstruction { 223 let OutOperandList = (outs type0:$dst); 224 let InOperandList = (ins type0:$src); 225 let hasSideEffects = false; 226} 227 228def G_LROUND: GenericInstruction { 229 let OutOperandList = (outs type0:$dst); 230 let InOperandList = (ins type1:$src); 231 let hasSideEffects = false; 232} 233 234def G_LLROUND: GenericInstruction { 235 let OutOperandList = (outs type0:$dst); 236 let InOperandList = (ins type1:$src); 237 let hasSideEffects = false; 238} 239 240//------------------------------------------------------------------------------ 241// Binary ops. 242//------------------------------------------------------------------------------ 243 244// Generic addition. 245def G_ADD : GenericInstruction { 246 let OutOperandList = (outs type0:$dst); 247 let InOperandList = (ins type0:$src1, type0:$src2); 248 let hasSideEffects = false; 249 let isCommutable = true; 250} 251 252// Generic subtraction. 253def G_SUB : GenericInstruction { 254 let OutOperandList = (outs type0:$dst); 255 let InOperandList = (ins type0:$src1, type0:$src2); 256 let hasSideEffects = false; 257 let isCommutable = false; 258} 259 260// Generic multiplication. 261def G_MUL : GenericInstruction { 262 let OutOperandList = (outs type0:$dst); 263 let InOperandList = (ins type0:$src1, type0:$src2); 264 let hasSideEffects = false; 265 let isCommutable = true; 266} 267 268// Generic signed division. 269def G_SDIV : GenericInstruction { 270 let OutOperandList = (outs type0:$dst); 271 let InOperandList = (ins type0:$src1, type0:$src2); 272 let hasSideEffects = false; 273 let isCommutable = false; 274} 275 276// Generic unsigned division. 277def G_UDIV : GenericInstruction { 278 let OutOperandList = (outs type0:$dst); 279 let InOperandList = (ins type0:$src1, type0:$src2); 280 let hasSideEffects = false; 281 let isCommutable = false; 282} 283 284// Generic signed remainder. 285def G_SREM : GenericInstruction { 286 let OutOperandList = (outs type0:$dst); 287 let InOperandList = (ins type0:$src1, type0:$src2); 288 let hasSideEffects = false; 289 let isCommutable = false; 290} 291 292// Generic unsigned remainder. 293def G_UREM : GenericInstruction { 294 let OutOperandList = (outs type0:$dst); 295 let InOperandList = (ins type0:$src1, type0:$src2); 296 let hasSideEffects = false; 297 let isCommutable = false; 298} 299 300// Generic signed division and remainder. 301def G_SDIVREM : GenericInstruction { 302 let OutOperandList = (outs type0:$div, type0:$rem); 303 let InOperandList = (ins type0:$src1, type0:$src2); 304 let hasSideEffects = false; 305 let isCommutable = false; 306} 307 308// Generic unsigned division and remainder. 309def G_UDIVREM : GenericInstruction { 310 let OutOperandList = (outs type0:$div, type0:$rem); 311 let InOperandList = (ins type0:$src1, type0:$src2); 312 let hasSideEffects = false; 313 let isCommutable = false; 314} 315 316// Generic bitwise and. 317def G_AND : GenericInstruction { 318 let OutOperandList = (outs type0:$dst); 319 let InOperandList = (ins type0:$src1, type0:$src2); 320 let hasSideEffects = false; 321 let isCommutable = true; 322} 323 324// Generic bitwise or. 325def G_OR : GenericInstruction { 326 let OutOperandList = (outs type0:$dst); 327 let InOperandList = (ins type0:$src1, type0:$src2); 328 let hasSideEffects = false; 329 let isCommutable = true; 330} 331 332// Generic bitwise xor. 333def G_XOR : GenericInstruction { 334 let OutOperandList = (outs type0:$dst); 335 let InOperandList = (ins type0:$src1, type0:$src2); 336 let hasSideEffects = false; 337 let isCommutable = true; 338} 339 340// Generic left-shift. 341def G_SHL : GenericInstruction { 342 let OutOperandList = (outs type0:$dst); 343 let InOperandList = (ins type0:$src1, type1:$src2); 344 let hasSideEffects = false; 345} 346 347// Generic logical right-shift. 348def G_LSHR : GenericInstruction { 349 let OutOperandList = (outs type0:$dst); 350 let InOperandList = (ins type0:$src1, type1:$src2); 351 let hasSideEffects = false; 352} 353 354// Generic arithmetic right-shift. 355def G_ASHR : GenericInstruction { 356 let OutOperandList = (outs type0:$dst); 357 let InOperandList = (ins type0:$src1, type1:$src2); 358 let hasSideEffects = false; 359} 360 361/// Funnel 'double' shifts take 3 operands, 2 inputs and the shift amount. 362/// fshl(X,Y,Z): (X << (Z % bitwidth)) | (Y >> (bitwidth - (Z % bitwidth))) 363def G_FSHL : GenericInstruction { 364 let OutOperandList = (outs type0:$dst); 365 let InOperandList = (ins type0:$src1, type0:$src2, type1:$src3); 366 let hasSideEffects = false; 367} 368 369/// Funnel 'double' shifts take 3 operands, 2 inputs and the shift amount. 370/// fshr(X,Y,Z): (X << (bitwidth - (Z % bitwidth))) | (Y >> (Z % bitwidth)) 371def G_FSHR : GenericInstruction { 372 let OutOperandList = (outs type0:$dst); 373 let InOperandList = (ins type0:$src1, type0:$src2, type1:$src3); 374 let hasSideEffects = false; 375} 376 377/// Rotate bits right. 378def G_ROTR : GenericInstruction { 379 let OutOperandList = (outs type0:$dst); 380 let InOperandList = (ins type0:$src1, type1:$src2); 381 let hasSideEffects = false; 382} 383 384/// Rotate bits left. 385def G_ROTL : GenericInstruction { 386 let OutOperandList = (outs type0:$dst); 387 let InOperandList = (ins type0:$src1, type1:$src2); 388 let hasSideEffects = false; 389} 390 391// Generic integer comparison. 392def G_ICMP : GenericInstruction { 393 let OutOperandList = (outs type0:$dst); 394 let InOperandList = (ins unknown:$tst, type1:$src1, type1:$src2); 395 let hasSideEffects = false; 396} 397 398// Generic floating-point comparison. 399def G_FCMP : GenericInstruction { 400 let OutOperandList = (outs type0:$dst); 401 let InOperandList = (ins unknown:$tst, type1:$src1, type1:$src2); 402 let hasSideEffects = false; 403} 404 405// Generic select 406def G_SELECT : GenericInstruction { 407 let OutOperandList = (outs type0:$dst); 408 let InOperandList = (ins type1:$tst, type0:$src1, type0:$src2); 409 let hasSideEffects = false; 410} 411 412// Generic pointer offset. 413def G_PTR_ADD : GenericInstruction { 414 let OutOperandList = (outs type0:$dst); 415 let InOperandList = (ins type0:$src1, type1:$src2); 416 let hasSideEffects = false; 417} 418 419// Generic pointer mask. type1 should be an integer with the same 420// bitwidth as the pointer type. 421def G_PTRMASK : GenericInstruction { 422 let OutOperandList = (outs ptype0:$dst); 423 let InOperandList = (ins ptype0:$src, type1:$bits); 424 let hasSideEffects = false; 425} 426 427// Generic signed integer minimum. 428def G_SMIN : GenericInstruction { 429 let OutOperandList = (outs type0:$dst); 430 let InOperandList = (ins type0:$src1, type0:$src2); 431 let hasSideEffects = false; 432 let isCommutable = true; 433} 434 435// Generic signed integer maximum. 436def G_SMAX : GenericInstruction { 437 let OutOperandList = (outs type0:$dst); 438 let InOperandList = (ins type0:$src1, type0:$src2); 439 let hasSideEffects = false; 440 let isCommutable = true; 441} 442 443// Generic unsigned integer minimum. 444def G_UMIN : GenericInstruction { 445 let OutOperandList = (outs type0:$dst); 446 let InOperandList = (ins type0:$src1, type0:$src2); 447 let hasSideEffects = false; 448 let isCommutable = true; 449} 450 451// Generic unsigned integer maximum. 452def G_UMAX : GenericInstruction { 453 let OutOperandList = (outs type0:$dst); 454 let InOperandList = (ins type0:$src1, type0:$src2); 455 let hasSideEffects = false; 456 let isCommutable = true; 457} 458 459// Generic integer absolute value. 460def G_ABS : GenericInstruction { 461 let OutOperandList = (outs type0:$dst); 462 let InOperandList = (ins type0:$src); 463 let hasSideEffects = false; 464} 465 466//------------------------------------------------------------------------------ 467// Overflow ops 468//------------------------------------------------------------------------------ 469 470// Generic unsigned addition producing a carry flag. 471def G_UADDO : GenericInstruction { 472 let OutOperandList = (outs type0:$dst, type1:$carry_out); 473 let InOperandList = (ins type0:$src1, type0:$src2); 474 let hasSideEffects = false; 475 let isCommutable = true; 476} 477 478// Generic unsigned addition consuming and producing a carry flag. 479def G_UADDE : GenericInstruction { 480 let OutOperandList = (outs type0:$dst, type1:$carry_out); 481 let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in); 482 let hasSideEffects = false; 483} 484 485// Generic signed addition producing a carry flag. 486def G_SADDO : GenericInstruction { 487 let OutOperandList = (outs type0:$dst, type1:$carry_out); 488 let InOperandList = (ins type0:$src1, type0:$src2); 489 let hasSideEffects = false; 490 let isCommutable = true; 491} 492 493// Generic signed addition consuming and producing a carry flag. 494def G_SADDE : GenericInstruction { 495 let OutOperandList = (outs type0:$dst, type1:$carry_out); 496 let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in); 497 let hasSideEffects = false; 498} 499 500// Generic unsigned subtraction producing a carry flag. 501def G_USUBO : GenericInstruction { 502 let OutOperandList = (outs type0:$dst, type1:$carry_out); 503 let InOperandList = (ins type0:$src1, type0:$src2); 504 let hasSideEffects = false; 505} 506// Generic unsigned subtraction consuming and producing a carry flag. 507def G_USUBE : GenericInstruction { 508 let OutOperandList = (outs type0:$dst, type1:$carry_out); 509 let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in); 510 let hasSideEffects = false; 511} 512 513// Generic signed subtraction producing a carry flag. 514def G_SSUBO : GenericInstruction { 515 let OutOperandList = (outs type0:$dst, type1:$carry_out); 516 let InOperandList = (ins type0:$src1, type0:$src2); 517 let hasSideEffects = false; 518} 519 520// Generic signed subtraction consuming and producing a carry flag. 521def G_SSUBE : GenericInstruction { 522 let OutOperandList = (outs type0:$dst, type1:$carry_out); 523 let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in); 524 let hasSideEffects = false; 525} 526 527// Generic unsigned multiplication producing a carry flag. 528def G_UMULO : GenericInstruction { 529 let OutOperandList = (outs type0:$dst, type1:$carry_out); 530 let InOperandList = (ins type0:$src1, type0:$src2); 531 let hasSideEffects = false; 532 let isCommutable = true; 533} 534 535// Generic signed multiplication producing a carry flag. 536def G_SMULO : GenericInstruction { 537 let OutOperandList = (outs type0:$dst, type1:$carry_out); 538 let InOperandList = (ins type0:$src1, type0:$src2); 539 let hasSideEffects = false; 540 let isCommutable = true; 541} 542 543// Multiply two numbers at twice the incoming bit width (unsigned) and return 544// the high half of the result. 545def G_UMULH : GenericInstruction { 546 let OutOperandList = (outs type0:$dst); 547 let InOperandList = (ins type0:$src1, type0:$src2); 548 let hasSideEffects = false; 549 let isCommutable = true; 550} 551 552// Multiply two numbers at twice the incoming bit width (signed) and return 553// the high half of the result. 554def G_SMULH : GenericInstruction { 555 let OutOperandList = (outs type0:$dst); 556 let InOperandList = (ins type0:$src1, type0:$src2); 557 let hasSideEffects = false; 558 let isCommutable = true; 559} 560 561//------------------------------------------------------------------------------ 562// Saturating ops 563//------------------------------------------------------------------------------ 564 565// Generic saturating unsigned addition. 566def G_UADDSAT : GenericInstruction { 567 let OutOperandList = (outs type0:$dst); 568 let InOperandList = (ins type0:$src1, type0:$src2); 569 let hasSideEffects = false; 570 let isCommutable = true; 571} 572 573// Generic saturating signed addition. 574def G_SADDSAT : GenericInstruction { 575 let OutOperandList = (outs type0:$dst); 576 let InOperandList = (ins type0:$src1, type0:$src2); 577 let hasSideEffects = false; 578 let isCommutable = true; 579} 580 581// Generic saturating unsigned subtraction. 582def G_USUBSAT : GenericInstruction { 583 let OutOperandList = (outs type0:$dst); 584 let InOperandList = (ins type0:$src1, type0:$src2); 585 let hasSideEffects = false; 586 let isCommutable = false; 587} 588 589// Generic saturating signed subtraction. 590def G_SSUBSAT : GenericInstruction { 591 let OutOperandList = (outs type0:$dst); 592 let InOperandList = (ins type0:$src1, type0:$src2); 593 let hasSideEffects = false; 594 let isCommutable = false; 595} 596 597// Generic saturating unsigned left shift. 598def G_USHLSAT : GenericInstruction { 599 let OutOperandList = (outs type0:$dst); 600 let InOperandList = (ins type0:$src1, type1:$src2); 601 let hasSideEffects = false; 602 let isCommutable = false; 603} 604 605// Generic saturating signed left shift. 606def G_SSHLSAT : GenericInstruction { 607 let OutOperandList = (outs type0:$dst); 608 let InOperandList = (ins type0:$src1, type1:$src2); 609 let hasSideEffects = false; 610 let isCommutable = false; 611} 612 613/// RESULT = [US]MULFIX(LHS, RHS, SCALE) - Perform fixed point 614/// multiplication on 2 integers with the same width and scale. SCALE 615/// represents the scale of both operands as fixed point numbers. This 616/// SCALE parameter must be a constant integer. A scale of zero is 617/// effectively performing multiplication on 2 integers. 618def G_SMULFIX : GenericInstruction { 619 let OutOperandList = (outs type0:$dst); 620 let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale); 621 let hasSideEffects = false; 622 let isCommutable = true; 623} 624 625def G_UMULFIX : GenericInstruction { 626 let OutOperandList = (outs type0:$dst); 627 let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale); 628 let hasSideEffects = false; 629 let isCommutable = true; 630} 631 632/// Same as the corresponding unsaturated fixed point instructions, but the 633/// result is clamped between the min and max values representable by the 634/// bits of the first 2 operands. 635def G_SMULFIXSAT : GenericInstruction { 636 let OutOperandList = (outs type0:$dst); 637 let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale); 638 let hasSideEffects = false; 639 let isCommutable = true; 640} 641 642def G_UMULFIXSAT : GenericInstruction { 643 let OutOperandList = (outs type0:$dst); 644 let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale); 645 let hasSideEffects = false; 646 let isCommutable = true; 647} 648 649/// RESULT = [US]DIVFIX(LHS, RHS, SCALE) - Perform fixed point division on 650/// 2 integers with the same width and scale. SCALE represents the scale 651/// of both operands as fixed point numbers. This SCALE parameter must be a 652/// constant integer. 653def G_SDIVFIX : GenericInstruction { 654 let OutOperandList = (outs type0:$dst); 655 let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale); 656 let hasSideEffects = false; 657 let isCommutable = false; 658} 659 660def G_UDIVFIX : GenericInstruction { 661 let OutOperandList = (outs type0:$dst); 662 let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale); 663 let hasSideEffects = false; 664 let isCommutable = false; 665} 666 667/// Same as the corresponding unsaturated fixed point instructions, 668/// but the result is clamped between the min and max values 669/// representable by the bits of the first 2 operands. 670def G_SDIVFIXSAT : GenericInstruction { 671 let OutOperandList = (outs type0:$dst); 672 let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale); 673 let hasSideEffects = false; 674 let isCommutable = false; 675} 676 677def G_UDIVFIXSAT : GenericInstruction { 678 let OutOperandList = (outs type0:$dst); 679 let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale); 680 let hasSideEffects = false; 681 let isCommutable = false; 682} 683 684//------------------------------------------------------------------------------ 685// Floating Point Unary Ops. 686//------------------------------------------------------------------------------ 687 688def G_FNEG : GenericInstruction { 689 let OutOperandList = (outs type0:$dst); 690 let InOperandList = (ins type0:$src); 691 let hasSideEffects = false; 692} 693 694def G_FPEXT : GenericInstruction { 695 let OutOperandList = (outs type0:$dst); 696 let InOperandList = (ins type1:$src); 697 let hasSideEffects = false; 698} 699 700def G_FPTRUNC : GenericInstruction { 701 let OutOperandList = (outs type0:$dst); 702 let InOperandList = (ins type1:$src); 703 let hasSideEffects = false; 704} 705 706def G_FPTOSI : GenericInstruction { 707 let OutOperandList = (outs type0:$dst); 708 let InOperandList = (ins type1:$src); 709 let hasSideEffects = false; 710} 711 712def G_FPTOUI : GenericInstruction { 713 let OutOperandList = (outs type0:$dst); 714 let InOperandList = (ins type1:$src); 715 let hasSideEffects = false; 716} 717 718def G_SITOFP : GenericInstruction { 719 let OutOperandList = (outs type0:$dst); 720 let InOperandList = (ins type1:$src); 721 let hasSideEffects = false; 722} 723 724def G_UITOFP : GenericInstruction { 725 let OutOperandList = (outs type0:$dst); 726 let InOperandList = (ins type1:$src); 727 let hasSideEffects = false; 728} 729 730def G_FABS : GenericInstruction { 731 let OutOperandList = (outs type0:$dst); 732 let InOperandList = (ins type0:$src); 733 let hasSideEffects = false; 734} 735 736def G_FCOPYSIGN : GenericInstruction { 737 let OutOperandList = (outs type0:$dst); 738 let InOperandList = (ins type0:$src0, type1:$src1); 739 let hasSideEffects = false; 740} 741 742def G_FCANONICALIZE : GenericInstruction { 743 let OutOperandList = (outs type0:$dst); 744 let InOperandList = (ins type0:$src); 745 let hasSideEffects = false; 746} 747 748// Generic opcode equivalent to the llvm.is_fpclass intrinsic. 749def G_IS_FPCLASS: GenericInstruction { 750 let OutOperandList = (outs type0:$dst); 751 let InOperandList = (ins type1:$src, unknown:$test, unknown:$fpsem); 752 let hasSideEffects = false; 753} 754 755// FMINNUM/FMAXNUM - Perform floating-point minimum or maximum on two 756// values. 757// 758// In the case where a single input is a NaN (either signaling or quiet), 759// the non-NaN input is returned. 760// 761// The return value of (FMINNUM 0.0, -0.0) could be either 0.0 or -0.0. 762def G_FMINNUM : GenericInstruction { 763 let OutOperandList = (outs type0:$dst); 764 let InOperandList = (ins type0:$src1, type0:$src2); 765 let hasSideEffects = false; 766 let isCommutable = true; 767} 768 769def G_FMAXNUM : GenericInstruction { 770 let OutOperandList = (outs type0:$dst); 771 let InOperandList = (ins type0:$src1, type0:$src2); 772 let hasSideEffects = false; 773 let isCommutable = true; 774} 775 776// FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimum or maximum on 777// two values, following the IEEE-754 2008 definition. This differs from 778// FMINNUM/FMAXNUM in the handling of signaling NaNs. If one input is a 779// signaling NaN, returns a quiet NaN. 780def G_FMINNUM_IEEE : GenericInstruction { 781 let OutOperandList = (outs type0:$dst); 782 let InOperandList = (ins type0:$src1, type0:$src2); 783 let hasSideEffects = false; 784 let isCommutable = true; 785} 786 787def G_FMAXNUM_IEEE : GenericInstruction { 788 let OutOperandList = (outs type0:$dst); 789 let InOperandList = (ins type0:$src1, type0:$src2); 790 let hasSideEffects = false; 791 let isCommutable = true; 792} 793 794// FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 795// as less than 0.0. While FMINNUM_IEEE/FMAXNUM_IEEE follow IEEE 754-2008 796// semantics, FMINIMUM/FMAXIMUM follow IEEE 754-2018 draft semantics. 797def G_FMINIMUM : GenericInstruction { 798 let OutOperandList = (outs type0:$dst); 799 let InOperandList = (ins type0:$src1, type0:$src2); 800 let hasSideEffects = false; 801 let isCommutable = true; 802} 803 804def G_FMAXIMUM : GenericInstruction { 805 let OutOperandList = (outs type0:$dst); 806 let InOperandList = (ins type0:$src1, type0:$src2); 807 let hasSideEffects = false; 808 let isCommutable = true; 809} 810 811//------------------------------------------------------------------------------ 812// Floating Point Binary ops. 813//------------------------------------------------------------------------------ 814 815// Generic FP addition. 816def G_FADD : GenericInstruction { 817 let OutOperandList = (outs type0:$dst); 818 let InOperandList = (ins type0:$src1, type0:$src2); 819 let hasSideEffects = false; 820 let isCommutable = true; 821} 822 823// Generic FP subtraction. 824def G_FSUB : GenericInstruction { 825 let OutOperandList = (outs type0:$dst); 826 let InOperandList = (ins type0:$src1, type0:$src2); 827 let hasSideEffects = false; 828 let isCommutable = false; 829} 830 831// Generic FP multiplication. 832def G_FMUL : GenericInstruction { 833 let OutOperandList = (outs type0:$dst); 834 let InOperandList = (ins type0:$src1, type0:$src2); 835 let hasSideEffects = false; 836 let isCommutable = true; 837} 838 839// Generic fused multiply-add instruction. 840// Behaves like llvm fma intrinsic ie src1 * src2 + src3 841def G_FMA : GenericInstruction { 842 let OutOperandList = (outs type0:$dst); 843 let InOperandList = (ins type0:$src1, type0:$src2, type0:$src3); 844 let hasSideEffects = false; 845 let isCommutable = false; 846} 847 848/// Generic FP multiply and add. Perform a * b + c, while getting the 849/// same result as the separately rounded operations, unlike G_FMA. 850def G_FMAD : GenericInstruction { 851 let OutOperandList = (outs type0:$dst); 852 let InOperandList = (ins type0:$src1, type0:$src2, type0:$src3); 853 let hasSideEffects = false; 854 let isCommutable = false; 855} 856 857// Generic FP division. 858def G_FDIV : GenericInstruction { 859 let OutOperandList = (outs type0:$dst); 860 let InOperandList = (ins type0:$src1, type0:$src2); 861 let hasSideEffects = false; 862} 863 864// Generic FP remainder. 865def G_FREM : GenericInstruction { 866 let OutOperandList = (outs type0:$dst); 867 let InOperandList = (ins type0:$src1, type0:$src2); 868 let hasSideEffects = false; 869} 870 871// Floating point exponentiation. 872def G_FPOW : GenericInstruction { 873 let OutOperandList = (outs type0:$dst); 874 let InOperandList = (ins type0:$src1, type0:$src2); 875 let hasSideEffects = false; 876} 877 878// Floating point exponentiation, with an integer power. 879def G_FPOWI : GenericInstruction { 880 let OutOperandList = (outs type0:$dst); 881 let InOperandList = (ins type0:$src0, type1:$src1); 882 let hasSideEffects = false; 883} 884 885// Floating point base-e exponential of a value. 886def G_FEXP : GenericInstruction { 887 let OutOperandList = (outs type0:$dst); 888 let InOperandList = (ins type0:$src1); 889 let hasSideEffects = false; 890} 891 892// Floating point base-2 exponential of a value. 893def G_FEXP2 : GenericInstruction { 894 let OutOperandList = (outs type0:$dst); 895 let InOperandList = (ins type0:$src1); 896 let hasSideEffects = false; 897} 898 899// Floating point base-e logarithm of a value. 900def G_FLOG : GenericInstruction { 901 let OutOperandList = (outs type0:$dst); 902 let InOperandList = (ins type0:$src1); 903 let hasSideEffects = false; 904} 905 906// Floating point base-2 logarithm of a value. 907def G_FLOG2 : GenericInstruction { 908 let OutOperandList = (outs type0:$dst); 909 let InOperandList = (ins type0:$src1); 910 let hasSideEffects = false; 911} 912 913// Floating point base-10 logarithm of a value. 914def G_FLOG10 : GenericInstruction { 915 let OutOperandList = (outs type0:$dst); 916 let InOperandList = (ins type0:$src1); 917 let hasSideEffects = false; 918} 919 920// Floating point ceiling of a value. 921def G_FCEIL : GenericInstruction { 922 let OutOperandList = (outs type0:$dst); 923 let InOperandList = (ins type0:$src1); 924 let hasSideEffects = false; 925} 926 927// Floating point cosine of a value. 928def G_FCOS : GenericInstruction { 929 let OutOperandList = (outs type0:$dst); 930 let InOperandList = (ins type0:$src1); 931 let hasSideEffects = false; 932} 933 934// Floating point sine of a value. 935def G_FSIN : GenericInstruction { 936 let OutOperandList = (outs type0:$dst); 937 let InOperandList = (ins type0:$src1); 938 let hasSideEffects = false; 939} 940 941// Floating point square root of a value. 942// This returns NaN for negative nonzero values. 943// NOTE: Unlike libm sqrt(), this never sets errno. In all other respects it's 944// libm-conformant. 945def G_FSQRT : GenericInstruction { 946 let OutOperandList = (outs type0:$dst); 947 let InOperandList = (ins type0:$src1); 948 let hasSideEffects = false; 949} 950 951// Floating point floor of a value. 952def G_FFLOOR : GenericInstruction { 953 let OutOperandList = (outs type0:$dst); 954 let InOperandList = (ins type0:$src1); 955 let hasSideEffects = false; 956} 957 958// Floating point round to next integer. 959def G_FRINT : GenericInstruction { 960 let OutOperandList = (outs type0:$dst); 961 let InOperandList = (ins type0:$src1); 962 let hasSideEffects = false; 963} 964 965// Floating point round to the nearest integer. 966def G_FNEARBYINT : GenericInstruction { 967 let OutOperandList = (outs type0:$dst); 968 let InOperandList = (ins type0:$src1); 969 let hasSideEffects = false; 970} 971 972//------------------------------------------------------------------------------ 973// Opcodes for LLVM Intrinsics 974//------------------------------------------------------------------------------ 975def G_INTRINSIC_FPTRUNC_ROUND : GenericInstruction { 976 let OutOperandList = (outs type0:$dst); 977 let InOperandList = (ins type1:$src1, i32imm:$round_mode); 978 let hasSideEffects = false; 979} 980 981def G_INTRINSIC_TRUNC : GenericInstruction { 982 let OutOperandList = (outs type0:$dst); 983 let InOperandList = (ins type0:$src1); 984 let hasSideEffects = false; 985} 986 987def G_INTRINSIC_ROUND : GenericInstruction { 988 let OutOperandList = (outs type0:$dst); 989 let InOperandList = (ins type0:$src1); 990 let hasSideEffects = false; 991} 992 993def G_INTRINSIC_LRINT : GenericInstruction { 994 let OutOperandList = (outs type0:$dst); 995 let InOperandList = (ins type1:$src); 996 let hasSideEffects = false; 997} 998 999def G_INTRINSIC_ROUNDEVEN : GenericInstruction { 1000 let OutOperandList = (outs type0:$dst); 1001 let InOperandList = (ins type0:$src1); 1002 let hasSideEffects = false; 1003} 1004 1005def G_READCYCLECOUNTER : GenericInstruction { 1006 let OutOperandList = (outs type0:$dst); 1007 let InOperandList = (ins); 1008 let hasSideEffects = true; 1009} 1010 1011//------------------------------------------------------------------------------ 1012// Memory ops 1013//------------------------------------------------------------------------------ 1014 1015// Generic load. Expects a MachineMemOperand in addition to explicit 1016// operands. If the result size is larger than the memory size, the 1017// high bits are undefined. If the result is a vector type and larger 1018// than the memory size, the high elements are undefined (i.e. this is 1019// not a per-element, vector anyextload) 1020def G_LOAD : GenericInstruction { 1021 let OutOperandList = (outs type0:$dst); 1022 let InOperandList = (ins ptype1:$addr); 1023 let hasSideEffects = false; 1024 let mayLoad = true; 1025} 1026 1027// Generic sign-extended load. Expects a MachineMemOperand in addition to explicit operands. 1028def G_SEXTLOAD : GenericInstruction { 1029 let OutOperandList = (outs type0:$dst); 1030 let InOperandList = (ins ptype1:$addr); 1031 let hasSideEffects = false; 1032 let mayLoad = true; 1033} 1034 1035// Generic zero-extended load. Expects a MachineMemOperand in addition to explicit operands. 1036def G_ZEXTLOAD : GenericInstruction { 1037 let OutOperandList = (outs type0:$dst); 1038 let InOperandList = (ins ptype1:$addr); 1039 let hasSideEffects = false; 1040 let mayLoad = true; 1041} 1042 1043// Generic indexed load. Combines a GEP with a load. $newaddr is set to $base + $offset. 1044// If $am is 0 (post-indexed), then the value is loaded from $base; if $am is 1 (pre-indexed) 1045// then the value is loaded from $newaddr. 1046def G_INDEXED_LOAD : GenericInstruction { 1047 let OutOperandList = (outs type0:$dst, ptype1:$newaddr); 1048 let InOperandList = (ins ptype1:$base, type2:$offset, unknown:$am); 1049 let hasSideEffects = false; 1050 let mayLoad = true; 1051} 1052 1053// Same as G_INDEXED_LOAD except that the load performed is sign-extending, as with G_SEXTLOAD. 1054def G_INDEXED_SEXTLOAD : GenericInstruction { 1055 let OutOperandList = (outs type0:$dst, ptype1:$newaddr); 1056 let InOperandList = (ins ptype1:$base, type2:$offset, unknown:$am); 1057 let hasSideEffects = false; 1058 let mayLoad = true; 1059} 1060 1061// Same as G_INDEXED_LOAD except that the load performed is zero-extending, as with G_ZEXTLOAD. 1062def G_INDEXED_ZEXTLOAD : GenericInstruction { 1063 let OutOperandList = (outs type0:$dst, ptype1:$newaddr); 1064 let InOperandList = (ins ptype1:$base, type2:$offset, unknown:$am); 1065 let hasSideEffects = false; 1066 let mayLoad = true; 1067} 1068 1069// Generic store. Expects a MachineMemOperand in addition to explicit operands. 1070def G_STORE : GenericInstruction { 1071 let OutOperandList = (outs); 1072 let InOperandList = (ins type0:$src, ptype1:$addr); 1073 let hasSideEffects = false; 1074 let mayStore = true; 1075} 1076 1077// Combines a store with a GEP. See description of G_INDEXED_LOAD for indexing behaviour. 1078def G_INDEXED_STORE : GenericInstruction { 1079 let OutOperandList = (outs ptype0:$newaddr); 1080 let InOperandList = (ins type1:$src, ptype0:$base, ptype2:$offset, 1081 unknown:$am); 1082 let hasSideEffects = false; 1083 let mayStore = true; 1084} 1085 1086// Generic atomic cmpxchg with internal success check. Expects a 1087// MachineMemOperand in addition to explicit operands. 1088def G_ATOMIC_CMPXCHG_WITH_SUCCESS : GenericInstruction { 1089 let OutOperandList = (outs type0:$oldval, type1:$success); 1090 let InOperandList = (ins type2:$addr, type0:$cmpval, type0:$newval); 1091 let hasSideEffects = false; 1092 let mayLoad = true; 1093 let mayStore = true; 1094} 1095 1096// Generic atomic cmpxchg. Expects a MachineMemOperand in addition to explicit 1097// operands. 1098def G_ATOMIC_CMPXCHG : GenericInstruction { 1099 let OutOperandList = (outs type0:$oldval); 1100 let InOperandList = (ins ptype1:$addr, type0:$cmpval, type0:$newval); 1101 let hasSideEffects = false; 1102 let mayLoad = true; 1103 let mayStore = true; 1104} 1105 1106// Generic atomicrmw. Expects a MachineMemOperand in addition to explicit 1107// operands. 1108class G_ATOMICRMW_OP : GenericInstruction { 1109 let OutOperandList = (outs type0:$oldval); 1110 let InOperandList = (ins ptype1:$addr, type0:$val); 1111 let hasSideEffects = false; 1112 let mayLoad = true; 1113 let mayStore = true; 1114} 1115 1116def G_ATOMICRMW_XCHG : G_ATOMICRMW_OP; 1117def G_ATOMICRMW_ADD : G_ATOMICRMW_OP; 1118def G_ATOMICRMW_SUB : G_ATOMICRMW_OP; 1119def G_ATOMICRMW_AND : G_ATOMICRMW_OP; 1120def G_ATOMICRMW_NAND : G_ATOMICRMW_OP; 1121def G_ATOMICRMW_OR : G_ATOMICRMW_OP; 1122def G_ATOMICRMW_XOR : G_ATOMICRMW_OP; 1123def G_ATOMICRMW_MAX : G_ATOMICRMW_OP; 1124def G_ATOMICRMW_MIN : G_ATOMICRMW_OP; 1125def G_ATOMICRMW_UMAX : G_ATOMICRMW_OP; 1126def G_ATOMICRMW_UMIN : G_ATOMICRMW_OP; 1127def G_ATOMICRMW_FADD : G_ATOMICRMW_OP; 1128def G_ATOMICRMW_FSUB : G_ATOMICRMW_OP; 1129def G_ATOMICRMW_FMAX : G_ATOMICRMW_OP; 1130def G_ATOMICRMW_FMIN : G_ATOMICRMW_OP; 1131 1132def G_FENCE : GenericInstruction { 1133 let OutOperandList = (outs); 1134 let InOperandList = (ins i32imm:$ordering, i32imm:$scope); 1135 let hasSideEffects = true; 1136} 1137 1138//------------------------------------------------------------------------------ 1139// Variadic ops 1140//------------------------------------------------------------------------------ 1141 1142// Extract a register of the specified size, starting from the block given by 1143// index. This will almost certainly be mapped to sub-register COPYs after 1144// register banks have been selected. 1145def G_EXTRACT : GenericInstruction { 1146 let OutOperandList = (outs type0:$res); 1147 let InOperandList = (ins type1:$src, untyped_imm_0:$offset); 1148 let hasSideEffects = false; 1149} 1150 1151// Extract multiple registers specified size, starting from blocks given by 1152// indexes. This will almost certainly be mapped to sub-register COPYs after 1153// register banks have been selected. 1154// The output operands are always ordered from lowest bits to highest: 1155// %bits_0_7:(s8), %bits_8_15:(s8), 1156// %bits_16_23:(s8), %bits_24_31:(s8) = G_UNMERGE_VALUES %0:(s32) 1157def G_UNMERGE_VALUES : GenericInstruction { 1158 let OutOperandList = (outs type0:$dst0, variable_ops); 1159 let InOperandList = (ins type1:$src); 1160 let hasSideEffects = false; 1161} 1162 1163// Insert a smaller register into a larger one at the specified bit-index. 1164def G_INSERT : GenericInstruction { 1165 let OutOperandList = (outs type0:$dst); 1166 let InOperandList = (ins type0:$src, type1:$op, untyped_imm_0:$offset); 1167 let hasSideEffects = false; 1168} 1169 1170// Concatenate multiple registers of the same size into a wider register. 1171// The input operands are always ordered from lowest bits to highest: 1172// %0:(s32) = G_MERGE_VALUES %bits_0_7:(s8), %bits_8_15:(s8), 1173// %bits_16_23:(s8), %bits_24_31:(s8) 1174def G_MERGE_VALUES : GenericInstruction { 1175 let OutOperandList = (outs type0:$dst); 1176 let InOperandList = (ins type1:$src0, variable_ops); 1177 let hasSideEffects = false; 1178} 1179 1180/// Create a vector from multiple scalar registers. No implicit 1181/// conversion is performed (i.e. the result element type must be the 1182/// same as all source operands) 1183def G_BUILD_VECTOR : GenericInstruction { 1184 let OutOperandList = (outs type0:$dst); 1185 let InOperandList = (ins type1:$src0, variable_ops); 1186 let hasSideEffects = false; 1187} 1188 1189/// Like G_BUILD_VECTOR, but truncates the larger operand types to fit the 1190/// destination vector elt type. 1191def G_BUILD_VECTOR_TRUNC : GenericInstruction { 1192 let OutOperandList = (outs type0:$dst); 1193 let InOperandList = (ins type1:$src0, variable_ops); 1194 let hasSideEffects = false; 1195} 1196 1197/// Create a vector by concatenating vectors together. 1198def G_CONCAT_VECTORS : GenericInstruction { 1199 let OutOperandList = (outs type0:$dst); 1200 let InOperandList = (ins type1:$src0, variable_ops); 1201 let hasSideEffects = false; 1202} 1203 1204// Intrinsic without side effects. 1205def G_INTRINSIC : GenericInstruction { 1206 let OutOperandList = (outs); 1207 let InOperandList = (ins unknown:$intrin, variable_ops); 1208 let hasSideEffects = false; 1209 1210 // Conservatively assume this is convergent. If there turnes out to 1211 // be a need, there should be separate convergent intrinsic opcodes. 1212 let isConvergent = 1; 1213} 1214 1215// Intrinsic with side effects. 1216def G_INTRINSIC_W_SIDE_EFFECTS : GenericInstruction { 1217 let OutOperandList = (outs); 1218 let InOperandList = (ins unknown:$intrin, variable_ops); 1219 let hasSideEffects = true; 1220 let mayLoad = true; 1221 let mayStore = true; 1222 1223 // Conservatively assume this is convergent. If there turnes out to 1224 // be a need, there should be separate convergent intrinsic opcodes. 1225 let isConvergent = true; 1226} 1227 1228//------------------------------------------------------------------------------ 1229// Branches. 1230//------------------------------------------------------------------------------ 1231 1232// Generic unconditional branch. 1233def G_BR : GenericInstruction { 1234 let OutOperandList = (outs); 1235 let InOperandList = (ins unknown:$src1); 1236 let hasSideEffects = false; 1237 let isBranch = true; 1238 let isTerminator = true; 1239 let isBarrier = true; 1240} 1241 1242// Generic conditional branch. 1243def G_BRCOND : GenericInstruction { 1244 let OutOperandList = (outs); 1245 let InOperandList = (ins type0:$tst, unknown:$truebb); 1246 let hasSideEffects = false; 1247 let isBranch = true; 1248 let isTerminator = true; 1249} 1250 1251// Generic indirect branch. 1252def G_BRINDIRECT : GenericInstruction { 1253 let OutOperandList = (outs); 1254 let InOperandList = (ins type0:$src1); 1255 let hasSideEffects = false; 1256 let isBranch = true; 1257 let isTerminator = true; 1258 let isBarrier = true; 1259 let isIndirectBranch = true; 1260} 1261 1262// Generic branch to jump table entry 1263def G_BRJT : GenericInstruction { 1264 let OutOperandList = (outs); 1265 let InOperandList = (ins ptype0:$tbl, unknown:$jti, type1:$idx); 1266 let hasSideEffects = false; 1267 let isBranch = true; 1268 let isTerminator = true; 1269 let isBarrier = true; 1270 let isIndirectBranch = true; 1271} 1272 1273def G_READ_REGISTER : GenericInstruction { 1274 let OutOperandList = (outs type0:$dst); 1275 let InOperandList = (ins unknown:$register); 1276 let hasSideEffects = true; 1277 1278 // Assume convergent. It's probably not worth the effort of somehow 1279 // modeling convergent and nonconvergent register accesses. 1280 let isConvergent = true; 1281} 1282 1283def G_WRITE_REGISTER : GenericInstruction { 1284 let OutOperandList = (outs); 1285 let InOperandList = (ins unknown:$register, type0:$value); 1286 let hasSideEffects = true; 1287 1288 // Assume convergent. It's probably not worth the effort of somehow 1289 // modeling convergent and nonconvergent register accesses. 1290 let isConvergent = true; 1291} 1292 1293//------------------------------------------------------------------------------ 1294// Vector ops 1295//------------------------------------------------------------------------------ 1296 1297// Generic insertelement. 1298def G_INSERT_VECTOR_ELT : GenericInstruction { 1299 let OutOperandList = (outs type0:$dst); 1300 let InOperandList = (ins type0:$src, type1:$elt, type2:$idx); 1301 let hasSideEffects = false; 1302} 1303 1304// Generic extractelement. 1305def G_EXTRACT_VECTOR_ELT : GenericInstruction { 1306 let OutOperandList = (outs type0:$dst); 1307 let InOperandList = (ins type1:$src, type2:$idx); 1308 let hasSideEffects = false; 1309} 1310 1311// Generic shufflevector. 1312// 1313// The mask operand should be an IR Constant which exactly matches the 1314// corresponding mask for the IR shufflevector instruction. 1315def G_SHUFFLE_VECTOR: GenericInstruction { 1316 let OutOperandList = (outs type0:$dst); 1317 let InOperandList = (ins type1:$v1, type1:$v2, unknown:$mask); 1318 let hasSideEffects = false; 1319} 1320 1321//------------------------------------------------------------------------------ 1322// Vector reductions 1323//------------------------------------------------------------------------------ 1324 1325class VectorReduction : GenericInstruction { 1326 let OutOperandList = (outs type0:$dst); 1327 let InOperandList = (ins type1:$v); 1328 let hasSideEffects = false; 1329} 1330 1331def G_VECREDUCE_SEQ_FADD : GenericInstruction { 1332 let OutOperandList = (outs type0:$dst); 1333 let InOperandList = (ins type1:$acc, type2:$v); 1334 let hasSideEffects = false; 1335} 1336 1337def G_VECREDUCE_SEQ_FMUL : GenericInstruction { 1338 let OutOperandList = (outs type0:$dst); 1339 let InOperandList = (ins type1:$acc, type2:$v); 1340 let hasSideEffects = false; 1341} 1342 1343def G_VECREDUCE_FADD : VectorReduction; 1344def G_VECREDUCE_FMUL : VectorReduction; 1345 1346def G_VECREDUCE_FMAX : VectorReduction; 1347def G_VECREDUCE_FMIN : VectorReduction; 1348 1349def G_VECREDUCE_ADD : VectorReduction; 1350def G_VECREDUCE_MUL : VectorReduction; 1351def G_VECREDUCE_AND : VectorReduction; 1352def G_VECREDUCE_OR : VectorReduction; 1353def G_VECREDUCE_XOR : VectorReduction; 1354def G_VECREDUCE_SMAX : VectorReduction; 1355def G_VECREDUCE_SMIN : VectorReduction; 1356def G_VECREDUCE_UMAX : VectorReduction; 1357def G_VECREDUCE_UMIN : VectorReduction; 1358 1359//------------------------------------------------------------------------------ 1360// Constrained floating point ops 1361//------------------------------------------------------------------------------ 1362 1363def G_STRICT_FADD : ConstrainedIntruction<G_FADD>; 1364def G_STRICT_FSUB : ConstrainedIntruction<G_FSUB>; 1365def G_STRICT_FMUL : ConstrainedIntruction<G_FMUL>; 1366def G_STRICT_FDIV : ConstrainedIntruction<G_FDIV>; 1367def G_STRICT_FREM : ConstrainedIntruction<G_FREM>; 1368def G_STRICT_FMA : ConstrainedIntruction<G_FMA>; 1369def G_STRICT_FSQRT : ConstrainedIntruction<G_FSQRT>; 1370 1371//------------------------------------------------------------------------------ 1372// Memory intrinsics 1373//------------------------------------------------------------------------------ 1374 1375def G_MEMCPY : GenericInstruction { 1376 let OutOperandList = (outs); 1377 let InOperandList = (ins ptype0:$dst_addr, ptype1:$src_addr, type2:$size, untyped_imm_0:$tailcall); 1378 let hasSideEffects = false; 1379 let mayLoad = true; 1380 let mayStore = true; 1381} 1382 1383def G_MEMCPY_INLINE : GenericInstruction { 1384 let OutOperandList = (outs); 1385 let InOperandList = (ins ptype0:$dst_addr, ptype1:$src_addr, type2:$size); 1386 let hasSideEffects = false; 1387 let mayLoad = true; 1388 let mayStore = true; 1389} 1390 1391def G_MEMMOVE : GenericInstruction { 1392 let OutOperandList = (outs); 1393 let InOperandList = (ins ptype0:$dst_addr, ptype1:$src_addr, type2:$size, untyped_imm_0:$tailcall); 1394 let hasSideEffects = false; 1395 let mayLoad = true; 1396 let mayStore = true; 1397} 1398 1399def G_MEMSET : GenericInstruction { 1400 let OutOperandList = (outs); 1401 let InOperandList = (ins ptype0:$dst_addr, type1:$value, type2:$size, untyped_imm_0:$tailcall); 1402 let hasSideEffects = false; 1403 let mayStore = true; 1404} 1405 1406def G_BZERO : GenericInstruction { 1407 let OutOperandList = (outs); 1408 let InOperandList = (ins ptype0:$dst_addr, type1:$size, untyped_imm_0:$tailcall); 1409 let hasSideEffects = false; 1410 let mayStore = true; 1411} 1412 1413//------------------------------------------------------------------------------ 1414// Bitfield extraction. 1415//------------------------------------------------------------------------------ 1416 1417// Generic signed bitfield extraction. The operands are in the range 1418// 0 <= lsb < lsb + width <= src bitwidth, where all values are unsigned. 1419def G_SBFX : GenericInstruction { 1420 let OutOperandList = (outs type0:$dst); 1421 let InOperandList = (ins type0:$src, type1:$lsb, type1:$width); 1422 let hasSideEffects = false; 1423} 1424 1425// Generic unsigned bitfield extraction. The operands are in the range 1426// 0 <= lsb < lsb + width <= src bitwidth, where all values are unsigned. 1427def G_UBFX : GenericInstruction { 1428 let OutOperandList = (outs type0:$dst); 1429 let InOperandList = (ins type0:$src, type1:$lsb, type1:$width); 1430 let hasSideEffects = false; 1431} 1432 1433//------------------------------------------------------------------------------ 1434// Optimization hints 1435//------------------------------------------------------------------------------ 1436 1437// Asserts that an operation has already been zero-extended from a specific 1438// type. 1439def G_ASSERT_ZEXT : GenericInstruction { 1440 let OutOperandList = (outs type0:$dst); 1441 let InOperandList = (ins type0:$src, untyped_imm_0:$sz); 1442 let hasSideEffects = false; 1443} 1444 1445// Asserts that an operation has already been sign-extended from a specific 1446// type. 1447def G_ASSERT_SEXT : GenericInstruction { 1448 let OutOperandList = (outs type0:$dst); 1449 let InOperandList = (ins type0:$src, untyped_imm_0:$sz); 1450 let hasSideEffects = false; 1451} 1452 1453// Asserts that a value has at least the given alignment. 1454def G_ASSERT_ALIGN : GenericInstruction { 1455 let OutOperandList = (outs type0:$dst); 1456 let InOperandList = (ins type0:$src, untyped_imm_0:$align); 1457 let hasSideEffects = false; 1458} 1459