Revert r354244 "[DAGCombiner] Eliminate dead stores to stack."
[llvm-complete.git] / include / llvm / Target / GenericOpcodes.td
blobe4b452e91b9da9298f064a73d5791a3e7fec147e
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 //------------------------------------------------------------------------------
173 // Binary ops.
174 //------------------------------------------------------------------------------
176 // Generic addition.
177 def G_ADD : GenericInstruction {
178   let OutOperandList = (outs type0:$dst);
179   let InOperandList = (ins type0:$src1, type0:$src2);
180   let hasSideEffects = 0;
181   let isCommutable = 1;
184 // Generic subtraction.
185 def G_SUB : GenericInstruction {
186   let OutOperandList = (outs type0:$dst);
187   let InOperandList = (ins type0:$src1, type0:$src2);
188   let hasSideEffects = 0;
189   let isCommutable = 0;
192 // Generic multiplication.
193 def G_MUL : GenericInstruction {
194   let OutOperandList = (outs type0:$dst);
195   let InOperandList = (ins type0:$src1, type0:$src2);
196   let hasSideEffects = 0;
197   let isCommutable = 1;
200 // Generic signed division.
201 def G_SDIV : GenericInstruction {
202   let OutOperandList = (outs type0:$dst);
203   let InOperandList = (ins type0:$src1, type0:$src2);
204   let hasSideEffects = 0;
205   let isCommutable = 0;
208 // Generic unsigned division.
209 def G_UDIV : GenericInstruction {
210   let OutOperandList = (outs type0:$dst);
211   let InOperandList = (ins type0:$src1, type0:$src2);
212   let hasSideEffects = 0;
213   let isCommutable = 0;
216 // Generic signed remainder.
217 def G_SREM : 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 unsigned remainder.
225 def G_UREM : GenericInstruction {
226   let OutOperandList = (outs type0:$dst);
227   let InOperandList = (ins type0:$src1, type0:$src2);
228   let hasSideEffects = 0;
229   let isCommutable = 0;
232 // Generic bitwise and.
233 def G_AND : GenericInstruction {
234   let OutOperandList = (outs type0:$dst);
235   let InOperandList = (ins type0:$src1, type0:$src2);
236   let hasSideEffects = 0;
237   let isCommutable = 1;
240 // Generic bitwise or.
241 def G_OR : GenericInstruction {
242   let OutOperandList = (outs type0:$dst);
243   let InOperandList = (ins type0:$src1, type0:$src2);
244   let hasSideEffects = 0;
245   let isCommutable = 1;
248 // Generic bitwise xor.
249 def G_XOR : GenericInstruction {
250   let OutOperandList = (outs type0:$dst);
251   let InOperandList = (ins type0:$src1, type0:$src2);
252   let hasSideEffects = 0;
253   let isCommutable = 1;
256 // Generic left-shift.
257 def G_SHL : GenericInstruction {
258   let OutOperandList = (outs type0:$dst);
259   let InOperandList = (ins type0:$src1, type1:$src2);
260   let hasSideEffects = 0;
263 // Generic logical right-shift.
264 def G_LSHR : GenericInstruction {
265   let OutOperandList = (outs type0:$dst);
266   let InOperandList = (ins type0:$src1, type1:$src2);
267   let hasSideEffects = 0;
270 // Generic arithmetic right-shift.
271 def G_ASHR : GenericInstruction {
272   let OutOperandList = (outs type0:$dst);
273   let InOperandList = (ins type0:$src1, type1:$src2);
274   let hasSideEffects = 0;
277 // Generic integer comparison.
278 def G_ICMP : GenericInstruction {
279   let OutOperandList = (outs type0:$dst);
280   let InOperandList = (ins unknown:$tst, type1:$src1, type1:$src2);
281   let hasSideEffects = 0;
284 // Generic floating-point comparison.
285 def G_FCMP : GenericInstruction {
286   let OutOperandList = (outs type0:$dst);
287   let InOperandList = (ins unknown:$tst, type1:$src1, type1:$src2);
288   let hasSideEffects = 0;
291 // Generic select
292 def G_SELECT : GenericInstruction {
293   let OutOperandList = (outs type0:$dst);
294   let InOperandList = (ins type1:$tst, type0:$src1, type0:$src2);
295   let hasSideEffects = 0;
298 // Generic pointer offset.
299 def G_GEP : GenericInstruction {
300   let OutOperandList = (outs type0:$dst);
301   let InOperandList = (ins type0:$src1, type1:$src2);
302   let hasSideEffects = 0;
305 def G_PTR_MASK : GenericInstruction {
306   let OutOperandList = (outs type0:$dst);
307   let InOperandList = (ins type0:$src, unknown:$bits);
308   let hasSideEffects = 0;
311 //------------------------------------------------------------------------------
312 // Overflow ops
313 //------------------------------------------------------------------------------
315 // Generic unsigned addition producing a carry flag.
316 def G_UADDO : GenericInstruction {
317   let OutOperandList = (outs type0:$dst, type1:$carry_out);
318   let InOperandList = (ins type0:$src1, type0:$src2);
319   let hasSideEffects = 0;
320   let isCommutable = 1;
323 // Generic unsigned addition consuming and producing a carry flag.
324 def G_UADDE : GenericInstruction {
325   let OutOperandList = (outs type0:$dst, type1:$carry_out);
326   let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
327   let hasSideEffects = 0;
330 // Generic signed addition producing a carry flag.
331 def G_SADDO : GenericInstruction {
332   let OutOperandList = (outs type0:$dst, type1:$carry_out);
333   let InOperandList = (ins type0:$src1, type0:$src2);
334   let hasSideEffects = 0;
335   let isCommutable = 1;
338 // Generic signed addition consuming and producing a carry flag.
339 def G_SADDE : GenericInstruction {
340   let OutOperandList = (outs type0:$dst, type1:$carry_out);
341   let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
342   let hasSideEffects = 0;
345 // Generic unsigned subtraction producing a carry flag.
346 def G_USUBO : GenericInstruction {
347   let OutOperandList = (outs type0:$dst, type1:$carry_out);
348   let InOperandList = (ins type0:$src1, type0:$src2);
349   let hasSideEffects = 0;
351 // Generic unsigned subtraction consuming and producing a carry flag.
352 def G_USUBE : GenericInstruction {
353   let OutOperandList = (outs type0:$dst, type1:$carry_out);
354   let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
355   let hasSideEffects = 0;
358 // Generic signed subtraction producing a carry flag.
359 def G_SSUBO : GenericInstruction {
360   let OutOperandList = (outs type0:$dst, type1:$carry_out);
361   let InOperandList = (ins type0:$src1, type0:$src2);
362   let hasSideEffects = 0;
365 // Generic signed subtraction consuming and producing a carry flag.
366 def G_SSUBE : GenericInstruction {
367   let OutOperandList = (outs type0:$dst, type1:$carry_out);
368   let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
369   let hasSideEffects = 0;
372 // Generic unsigned multiplication producing a carry flag.
373 def G_UMULO : GenericInstruction {
374   let OutOperandList = (outs type0:$dst, type1:$carry_out);
375   let InOperandList = (ins type0:$src1, type0:$src2);
376   let hasSideEffects = 0;
377   let isCommutable = 1;
380 // Generic signed multiplication producing a carry flag.
381 def G_SMULO : GenericInstruction {
382   let OutOperandList = (outs type0:$dst, type1:$carry_out);
383   let InOperandList = (ins type0:$src1, type0:$src2);
384   let hasSideEffects = 0;
385   let isCommutable = 1;
388 // Multiply two numbers at twice the incoming bit width (unsigned) and return
389 // the high half of the result.
390 def G_UMULH : GenericInstruction {
391   let OutOperandList = (outs type0:$dst);
392   let InOperandList = (ins type0:$src1, type0:$src2);
393   let hasSideEffects = 0;
394   let isCommutable = 1;
397 // Multiply two numbers at twice the incoming bit width (signed) and return
398 // the high half of the result.
399 def G_SMULH : GenericInstruction {
400   let OutOperandList = (outs type0:$dst);
401   let InOperandList = (ins type0:$src1, type0:$src2);
402   let hasSideEffects = 0;
403   let isCommutable = 1;
406 //------------------------------------------------------------------------------
407 // Floating Point Unary Ops.
408 //------------------------------------------------------------------------------
410 def G_FNEG : GenericInstruction {
411   let OutOperandList = (outs type0:$dst);
412   let InOperandList = (ins type0:$src);
413   let hasSideEffects = 0;
416 def G_FPEXT : GenericInstruction {
417   let OutOperandList = (outs type0:$dst);
418   let InOperandList = (ins type1:$src);
419   let hasSideEffects = 0;
422 def G_FPTRUNC : GenericInstruction {
423   let OutOperandList = (outs type0:$dst);
424   let InOperandList = (ins type1:$src);
425   let hasSideEffects = 0;
428 def G_FPTOSI : GenericInstruction {
429   let OutOperandList = (outs type0:$dst);
430   let InOperandList = (ins type1:$src);
431   let hasSideEffects = 0;
434 def G_FPTOUI : GenericInstruction {
435   let OutOperandList = (outs type0:$dst);
436   let InOperandList = (ins type1:$src);
437   let hasSideEffects = 0;
440 def G_SITOFP : GenericInstruction {
441   let OutOperandList = (outs type0:$dst);
442   let InOperandList = (ins type1:$src);
443   let hasSideEffects = 0;
446 def G_UITOFP : GenericInstruction {
447   let OutOperandList = (outs type0:$dst);
448   let InOperandList = (ins type1:$src);
449   let hasSideEffects = 0;
452 def G_FABS : GenericInstruction {
453   let OutOperandList = (outs type0:$dst);
454   let InOperandList = (ins type0:$src);
455   let hasSideEffects = 0;
458 def G_FCANONICALIZE : GenericInstruction {
459   let OutOperandList = (outs type0:$dst);
460   let InOperandList = (ins type0:$src);
461   let hasSideEffects = 0;
464 //------------------------------------------------------------------------------
465 // Floating Point Binary ops.
466 //------------------------------------------------------------------------------
468 // Generic FP addition.
469 def G_FADD : GenericInstruction {
470   let OutOperandList = (outs type0:$dst);
471   let InOperandList = (ins type0:$src1, type0:$src2);
472   let hasSideEffects = 0;
473   let isCommutable = 1;
476 // Generic FP subtraction.
477 def G_FSUB : GenericInstruction {
478   let OutOperandList = (outs type0:$dst);
479   let InOperandList = (ins type0:$src1, type0:$src2);
480   let hasSideEffects = 0;
481   let isCommutable = 0;
484 // Generic FP multiplication.
485 def G_FMUL : GenericInstruction {
486   let OutOperandList = (outs type0:$dst);
487   let InOperandList = (ins type0:$src1, type0:$src2);
488   let hasSideEffects = 0;
489   let isCommutable = 1;
492 // Generic fused multiply-add instruction.
493 // Behaves like llvm fma intrinsic ie src1 * src2 + src3
494 def G_FMA : GenericInstruction {
495   let OutOperandList = (outs type0:$dst);
496   let InOperandList = (ins type0:$src1, type0:$src2, type0:$src3);
497   let hasSideEffects = 0;
498   let isCommutable = 0;
501 // Generic FP division.
502 def G_FDIV : GenericInstruction {
503   let OutOperandList = (outs type0:$dst);
504   let InOperandList = (ins type0:$src1, type0:$src2);
505   let hasSideEffects = 0;
508 // Generic FP remainder.
509 def G_FREM : GenericInstruction {
510   let OutOperandList = (outs type0:$dst);
511   let InOperandList = (ins type0:$src1, type0:$src2);
512   let hasSideEffects = 0;
515 // Floating point exponentiation.
516 def G_FPOW : GenericInstruction {
517   let OutOperandList = (outs type0:$dst);
518   let InOperandList = (ins type0:$src1, type0:$src2);
519   let hasSideEffects = 0;
522 // Floating point base-e exponential of a value.
523 def G_FEXP : GenericInstruction {
524   let OutOperandList = (outs type0:$dst);
525   let InOperandList = (ins type0:$src1);
526   let hasSideEffects = 0;
529 // Floating point base-2 exponential of a value.
530 def G_FEXP2 : GenericInstruction {
531   let OutOperandList = (outs type0:$dst);
532   let InOperandList = (ins type0:$src1);
533   let hasSideEffects = 0;
536 // Floating point base-2 logarithm of a value.
537 def G_FLOG : GenericInstruction {
538   let OutOperandList = (outs type0:$dst);
539   let InOperandList = (ins type0:$src1);
540   let hasSideEffects = 0;
543 // Floating point base-2 logarithm of a value.
544 def G_FLOG2 : GenericInstruction {
545   let OutOperandList = (outs type0:$dst);
546   let InOperandList = (ins type0:$src1);
547   let hasSideEffects = 0;
550 // Floating point base-10 logarithm of a value.
551 def G_FLOG10 : GenericInstruction {
552   let OutOperandList = (outs type0:$dst);
553   let InOperandList = (ins type0:$src1);
554   let hasSideEffects = 0;
557 // Floating point ceiling of a value.
558 def G_FCEIL : GenericInstruction {
559   let OutOperandList = (outs type0:$dst);
560   let InOperandList = (ins type0:$src1);
561   let hasSideEffects = 0;
564 // Floating point cosine of a value.
565 def G_FCOS : GenericInstruction {
566   let OutOperandList = (outs type0:$dst);
567   let InOperandList = (ins type0:$src1);
568   let hasSideEffects = 0;
571 // Floating point sine of a value.
572 def G_FSIN : GenericInstruction {
573   let OutOperandList = (outs type0:$dst);
574   let InOperandList = (ins type0:$src1);
575   let hasSideEffects = 0;
578 // Floating point square root of a value.
579 // This returns NaN for negative nonzero values.
580 // NOTE: Unlike libm sqrt(), this never sets errno. In all other respects it's
581 // libm-conformant.
582 def G_FSQRT : GenericInstruction {
583   let OutOperandList = (outs type0:$dst);
584   let InOperandList = (ins type0:$src1);
585   let hasSideEffects = 0;
588 // Floating point floor of a value.
589 def G_FFLOOR : GenericInstruction {
590   let OutOperandList = (outs type0:$dst);
591   let InOperandList = (ins type0:$src1);
592   let hasSideEffects = 0;
595 //------------------------------------------------------------------------------
596 // Opcodes for LLVM Intrinsics
597 //------------------------------------------------------------------------------
598 def G_INTRINSIC_TRUNC : GenericInstruction {
599   let OutOperandList = (outs type0:$dst);
600   let InOperandList = (ins type0:$src1);
601   let hasSideEffects = 0;
604 def G_INTRINSIC_ROUND : GenericInstruction {
605   let OutOperandList = (outs type0:$dst);
606   let InOperandList = (ins type0:$src1);
607   let hasSideEffects = 0;
610 //------------------------------------------------------------------------------
611 // Memory ops
612 //------------------------------------------------------------------------------
614 // Generic load. Expects a MachineMemOperand in addition to explicit operands.
615 def G_LOAD : GenericInstruction {
616   let OutOperandList = (outs type0:$dst);
617   let InOperandList = (ins ptype1:$addr);
618   let hasSideEffects = 0;
619   let mayLoad = 1;
622 // Generic sign-extended load. Expects a MachineMemOperand in addition to explicit operands.
623 def G_SEXTLOAD : GenericInstruction {
624   let OutOperandList = (outs type0:$dst);
625   let InOperandList = (ins ptype1:$addr);
626   let hasSideEffects = 0;
627   let mayLoad = 1;
630 // Generic zero-extended load. Expects a MachineMemOperand in addition to explicit operands.
631 def G_ZEXTLOAD : GenericInstruction {
632   let OutOperandList = (outs type0:$dst);
633   let InOperandList = (ins ptype1:$addr);
634   let hasSideEffects = 0;
635   let mayLoad = 1;
638 // Generic store. Expects a MachineMemOperand in addition to explicit operands.
639 def G_STORE : GenericInstruction {
640   let OutOperandList = (outs);
641   let InOperandList = (ins type0:$src, ptype1:$addr);
642   let hasSideEffects = 0;
643   let mayStore = 1;
646 // Generic atomic cmpxchg with internal success check. Expects a
647 // MachineMemOperand in addition to explicit operands.
648 def G_ATOMIC_CMPXCHG_WITH_SUCCESS : GenericInstruction {
649   let OutOperandList = (outs type0:$oldval, type1:$success);
650   let InOperandList = (ins type2:$addr, type0:$cmpval, type0:$newval);
651   let hasSideEffects = 0;
652   let mayLoad = 1;
653   let mayStore = 1;
656 // Generic atomic cmpxchg. Expects a MachineMemOperand in addition to explicit
657 // operands.
658 def G_ATOMIC_CMPXCHG : GenericInstruction {
659   let OutOperandList = (outs type0:$oldval);
660   let InOperandList = (ins ptype1:$addr, type0:$cmpval, type0:$newval);
661   let hasSideEffects = 0;
662   let mayLoad = 1;
663   let mayStore = 1;
666 // Generic atomicrmw. Expects a MachineMemOperand in addition to explicit
667 // operands.
668 class G_ATOMICRMW_OP : GenericInstruction {
669   let OutOperandList = (outs type0:$oldval);
670   let InOperandList = (ins ptype1:$addr, type0:$val);
671   let hasSideEffects = 0;
672   let mayLoad = 1;
673   let mayStore = 1;
676 def G_ATOMICRMW_XCHG : G_ATOMICRMW_OP;
677 def G_ATOMICRMW_ADD : G_ATOMICRMW_OP;
678 def G_ATOMICRMW_SUB : G_ATOMICRMW_OP;
679 def G_ATOMICRMW_AND : G_ATOMICRMW_OP;
680 def G_ATOMICRMW_NAND : G_ATOMICRMW_OP;
681 def G_ATOMICRMW_OR : G_ATOMICRMW_OP;
682 def G_ATOMICRMW_XOR : G_ATOMICRMW_OP;
683 def G_ATOMICRMW_MAX : G_ATOMICRMW_OP;
684 def G_ATOMICRMW_MIN : G_ATOMICRMW_OP;
685 def G_ATOMICRMW_UMAX : G_ATOMICRMW_OP;
686 def G_ATOMICRMW_UMIN : G_ATOMICRMW_OP;
688 //------------------------------------------------------------------------------
689 // Variadic ops
690 //------------------------------------------------------------------------------
692 // Extract a register of the specified size, starting from the block given by
693 // index. This will almost certainly be mapped to sub-register COPYs after
694 // register banks have been selected.
695 def G_EXTRACT : GenericInstruction {
696   let OutOperandList = (outs type0:$res);
697   let InOperandList = (ins type1:$src, unknown:$offset);
698   let hasSideEffects = 0;
701 // Extract multiple registers specified size, starting from blocks given by
702 // indexes. This will almost certainly be mapped to sub-register COPYs after
703 // register banks have been selected.
704 // The output operands are always ordered from lowest bits to highest:
705 //   %bits_0_7:(s8), %bits_8_15:(s8),
706 //       %bits_16_23:(s8), %bits_24_31:(s8) = G_UNMERGE_VALUES %0:(s32)
707 def G_UNMERGE_VALUES : GenericInstruction {
708   let OutOperandList = (outs type0:$dst0, variable_ops);
709   let InOperandList = (ins type1:$src);
710   let hasSideEffects = 0;
713 // Insert a smaller register into a larger one at the specified bit-index.
714 def G_INSERT : GenericInstruction {
715   let OutOperandList = (outs type0:$dst);
716   let InOperandList = (ins type0:$src, type1:$op, unknown:$offset);
717   let hasSideEffects = 0;
720 // Concatenate multiple registers of the same size into a wider register.
721 // The input operands are always ordered from lowest bits to highest:
722 //   %0:(s32) = G_MERGE_VALUES %bits_0_7:(s8), %bits_8_15:(s8),
723 //                             %bits_16_23:(s8), %bits_24_31:(s8)
724 def G_MERGE_VALUES : GenericInstruction {
725   let OutOperandList = (outs type0:$dst);
726   let InOperandList = (ins type1:$src0, variable_ops);
727   let hasSideEffects = 0;
730 /// Create a vector from multiple scalar registers. No implicit
731 /// conversion is performed (i.e. the result element type must be the
732 /// same as all source operands)
733 def G_BUILD_VECTOR : GenericInstruction {
734   let OutOperandList = (outs type0:$dst);
735   let InOperandList = (ins type1:$src0, variable_ops);
736   let hasSideEffects = 0;
739 /// Like G_BUILD_VECTOR, but truncates the larger operand types to fit the
740 /// destination vector elt type.
741 def G_BUILD_VECTOR_TRUNC : GenericInstruction {
742   let OutOperandList = (outs type0:$dst);
743   let InOperandList = (ins type1:$src0, variable_ops);
744   let hasSideEffects = 0;
747 /// Create a vector by concatenating vectors together.
748 def G_CONCAT_VECTORS : GenericInstruction {
749   let OutOperandList = (outs type0:$dst);
750   let InOperandList = (ins type1:$src0, variable_ops);
751   let hasSideEffects = 0;
754 // Intrinsic without side effects.
755 def G_INTRINSIC : GenericInstruction {
756   let OutOperandList = (outs);
757   let InOperandList = (ins unknown:$intrin, variable_ops);
758   let hasSideEffects = 0;
761 // Intrinsic with side effects.
762 def G_INTRINSIC_W_SIDE_EFFECTS : GenericInstruction {
763   let OutOperandList = (outs);
764   let InOperandList = (ins unknown:$intrin, variable_ops);
765   let hasSideEffects = 1;
766   let mayLoad = 1;
767   let mayStore = 1;
770 //------------------------------------------------------------------------------
771 // Branches.
772 //------------------------------------------------------------------------------
774 // Generic unconditional branch.
775 def G_BR : GenericInstruction {
776   let OutOperandList = (outs);
777   let InOperandList = (ins unknown:$src1);
778   let hasSideEffects = 0;
779   let isBranch = 1;
780   let isTerminator = 1;
781   let isBarrier = 1;
784 // Generic conditional branch.
785 def G_BRCOND : GenericInstruction {
786   let OutOperandList = (outs);
787   let InOperandList = (ins type0:$tst, unknown:$truebb);
788   let hasSideEffects = 0;
789   let isBranch = 1;
790   let isTerminator = 1;
793 // Generic indirect branch.
794 def G_BRINDIRECT : GenericInstruction {
795   let OutOperandList = (outs);
796   let InOperandList = (ins type0:$src1);
797   let hasSideEffects = 0;
798   let isBranch = 1;
799   let isTerminator = 1;
802 //------------------------------------------------------------------------------
803 // Vector ops
804 //------------------------------------------------------------------------------
806 // Generic insertelement.
807 def G_INSERT_VECTOR_ELT : GenericInstruction {
808   let OutOperandList = (outs type0:$dst);
809   let InOperandList = (ins type0:$src, type1:$elt, type2:$idx);
810   let hasSideEffects = 0;
813 // Generic extractelement.
814 def G_EXTRACT_VECTOR_ELT : GenericInstruction {
815   let OutOperandList = (outs type0:$dst);
816   let InOperandList = (ins type1:$src, type2:$idx);
817   let hasSideEffects = 0;
820 // Generic shufflevector.
821 def G_SHUFFLE_VECTOR: GenericInstruction {
822   let OutOperandList = (outs type0:$dst);
823   let InOperandList = (ins type1:$v1, type1:$v2, type2:$mask);
824   let hasSideEffects = 0;
827 // TODO: Add the other generic opcodes.