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