1 //===-- GenericOpcodes.td - Opcodes used with GlobalISel ---*- tablegen -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the generic opcodes used with GlobalISel.
11 // After instruction selection, these opcodes should not appear.
13 //===----------------------------------------------------------------------===//
15 //------------------------------------------------------------------------------
17 //------------------------------------------------------------------------------
19 class GenericInstruction : StandardPseudoInstruction;
21 // Extend the underlying scalar type of an operation, leaving the high bits
23 def G_ANYEXT : GenericInstruction {
24 let OutOperandList = (outs type0:$dst);
25 let InOperandList = (ins type1:$src);
26 let hasSideEffects = 0;
29 // Sign extend the underlying scalar type of an operation, copying the sign bit
30 // into the newly-created space.
31 def G_SEXT : GenericInstruction {
32 let OutOperandList = (outs type0:$dst);
33 let InOperandList = (ins type1:$src);
34 let hasSideEffects = 0;
37 // Zero extend the underlying scalar type of an operation, putting zero bits
38 // into the newly-created space.
39 def G_ZEXT : GenericInstruction {
40 let OutOperandList = (outs type0:$dst);
41 let InOperandList = (ins type1:$src);
42 let hasSideEffects = 0;
46 // Truncate the underlying scalar type of an operation. This is equivalent to
47 // G_EXTRACT for scalar types, but acts elementwise on vectors.
48 def G_TRUNC : GenericInstruction {
49 let OutOperandList = (outs type0:$dst);
50 let InOperandList = (ins type1:$src);
51 let hasSideEffects = 0;
54 def G_IMPLICIT_DEF : GenericInstruction {
55 let OutOperandList = (outs type0:$dst);
56 let InOperandList = (ins);
57 let hasSideEffects = 0;
60 def G_PHI : GenericInstruction {
61 let OutOperandList = (outs type0:$dst);
62 let InOperandList = (ins variable_ops);
63 let hasSideEffects = 0;
66 def G_FRAME_INDEX : GenericInstruction {
67 let OutOperandList = (outs type0:$dst);
68 let InOperandList = (ins unknown:$src2);
69 let hasSideEffects = 0;
72 def G_GLOBAL_VALUE : GenericInstruction {
73 let OutOperandList = (outs type0:$dst);
74 let InOperandList = (ins unknown:$src);
75 let hasSideEffects = 0;
78 def G_INTTOPTR : GenericInstruction {
79 let OutOperandList = (outs type0:$dst);
80 let InOperandList = (ins type1:$src);
81 let hasSideEffects = 0;
84 def G_PTRTOINT : GenericInstruction {
85 let OutOperandList = (outs type0:$dst);
86 let InOperandList = (ins type1:$src);
87 let hasSideEffects = 0;
90 def G_BITCAST : GenericInstruction {
91 let OutOperandList = (outs type0:$dst);
92 let InOperandList = (ins type1:$src);
93 let hasSideEffects = 0;
96 def G_CONSTANT : GenericInstruction {
97 let OutOperandList = (outs type0:$dst);
98 let InOperandList = (ins unknown:$imm);
99 let hasSideEffects = 0;
102 def G_FCONSTANT : GenericInstruction {
103 let OutOperandList = (outs type0:$dst);
104 let InOperandList = (ins unknown:$imm);
105 let hasSideEffects = 0;
108 def G_VASTART : GenericInstruction {
109 let OutOperandList = (outs);
110 let InOperandList = (ins type0:$list);
111 let hasSideEffects = 0;
115 def G_VAARG : GenericInstruction {
116 let OutOperandList = (outs type0:$val);
117 let InOperandList = (ins type1:$list, unknown:$align);
118 let hasSideEffects = 0;
123 def G_BSWAP : GenericInstruction {
124 let OutOperandList = (outs type0:$dst);
125 let InOperandList = (ins type0:$src);
126 let hasSideEffects = 0;
129 def G_ADDRSPACE_CAST : GenericInstruction {
130 let OutOperandList = (outs type0:$dst);
131 let InOperandList = (ins type1:$src);
132 let hasSideEffects = 0;
135 def G_BLOCK_ADDR : GenericInstruction {
136 let OutOperandList = (outs type0:$dst);
137 let InOperandList = (ins unknown:$ba);
138 let hasSideEffects = 0;
141 //------------------------------------------------------------------------------
143 //------------------------------------------------------------------------------
146 def G_ADD : GenericInstruction {
147 let OutOperandList = (outs type0:$dst);
148 let InOperandList = (ins type0:$src1, type0:$src2);
149 let hasSideEffects = 0;
150 let isCommutable = 1;
153 // Generic subtraction.
154 def G_SUB : GenericInstruction {
155 let OutOperandList = (outs type0:$dst);
156 let InOperandList = (ins type0:$src1, type0:$src2);
157 let hasSideEffects = 0;
158 let isCommutable = 0;
161 // Generic multiplication.
162 def G_MUL : GenericInstruction {
163 let OutOperandList = (outs type0:$dst);
164 let InOperandList = (ins type0:$src1, type0:$src2);
165 let hasSideEffects = 0;
166 let isCommutable = 1;
169 // Generic signed division.
170 def G_SDIV : GenericInstruction {
171 let OutOperandList = (outs type0:$dst);
172 let InOperandList = (ins type0:$src1, type0:$src2);
173 let hasSideEffects = 0;
174 let isCommutable = 0;
177 // Generic unsigned division.
178 def G_UDIV : GenericInstruction {
179 let OutOperandList = (outs type0:$dst);
180 let InOperandList = (ins type0:$src1, type0:$src2);
181 let hasSideEffects = 0;
182 let isCommutable = 0;
185 // Generic signed remainder.
186 def G_SREM : GenericInstruction {
187 let OutOperandList = (outs type0:$dst);
188 let InOperandList = (ins type0:$src1, type0:$src2);
189 let hasSideEffects = 0;
190 let isCommutable = 0;
193 // Generic unsigned remainder.
194 def G_UREM : GenericInstruction {
195 let OutOperandList = (outs type0:$dst);
196 let InOperandList = (ins type0:$src1, type0:$src2);
197 let hasSideEffects = 0;
198 let isCommutable = 0;
201 // Generic bitwise and.
202 def G_AND : GenericInstruction {
203 let OutOperandList = (outs type0:$dst);
204 let InOperandList = (ins type0:$src1, type0:$src2);
205 let hasSideEffects = 0;
206 let isCommutable = 1;
209 // Generic bitwise or.
210 def G_OR : GenericInstruction {
211 let OutOperandList = (outs type0:$dst);
212 let InOperandList = (ins type0:$src1, type0:$src2);
213 let hasSideEffects = 0;
214 let isCommutable = 1;
217 // Generic bitwise xor.
218 def G_XOR : GenericInstruction {
219 let OutOperandList = (outs type0:$dst);
220 let InOperandList = (ins type0:$src1, type0:$src2);
221 let hasSideEffects = 0;
222 let isCommutable = 1;
225 // Generic left-shift.
226 def G_SHL : GenericInstruction {
227 let OutOperandList = (outs type0:$dst);
228 let InOperandList = (ins type0:$src1, type0:$src2);
229 let hasSideEffects = 0;
232 // Generic logical right-shift.
233 def G_LSHR : GenericInstruction {
234 let OutOperandList = (outs type0:$dst);
235 let InOperandList = (ins type0:$src1, type0:$src2);
236 let hasSideEffects = 0;
239 // Generic arithmetic right-shift.
240 def G_ASHR : GenericInstruction {
241 let OutOperandList = (outs type0:$dst);
242 let InOperandList = (ins type0:$src1, type0:$src2);
243 let hasSideEffects = 0;
246 // Generic integer comparison.
247 def G_ICMP : GenericInstruction {
248 let OutOperandList = (outs type0:$dst);
249 let InOperandList = (ins unknown:$tst, type1:$src1, type1:$src2);
250 let hasSideEffects = 0;
253 // Generic floating-point comparison.
254 def G_FCMP : GenericInstruction {
255 let OutOperandList = (outs type0:$dst);
256 let InOperandList = (ins unknown:$tst, type1:$src1, type1:$src2);
257 let hasSideEffects = 0;
261 def G_SELECT : GenericInstruction {
262 let OutOperandList = (outs type0:$dst);
263 let InOperandList = (ins type1:$tst, type0:$src1, type0:$src2);
264 let hasSideEffects = 0;
267 // Generic pointer offset.
268 def G_GEP : GenericInstruction {
269 let OutOperandList = (outs type0:$dst);
270 let InOperandList = (ins type0:$src1, type1:$src2);
271 let hasSideEffects = 0;
274 def G_PTR_MASK : GenericInstruction {
275 let OutOperandList = (outs type0:$dst);
276 let InOperandList = (ins type0:$src, unknown:$bits);
277 let hasSideEffects = 0;
280 //------------------------------------------------------------------------------
282 //------------------------------------------------------------------------------
284 // Generic unsigned addition consuming and producing a carry flag.
285 def G_UADDE : GenericInstruction {
286 let OutOperandList = (outs type0:$dst, type1:$carry_out);
287 let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
288 let hasSideEffects = 0;
291 // Generic signed addition producing a carry flag.
292 def G_SADDO : GenericInstruction {
293 let OutOperandList = (outs type0:$dst, type1:$carry_out);
294 let InOperandList = (ins type0:$src1, type0:$src2);
295 let hasSideEffects = 0;
296 let isCommutable = 1;
299 // Generic unsigned subtraction consuming and producing a carry flag.
300 def G_USUBE : GenericInstruction {
301 let OutOperandList = (outs type0:$dst, type1:$carry_out);
302 let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
303 let hasSideEffects = 0;
306 // Generic unsigned subtraction producing a carry flag.
307 def G_SSUBO : GenericInstruction {
308 let OutOperandList = (outs type0:$dst, type1:$carry_out);
309 let InOperandList = (ins type0:$src1, type0:$src2);
310 let hasSideEffects = 0;
313 // Generic unsigned multiplication producing a carry flag.
314 def G_UMULO : GenericInstruction {
315 let OutOperandList = (outs type0:$dst, type1:$carry_out);
316 let InOperandList = (ins type0:$src1, type0:$src2);
317 let hasSideEffects = 0;
318 let isCommutable = 1;
321 // Generic signed multiplication producing a carry flag.
322 def G_SMULO : GenericInstruction {
323 let OutOperandList = (outs type0:$dst, type1:$carry_out);
324 let InOperandList = (ins type0:$src1, type0:$src2);
325 let hasSideEffects = 0;
326 let isCommutable = 1;
329 // Multiply two numbers at twice the incoming bit width (unsigned) and return
330 // the high half of the result.
331 def G_UMULH : GenericInstruction {
332 let OutOperandList = (outs type0:$dst);
333 let InOperandList = (ins type0:$src1, type0:$src2);
334 let hasSideEffects = 0;
335 let isCommutable = 1;
338 // Multiply two numbers at twice the incoming bit width (signed) and return
339 // the high half of the result.
340 def G_SMULH : GenericInstruction {
341 let OutOperandList = (outs type0:$dst);
342 let InOperandList = (ins type0:$src1, type0:$src2);
343 let hasSideEffects = 0;
344 let isCommutable = 1;
347 //------------------------------------------------------------------------------
348 // Floating Point Unary Ops.
349 //------------------------------------------------------------------------------
351 def G_FNEG : GenericInstruction {
352 let OutOperandList = (outs type0:$dst);
353 let InOperandList = (ins type0:$src);
354 let hasSideEffects = 0;
357 def G_FPEXT : GenericInstruction {
358 let OutOperandList = (outs type0:$dst);
359 let InOperandList = (ins type1:$src);
360 let hasSideEffects = 0;
363 def G_FPTRUNC : GenericInstruction {
364 let OutOperandList = (outs type0:$dst);
365 let InOperandList = (ins type1:$src);
366 let hasSideEffects = 0;
369 def G_FPTOSI : GenericInstruction {
370 let OutOperandList = (outs type0:$dst);
371 let InOperandList = (ins type1:$src);
372 let hasSideEffects = 0;
375 def G_FPTOUI : GenericInstruction {
376 let OutOperandList = (outs type0:$dst);
377 let InOperandList = (ins type1:$src);
378 let hasSideEffects = 0;
381 def G_SITOFP : GenericInstruction {
382 let OutOperandList = (outs type0:$dst);
383 let InOperandList = (ins type1:$src);
384 let hasSideEffects = 0;
387 def G_UITOFP : GenericInstruction {
388 let OutOperandList = (outs type0:$dst);
389 let InOperandList = (ins type1:$src);
390 let hasSideEffects = 0;
393 def G_FABS : GenericInstruction {
394 let OutOperandList = (outs type0:$dst);
395 let InOperandList = (ins type0:$src);
396 let hasSideEffects = 0;
399 //------------------------------------------------------------------------------
400 // Floating Point Binary ops.
401 //------------------------------------------------------------------------------
403 // Generic FP addition.
404 def G_FADD : GenericInstruction {
405 let OutOperandList = (outs type0:$dst);
406 let InOperandList = (ins type0:$src1, type0:$src2);
407 let hasSideEffects = 0;
408 let isCommutable = 1;
411 // Generic FP subtraction.
412 def G_FSUB : GenericInstruction {
413 let OutOperandList = (outs type0:$dst);
414 let InOperandList = (ins type0:$src1, type0:$src2);
415 let hasSideEffects = 0;
416 let isCommutable = 0;
419 // Generic FP multiplication.
420 def G_FMUL : GenericInstruction {
421 let OutOperandList = (outs type0:$dst);
422 let InOperandList = (ins type0:$src1, type0:$src2);
423 let hasSideEffects = 0;
424 let isCommutable = 1;
427 // Generic fused multiply-add instruction.
428 // Behaves like llvm fma intrinsic ie src1 * src2 + src3
429 def G_FMA : GenericInstruction {
430 let OutOperandList = (outs type0:$dst);
431 let InOperandList = (ins type0:$src1, type0:$src2, type0:$src3);
432 let hasSideEffects = 0;
433 let isCommutable = 0;
436 // Generic FP division.
437 def G_FDIV : GenericInstruction {
438 let OutOperandList = (outs type0:$dst);
439 let InOperandList = (ins type0:$src1, type0:$src2);
440 let hasSideEffects = 0;
443 // Generic FP remainder.
444 def G_FREM : GenericInstruction {
445 let OutOperandList = (outs type0:$dst);
446 let InOperandList = (ins type0:$src1, type0:$src2);
447 let hasSideEffects = 0;
450 // Floating point exponentiation.
451 def G_FPOW : GenericInstruction {
452 let OutOperandList = (outs type0:$dst);
453 let InOperandList = (ins type0:$src1, type0:$src2);
454 let hasSideEffects = 0;
457 // Floating point base-e exponential of a value.
458 def G_FEXP : GenericInstruction {
459 let OutOperandList = (outs type0:$dst);
460 let InOperandList = (ins type0:$src1);
461 let hasSideEffects = 0;
464 // Floating point base-2 exponential of a value.
465 def G_FEXP2 : GenericInstruction {
466 let OutOperandList = (outs type0:$dst);
467 let InOperandList = (ins type0:$src1);
468 let hasSideEffects = 0;
471 // Floating point base-2 logarithm of a value.
472 def G_FLOG : GenericInstruction {
473 let OutOperandList = (outs type0:$dst);
474 let InOperandList = (ins type0:$src1);
475 let hasSideEffects = 0;
478 // Floating point base-2 logarithm of a value.
479 def G_FLOG2 : GenericInstruction {
480 let OutOperandList = (outs type0:$dst);
481 let InOperandList = (ins type0:$src1);
482 let hasSideEffects = 0;
485 //------------------------------------------------------------------------------
487 //------------------------------------------------------------------------------
489 // Generic load. Expects a MachineMemOperand in addition to explicit operands.
490 def G_LOAD : GenericInstruction {
491 let OutOperandList = (outs type0:$dst);
492 let InOperandList = (ins ptype1:$addr);
493 let hasSideEffects = 0;
497 // Generic sign-extended load. Expects a MachineMemOperand in addition to explicit operands.
498 def G_SEXTLOAD : GenericInstruction {
499 let OutOperandList = (outs type0:$dst);
500 let InOperandList = (ins ptype1:$addr);
501 let hasSideEffects = 0;
505 // Generic zero-extended load. Expects a MachineMemOperand in addition to explicit operands.
506 def G_ZEXTLOAD : GenericInstruction {
507 let OutOperandList = (outs type0:$dst);
508 let InOperandList = (ins ptype1:$addr);
509 let hasSideEffects = 0;
513 // Generic store. Expects a MachineMemOperand in addition to explicit operands.
514 def G_STORE : GenericInstruction {
515 let OutOperandList = (outs);
516 let InOperandList = (ins type0:$src, ptype1:$addr);
517 let hasSideEffects = 0;
521 // Generic atomic cmpxchg with internal success check. Expects a
522 // MachineMemOperand in addition to explicit operands.
523 def G_ATOMIC_CMPXCHG_WITH_SUCCESS : GenericInstruction {
524 let OutOperandList = (outs type0:$oldval, type1:$success);
525 let InOperandList = (ins type2:$addr, type0:$cmpval, type0:$newval);
526 let hasSideEffects = 0;
531 // Generic atomic cmpxchg. Expects a MachineMemOperand in addition to explicit
533 def G_ATOMIC_CMPXCHG : GenericInstruction {
534 let OutOperandList = (outs type0:$oldval);
535 let InOperandList = (ins ptype1:$addr, type0:$cmpval, type0:$newval);
536 let hasSideEffects = 0;
541 // Generic atomicrmw. Expects a MachineMemOperand in addition to explicit
543 class G_ATOMICRMW_OP : GenericInstruction {
544 let OutOperandList = (outs type0:$oldval);
545 let InOperandList = (ins ptype1:$addr, type0:$val);
546 let hasSideEffects = 0;
551 def G_ATOMICRMW_XCHG : G_ATOMICRMW_OP;
552 def G_ATOMICRMW_ADD : G_ATOMICRMW_OP;
553 def G_ATOMICRMW_SUB : G_ATOMICRMW_OP;
554 def G_ATOMICRMW_AND : G_ATOMICRMW_OP;
555 def G_ATOMICRMW_NAND : G_ATOMICRMW_OP;
556 def G_ATOMICRMW_OR : G_ATOMICRMW_OP;
557 def G_ATOMICRMW_XOR : G_ATOMICRMW_OP;
558 def G_ATOMICRMW_MAX : G_ATOMICRMW_OP;
559 def G_ATOMICRMW_MIN : G_ATOMICRMW_OP;
560 def G_ATOMICRMW_UMAX : G_ATOMICRMW_OP;
561 def G_ATOMICRMW_UMIN : G_ATOMICRMW_OP;
563 //------------------------------------------------------------------------------
565 //------------------------------------------------------------------------------
567 // Extract a register of the specified size, starting from the block given by
568 // index. This will almost certainly be mapped to sub-register COPYs after
569 // register banks have been selected.
570 def G_EXTRACT : GenericInstruction {
571 let OutOperandList = (outs type0:$res);
572 let InOperandList = (ins type1:$src, unknown:$offset);
573 let hasSideEffects = 0;
576 // Extract multiple registers specified size, starting from blocks given by
577 // indexes. This will almost certainly be mapped to sub-register COPYs after
578 // register banks have been selected.
579 def G_UNMERGE_VALUES : GenericInstruction {
580 let OutOperandList = (outs type0:$dst0, variable_ops);
581 let InOperandList = (ins type1:$src);
582 let hasSideEffects = 0;
585 // Insert a smaller register into a larger one at the specified bit-index.
586 def G_INSERT : GenericInstruction {
587 let OutOperandList = (outs type0:$dst);
588 let InOperandList = (ins type0:$src, type1:$op, unknown:$offset);
589 let hasSideEffects = 0;
592 /// Concatenate multiple registers of the same size into a wider register.
593 def G_MERGE_VALUES : GenericInstruction {
594 let OutOperandList = (outs type0:$dst);
595 let InOperandList = (ins type1:$src0, variable_ops);
596 let hasSideEffects = 0;
599 // Intrinsic without side effects.
600 def G_INTRINSIC : GenericInstruction {
601 let OutOperandList = (outs);
602 let InOperandList = (ins unknown:$intrin, variable_ops);
603 let hasSideEffects = 0;
606 // Intrinsic with side effects.
607 def G_INTRINSIC_W_SIDE_EFFECTS : GenericInstruction {
608 let OutOperandList = (outs);
609 let InOperandList = (ins unknown:$intrin, variable_ops);
610 let hasSideEffects = 1;
615 //------------------------------------------------------------------------------
617 //------------------------------------------------------------------------------
619 // Generic unconditional branch.
620 def G_BR : GenericInstruction {
621 let OutOperandList = (outs);
622 let InOperandList = (ins unknown:$src1);
623 let hasSideEffects = 0;
625 let isTerminator = 1;
629 // Generic conditional branch.
630 def G_BRCOND : GenericInstruction {
631 let OutOperandList = (outs);
632 let InOperandList = (ins type0:$tst, unknown:$truebb);
633 let hasSideEffects = 0;
635 let isTerminator = 1;
638 // Generic indirect branch.
639 def G_BRINDIRECT : GenericInstruction {
640 let OutOperandList = (outs);
641 let InOperandList = (ins type0:$src1);
642 let hasSideEffects = 0;
644 let isTerminator = 1;
647 //------------------------------------------------------------------------------
649 //------------------------------------------------------------------------------
651 // Generic insertelement.
652 def G_INSERT_VECTOR_ELT : GenericInstruction {
653 let OutOperandList = (outs type0:$dst);
654 let InOperandList = (ins type0:$src, type1:$elt, type2:$idx);
655 let hasSideEffects = 0;
658 // Generic extractelement.
659 def G_EXTRACT_VECTOR_ELT : GenericInstruction {
660 let OutOperandList = (outs type0:$dst);
661 let InOperandList = (ins type1:$src, type2:$idx);
662 let hasSideEffects = 0;
665 // Generic shufflevector.
666 def G_SHUFFLE_VECTOR: GenericInstruction {
667 let OutOperandList = (outs type0:$dst);
668 let InOperandList = (ins type1:$v1, type1:$v2, type2:$mask);
669 let hasSideEffects = 0;
672 // TODO: Add the other generic opcodes.