[ARM] MVE integer min and max
[llvm-complete.git] / include / llvm / Target / GenericOpcodes.td
blob45718327b4a77fd4ee4c202682b69baaa8f29e96
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.
12 //===----------------------------------------------------------------------===//
14 //------------------------------------------------------------------------------
15 // Unary ops.
16 //------------------------------------------------------------------------------
18 class GenericInstruction : StandardPseudoInstruction;
20 // Extend the underlying scalar type of an operation, leaving the high bits
21 // unspecified.
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;
113   let mayStore = 1;
116 def G_VAARG : GenericInstruction {
117   let OutOperandList = (outs type0:$val);
118   let InOperandList = (ins type1:$list, unknown:$align);
119   let hasSideEffects = 0;
120   let mayLoad = 1;
121   let mayStore = 1;
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 //------------------------------------------------------------------------------
179 // Binary ops.
180 //------------------------------------------------------------------------------
182 // Generic addition.
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;
297 // Generic select
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 //------------------------------------------------------------------------------
350 // Overflow ops
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
509 // values.
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
681 // libm-conformant.
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 //------------------------------------------------------------------------------
725 // Memory ops
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;
733   let mayLoad = 1;
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;
741   let mayLoad = 1;
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;
749   let mayLoad = 1;
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;
757   let mayStore = 1;
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;
766   let mayLoad = 1;
767   let mayStore = 1;
770 // Generic atomic cmpxchg. Expects a MachineMemOperand in addition to explicit
771 // operands.
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;
776   let mayLoad = 1;
777   let mayStore = 1;
780 // Generic atomicrmw. Expects a MachineMemOperand in addition to explicit
781 // operands.
782 class G_ATOMICRMW_OP : GenericInstruction {
783   let OutOperandList = (outs type0:$oldval);
784   let InOperandList = (ins ptype1:$addr, type0:$val);
785   let hasSideEffects = 0;
786   let mayLoad = 1;
787   let mayStore = 1;
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 //------------------------------------------------------------------------------
809 // Variadic ops
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;
886   let mayLoad = 1;
887   let mayStore = 1;
890 //------------------------------------------------------------------------------
891 // Branches.
892 //------------------------------------------------------------------------------
894 // Generic unconditional branch.
895 def G_BR : GenericInstruction {
896   let OutOperandList = (outs);
897   let InOperandList = (ins unknown:$src1);
898   let hasSideEffects = 0;
899   let isBranch = 1;
900   let isTerminator = 1;
901   let isBarrier = 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;
909   let isBranch = 1;
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;
918   let isBranch = 1;
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;
927   let isBranch = 1;
928   let isTerminator = 1;
931 //------------------------------------------------------------------------------
932 // Vector ops
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.