1 //===-- GenericOpcodes.td - Opcodes used with GlobalISel ---*- tablegen -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines the generic opcodes used with GlobalISel. 11 // After instruction selection, these opcodes should not appear. 12 // 13 //===----------------------------------------------------------------------===// 14 15 //------------------------------------------------------------------------------ 16 // Unary ops. 17 //------------------------------------------------------------------------------ 18 19 // Extend the underlying scalar type of an operation, leaving the high bits 20 // unspecified. 21 def G_ANYEXT : Instruction { 22 let OutOperandList = (outs type0:$dst); 23 let InOperandList = (ins type1:$src); 24 let hasSideEffects = 0; 25 } 26 27 // Sign extend the underlying scalar type of an operation, copying the sign bit 28 // into the newly-created space. 29 def G_SEXT : Instruction { 30 let OutOperandList = (outs type0:$dst); 31 let InOperandList = (ins type1:$src); 32 let hasSideEffects = 0; 33 } 34 35 // Zero extend the underlying scalar type of an operation, putting zero bits 36 // into the newly-created space. 37 def G_ZEXT : Instruction { 38 let OutOperandList = (outs type0:$dst); 39 let InOperandList = (ins type1:$src); 40 let hasSideEffects = 0; 41 } 42 43 44 // Truncate the underlying scalar type of an operation. This is equivalent to 45 // G_EXTRACT for scalar types, but acts elementwise on vectors. 46 def G_TRUNC : Instruction { 47 let OutOperandList = (outs type0:$dst); 48 let InOperandList = (ins type1:$src); 49 let hasSideEffects = 0; 50 } 51 52 def G_IMPLICIT_DEF : Instruction { 53 let OutOperandList = (outs type0:$dst); 54 let InOperandList = (ins); 55 let hasSideEffects = 0; 56 } 57 58 def G_PHI : Instruction { 59 let OutOperandList = (outs type0:$dst); 60 let InOperandList = (ins variable_ops); 61 let hasSideEffects = 0; 62 } 63 64 def G_FRAME_INDEX : Instruction { 65 let OutOperandList = (outs type0:$dst); 66 let InOperandList = (ins unknown:$src2); 67 let hasSideEffects = 0; 68 } 69 70 def G_GLOBAL_VALUE : Instruction { 71 let OutOperandList = (outs type0:$dst); 72 let InOperandList = (ins unknown:$src); 73 let hasSideEffects = 0; 74 } 75 76 def G_INTTOPTR : Instruction { 77 let OutOperandList = (outs type0:$dst); 78 let InOperandList = (ins type1:$src); 79 let hasSideEffects = 0; 80 } 81 82 def G_PTRTOINT : Instruction { 83 let OutOperandList = (outs type0:$dst); 84 let InOperandList = (ins type1:$src); 85 let hasSideEffects = 0; 86 } 87 88 def G_BITCAST : Instruction { 89 let OutOperandList = (outs type0:$dst); 90 let InOperandList = (ins type1:$src); 91 let hasSideEffects = 0; 92 } 93 94 def G_CONSTANT : Instruction { 95 let OutOperandList = (outs type0:$dst); 96 let InOperandList = (ins unknown:$imm); 97 let hasSideEffects = 0; 98 } 99 100 def G_FCONSTANT : Instruction { 101 let OutOperandList = (outs type0:$dst); 102 let InOperandList = (ins unknown:$imm); 103 let hasSideEffects = 0; 104 } 105 106 def G_VASTART : Instruction { 107 let OutOperandList = (outs); 108 let InOperandList = (ins type0:$list); 109 let hasSideEffects = 0; 110 let mayStore = 1; 111 } 112 113 def G_VAARG : Instruction { 114 let OutOperandList = (outs type0:$val); 115 let InOperandList = (ins type1:$list, unknown:$align); 116 let hasSideEffects = 0; 117 let mayLoad = 1; 118 let mayStore = 1; 119 } 120 121 def G_BSWAP : Instruction { 122 let OutOperandList = (outs type0:$dst); 123 let InOperandList = (ins type0:$src); 124 let hasSideEffects = 0; 125 } 126 127 //------------------------------------------------------------------------------ 128 // Binary ops. 129 //------------------------------------------------------------------------------ 130 131 // Generic addition. 132 def G_ADD : Instruction { 133 let OutOperandList = (outs type0:$dst); 134 let InOperandList = (ins type0:$src1, type0:$src2); 135 let hasSideEffects = 0; 136 let isCommutable = 1; 137 } 138 139 // Generic subtraction. 140 def G_SUB : Instruction { 141 let OutOperandList = (outs type0:$dst); 142 let InOperandList = (ins type0:$src1, type0:$src2); 143 let hasSideEffects = 0; 144 let isCommutable = 0; 145 } 146 147 // Generic multiplication. 148 def G_MUL : Instruction { 149 let OutOperandList = (outs type0:$dst); 150 let InOperandList = (ins type0:$src1, type0:$src2); 151 let hasSideEffects = 0; 152 let isCommutable = 1; 153 } 154 155 // Generic signed division. 156 def G_SDIV : Instruction { 157 let OutOperandList = (outs type0:$dst); 158 let InOperandList = (ins type0:$src1, type0:$src2); 159 let hasSideEffects = 0; 160 let isCommutable = 0; 161 } 162 163 // Generic unsigned division. 164 def G_UDIV : Instruction { 165 let OutOperandList = (outs type0:$dst); 166 let InOperandList = (ins type0:$src1, type0:$src2); 167 let hasSideEffects = 0; 168 let isCommutable = 0; 169 } 170 171 // Generic signed remainder. 172 def G_SREM : Instruction { 173 let OutOperandList = (outs type0:$dst); 174 let InOperandList = (ins type0:$src1, type0:$src2); 175 let hasSideEffects = 0; 176 let isCommutable = 0; 177 } 178 179 // Generic unsigned remainder. 180 def G_UREM : Instruction { 181 let OutOperandList = (outs type0:$dst); 182 let InOperandList = (ins type0:$src1, type0:$src2); 183 let hasSideEffects = 0; 184 let isCommutable = 0; 185 } 186 187 // Generic bitwise and. 188 def G_AND : Instruction { 189 let OutOperandList = (outs type0:$dst); 190 let InOperandList = (ins type0:$src1, type0:$src2); 191 let hasSideEffects = 0; 192 let isCommutable = 1; 193 } 194 195 // Generic bitwise or. 196 def G_OR : Instruction { 197 let OutOperandList = (outs type0:$dst); 198 let InOperandList = (ins type0:$src1, type0:$src2); 199 let hasSideEffects = 0; 200 let isCommutable = 1; 201 } 202 203 // Generic bitwise xor. 204 def G_XOR : Instruction { 205 let OutOperandList = (outs type0:$dst); 206 let InOperandList = (ins type0:$src1, type0:$src2); 207 let hasSideEffects = 0; 208 let isCommutable = 1; 209 } 210 211 // Generic left-shift. 212 def G_SHL : Instruction { 213 let OutOperandList = (outs type0:$dst); 214 let InOperandList = (ins type0:$src1, type0:$src2); 215 let hasSideEffects = 0; 216 } 217 218 // Generic logical right-shift. 219 def G_LSHR : Instruction { 220 let OutOperandList = (outs type0:$dst); 221 let InOperandList = (ins type0:$src1, type0:$src2); 222 let hasSideEffects = 0; 223 } 224 225 // Generic arithmetic right-shift. 226 def G_ASHR : Instruction { 227 let OutOperandList = (outs type0:$dst); 228 let InOperandList = (ins type0:$src1, type0:$src2); 229 let hasSideEffects = 0; 230 } 231 232 // Generic integer comparison. 233 def G_ICMP : Instruction { 234 let OutOperandList = (outs type0:$dst); 235 let InOperandList = (ins unknown:$tst, type1:$src1, type1:$src2); 236 let hasSideEffects = 0; 237 } 238 239 // Generic floating-point comparison. 240 def G_FCMP : Instruction { 241 let OutOperandList = (outs type0:$dst); 242 let InOperandList = (ins unknown:$tst, type1:$src1, type1:$src2); 243 let hasSideEffects = 0; 244 } 245 246 // Generic select 247 def G_SELECT : Instruction { 248 let OutOperandList = (outs type0:$dst); 249 let InOperandList = (ins type1:$tst, type0:$src1, type0:$src2); 250 let hasSideEffects = 0; 251 } 252 253 // Generic pointer offset. 254 def G_GEP : Instruction { 255 let OutOperandList = (outs type0:$dst); 256 let InOperandList = (ins type0:$src1, type1:$src2); 257 let hasSideEffects = 0; 258 } 259 260 def G_PTR_MASK : Instruction { 261 let OutOperandList = (outs type0:$dst); 262 let InOperandList = (ins type0:$src, unknown:$bits); 263 let hasSideEffects = 0; 264 } 265 266 //------------------------------------------------------------------------------ 267 // Overflow ops 268 //------------------------------------------------------------------------------ 269 270 // Generic unsigned addition consuming and producing a carry flag. 271 def G_UADDE : Instruction { 272 let OutOperandList = (outs type0:$dst, type1:$carry_out); 273 let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in); 274 let hasSideEffects = 0; 275 } 276 277 // Generic signed addition producing a carry flag. 278 def G_SADDO : Instruction { 279 let OutOperandList = (outs type0:$dst, type1:$carry_out); 280 let InOperandList = (ins type0:$src1, type0:$src2); 281 let hasSideEffects = 0; 282 let isCommutable = 1; 283 } 284 285 // Generic unsigned subtraction consuming and producing a carry flag. 286 def G_USUBE : Instruction { 287 let OutOperandList = (outs type0:$dst, type1:$carry_out); 288 let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in); 289 let hasSideEffects = 0; 290 } 291 292 // Generic unsigned subtraction producing a carry flag. 293 def G_SSUBO : Instruction { 294 let OutOperandList = (outs type0:$dst, type1:$carry_out); 295 let InOperandList = (ins type0:$src1, type0:$src2); 296 let hasSideEffects = 0; 297 } 298 299 // Generic unsigned multiplication producing a carry flag. 300 def G_UMULO : Instruction { 301 let OutOperandList = (outs type0:$dst, type1:$carry_out); 302 let InOperandList = (ins type0:$src1, type0:$src2); 303 let hasSideEffects = 0; 304 let isCommutable = 1; 305 } 306 307 // Generic signed multiplication producing a carry flag. 308 def G_SMULO : Instruction { 309 let OutOperandList = (outs type0:$dst, type1:$carry_out); 310 let InOperandList = (ins type0:$src1, type0:$src2); 311 let hasSideEffects = 0; 312 let isCommutable = 1; 313 } 314 315 // Multiply two numbers at twice the incoming bit width (unsigned) and return 316 // the high half of the result. 317 def G_UMULH : Instruction { 318 let OutOperandList = (outs type0:$dst); 319 let InOperandList = (ins type0:$src1, type0:$src2); 320 let hasSideEffects = 0; 321 let isCommutable = 1; 322 } 323 324 // Multiply two numbers at twice the incoming bit width (signed) and return 325 // the high half of the result. 326 def G_SMULH : Instruction { 327 let OutOperandList = (outs type0:$dst); 328 let InOperandList = (ins type0:$src1, type0:$src2); 329 let hasSideEffects = 0; 330 let isCommutable = 1; 331 } 332 333 //------------------------------------------------------------------------------ 334 // Floating Point Unary Ops. 335 //------------------------------------------------------------------------------ 336 337 def G_FNEG : Instruction { 338 let OutOperandList = (outs type0:$dst); 339 let InOperandList = (ins type0:$src); 340 let hasSideEffects = 0; 341 } 342 343 def G_FPEXT : Instruction { 344 let OutOperandList = (outs type0:$dst); 345 let InOperandList = (ins type1:$src); 346 let hasSideEffects = 0; 347 } 348 349 def G_FPTRUNC : Instruction { 350 let OutOperandList = (outs type0:$dst); 351 let InOperandList = (ins type1:$src); 352 let hasSideEffects = 0; 353 } 354 355 def G_FPTOSI : Instruction { 356 let OutOperandList = (outs type0:$dst); 357 let InOperandList = (ins type1:$src); 358 let hasSideEffects = 0; 359 } 360 361 def G_FPTOUI : Instruction { 362 let OutOperandList = (outs type0:$dst); 363 let InOperandList = (ins type1:$src); 364 let hasSideEffects = 0; 365 } 366 367 def G_SITOFP : Instruction { 368 let OutOperandList = (outs type0:$dst); 369 let InOperandList = (ins type1:$src); 370 let hasSideEffects = 0; 371 } 372 373 def G_UITOFP : Instruction { 374 let OutOperandList = (outs type0:$dst); 375 let InOperandList = (ins type1:$src); 376 let hasSideEffects = 0; 377 } 378 379 //------------------------------------------------------------------------------ 380 // Floating Point Binary ops. 381 //------------------------------------------------------------------------------ 382 383 // Generic FP addition. 384 def G_FADD : Instruction { 385 let OutOperandList = (outs type0:$dst); 386 let InOperandList = (ins type0:$src1, type0:$src2); 387 let hasSideEffects = 0; 388 let isCommutable = 1; 389 } 390 391 // Generic FP subtraction. 392 def G_FSUB : Instruction { 393 let OutOperandList = (outs type0:$dst); 394 let InOperandList = (ins type0:$src1, type0:$src2); 395 let hasSideEffects = 0; 396 let isCommutable = 0; 397 } 398 399 // Generic FP multiplication. 400 def G_FMUL : Instruction { 401 let OutOperandList = (outs type0:$dst); 402 let InOperandList = (ins type0:$src1, type0:$src2); 403 let hasSideEffects = 0; 404 let isCommutable = 1; 405 } 406 407 // Generic fused multiply-add instruction. 408 // Behaves like llvm fma intrinsic ie src1 * src2 + src3 409 def G_FMA : Instruction { 410 let OutOperandList = (outs type0:$dst); 411 let InOperandList = (ins type0:$src1, type0:$src2, type0:$src3); 412 let hasSideEffects = 0; 413 let isCommutable = 0; 414 } 415 416 // Generic FP division. 417 def G_FDIV : Instruction { 418 let OutOperandList = (outs type0:$dst); 419 let InOperandList = (ins type0:$src1, type0:$src2); 420 let hasSideEffects = 0; 421 } 422 423 // Generic FP remainder. 424 def G_FREM : Instruction { 425 let OutOperandList = (outs type0:$dst); 426 let InOperandList = (ins type0:$src1, type0:$src2); 427 let hasSideEffects = 0; 428 } 429 430 // Floating point exponentiation. 431 def G_FPOW : Instruction { 432 let OutOperandList = (outs type0:$dst); 433 let InOperandList = (ins type0:$src1, type0:$src2); 434 let hasSideEffects = 0; 435 } 436 437 // Floating point base-e exponential of a value. 438 def G_FEXP : Instruction { 439 let OutOperandList = (outs type0:$dst); 440 let InOperandList = (ins type0:$src1); 441 let hasSideEffects = 0; 442 } 443 444 // Floating point base-2 exponential of a value. 445 def G_FEXP2 : Instruction { 446 let OutOperandList = (outs type0:$dst); 447 let InOperandList = (ins type0:$src1); 448 let hasSideEffects = 0; 449 } 450 451 // Floating point base-2 logarithm of a value. 452 def G_FLOG : Instruction { 453 let OutOperandList = (outs type0:$dst); 454 let InOperandList = (ins type0:$src1); 455 let hasSideEffects = 0; 456 } 457 458 // Floating point base-2 logarithm of a value. 459 def G_FLOG2 : Instruction { 460 let OutOperandList = (outs type0:$dst); 461 let InOperandList = (ins type0:$src1); 462 let hasSideEffects = 0; 463 } 464 465 //------------------------------------------------------------------------------ 466 // Memory ops 467 //------------------------------------------------------------------------------ 468 469 // Generic load. Expects a MachineMemOperand in addition to explicit operands. 470 def G_LOAD : Instruction { 471 let OutOperandList = (outs type0:$dst); 472 let InOperandList = (ins type1:$addr); 473 let hasSideEffects = 0; 474 let mayLoad = 1; 475 } 476 477 // Generic store. Expects a MachineMemOperand in addition to explicit operands. 478 def G_STORE : Instruction { 479 let OutOperandList = (outs); 480 let InOperandList = (ins type0:$src, type1:$addr); 481 let hasSideEffects = 0; 482 let mayStore = 1; 483 } 484 485 //------------------------------------------------------------------------------ 486 // Variadic ops 487 //------------------------------------------------------------------------------ 488 489 // Extract a register of the specified size, starting from the block given by 490 // index. This will almost certainly be mapped to sub-register COPYs after 491 // register banks have been selected. 492 def G_EXTRACT : Instruction { 493 let OutOperandList = (outs type0:$res); 494 let InOperandList = (ins type1:$src, unknown:$offset); 495 let hasSideEffects = 0; 496 } 497 498 // Extract multiple registers specified size, starting from blocks given by 499 // indexes. This will almost certainly be mapped to sub-register COPYs after 500 // register banks have been selected. 501 def G_UNMERGE_VALUES : Instruction { 502 let OutOperandList = (outs); 503 let InOperandList = (ins variable_ops); 504 let hasSideEffects = 0; 505 } 506 507 // Insert a smaller register into a larger one at the specified bit-index. 508 def G_INSERT : Instruction { 509 let OutOperandList = (outs type0:$dst); 510 let InOperandList = (ins type0:$src, type1:$op, unknown:$offset); 511 let hasSideEffects = 0; 512 } 513 514 /// Concatenante multiple registers of the same size into a wider register. 515 def G_MERGE_VALUES : Instruction { 516 let OutOperandList = (outs type0:$dst); 517 let InOperandList = (ins variable_ops); 518 let hasSideEffects = 0; 519 } 520 521 // Intrinsic without side effects. 522 def G_INTRINSIC : Instruction { 523 let OutOperandList = (outs); 524 let InOperandList = (ins unknown:$intrin, variable_ops); 525 let hasSideEffects = 0; 526 } 527 528 // Intrinsic with side effects. 529 def G_INTRINSIC_W_SIDE_EFFECTS : Instruction { 530 let OutOperandList = (outs); 531 let InOperandList = (ins unknown:$intrin, variable_ops); 532 let hasSideEffects = 1; 533 let mayLoad = 1; 534 let mayStore = 1; 535 } 536 537 //------------------------------------------------------------------------------ 538 // Branches. 539 //------------------------------------------------------------------------------ 540 541 // Generic unconditional branch. 542 def G_BR : Instruction { 543 let OutOperandList = (outs); 544 let InOperandList = (ins unknown:$src1); 545 let hasSideEffects = 0; 546 let isBranch = 1; 547 let isTerminator = 1; 548 let isBarrier = 1; 549 } 550 551 // Generic conditional branch. 552 def G_BRCOND : Instruction { 553 let OutOperandList = (outs); 554 let InOperandList = (ins type0:$tst, unknown:$truebb); 555 let hasSideEffects = 0; 556 let isBranch = 1; 557 let isTerminator = 1; 558 } 559 560 // Generic indirect branch. 561 def G_BRINDIRECT : Instruction { 562 let OutOperandList = (outs); 563 let InOperandList = (ins type0:$src1); 564 let hasSideEffects = 0; 565 let isBranch = 1; 566 let isTerminator = 1; 567 } 568 569 //------------------------------------------------------------------------------ 570 // Vector ops 571 //------------------------------------------------------------------------------ 572 573 // Generic insertelement. 574 def G_INSERT_VECTOR_ELT : Instruction { 575 let OutOperandList = (outs type0:$dst); 576 let InOperandList = (ins type0:$src, type1:$elt, type2:$idx); 577 let hasSideEffects = 0; 578 } 579 580 // Generic extractelement. 581 def G_EXTRACT_VECTOR_ELT : Instruction { 582 let OutOperandList = (outs type0:$dst); 583 let InOperandList = (ins type1:$src, type2:$idx); 584 let hasSideEffects = 0; 585 } 586 587 // Generic shufflevector. 588 def G_SHUFFLE_VECTOR: Instruction { 589 let OutOperandList = (outs type0:$dst); 590 let InOperandList = (ins type1:$v1, type1:$v2, type2:$mask); 591 let hasSideEffects = 0; 592 } 593 594 // TODO: Add the other generic opcodes. 595