1 //===-- GenericOpcodes.td - Opcodes used with GlobalISel ---*- tablegen -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file defines the generic opcodes used with GlobalISel.
10 // After instruction selection, these opcodes should not appear.
12 //===----------------------------------------------------------------------===//
14 //------------------------------------------------------------------------------
16 //------------------------------------------------------------------------------
18 class GenericInstruction : StandardPseudoInstruction;
20 // Extend the underlying scalar type of an operation, leaving the high bits
22 def G_ANYEXT : GenericInstruction {
23 let OutOperandList = (outs type0:$dst);
24 let InOperandList = (ins type1:$src);
25 let hasSideEffects = 0;
28 // Sign extend the underlying scalar type of an operation, copying the sign bit
29 // into the newly-created space.
30 def G_SEXT : GenericInstruction {
31 let OutOperandList = (outs type0:$dst);
32 let InOperandList = (ins type1:$src);
33 let hasSideEffects = 0;
36 // Zero extend the underlying scalar type of an operation, putting zero bits
37 // into the newly-created space.
38 def G_ZEXT : GenericInstruction {
39 let OutOperandList = (outs type0:$dst);
40 let InOperandList = (ins type1:$src);
41 let hasSideEffects = 0;
45 // Truncate the underlying scalar type of an operation. This is equivalent to
46 // G_EXTRACT for scalar types, but acts elementwise on vectors.
47 def G_TRUNC : GenericInstruction {
48 let OutOperandList = (outs type0:$dst);
49 let InOperandList = (ins type1:$src);
50 let hasSideEffects = 0;
53 def G_IMPLICIT_DEF : GenericInstruction {
54 let OutOperandList = (outs type0:$dst);
55 let InOperandList = (ins);
56 let hasSideEffects = 0;
59 def G_PHI : GenericInstruction {
60 let OutOperandList = (outs type0:$dst);
61 let InOperandList = (ins variable_ops);
62 let hasSideEffects = 0;
65 def G_FRAME_INDEX : GenericInstruction {
66 let OutOperandList = (outs type0:$dst);
67 let InOperandList = (ins unknown:$src2);
68 let hasSideEffects = 0;
71 def G_GLOBAL_VALUE : GenericInstruction {
72 let OutOperandList = (outs type0:$dst);
73 let InOperandList = (ins unknown:$src);
74 let hasSideEffects = 0;
77 def G_INTTOPTR : GenericInstruction {
78 let OutOperandList = (outs type0:$dst);
79 let InOperandList = (ins type1:$src);
80 let hasSideEffects = 0;
83 def G_PTRTOINT : GenericInstruction {
84 let OutOperandList = (outs type0:$dst);
85 let InOperandList = (ins type1:$src);
86 let hasSideEffects = 0;
89 def G_BITCAST : GenericInstruction {
90 let OutOperandList = (outs type0:$dst);
91 let InOperandList = (ins type1:$src);
92 let hasSideEffects = 0;
95 // Only supports scalar result types
96 def G_CONSTANT : GenericInstruction {
97 let OutOperandList = (outs type0:$dst);
98 let InOperandList = (ins unknown:$imm);
99 let hasSideEffects = 0;
102 // Only supports scalar result types
103 def G_FCONSTANT : GenericInstruction {
104 let OutOperandList = (outs type0:$dst);
105 let InOperandList = (ins unknown:$imm);
106 let hasSideEffects = 0;
109 def G_VASTART : GenericInstruction {
110 let OutOperandList = (outs);
111 let InOperandList = (ins type0:$list);
112 let hasSideEffects = 0;
116 def G_VAARG : GenericInstruction {
117 let OutOperandList = (outs type0:$val);
118 let InOperandList = (ins type1:$list, unknown:$align);
119 let hasSideEffects = 0;
124 def G_CTLZ : GenericInstruction {
125 let OutOperandList = (outs type0:$dst);
126 let InOperandList = (ins type1:$src);
127 let hasSideEffects = 0;
130 def G_CTLZ_ZERO_UNDEF : GenericInstruction {
131 let OutOperandList = (outs type0:$dst);
132 let InOperandList = (ins type1:$src);
133 let hasSideEffects = 0;
136 def G_CTTZ : GenericInstruction {
137 let OutOperandList = (outs type0:$dst);
138 let InOperandList = (ins type1:$src);
139 let hasSideEffects = 0;
142 def G_CTTZ_ZERO_UNDEF : GenericInstruction {
143 let OutOperandList = (outs type0:$dst);
144 let InOperandList = (ins type1:$src);
145 let hasSideEffects = 0;
148 def G_CTPOP : GenericInstruction {
149 let OutOperandList = (outs type0:$dst);
150 let InOperandList = (ins type1:$src);
151 let hasSideEffects = 0;
154 def G_BSWAP : GenericInstruction {
155 let OutOperandList = (outs type0:$dst);
156 let InOperandList = (ins type0:$src);
157 let hasSideEffects = 0;
160 def G_ADDRSPACE_CAST : GenericInstruction {
161 let OutOperandList = (outs type0:$dst);
162 let InOperandList = (ins type1:$src);
163 let hasSideEffects = 0;
166 def G_BLOCK_ADDR : GenericInstruction {
167 let OutOperandList = (outs type0:$dst);
168 let InOperandList = (ins unknown:$ba);
169 let hasSideEffects = 0;
172 def G_JUMP_TABLE : GenericInstruction {
173 let OutOperandList = (outs type0:$dst);
174 let InOperandList = (ins unknown:$jti);
175 let hasSideEffects = 0;
178 //------------------------------------------------------------------------------
180 //------------------------------------------------------------------------------
183 def G_ADD : GenericInstruction {
184 let OutOperandList = (outs type0:$dst);
185 let InOperandList = (ins type0:$src1, type0:$src2);
186 let hasSideEffects = 0;
187 let isCommutable = 1;
190 // Generic subtraction.
191 def G_SUB : GenericInstruction {
192 let OutOperandList = (outs type0:$dst);
193 let InOperandList = (ins type0:$src1, type0:$src2);
194 let hasSideEffects = 0;
195 let isCommutable = 0;
198 // Generic multiplication.
199 def G_MUL : GenericInstruction {
200 let OutOperandList = (outs type0:$dst);
201 let InOperandList = (ins type0:$src1, type0:$src2);
202 let hasSideEffects = 0;
203 let isCommutable = 1;
206 // Generic signed division.
207 def G_SDIV : GenericInstruction {
208 let OutOperandList = (outs type0:$dst);
209 let InOperandList = (ins type0:$src1, type0:$src2);
210 let hasSideEffects = 0;
211 let isCommutable = 0;
214 // Generic unsigned division.
215 def G_UDIV : GenericInstruction {
216 let OutOperandList = (outs type0:$dst);
217 let InOperandList = (ins type0:$src1, type0:$src2);
218 let hasSideEffects = 0;
219 let isCommutable = 0;
222 // Generic signed remainder.
223 def G_SREM : GenericInstruction {
224 let OutOperandList = (outs type0:$dst);
225 let InOperandList = (ins type0:$src1, type0:$src2);
226 let hasSideEffects = 0;
227 let isCommutable = 0;
230 // Generic unsigned remainder.
231 def G_UREM : GenericInstruction {
232 let OutOperandList = (outs type0:$dst);
233 let InOperandList = (ins type0:$src1, type0:$src2);
234 let hasSideEffects = 0;
235 let isCommutable = 0;
238 // Generic bitwise and.
239 def G_AND : GenericInstruction {
240 let OutOperandList = (outs type0:$dst);
241 let InOperandList = (ins type0:$src1, type0:$src2);
242 let hasSideEffects = 0;
243 let isCommutable = 1;
246 // Generic bitwise or.
247 def G_OR : GenericInstruction {
248 let OutOperandList = (outs type0:$dst);
249 let InOperandList = (ins type0:$src1, type0:$src2);
250 let hasSideEffects = 0;
251 let isCommutable = 1;
254 // Generic bitwise xor.
255 def G_XOR : GenericInstruction {
256 let OutOperandList = (outs type0:$dst);
257 let InOperandList = (ins type0:$src1, type0:$src2);
258 let hasSideEffects = 0;
259 let isCommutable = 1;
262 // Generic left-shift.
263 def G_SHL : GenericInstruction {
264 let OutOperandList = (outs type0:$dst);
265 let InOperandList = (ins type0:$src1, type1:$src2);
266 let hasSideEffects = 0;
269 // Generic logical right-shift.
270 def G_LSHR : GenericInstruction {
271 let OutOperandList = (outs type0:$dst);
272 let InOperandList = (ins type0:$src1, type1:$src2);
273 let hasSideEffects = 0;
276 // Generic arithmetic right-shift.
277 def G_ASHR : GenericInstruction {
278 let OutOperandList = (outs type0:$dst);
279 let InOperandList = (ins type0:$src1, type1:$src2);
280 let hasSideEffects = 0;
283 // Generic integer comparison.
284 def G_ICMP : GenericInstruction {
285 let OutOperandList = (outs type0:$dst);
286 let InOperandList = (ins unknown:$tst, type1:$src1, type1:$src2);
287 let hasSideEffects = 0;
290 // Generic floating-point comparison.
291 def G_FCMP : GenericInstruction {
292 let OutOperandList = (outs type0:$dst);
293 let InOperandList = (ins unknown:$tst, type1:$src1, type1:$src2);
294 let hasSideEffects = 0;
298 def G_SELECT : GenericInstruction {
299 let OutOperandList = (outs type0:$dst);
300 let InOperandList = (ins type1:$tst, type0:$src1, type0:$src2);
301 let hasSideEffects = 0;
304 // Generic pointer offset.
305 def G_GEP : GenericInstruction {
306 let OutOperandList = (outs type0:$dst);
307 let InOperandList = (ins type0:$src1, type1:$src2);
308 let hasSideEffects = 0;
311 def G_PTR_MASK : GenericInstruction {
312 let OutOperandList = (outs type0:$dst);
313 let InOperandList = (ins type0:$src, unknown:$bits);
314 let hasSideEffects = 0;
317 // Generic signed integer minimum.
318 def G_SMIN : GenericInstruction {
319 let OutOperandList = (outs type0:$dst);
320 let InOperandList = (ins type0:$src1, type0:$src2);
321 let hasSideEffects = 0;
322 let isCommutable = 1;
325 // Generic signed integer maximum.
326 def G_SMAX : GenericInstruction {
327 let OutOperandList = (outs type0:$dst);
328 let InOperandList = (ins type0:$src1, type0:$src2);
329 let hasSideEffects = 0;
330 let isCommutable = 1;
333 // Generic unsigned integer minimum.
334 def G_UMIN : GenericInstruction {
335 let OutOperandList = (outs type0:$dst);
336 let InOperandList = (ins type0:$src1, type0:$src2);
337 let hasSideEffects = 0;
338 let isCommutable = 1;
341 // Generic unsigned integer maximum.
342 def G_UMAX : GenericInstruction {
343 let OutOperandList = (outs type0:$dst);
344 let InOperandList = (ins type0:$src1, type0:$src2);
345 let hasSideEffects = 0;
346 let isCommutable = 1;
349 //------------------------------------------------------------------------------
351 //------------------------------------------------------------------------------
353 // Generic unsigned addition producing a carry flag.
354 def G_UADDO : GenericInstruction {
355 let OutOperandList = (outs type0:$dst, type1:$carry_out);
356 let InOperandList = (ins type0:$src1, type0:$src2);
357 let hasSideEffects = 0;
358 let isCommutable = 1;
361 // Generic unsigned addition consuming and producing a carry flag.
362 def G_UADDE : GenericInstruction {
363 let OutOperandList = (outs type0:$dst, type1:$carry_out);
364 let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
365 let hasSideEffects = 0;
368 // Generic signed addition producing a carry flag.
369 def G_SADDO : GenericInstruction {
370 let OutOperandList = (outs type0:$dst, type1:$carry_out);
371 let InOperandList = (ins type0:$src1, type0:$src2);
372 let hasSideEffects = 0;
373 let isCommutable = 1;
376 // Generic signed addition consuming and producing a carry flag.
377 def G_SADDE : GenericInstruction {
378 let OutOperandList = (outs type0:$dst, type1:$carry_out);
379 let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
380 let hasSideEffects = 0;
383 // Generic unsigned subtraction producing a carry flag.
384 def G_USUBO : GenericInstruction {
385 let OutOperandList = (outs type0:$dst, type1:$carry_out);
386 let InOperandList = (ins type0:$src1, type0:$src2);
387 let hasSideEffects = 0;
389 // Generic unsigned subtraction consuming and producing a carry flag.
390 def G_USUBE : GenericInstruction {
391 let OutOperandList = (outs type0:$dst, type1:$carry_out);
392 let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
393 let hasSideEffects = 0;
396 // Generic signed subtraction producing a carry flag.
397 def G_SSUBO : GenericInstruction {
398 let OutOperandList = (outs type0:$dst, type1:$carry_out);
399 let InOperandList = (ins type0:$src1, type0:$src2);
400 let hasSideEffects = 0;
403 // Generic signed subtraction consuming and producing a carry flag.
404 def G_SSUBE : GenericInstruction {
405 let OutOperandList = (outs type0:$dst, type1:$carry_out);
406 let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
407 let hasSideEffects = 0;
410 // Generic unsigned multiplication producing a carry flag.
411 def G_UMULO : GenericInstruction {
412 let OutOperandList = (outs type0:$dst, type1:$carry_out);
413 let InOperandList = (ins type0:$src1, type0:$src2);
414 let hasSideEffects = 0;
415 let isCommutable = 1;
418 // Generic signed multiplication producing a carry flag.
419 def G_SMULO : GenericInstruction {
420 let OutOperandList = (outs type0:$dst, type1:$carry_out);
421 let InOperandList = (ins type0:$src1, type0:$src2);
422 let hasSideEffects = 0;
423 let isCommutable = 1;
426 // Multiply two numbers at twice the incoming bit width (unsigned) and return
427 // the high half of the result.
428 def G_UMULH : GenericInstruction {
429 let OutOperandList = (outs type0:$dst);
430 let InOperandList = (ins type0:$src1, type0:$src2);
431 let hasSideEffects = 0;
432 let isCommutable = 1;
435 // Multiply two numbers at twice the incoming bit width (signed) and return
436 // the high half of the result.
437 def G_SMULH : GenericInstruction {
438 let OutOperandList = (outs type0:$dst);
439 let InOperandList = (ins type0:$src1, type0:$src2);
440 let hasSideEffects = 0;
441 let isCommutable = 1;
444 //------------------------------------------------------------------------------
445 // Floating Point Unary Ops.
446 //------------------------------------------------------------------------------
448 def G_FNEG : GenericInstruction {
449 let OutOperandList = (outs type0:$dst);
450 let InOperandList = (ins type0:$src);
451 let hasSideEffects = 0;
454 def G_FPEXT : GenericInstruction {
455 let OutOperandList = (outs type0:$dst);
456 let InOperandList = (ins type1:$src);
457 let hasSideEffects = 0;
460 def G_FPTRUNC : GenericInstruction {
461 let OutOperandList = (outs type0:$dst);
462 let InOperandList = (ins type1:$src);
463 let hasSideEffects = 0;
466 def G_FPTOSI : GenericInstruction {
467 let OutOperandList = (outs type0:$dst);
468 let InOperandList = (ins type1:$src);
469 let hasSideEffects = 0;
472 def G_FPTOUI : GenericInstruction {
473 let OutOperandList = (outs type0:$dst);
474 let InOperandList = (ins type1:$src);
475 let hasSideEffects = 0;
478 def G_SITOFP : GenericInstruction {
479 let OutOperandList = (outs type0:$dst);
480 let InOperandList = (ins type1:$src);
481 let hasSideEffects = 0;
484 def G_UITOFP : GenericInstruction {
485 let OutOperandList = (outs type0:$dst);
486 let InOperandList = (ins type1:$src);
487 let hasSideEffects = 0;
490 def G_FABS : GenericInstruction {
491 let OutOperandList = (outs type0:$dst);
492 let InOperandList = (ins type0:$src);
493 let hasSideEffects = 0;
496 def G_FCOPYSIGN : GenericInstruction {
497 let OutOperandList = (outs type0:$dst);
498 let InOperandList = (ins type0:$src0, type1:$src1);
499 let hasSideEffects = 0;
502 def G_FCANONICALIZE : GenericInstruction {
503 let OutOperandList = (outs type0:$dst);
504 let InOperandList = (ins type0:$src);
505 let hasSideEffects = 0;
508 // FMINNUM/FMAXNUM - Perform floating-point minimum or maximum on two
511 // In the case where a single input is a NaN (either signaling or quiet),
512 // the non-NaN input is returned.
514 // The return value of (FMINNUM 0.0, -0.0) could be either 0.0 or -0.0.
515 def G_FMINNUM : GenericInstruction {
516 let OutOperandList = (outs type0:$dst);
517 let InOperandList = (ins type0:$src1, type0:$src2);
518 let hasSideEffects = 0;
519 let isCommutable = 1;
522 def G_FMAXNUM : GenericInstruction {
523 let OutOperandList = (outs type0:$dst);
524 let InOperandList = (ins type0:$src1, type0:$src2);
525 let hasSideEffects = 0;
526 let isCommutable = 1;
529 // FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimum or maximum on
530 // two values, following the IEEE-754 2008 definition. This differs from
531 // FMINNUM/FMAXNUM in the handling of signaling NaNs. If one input is a
532 // signaling NaN, returns a quiet NaN.
533 def G_FMINNUM_IEEE : GenericInstruction {
534 let OutOperandList = (outs type0:$dst);
535 let InOperandList = (ins type0:$src1, type0:$src2);
536 let hasSideEffects = 0;
537 let isCommutable = 1;
540 def G_FMAXNUM_IEEE : GenericInstruction {
541 let OutOperandList = (outs type0:$dst);
542 let InOperandList = (ins type0:$src1, type0:$src2);
543 let hasSideEffects = 0;
544 let isCommutable = 1;
547 // FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0
548 // as less than 0.0. While FMINNUM_IEEE/FMAXNUM_IEEE follow IEEE 754-2008
549 // semantics, FMINIMUM/FMAXIMUM follow IEEE 754-2018 draft semantics.
550 def G_FMINIMUM : GenericInstruction {
551 let OutOperandList = (outs type0:$dst);
552 let InOperandList = (ins type0:$src1, type0:$src2);
553 let hasSideEffects = 0;
554 let isCommutable = 1;
557 def G_FMAXIMUM : GenericInstruction {
558 let OutOperandList = (outs type0:$dst);
559 let InOperandList = (ins type0:$src1, type0:$src2);
560 let hasSideEffects = 0;
561 let isCommutable = 1;
564 //------------------------------------------------------------------------------
565 // Floating Point Binary ops.
566 //------------------------------------------------------------------------------
568 // Generic FP addition.
569 def G_FADD : GenericInstruction {
570 let OutOperandList = (outs type0:$dst);
571 let InOperandList = (ins type0:$src1, type0:$src2);
572 let hasSideEffects = 0;
573 let isCommutable = 1;
576 // Generic FP subtraction.
577 def G_FSUB : GenericInstruction {
578 let OutOperandList = (outs type0:$dst);
579 let InOperandList = (ins type0:$src1, type0:$src2);
580 let hasSideEffects = 0;
581 let isCommutable = 0;
584 // Generic FP multiplication.
585 def G_FMUL : GenericInstruction {
586 let OutOperandList = (outs type0:$dst);
587 let InOperandList = (ins type0:$src1, type0:$src2);
588 let hasSideEffects = 0;
589 let isCommutable = 1;
592 // Generic fused multiply-add instruction.
593 // Behaves like llvm fma intrinsic ie src1 * src2 + src3
594 def G_FMA : GenericInstruction {
595 let OutOperandList = (outs type0:$dst);
596 let InOperandList = (ins type0:$src1, type0:$src2, type0:$src3);
597 let hasSideEffects = 0;
598 let isCommutable = 0;
601 // Generic FP division.
602 def G_FDIV : GenericInstruction {
603 let OutOperandList = (outs type0:$dst);
604 let InOperandList = (ins type0:$src1, type0:$src2);
605 let hasSideEffects = 0;
608 // Generic FP remainder.
609 def G_FREM : GenericInstruction {
610 let OutOperandList = (outs type0:$dst);
611 let InOperandList = (ins type0:$src1, type0:$src2);
612 let hasSideEffects = 0;
615 // Floating point exponentiation.
616 def G_FPOW : GenericInstruction {
617 let OutOperandList = (outs type0:$dst);
618 let InOperandList = (ins type0:$src1, type0:$src2);
619 let hasSideEffects = 0;
622 // Floating point base-e exponential of a value.
623 def G_FEXP : GenericInstruction {
624 let OutOperandList = (outs type0:$dst);
625 let InOperandList = (ins type0:$src1);
626 let hasSideEffects = 0;
629 // Floating point base-2 exponential of a value.
630 def G_FEXP2 : GenericInstruction {
631 let OutOperandList = (outs type0:$dst);
632 let InOperandList = (ins type0:$src1);
633 let hasSideEffects = 0;
636 // Floating point base-2 logarithm of a value.
637 def G_FLOG : GenericInstruction {
638 let OutOperandList = (outs type0:$dst);
639 let InOperandList = (ins type0:$src1);
640 let hasSideEffects = 0;
643 // Floating point base-2 logarithm of a value.
644 def G_FLOG2 : GenericInstruction {
645 let OutOperandList = (outs type0:$dst);
646 let InOperandList = (ins type0:$src1);
647 let hasSideEffects = 0;
650 // Floating point base-10 logarithm of a value.
651 def G_FLOG10 : GenericInstruction {
652 let OutOperandList = (outs type0:$dst);
653 let InOperandList = (ins type0:$src1);
654 let hasSideEffects = 0;
657 // Floating point ceiling of a value.
658 def G_FCEIL : GenericInstruction {
659 let OutOperandList = (outs type0:$dst);
660 let InOperandList = (ins type0:$src1);
661 let hasSideEffects = 0;
664 // Floating point cosine of a value.
665 def G_FCOS : GenericInstruction {
666 let OutOperandList = (outs type0:$dst);
667 let InOperandList = (ins type0:$src1);
668 let hasSideEffects = 0;
671 // Floating point sine of a value.
672 def G_FSIN : GenericInstruction {
673 let OutOperandList = (outs type0:$dst);
674 let InOperandList = (ins type0:$src1);
675 let hasSideEffects = 0;
678 // Floating point square root of a value.
679 // This returns NaN for negative nonzero values.
680 // NOTE: Unlike libm sqrt(), this never sets errno. In all other respects it's
682 def G_FSQRT : GenericInstruction {
683 let OutOperandList = (outs type0:$dst);
684 let InOperandList = (ins type0:$src1);
685 let hasSideEffects = 0;
688 // Floating point floor of a value.
689 def G_FFLOOR : GenericInstruction {
690 let OutOperandList = (outs type0:$dst);
691 let InOperandList = (ins type0:$src1);
692 let hasSideEffects = 0;
695 // Floating point round to next integer.
696 def G_FRINT : GenericInstruction {
697 let OutOperandList = (outs type0:$dst);
698 let InOperandList = (ins type0:$src1);
699 let hasSideEffects = 0;
702 // Floating point round to the nearest integer.
703 def G_FNEARBYINT : GenericInstruction {
704 let OutOperandList = (outs type0:$dst);
705 let InOperandList = (ins type0:$src1);
706 let hasSideEffects = 0;
709 //------------------------------------------------------------------------------
710 // Opcodes for LLVM Intrinsics
711 //------------------------------------------------------------------------------
712 def G_INTRINSIC_TRUNC : GenericInstruction {
713 let OutOperandList = (outs type0:$dst);
714 let InOperandList = (ins type0:$src1);
715 let hasSideEffects = 0;
718 def G_INTRINSIC_ROUND : GenericInstruction {
719 let OutOperandList = (outs type0:$dst);
720 let InOperandList = (ins type0:$src1);
721 let hasSideEffects = 0;
724 //------------------------------------------------------------------------------
726 //------------------------------------------------------------------------------
728 // Generic load. Expects a MachineMemOperand in addition to explicit operands.
729 def G_LOAD : GenericInstruction {
730 let OutOperandList = (outs type0:$dst);
731 let InOperandList = (ins ptype1:$addr);
732 let hasSideEffects = 0;
736 // Generic sign-extended load. Expects a MachineMemOperand in addition to explicit operands.
737 def G_SEXTLOAD : GenericInstruction {
738 let OutOperandList = (outs type0:$dst);
739 let InOperandList = (ins ptype1:$addr);
740 let hasSideEffects = 0;
744 // Generic zero-extended load. Expects a MachineMemOperand in addition to explicit operands.
745 def G_ZEXTLOAD : GenericInstruction {
746 let OutOperandList = (outs type0:$dst);
747 let InOperandList = (ins ptype1:$addr);
748 let hasSideEffects = 0;
752 // Generic store. Expects a MachineMemOperand in addition to explicit operands.
753 def G_STORE : GenericInstruction {
754 let OutOperandList = (outs);
755 let InOperandList = (ins type0:$src, ptype1:$addr);
756 let hasSideEffects = 0;
760 // Generic atomic cmpxchg with internal success check. Expects a
761 // MachineMemOperand in addition to explicit operands.
762 def G_ATOMIC_CMPXCHG_WITH_SUCCESS : GenericInstruction {
763 let OutOperandList = (outs type0:$oldval, type1:$success);
764 let InOperandList = (ins type2:$addr, type0:$cmpval, type0:$newval);
765 let hasSideEffects = 0;
770 // Generic atomic cmpxchg. Expects a MachineMemOperand in addition to explicit
772 def G_ATOMIC_CMPXCHG : GenericInstruction {
773 let OutOperandList = (outs type0:$oldval);
774 let InOperandList = (ins ptype1:$addr, type0:$cmpval, type0:$newval);
775 let hasSideEffects = 0;
780 // Generic atomicrmw. Expects a MachineMemOperand in addition to explicit
782 class G_ATOMICRMW_OP : GenericInstruction {
783 let OutOperandList = (outs type0:$oldval);
784 let InOperandList = (ins ptype1:$addr, type0:$val);
785 let hasSideEffects = 0;
790 def G_ATOMICRMW_XCHG : G_ATOMICRMW_OP;
791 def G_ATOMICRMW_ADD : G_ATOMICRMW_OP;
792 def G_ATOMICRMW_SUB : G_ATOMICRMW_OP;
793 def G_ATOMICRMW_AND : G_ATOMICRMW_OP;
794 def G_ATOMICRMW_NAND : G_ATOMICRMW_OP;
795 def G_ATOMICRMW_OR : G_ATOMICRMW_OP;
796 def G_ATOMICRMW_XOR : G_ATOMICRMW_OP;
797 def G_ATOMICRMW_MAX : G_ATOMICRMW_OP;
798 def G_ATOMICRMW_MIN : G_ATOMICRMW_OP;
799 def G_ATOMICRMW_UMAX : G_ATOMICRMW_OP;
800 def G_ATOMICRMW_UMIN : G_ATOMICRMW_OP;
802 def G_FENCE : GenericInstruction {
803 let OutOperandList = (outs);
804 let InOperandList = (ins i32imm:$ordering, i32imm:$scope);
805 let hasSideEffects = 1;
808 //------------------------------------------------------------------------------
810 //------------------------------------------------------------------------------
812 // Extract a register of the specified size, starting from the block given by
813 // index. This will almost certainly be mapped to sub-register COPYs after
814 // register banks have been selected.
815 def G_EXTRACT : GenericInstruction {
816 let OutOperandList = (outs type0:$res);
817 let InOperandList = (ins type1:$src, unknown:$offset);
818 let hasSideEffects = 0;
821 // Extract multiple registers specified size, starting from blocks given by
822 // indexes. This will almost certainly be mapped to sub-register COPYs after
823 // register banks have been selected.
824 // The output operands are always ordered from lowest bits to highest:
825 // %bits_0_7:(s8), %bits_8_15:(s8),
826 // %bits_16_23:(s8), %bits_24_31:(s8) = G_UNMERGE_VALUES %0:(s32)
827 def G_UNMERGE_VALUES : GenericInstruction {
828 let OutOperandList = (outs type0:$dst0, variable_ops);
829 let InOperandList = (ins type1:$src);
830 let hasSideEffects = 0;
833 // Insert a smaller register into a larger one at the specified bit-index.
834 def G_INSERT : GenericInstruction {
835 let OutOperandList = (outs type0:$dst);
836 let InOperandList = (ins type0:$src, type1:$op, unknown:$offset);
837 let hasSideEffects = 0;
840 // Concatenate multiple registers of the same size into a wider register.
841 // The input operands are always ordered from lowest bits to highest:
842 // %0:(s32) = G_MERGE_VALUES %bits_0_7:(s8), %bits_8_15:(s8),
843 // %bits_16_23:(s8), %bits_24_31:(s8)
844 def G_MERGE_VALUES : GenericInstruction {
845 let OutOperandList = (outs type0:$dst);
846 let InOperandList = (ins type1:$src0, variable_ops);
847 let hasSideEffects = 0;
850 /// Create a vector from multiple scalar registers. No implicit
851 /// conversion is performed (i.e. the result element type must be the
852 /// same as all source operands)
853 def G_BUILD_VECTOR : GenericInstruction {
854 let OutOperandList = (outs type0:$dst);
855 let InOperandList = (ins type1:$src0, variable_ops);
856 let hasSideEffects = 0;
859 /// Like G_BUILD_VECTOR, but truncates the larger operand types to fit the
860 /// destination vector elt type.
861 def G_BUILD_VECTOR_TRUNC : GenericInstruction {
862 let OutOperandList = (outs type0:$dst);
863 let InOperandList = (ins type1:$src0, variable_ops);
864 let hasSideEffects = 0;
867 /// Create a vector by concatenating vectors together.
868 def G_CONCAT_VECTORS : GenericInstruction {
869 let OutOperandList = (outs type0:$dst);
870 let InOperandList = (ins type1:$src0, variable_ops);
871 let hasSideEffects = 0;
874 // Intrinsic without side effects.
875 def G_INTRINSIC : GenericInstruction {
876 let OutOperandList = (outs);
877 let InOperandList = (ins unknown:$intrin, variable_ops);
878 let hasSideEffects = 0;
881 // Intrinsic with side effects.
882 def G_INTRINSIC_W_SIDE_EFFECTS : GenericInstruction {
883 let OutOperandList = (outs);
884 let InOperandList = (ins unknown:$intrin, variable_ops);
885 let hasSideEffects = 1;
890 //------------------------------------------------------------------------------
892 //------------------------------------------------------------------------------
894 // Generic unconditional branch.
895 def G_BR : GenericInstruction {
896 let OutOperandList = (outs);
897 let InOperandList = (ins unknown:$src1);
898 let hasSideEffects = 0;
900 let isTerminator = 1;
904 // Generic conditional branch.
905 def G_BRCOND : GenericInstruction {
906 let OutOperandList = (outs);
907 let InOperandList = (ins type0:$tst, unknown:$truebb);
908 let hasSideEffects = 0;
910 let isTerminator = 1;
913 // Generic indirect branch.
914 def G_BRINDIRECT : GenericInstruction {
915 let OutOperandList = (outs);
916 let InOperandList = (ins type0:$src1);
917 let hasSideEffects = 0;
919 let isTerminator = 1;
922 // Generic branch to jump table entry
923 def G_BRJT : GenericInstruction {
924 let OutOperandList = (outs);
925 let InOperandList = (ins ptype0:$tbl, unknown:$jti, type1:$idx);
926 let hasSideEffects = 0;
928 let isTerminator = 1;
931 //------------------------------------------------------------------------------
933 //------------------------------------------------------------------------------
935 // Generic insertelement.
936 def G_INSERT_VECTOR_ELT : GenericInstruction {
937 let OutOperandList = (outs type0:$dst);
938 let InOperandList = (ins type0:$src, type1:$elt, type2:$idx);
939 let hasSideEffects = 0;
942 // Generic extractelement.
943 def G_EXTRACT_VECTOR_ELT : GenericInstruction {
944 let OutOperandList = (outs type0:$dst);
945 let InOperandList = (ins type1:$src, type2:$idx);
946 let hasSideEffects = 0;
949 // Generic shufflevector.
950 def G_SHUFFLE_VECTOR: GenericInstruction {
951 let OutOperandList = (outs type0:$dst);
952 let InOperandList = (ins type1:$v1, type1:$v2, type2:$mask);
953 let hasSideEffects = 0;
956 // TODO: Add the other generic opcodes.