[ValueTracking] Remove unused matchSelectPattern optional argument. NFCI.
[llvm-core.git] / include / llvm / Target / GenericOpcodes.td
blobad32b9fab75d38d29e5657ad376cdef6199f16c6
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 // Sign extend the a value from an arbitrary bit position, copying the sign bit
37 // into all bits above it. This is equivalent to a shl + ashr pair with an
38 // appropriate shift amount. $sz is an immediate (MachineOperand::isImm()
39 // returns true) to allow targets to have some bitwidths legal and others
40 // lowered. This opcode is particularly useful if the target has sign-extension
41 // instructions that are cheaper than the constituent shifts as the optimizer is
42 // able to make decisions on whether it's better to hang on to the G_SEXT_INREG
43 // or to lower it and optimize the individual shifts.
44 def G_SEXT_INREG : GenericInstruction {
45   let OutOperandList = (outs type0:$dst);
46   let InOperandList = (ins type0:$src, untyped_imm_0:$sz);
47   let hasSideEffects = 0;
50 // Zero extend the underlying scalar type of an operation, putting zero bits
51 // into the newly-created space.
52 def G_ZEXT : GenericInstruction {
53   let OutOperandList = (outs type0:$dst);
54   let InOperandList = (ins type1:$src);
55   let hasSideEffects = 0;
59 // Truncate the underlying scalar type of an operation. This is equivalent to
60 // G_EXTRACT for scalar types, but acts elementwise on vectors.
61 def G_TRUNC : GenericInstruction {
62   let OutOperandList = (outs type0:$dst);
63   let InOperandList = (ins type1:$src);
64   let hasSideEffects = 0;
67 def G_IMPLICIT_DEF : GenericInstruction {
68   let OutOperandList = (outs type0:$dst);
69   let InOperandList = (ins);
70   let hasSideEffects = 0;
73 def G_PHI : GenericInstruction {
74   let OutOperandList = (outs type0:$dst);
75   let InOperandList = (ins variable_ops);
76   let hasSideEffects = 0;
79 def G_FRAME_INDEX : GenericInstruction {
80   let OutOperandList = (outs type0:$dst);
81   let InOperandList = (ins unknown:$src2);
82   let hasSideEffects = 0;
85 def G_GLOBAL_VALUE : GenericInstruction {
86   let OutOperandList = (outs type0:$dst);
87   let InOperandList = (ins unknown:$src);
88   let hasSideEffects = 0;
91 def G_INTTOPTR : GenericInstruction {
92   let OutOperandList = (outs type0:$dst);
93   let InOperandList = (ins type1:$src);
94   let hasSideEffects = 0;
97 def G_PTRTOINT : GenericInstruction {
98   let OutOperandList = (outs type0:$dst);
99   let InOperandList = (ins type1:$src);
100   let hasSideEffects = 0;
103 def G_BITCAST : GenericInstruction {
104   let OutOperandList = (outs type0:$dst);
105   let InOperandList = (ins type1:$src);
106   let hasSideEffects = 0;
109 // Only supports scalar result types
110 def G_CONSTANT : GenericInstruction {
111   let OutOperandList = (outs type0:$dst);
112   let InOperandList = (ins unknown:$imm);
113   let hasSideEffects = 0;
116 // Only supports scalar result types
117 def G_FCONSTANT : GenericInstruction {
118   let OutOperandList = (outs type0:$dst);
119   let InOperandList = (ins unknown:$imm);
120   let hasSideEffects = 0;
123 def G_VASTART : GenericInstruction {
124   let OutOperandList = (outs);
125   let InOperandList = (ins type0:$list);
126   let hasSideEffects = 0;
127   let mayStore = 1;
130 def G_VAARG : GenericInstruction {
131   let OutOperandList = (outs type0:$val);
132   let InOperandList = (ins type1:$list, unknown:$align);
133   let hasSideEffects = 0;
134   let mayLoad = 1;
135   let mayStore = 1;
138 def G_CTLZ : GenericInstruction {
139   let OutOperandList = (outs type0:$dst);
140   let InOperandList = (ins type1:$src);
141   let hasSideEffects = 0;
144 def G_CTLZ_ZERO_UNDEF : GenericInstruction {
145   let OutOperandList = (outs type0:$dst);
146   let InOperandList = (ins type1:$src);
147   let hasSideEffects = 0;
150 def G_CTTZ : GenericInstruction {
151   let OutOperandList = (outs type0:$dst);
152   let InOperandList = (ins type1:$src);
153   let hasSideEffects = 0;
156 def G_CTTZ_ZERO_UNDEF : GenericInstruction {
157   let OutOperandList = (outs type0:$dst);
158   let InOperandList = (ins type1:$src);
159   let hasSideEffects = 0;
162 def G_CTPOP : GenericInstruction {
163   let OutOperandList = (outs type0:$dst);
164   let InOperandList = (ins type1:$src);
165   let hasSideEffects = 0;
168 def G_BSWAP : GenericInstruction {
169   let OutOperandList = (outs type0:$dst);
170   let InOperandList = (ins type0:$src);
171   let hasSideEffects = 0;
174 def G_BITREVERSE : GenericInstruction {
175   let OutOperandList = (outs type0:$dst);
176   let InOperandList = (ins type0:$src);
177   let hasSideEffects = 0;
180 def G_ADDRSPACE_CAST : GenericInstruction {
181   let OutOperandList = (outs type0:$dst);
182   let InOperandList = (ins type1:$src);
183   let hasSideEffects = 0;
186 def G_BLOCK_ADDR : GenericInstruction {
187   let OutOperandList = (outs type0:$dst);
188   let InOperandList = (ins unknown:$ba);
189   let hasSideEffects = 0;
192 def G_JUMP_TABLE : GenericInstruction {
193   let OutOperandList = (outs type0:$dst);
194   let InOperandList = (ins unknown:$jti);
195   let hasSideEffects = 0;
198 def G_DYN_STACKALLOC : GenericInstruction {
199   let OutOperandList = (outs ptype0:$dst);
200   let InOperandList = (ins type1:$size, i32imm:$align);
201   let hasSideEffects = 1;
204 //------------------------------------------------------------------------------
205 // Binary ops.
206 //------------------------------------------------------------------------------
208 // Generic addition.
209 def G_ADD : GenericInstruction {
210   let OutOperandList = (outs type0:$dst);
211   let InOperandList = (ins type0:$src1, type0:$src2);
212   let hasSideEffects = 0;
213   let isCommutable = 1;
216 // Generic subtraction.
217 def G_SUB : GenericInstruction {
218   let OutOperandList = (outs type0:$dst);
219   let InOperandList = (ins type0:$src1, type0:$src2);
220   let hasSideEffects = 0;
221   let isCommutable = 0;
224 // Generic multiplication.
225 def G_MUL : GenericInstruction {
226   let OutOperandList = (outs type0:$dst);
227   let InOperandList = (ins type0:$src1, type0:$src2);
228   let hasSideEffects = 0;
229   let isCommutable = 1;
232 // Generic signed division.
233 def G_SDIV : GenericInstruction {
234   let OutOperandList = (outs type0:$dst);
235   let InOperandList = (ins type0:$src1, type0:$src2);
236   let hasSideEffects = 0;
237   let isCommutable = 0;
240 // Generic unsigned division.
241 def G_UDIV : GenericInstruction {
242   let OutOperandList = (outs type0:$dst);
243   let InOperandList = (ins type0:$src1, type0:$src2);
244   let hasSideEffects = 0;
245   let isCommutable = 0;
248 // Generic signed remainder.
249 def G_SREM : GenericInstruction {
250   let OutOperandList = (outs type0:$dst);
251   let InOperandList = (ins type0:$src1, type0:$src2);
252   let hasSideEffects = 0;
253   let isCommutable = 0;
256 // Generic unsigned remainder.
257 def G_UREM : GenericInstruction {
258   let OutOperandList = (outs type0:$dst);
259   let InOperandList = (ins type0:$src1, type0:$src2);
260   let hasSideEffects = 0;
261   let isCommutable = 0;
264 // Generic bitwise and.
265 def G_AND : GenericInstruction {
266   let OutOperandList = (outs type0:$dst);
267   let InOperandList = (ins type0:$src1, type0:$src2);
268   let hasSideEffects = 0;
269   let isCommutable = 1;
272 // Generic bitwise or.
273 def G_OR : GenericInstruction {
274   let OutOperandList = (outs type0:$dst);
275   let InOperandList = (ins type0:$src1, type0:$src2);
276   let hasSideEffects = 0;
277   let isCommutable = 1;
280 // Generic bitwise xor.
281 def G_XOR : GenericInstruction {
282   let OutOperandList = (outs type0:$dst);
283   let InOperandList = (ins type0:$src1, type0:$src2);
284   let hasSideEffects = 0;
285   let isCommutable = 1;
288 // Generic left-shift.
289 def G_SHL : GenericInstruction {
290   let OutOperandList = (outs type0:$dst);
291   let InOperandList = (ins type0:$src1, type1:$src2);
292   let hasSideEffects = 0;
295 // Generic logical right-shift.
296 def G_LSHR : GenericInstruction {
297   let OutOperandList = (outs type0:$dst);
298   let InOperandList = (ins type0:$src1, type1:$src2);
299   let hasSideEffects = 0;
302 // Generic arithmetic right-shift.
303 def G_ASHR : GenericInstruction {
304   let OutOperandList = (outs type0:$dst);
305   let InOperandList = (ins type0:$src1, type1:$src2);
306   let hasSideEffects = 0;
309 // Generic integer comparison.
310 def G_ICMP : GenericInstruction {
311   let OutOperandList = (outs type0:$dst);
312   let InOperandList = (ins unknown:$tst, type1:$src1, type1:$src2);
313   let hasSideEffects = 0;
316 // Generic floating-point comparison.
317 def G_FCMP : GenericInstruction {
318   let OutOperandList = (outs type0:$dst);
319   let InOperandList = (ins unknown:$tst, type1:$src1, type1:$src2);
320   let hasSideEffects = 0;
323 // Generic select
324 def G_SELECT : GenericInstruction {
325   let OutOperandList = (outs type0:$dst);
326   let InOperandList = (ins type1:$tst, type0:$src1, type0:$src2);
327   let hasSideEffects = 0;
330 // Generic pointer offset.
331 def G_GEP : GenericInstruction {
332   let OutOperandList = (outs type0:$dst);
333   let InOperandList = (ins type0:$src1, type1:$src2);
334   let hasSideEffects = 0;
337 def G_PTR_MASK : GenericInstruction {
338   let OutOperandList = (outs type0:$dst);
339   let InOperandList = (ins type0:$src, unknown:$bits);
340   let hasSideEffects = 0;
343 // Generic signed integer minimum.
344 def G_SMIN : GenericInstruction {
345   let OutOperandList = (outs type0:$dst);
346   let InOperandList = (ins type0:$src1, type0:$src2);
347   let hasSideEffects = 0;
348   let isCommutable = 1;
351 // Generic signed integer maximum.
352 def G_SMAX : GenericInstruction {
353   let OutOperandList = (outs type0:$dst);
354   let InOperandList = (ins type0:$src1, type0:$src2);
355   let hasSideEffects = 0;
356   let isCommutable = 1;
359 // Generic unsigned integer minimum.
360 def G_UMIN : GenericInstruction {
361   let OutOperandList = (outs type0:$dst);
362   let InOperandList = (ins type0:$src1, type0:$src2);
363   let hasSideEffects = 0;
364   let isCommutable = 1;
367 // Generic unsigned integer maximum.
368 def G_UMAX : GenericInstruction {
369   let OutOperandList = (outs type0:$dst);
370   let InOperandList = (ins type0:$src1, type0:$src2);
371   let hasSideEffects = 0;
372   let isCommutable = 1;
375 //------------------------------------------------------------------------------
376 // Overflow ops
377 //------------------------------------------------------------------------------
379 // Generic unsigned addition producing a carry flag.
380 def G_UADDO : GenericInstruction {
381   let OutOperandList = (outs type0:$dst, type1:$carry_out);
382   let InOperandList = (ins type0:$src1, type0:$src2);
383   let hasSideEffects = 0;
384   let isCommutable = 1;
387 // Generic unsigned addition consuming and producing a carry flag.
388 def G_UADDE : GenericInstruction {
389   let OutOperandList = (outs type0:$dst, type1:$carry_out);
390   let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
391   let hasSideEffects = 0;
394 // Generic signed addition producing a carry flag.
395 def G_SADDO : GenericInstruction {
396   let OutOperandList = (outs type0:$dst, type1:$carry_out);
397   let InOperandList = (ins type0:$src1, type0:$src2);
398   let hasSideEffects = 0;
399   let isCommutable = 1;
402 // Generic signed addition consuming and producing a carry flag.
403 def G_SADDE : GenericInstruction {
404   let OutOperandList = (outs type0:$dst, type1:$carry_out);
405   let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
406   let hasSideEffects = 0;
409 // Generic unsigned subtraction producing a carry flag.
410 def G_USUBO : GenericInstruction {
411   let OutOperandList = (outs type0:$dst, type1:$carry_out);
412   let InOperandList = (ins type0:$src1, type0:$src2);
413   let hasSideEffects = 0;
415 // Generic unsigned subtraction consuming and producing a carry flag.
416 def G_USUBE : GenericInstruction {
417   let OutOperandList = (outs type0:$dst, type1:$carry_out);
418   let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
419   let hasSideEffects = 0;
422 // Generic signed subtraction producing a carry flag.
423 def G_SSUBO : GenericInstruction {
424   let OutOperandList = (outs type0:$dst, type1:$carry_out);
425   let InOperandList = (ins type0:$src1, type0:$src2);
426   let hasSideEffects = 0;
429 // Generic signed subtraction consuming and producing a carry flag.
430 def G_SSUBE : GenericInstruction {
431   let OutOperandList = (outs type0:$dst, type1:$carry_out);
432   let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
433   let hasSideEffects = 0;
436 // Generic unsigned multiplication producing a carry flag.
437 def G_UMULO : GenericInstruction {
438   let OutOperandList = (outs type0:$dst, type1:$carry_out);
439   let InOperandList = (ins type0:$src1, type0:$src2);
440   let hasSideEffects = 0;
441   let isCommutable = 1;
444 // Generic signed multiplication producing a carry flag.
445 def G_SMULO : GenericInstruction {
446   let OutOperandList = (outs type0:$dst, type1:$carry_out);
447   let InOperandList = (ins type0:$src1, type0:$src2);
448   let hasSideEffects = 0;
449   let isCommutable = 1;
452 // Multiply two numbers at twice the incoming bit width (unsigned) and return
453 // the high half of the result.
454 def G_UMULH : GenericInstruction {
455   let OutOperandList = (outs type0:$dst);
456   let InOperandList = (ins type0:$src1, type0:$src2);
457   let hasSideEffects = 0;
458   let isCommutable = 1;
461 // Multiply two numbers at twice the incoming bit width (signed) and return
462 // the high half of the result.
463 def G_SMULH : GenericInstruction {
464   let OutOperandList = (outs type0:$dst);
465   let InOperandList = (ins type0:$src1, type0:$src2);
466   let hasSideEffects = 0;
467   let isCommutable = 1;
470 //------------------------------------------------------------------------------
471 // Floating Point Unary Ops.
472 //------------------------------------------------------------------------------
474 def G_FNEG : GenericInstruction {
475   let OutOperandList = (outs type0:$dst);
476   let InOperandList = (ins type0:$src);
477   let hasSideEffects = 0;
480 def G_FPEXT : GenericInstruction {
481   let OutOperandList = (outs type0:$dst);
482   let InOperandList = (ins type1:$src);
483   let hasSideEffects = 0;
486 def G_FPTRUNC : GenericInstruction {
487   let OutOperandList = (outs type0:$dst);
488   let InOperandList = (ins type1:$src);
489   let hasSideEffects = 0;
492 def G_FPTOSI : GenericInstruction {
493   let OutOperandList = (outs type0:$dst);
494   let InOperandList = (ins type1:$src);
495   let hasSideEffects = 0;
498 def G_FPTOUI : GenericInstruction {
499   let OutOperandList = (outs type0:$dst);
500   let InOperandList = (ins type1:$src);
501   let hasSideEffects = 0;
504 def G_SITOFP : GenericInstruction {
505   let OutOperandList = (outs type0:$dst);
506   let InOperandList = (ins type1:$src);
507   let hasSideEffects = 0;
510 def G_UITOFP : GenericInstruction {
511   let OutOperandList = (outs type0:$dst);
512   let InOperandList = (ins type1:$src);
513   let hasSideEffects = 0;
516 def G_FABS : GenericInstruction {
517   let OutOperandList = (outs type0:$dst);
518   let InOperandList = (ins type0:$src);
519   let hasSideEffects = 0;
522 def G_FCOPYSIGN : GenericInstruction {
523   let OutOperandList = (outs type0:$dst);
524   let InOperandList = (ins type0:$src0, type1:$src1);
525   let hasSideEffects = 0;
528 def G_FCANONICALIZE : GenericInstruction {
529   let OutOperandList = (outs type0:$dst);
530   let InOperandList = (ins type0:$src);
531   let hasSideEffects = 0;
534 // FMINNUM/FMAXNUM - Perform floating-point minimum or maximum on two
535 // values.
537 // In the case where a single input is a NaN (either signaling or quiet),
538 // the non-NaN input is returned.
540 // The return value of (FMINNUM 0.0, -0.0) could be either 0.0 or -0.0.
541 def G_FMINNUM : GenericInstruction {
542   let OutOperandList = (outs type0:$dst);
543   let InOperandList = (ins type0:$src1, type0:$src2);
544   let hasSideEffects = 0;
545   let isCommutable = 1;
548 def G_FMAXNUM : GenericInstruction {
549   let OutOperandList = (outs type0:$dst);
550   let InOperandList = (ins type0:$src1, type0:$src2);
551   let hasSideEffects = 0;
552   let isCommutable = 1;
555 // FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimum or maximum on
556 // two values, following the IEEE-754 2008 definition. This differs from
557 // FMINNUM/FMAXNUM in the handling of signaling NaNs. If one input is a
558 // signaling NaN, returns a quiet NaN.
559 def G_FMINNUM_IEEE : GenericInstruction {
560   let OutOperandList = (outs type0:$dst);
561   let InOperandList = (ins type0:$src1, type0:$src2);
562   let hasSideEffects = 0;
563   let isCommutable = 1;
566 def G_FMAXNUM_IEEE : GenericInstruction {
567   let OutOperandList = (outs type0:$dst);
568   let InOperandList = (ins type0:$src1, type0:$src2);
569   let hasSideEffects = 0;
570   let isCommutable = 1;
573 // FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0
574 // as less than 0.0. While FMINNUM_IEEE/FMAXNUM_IEEE follow IEEE 754-2008
575 // semantics, FMINIMUM/FMAXIMUM follow IEEE 754-2018 draft semantics.
576 def G_FMINIMUM : GenericInstruction {
577   let OutOperandList = (outs type0:$dst);
578   let InOperandList = (ins type0:$src1, type0:$src2);
579   let hasSideEffects = 0;
580   let isCommutable = 1;
583 def G_FMAXIMUM : GenericInstruction {
584   let OutOperandList = (outs type0:$dst);
585   let InOperandList = (ins type0:$src1, type0:$src2);
586   let hasSideEffects = 0;
587   let isCommutable = 1;
590 //------------------------------------------------------------------------------
591 // Floating Point Binary ops.
592 //------------------------------------------------------------------------------
594 // Generic FP addition.
595 def G_FADD : GenericInstruction {
596   let OutOperandList = (outs type0:$dst);
597   let InOperandList = (ins type0:$src1, type0:$src2);
598   let hasSideEffects = 0;
599   let isCommutable = 1;
602 // Generic FP subtraction.
603 def G_FSUB : GenericInstruction {
604   let OutOperandList = (outs type0:$dst);
605   let InOperandList = (ins type0:$src1, type0:$src2);
606   let hasSideEffects = 0;
607   let isCommutable = 0;
610 // Generic FP multiplication.
611 def G_FMUL : GenericInstruction {
612   let OutOperandList = (outs type0:$dst);
613   let InOperandList = (ins type0:$src1, type0:$src2);
614   let hasSideEffects = 0;
615   let isCommutable = 1;
618 // Generic fused multiply-add instruction.
619 // Behaves like llvm fma intrinsic ie src1 * src2 + src3
620 def G_FMA : GenericInstruction {
621   let OutOperandList = (outs type0:$dst);
622   let InOperandList = (ins type0:$src1, type0:$src2, type0:$src3);
623   let hasSideEffects = 0;
624   let isCommutable = 0;
627 /// Generic FP multiply and add. Perform a * b + c, while getting the
628 /// same result as the separately rounded operations, unlike G_FMA.
629 def G_FMAD : GenericInstruction {
630   let OutOperandList = (outs type0:$dst);
631   let InOperandList = (ins type0:$src1, type0:$src2, type0:$src3);
632   let hasSideEffects = 0;
633   let isCommutable = 0;
636 // Generic FP division.
637 def G_FDIV : GenericInstruction {
638   let OutOperandList = (outs type0:$dst);
639   let InOperandList = (ins type0:$src1, type0:$src2);
640   let hasSideEffects = 0;
643 // Generic FP remainder.
644 def G_FREM : GenericInstruction {
645   let OutOperandList = (outs type0:$dst);
646   let InOperandList = (ins type0:$src1, type0:$src2);
647   let hasSideEffects = 0;
650 // Floating point exponentiation.
651 def G_FPOW : GenericInstruction {
652   let OutOperandList = (outs type0:$dst);
653   let InOperandList = (ins type0:$src1, type0:$src2);
654   let hasSideEffects = 0;
657 // Floating point base-e exponential of a value.
658 def G_FEXP : GenericInstruction {
659   let OutOperandList = (outs type0:$dst);
660   let InOperandList = (ins type0:$src1);
661   let hasSideEffects = 0;
664 // Floating point base-2 exponential of a value.
665 def G_FEXP2 : GenericInstruction {
666   let OutOperandList = (outs type0:$dst);
667   let InOperandList = (ins type0:$src1);
668   let hasSideEffects = 0;
671 // Floating point base-2 logarithm of a value.
672 def G_FLOG : GenericInstruction {
673   let OutOperandList = (outs type0:$dst);
674   let InOperandList = (ins type0:$src1);
675   let hasSideEffects = 0;
678 // Floating point base-2 logarithm of a value.
679 def G_FLOG2 : GenericInstruction {
680   let OutOperandList = (outs type0:$dst);
681   let InOperandList = (ins type0:$src1);
682   let hasSideEffects = 0;
685 // Floating point base-10 logarithm of a value.
686 def G_FLOG10 : GenericInstruction {
687   let OutOperandList = (outs type0:$dst);
688   let InOperandList = (ins type0:$src1);
689   let hasSideEffects = 0;
692 // Floating point ceiling of a value.
693 def G_FCEIL : GenericInstruction {
694   let OutOperandList = (outs type0:$dst);
695   let InOperandList = (ins type0:$src1);
696   let hasSideEffects = 0;
699 // Floating point cosine of a value.
700 def G_FCOS : GenericInstruction {
701   let OutOperandList = (outs type0:$dst);
702   let InOperandList = (ins type0:$src1);
703   let hasSideEffects = 0;
706 // Floating point sine of a value.
707 def G_FSIN : GenericInstruction {
708   let OutOperandList = (outs type0:$dst);
709   let InOperandList = (ins type0:$src1);
710   let hasSideEffects = 0;
713 // Floating point square root of a value.
714 // This returns NaN for negative nonzero values.
715 // NOTE: Unlike libm sqrt(), this never sets errno. In all other respects it's
716 // libm-conformant.
717 def G_FSQRT : GenericInstruction {
718   let OutOperandList = (outs type0:$dst);
719   let InOperandList = (ins type0:$src1);
720   let hasSideEffects = 0;
723 // Floating point floor of a value.
724 def G_FFLOOR : GenericInstruction {
725   let OutOperandList = (outs type0:$dst);
726   let InOperandList = (ins type0:$src1);
727   let hasSideEffects = 0;
730 // Floating point round to next integer.
731 def G_FRINT : GenericInstruction {
732   let OutOperandList = (outs type0:$dst);
733   let InOperandList = (ins type0:$src1);
734   let hasSideEffects = 0;
737 // Floating point round to the nearest integer.
738 def G_FNEARBYINT : GenericInstruction {
739   let OutOperandList = (outs type0:$dst);
740   let InOperandList = (ins type0:$src1);
741   let hasSideEffects = 0;
744 //------------------------------------------------------------------------------
745 // Opcodes for LLVM Intrinsics
746 //------------------------------------------------------------------------------
747 def G_INTRINSIC_TRUNC : GenericInstruction {
748   let OutOperandList = (outs type0:$dst);
749   let InOperandList = (ins type0:$src1);
750   let hasSideEffects = 0;
753 def G_INTRINSIC_ROUND : GenericInstruction {
754   let OutOperandList = (outs type0:$dst);
755   let InOperandList = (ins type0:$src1);
756   let hasSideEffects = 0;
759 //------------------------------------------------------------------------------
760 // Memory ops
761 //------------------------------------------------------------------------------
763 // Generic load. Expects a MachineMemOperand in addition to explicit
764 // operands. If the result size is larger than the memory size, the
765 // high bits are undefined. If the result is a vector type and larger
766 // than the memory size, the high elements are undefined (i.e. this is
767 // not a per-element, vector anyextload)
768 def G_LOAD : GenericInstruction {
769   let OutOperandList = (outs type0:$dst);
770   let InOperandList = (ins ptype1:$addr);
771   let hasSideEffects = 0;
772   let mayLoad = 1;
775 // Generic sign-extended load. Expects a MachineMemOperand in addition to explicit operands.
776 def G_SEXTLOAD : GenericInstruction {
777   let OutOperandList = (outs type0:$dst);
778   let InOperandList = (ins ptype1:$addr);
779   let hasSideEffects = 0;
780   let mayLoad = 1;
783 // Generic zero-extended load. Expects a MachineMemOperand in addition to explicit operands.
784 def G_ZEXTLOAD : GenericInstruction {
785   let OutOperandList = (outs type0:$dst);
786   let InOperandList = (ins ptype1:$addr);
787   let hasSideEffects = 0;
788   let mayLoad = 1;
791 // Generic indexed load. Combines a GEP with a load. $newaddr is set to $base + $offset.
792 // If $am is 0 (post-indexed), then the value is loaded from $base; if $am is 1 (pre-indexed)
793 //  then the value is loaded from $newaddr.
794 def G_INDEXED_LOAD : GenericInstruction {
795   let OutOperandList = (outs type0:$dst, ptype1:$newaddr);
796   let InOperandList = (ins ptype1:$base, type2:$offset, unknown:$am);
797   let hasSideEffects = 0;
798   let mayLoad = 1;
801 // Same as G_INDEXED_LOAD except that the load performed is sign-extending, as with G_SEXTLOAD.
802 def G_INDEXED_SEXTLOAD : GenericInstruction {
803   let OutOperandList = (outs type0:$dst, ptype1:$newaddr);
804   let InOperandList = (ins ptype1:$base, type2:$offset, unknown:$am);
805   let hasSideEffects = 0;
806   let mayLoad = 1;
809 // Same as G_INDEXED_LOAD except that the load performed is zero-extending, as with G_ZEXTLOAD.
810 def G_INDEXED_ZEXTLOAD : GenericInstruction {
811   let OutOperandList = (outs type0:$dst, ptype1:$newaddr);
812   let InOperandList = (ins ptype1:$base, type2:$offset, unknown:$am);
813   let hasSideEffects = 0;
814   let mayLoad = 1;
817 // Generic store. Expects a MachineMemOperand in addition to explicit operands.
818 def G_STORE : GenericInstruction {
819   let OutOperandList = (outs);
820   let InOperandList = (ins type0:$src, ptype1:$addr);
821   let hasSideEffects = 0;
822   let mayStore = 1;
825 // Combines a store with a GEP. See description of G_INDEXED_LOAD for indexing behaviour.
826 def G_INDEXED_STORE : GenericInstruction {
827   let OutOperandList = (outs ptype0:$newaddr);
828   let InOperandList = (ins type1:$src, ptype0:$base, ptype2:$offset,
829                            unknown:$am);
830   let hasSideEffects = 0;
831   let mayStore = 1;
834 // Generic atomic cmpxchg with internal success check. Expects a
835 // MachineMemOperand in addition to explicit operands.
836 def G_ATOMIC_CMPXCHG_WITH_SUCCESS : GenericInstruction {
837   let OutOperandList = (outs type0:$oldval, type1:$success);
838   let InOperandList = (ins type2:$addr, type0:$cmpval, type0:$newval);
839   let hasSideEffects = 0;
840   let mayLoad = 1;
841   let mayStore = 1;
844 // Generic atomic cmpxchg. Expects a MachineMemOperand in addition to explicit
845 // operands.
846 def G_ATOMIC_CMPXCHG : GenericInstruction {
847   let OutOperandList = (outs type0:$oldval);
848   let InOperandList = (ins ptype1:$addr, type0:$cmpval, type0:$newval);
849   let hasSideEffects = 0;
850   let mayLoad = 1;
851   let mayStore = 1;
854 // Generic atomicrmw. Expects a MachineMemOperand in addition to explicit
855 // operands.
856 class G_ATOMICRMW_OP : GenericInstruction {
857   let OutOperandList = (outs type0:$oldval);
858   let InOperandList = (ins ptype1:$addr, type0:$val);
859   let hasSideEffects = 0;
860   let mayLoad = 1;
861   let mayStore = 1;
864 def G_ATOMICRMW_XCHG : G_ATOMICRMW_OP;
865 def G_ATOMICRMW_ADD : G_ATOMICRMW_OP;
866 def G_ATOMICRMW_SUB : G_ATOMICRMW_OP;
867 def G_ATOMICRMW_AND : G_ATOMICRMW_OP;
868 def G_ATOMICRMW_NAND : G_ATOMICRMW_OP;
869 def G_ATOMICRMW_OR : G_ATOMICRMW_OP;
870 def G_ATOMICRMW_XOR : G_ATOMICRMW_OP;
871 def G_ATOMICRMW_MAX : G_ATOMICRMW_OP;
872 def G_ATOMICRMW_MIN : G_ATOMICRMW_OP;
873 def G_ATOMICRMW_UMAX : G_ATOMICRMW_OP;
874 def G_ATOMICRMW_UMIN : G_ATOMICRMW_OP;
875 def G_ATOMICRMW_FADD : G_ATOMICRMW_OP;
876 def G_ATOMICRMW_FSUB : G_ATOMICRMW_OP;
878 def G_FENCE : GenericInstruction {
879   let OutOperandList = (outs);
880   let InOperandList = (ins i32imm:$ordering, i32imm:$scope);
881   let hasSideEffects = 1;
884 //------------------------------------------------------------------------------
885 // Variadic ops
886 //------------------------------------------------------------------------------
888 // Extract a register of the specified size, starting from the block given by
889 // index. This will almost certainly be mapped to sub-register COPYs after
890 // register banks have been selected.
891 def G_EXTRACT : GenericInstruction {
892   let OutOperandList = (outs type0:$res);
893   let InOperandList = (ins type1:$src, unknown:$offset);
894   let hasSideEffects = 0;
897 // Extract multiple registers specified size, starting from blocks given by
898 // indexes. This will almost certainly be mapped to sub-register COPYs after
899 // register banks have been selected.
900 // The output operands are always ordered from lowest bits to highest:
901 //   %bits_0_7:(s8), %bits_8_15:(s8),
902 //       %bits_16_23:(s8), %bits_24_31:(s8) = G_UNMERGE_VALUES %0:(s32)
903 def G_UNMERGE_VALUES : GenericInstruction {
904   let OutOperandList = (outs type0:$dst0, variable_ops);
905   let InOperandList = (ins type1:$src);
906   let hasSideEffects = 0;
909 // Insert a smaller register into a larger one at the specified bit-index.
910 def G_INSERT : GenericInstruction {
911   let OutOperandList = (outs type0:$dst);
912   let InOperandList = (ins type0:$src, type1:$op, unknown:$offset);
913   let hasSideEffects = 0;
916 // Concatenate multiple registers of the same size into a wider register.
917 // The input operands are always ordered from lowest bits to highest:
918 //   %0:(s32) = G_MERGE_VALUES %bits_0_7:(s8), %bits_8_15:(s8),
919 //                             %bits_16_23:(s8), %bits_24_31:(s8)
920 def G_MERGE_VALUES : GenericInstruction {
921   let OutOperandList = (outs type0:$dst);
922   let InOperandList = (ins type1:$src0, variable_ops);
923   let hasSideEffects = 0;
926 /// Create a vector from multiple scalar registers. No implicit
927 /// conversion is performed (i.e. the result element type must be the
928 /// same as all source operands)
929 def G_BUILD_VECTOR : GenericInstruction {
930   let OutOperandList = (outs type0:$dst);
931   let InOperandList = (ins type1:$src0, variable_ops);
932   let hasSideEffects = 0;
935 /// Like G_BUILD_VECTOR, but truncates the larger operand types to fit the
936 /// destination vector elt type.
937 def G_BUILD_VECTOR_TRUNC : GenericInstruction {
938   let OutOperandList = (outs type0:$dst);
939   let InOperandList = (ins type1:$src0, variable_ops);
940   let hasSideEffects = 0;
943 /// Create a vector by concatenating vectors together.
944 def G_CONCAT_VECTORS : GenericInstruction {
945   let OutOperandList = (outs type0:$dst);
946   let InOperandList = (ins type1:$src0, variable_ops);
947   let hasSideEffects = 0;
950 // Intrinsic without side effects.
951 def G_INTRINSIC : GenericInstruction {
952   let OutOperandList = (outs);
953   let InOperandList = (ins unknown:$intrin, variable_ops);
954   let hasSideEffects = 0;
957 // Intrinsic with side effects.
958 def G_INTRINSIC_W_SIDE_EFFECTS : GenericInstruction {
959   let OutOperandList = (outs);
960   let InOperandList = (ins unknown:$intrin, variable_ops);
961   let hasSideEffects = 1;
962   let mayLoad = 1;
963   let mayStore = 1;
966 //------------------------------------------------------------------------------
967 // Branches.
968 //------------------------------------------------------------------------------
970 // Generic unconditional branch.
971 def G_BR : GenericInstruction {
972   let OutOperandList = (outs);
973   let InOperandList = (ins unknown:$src1);
974   let hasSideEffects = 0;
975   let isBranch = 1;
976   let isTerminator = 1;
977   let isBarrier = 1;
980 // Generic conditional branch.
981 def G_BRCOND : GenericInstruction {
982   let OutOperandList = (outs);
983   let InOperandList = (ins type0:$tst, unknown:$truebb);
984   let hasSideEffects = 0;
985   let isBranch = 1;
986   let isTerminator = 1;
989 // Generic indirect branch.
990 def G_BRINDIRECT : GenericInstruction {
991   let OutOperandList = (outs);
992   let InOperandList = (ins type0:$src1);
993   let hasSideEffects = 0;
994   let isBranch = 1;
995   let isTerminator = 1;
998 // Generic branch to jump table entry
999 def G_BRJT : GenericInstruction {
1000   let OutOperandList = (outs);
1001   let InOperandList = (ins ptype0:$tbl, unknown:$jti, type1:$idx);
1002   let hasSideEffects = 0;
1003   let isBranch = 1;
1004   let isTerminator = 1;
1007 //------------------------------------------------------------------------------
1008 // Vector ops
1009 //------------------------------------------------------------------------------
1011 // Generic insertelement.
1012 def G_INSERT_VECTOR_ELT : GenericInstruction {
1013   let OutOperandList = (outs type0:$dst);
1014   let InOperandList = (ins type0:$src, type1:$elt, type2:$idx);
1015   let hasSideEffects = 0;
1018 // Generic extractelement.
1019 def G_EXTRACT_VECTOR_ELT : GenericInstruction {
1020   let OutOperandList = (outs type0:$dst);
1021   let InOperandList = (ins type1:$src, type2:$idx);
1022   let hasSideEffects = 0;
1025 // Generic shufflevector.
1027 // The mask operand should be an IR Constant which exactly matches the
1028 // corresponding mask for the IR shufflevector instruction.
1029 def G_SHUFFLE_VECTOR: GenericInstruction {
1030   let OutOperandList = (outs type0:$dst);
1031   let InOperandList = (ins type1:$v1, type1:$v2, unknown:$mask);
1032   let hasSideEffects = 0;
1035 // TODO: Add the other generic opcodes.