[Alignment][NFC] Use Align with TargetLowering::setMinFunctionAlignment
[llvm-core.git] / include / llvm / Target / GenericOpcodes.td
blob840646ef2b9f91487a6cb6151b1a9542f52e5ecf
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 division.
628 def G_FDIV : GenericInstruction {
629   let OutOperandList = (outs type0:$dst);
630   let InOperandList = (ins type0:$src1, type0:$src2);
631   let hasSideEffects = 0;
634 // Generic FP remainder.
635 def G_FREM : GenericInstruction {
636   let OutOperandList = (outs type0:$dst);
637   let InOperandList = (ins type0:$src1, type0:$src2);
638   let hasSideEffects = 0;
641 // Floating point exponentiation.
642 def G_FPOW : GenericInstruction {
643   let OutOperandList = (outs type0:$dst);
644   let InOperandList = (ins type0:$src1, type0:$src2);
645   let hasSideEffects = 0;
648 // Floating point base-e exponential of a value.
649 def G_FEXP : GenericInstruction {
650   let OutOperandList = (outs type0:$dst);
651   let InOperandList = (ins type0:$src1);
652   let hasSideEffects = 0;
655 // Floating point base-2 exponential of a value.
656 def G_FEXP2 : GenericInstruction {
657   let OutOperandList = (outs type0:$dst);
658   let InOperandList = (ins type0:$src1);
659   let hasSideEffects = 0;
662 // Floating point base-2 logarithm of a value.
663 def G_FLOG : GenericInstruction {
664   let OutOperandList = (outs type0:$dst);
665   let InOperandList = (ins type0:$src1);
666   let hasSideEffects = 0;
669 // Floating point base-2 logarithm of a value.
670 def G_FLOG2 : GenericInstruction {
671   let OutOperandList = (outs type0:$dst);
672   let InOperandList = (ins type0:$src1);
673   let hasSideEffects = 0;
676 // Floating point base-10 logarithm of a value.
677 def G_FLOG10 : GenericInstruction {
678   let OutOperandList = (outs type0:$dst);
679   let InOperandList = (ins type0:$src1);
680   let hasSideEffects = 0;
683 // Floating point ceiling of a value.
684 def G_FCEIL : GenericInstruction {
685   let OutOperandList = (outs type0:$dst);
686   let InOperandList = (ins type0:$src1);
687   let hasSideEffects = 0;
690 // Floating point cosine of a value.
691 def G_FCOS : GenericInstruction {
692   let OutOperandList = (outs type0:$dst);
693   let InOperandList = (ins type0:$src1);
694   let hasSideEffects = 0;
697 // Floating point sine of a value.
698 def G_FSIN : GenericInstruction {
699   let OutOperandList = (outs type0:$dst);
700   let InOperandList = (ins type0:$src1);
701   let hasSideEffects = 0;
704 // Floating point square root of a value.
705 // This returns NaN for negative nonzero values.
706 // NOTE: Unlike libm sqrt(), this never sets errno. In all other respects it's
707 // libm-conformant.
708 def G_FSQRT : GenericInstruction {
709   let OutOperandList = (outs type0:$dst);
710   let InOperandList = (ins type0:$src1);
711   let hasSideEffects = 0;
714 // Floating point floor of a value.
715 def G_FFLOOR : GenericInstruction {
716   let OutOperandList = (outs type0:$dst);
717   let InOperandList = (ins type0:$src1);
718   let hasSideEffects = 0;
721 // Floating point round to next integer.
722 def G_FRINT : GenericInstruction {
723   let OutOperandList = (outs type0:$dst);
724   let InOperandList = (ins type0:$src1);
725   let hasSideEffects = 0;
728 // Floating point round to the nearest integer.
729 def G_FNEARBYINT : GenericInstruction {
730   let OutOperandList = (outs type0:$dst);
731   let InOperandList = (ins type0:$src1);
732   let hasSideEffects = 0;
735 //------------------------------------------------------------------------------
736 // Opcodes for LLVM Intrinsics
737 //------------------------------------------------------------------------------
738 def G_INTRINSIC_TRUNC : GenericInstruction {
739   let OutOperandList = (outs type0:$dst);
740   let InOperandList = (ins type0:$src1);
741   let hasSideEffects = 0;
744 def G_INTRINSIC_ROUND : GenericInstruction {
745   let OutOperandList = (outs type0:$dst);
746   let InOperandList = (ins type0:$src1);
747   let hasSideEffects = 0;
750 //------------------------------------------------------------------------------
751 // Memory ops
752 //------------------------------------------------------------------------------
754 // Generic load. Expects a MachineMemOperand in addition to explicit
755 // operands. If the result size is larger than the memory size, the
756 // high bits are undefined. If the result is a vector type and larger
757 // than the memory size, the high elements are undefined (i.e. this is
758 // not a per-element, vector anyextload)
759 def G_LOAD : GenericInstruction {
760   let OutOperandList = (outs type0:$dst);
761   let InOperandList = (ins ptype1:$addr);
762   let hasSideEffects = 0;
763   let mayLoad = 1;
766 // Generic sign-extended load. Expects a MachineMemOperand in addition to explicit operands.
767 def G_SEXTLOAD : GenericInstruction {
768   let OutOperandList = (outs type0:$dst);
769   let InOperandList = (ins ptype1:$addr);
770   let hasSideEffects = 0;
771   let mayLoad = 1;
774 // Generic zero-extended load. Expects a MachineMemOperand in addition to explicit operands.
775 def G_ZEXTLOAD : GenericInstruction {
776   let OutOperandList = (outs type0:$dst);
777   let InOperandList = (ins ptype1:$addr);
778   let hasSideEffects = 0;
779   let mayLoad = 1;
782 // Generic store. Expects a MachineMemOperand in addition to explicit operands.
783 def G_STORE : GenericInstruction {
784   let OutOperandList = (outs);
785   let InOperandList = (ins type0:$src, ptype1:$addr);
786   let hasSideEffects = 0;
787   let mayStore = 1;
790 // Generic atomic cmpxchg with internal success check. Expects a
791 // MachineMemOperand in addition to explicit operands.
792 def G_ATOMIC_CMPXCHG_WITH_SUCCESS : GenericInstruction {
793   let OutOperandList = (outs type0:$oldval, type1:$success);
794   let InOperandList = (ins type2:$addr, type0:$cmpval, type0:$newval);
795   let hasSideEffects = 0;
796   let mayLoad = 1;
797   let mayStore = 1;
800 // Generic atomic cmpxchg. Expects a MachineMemOperand in addition to explicit
801 // operands.
802 def G_ATOMIC_CMPXCHG : GenericInstruction {
803   let OutOperandList = (outs type0:$oldval);
804   let InOperandList = (ins ptype1:$addr, type0:$cmpval, type0:$newval);
805   let hasSideEffects = 0;
806   let mayLoad = 1;
807   let mayStore = 1;
810 // Generic atomicrmw. Expects a MachineMemOperand in addition to explicit
811 // operands.
812 class G_ATOMICRMW_OP : GenericInstruction {
813   let OutOperandList = (outs type0:$oldval);
814   let InOperandList = (ins ptype1:$addr, type0:$val);
815   let hasSideEffects = 0;
816   let mayLoad = 1;
817   let mayStore = 1;
820 def G_ATOMICRMW_XCHG : G_ATOMICRMW_OP;
821 def G_ATOMICRMW_ADD : G_ATOMICRMW_OP;
822 def G_ATOMICRMW_SUB : G_ATOMICRMW_OP;
823 def G_ATOMICRMW_AND : G_ATOMICRMW_OP;
824 def G_ATOMICRMW_NAND : G_ATOMICRMW_OP;
825 def G_ATOMICRMW_OR : G_ATOMICRMW_OP;
826 def G_ATOMICRMW_XOR : G_ATOMICRMW_OP;
827 def G_ATOMICRMW_MAX : G_ATOMICRMW_OP;
828 def G_ATOMICRMW_MIN : G_ATOMICRMW_OP;
829 def G_ATOMICRMW_UMAX : G_ATOMICRMW_OP;
830 def G_ATOMICRMW_UMIN : G_ATOMICRMW_OP;
831 def G_ATOMICRMW_FADD : G_ATOMICRMW_OP;
832 def G_ATOMICRMW_FSUB : G_ATOMICRMW_OP;
834 def G_FENCE : GenericInstruction {
835   let OutOperandList = (outs);
836   let InOperandList = (ins i32imm:$ordering, i32imm:$scope);
837   let hasSideEffects = 1;
840 //------------------------------------------------------------------------------
841 // Variadic ops
842 //------------------------------------------------------------------------------
844 // Extract a register of the specified size, starting from the block given by
845 // index. This will almost certainly be mapped to sub-register COPYs after
846 // register banks have been selected.
847 def G_EXTRACT : GenericInstruction {
848   let OutOperandList = (outs type0:$res);
849   let InOperandList = (ins type1:$src, unknown:$offset);
850   let hasSideEffects = 0;
853 // Extract multiple registers specified size, starting from blocks given by
854 // indexes. This will almost certainly be mapped to sub-register COPYs after
855 // register banks have been selected.
856 // The output operands are always ordered from lowest bits to highest:
857 //   %bits_0_7:(s8), %bits_8_15:(s8),
858 //       %bits_16_23:(s8), %bits_24_31:(s8) = G_UNMERGE_VALUES %0:(s32)
859 def G_UNMERGE_VALUES : GenericInstruction {
860   let OutOperandList = (outs type0:$dst0, variable_ops);
861   let InOperandList = (ins type1:$src);
862   let hasSideEffects = 0;
865 // Insert a smaller register into a larger one at the specified bit-index.
866 def G_INSERT : GenericInstruction {
867   let OutOperandList = (outs type0:$dst);
868   let InOperandList = (ins type0:$src, type1:$op, unknown:$offset);
869   let hasSideEffects = 0;
872 // Concatenate multiple registers of the same size into a wider register.
873 // The input operands are always ordered from lowest bits to highest:
874 //   %0:(s32) = G_MERGE_VALUES %bits_0_7:(s8), %bits_8_15:(s8),
875 //                             %bits_16_23:(s8), %bits_24_31:(s8)
876 def G_MERGE_VALUES : GenericInstruction {
877   let OutOperandList = (outs type0:$dst);
878   let InOperandList = (ins type1:$src0, variable_ops);
879   let hasSideEffects = 0;
882 /// Create a vector from multiple scalar registers. No implicit
883 /// conversion is performed (i.e. the result element type must be the
884 /// same as all source operands)
885 def G_BUILD_VECTOR : GenericInstruction {
886   let OutOperandList = (outs type0:$dst);
887   let InOperandList = (ins type1:$src0, variable_ops);
888   let hasSideEffects = 0;
891 /// Like G_BUILD_VECTOR, but truncates the larger operand types to fit the
892 /// destination vector elt type.
893 def G_BUILD_VECTOR_TRUNC : GenericInstruction {
894   let OutOperandList = (outs type0:$dst);
895   let InOperandList = (ins type1:$src0, variable_ops);
896   let hasSideEffects = 0;
899 /// Create a vector by concatenating vectors together.
900 def G_CONCAT_VECTORS : GenericInstruction {
901   let OutOperandList = (outs type0:$dst);
902   let InOperandList = (ins type1:$src0, variable_ops);
903   let hasSideEffects = 0;
906 // Intrinsic without side effects.
907 def G_INTRINSIC : GenericInstruction {
908   let OutOperandList = (outs);
909   let InOperandList = (ins unknown:$intrin, variable_ops);
910   let hasSideEffects = 0;
913 // Intrinsic with side effects.
914 def G_INTRINSIC_W_SIDE_EFFECTS : GenericInstruction {
915   let OutOperandList = (outs);
916   let InOperandList = (ins unknown:$intrin, variable_ops);
917   let hasSideEffects = 1;
918   let mayLoad = 1;
919   let mayStore = 1;
922 //------------------------------------------------------------------------------
923 // Branches.
924 //------------------------------------------------------------------------------
926 // Generic unconditional branch.
927 def G_BR : GenericInstruction {
928   let OutOperandList = (outs);
929   let InOperandList = (ins unknown:$src1);
930   let hasSideEffects = 0;
931   let isBranch = 1;
932   let isTerminator = 1;
933   let isBarrier = 1;
936 // Generic conditional branch.
937 def G_BRCOND : GenericInstruction {
938   let OutOperandList = (outs);
939   let InOperandList = (ins type0:$tst, unknown:$truebb);
940   let hasSideEffects = 0;
941   let isBranch = 1;
942   let isTerminator = 1;
945 // Generic indirect branch.
946 def G_BRINDIRECT : GenericInstruction {
947   let OutOperandList = (outs);
948   let InOperandList = (ins type0:$src1);
949   let hasSideEffects = 0;
950   let isBranch = 1;
951   let isTerminator = 1;
954 // Generic branch to jump table entry
955 def G_BRJT : GenericInstruction {
956   let OutOperandList = (outs);
957   let InOperandList = (ins ptype0:$tbl, unknown:$jti, type1:$idx);
958   let hasSideEffects = 0;
959   let isBranch = 1;
960   let isTerminator = 1;
963 //------------------------------------------------------------------------------
964 // Vector ops
965 //------------------------------------------------------------------------------
967 // Generic insertelement.
968 def G_INSERT_VECTOR_ELT : GenericInstruction {
969   let OutOperandList = (outs type0:$dst);
970   let InOperandList = (ins type0:$src, type1:$elt, type2:$idx);
971   let hasSideEffects = 0;
974 // Generic extractelement.
975 def G_EXTRACT_VECTOR_ELT : GenericInstruction {
976   let OutOperandList = (outs type0:$dst);
977   let InOperandList = (ins type1:$src, type2:$idx);
978   let hasSideEffects = 0;
981 // Generic shufflevector.
983 // The mask operand should be an IR Constant which exactly matches the
984 // corresponding mask for the IR shufflevector instruction.
985 def G_SHUFFLE_VECTOR: GenericInstruction {
986   let OutOperandList = (outs type0:$dst);
987   let InOperandList = (ins type1:$v1, type1:$v2, unknown:$mask);
988   let hasSideEffects = 0;
991 // TODO: Add the other generic opcodes.