Home | History | Annotate | Download | only in Target
      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