1 //===-- GenericOpcodes.td - Opcodes used with GlobalISel ---*- tablegen -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file defines the generic opcodes used with GlobalISel.
10 // After instruction selection, these opcodes should not appear.
12 //===----------------------------------------------------------------------===//
14 //------------------------------------------------------------------------------
16 //------------------------------------------------------------------------------
18 class GenericInstruction : StandardPseudoInstruction;
20 // Extend the underlying scalar type of an operation, leaving the high bits
22 def G_ANYEXT : GenericInstruction {
23 let OutOperandList = (outs type0:$dst);
24 let InOperandList = (ins type1:$src);
25 let hasSideEffects = 0;
28 // Sign extend the underlying scalar type of an operation, copying the sign bit
29 // into the newly-created space.
30 def G_SEXT : GenericInstruction {
31 let OutOperandList = (outs type0:$dst);
32 let InOperandList = (ins type1:$src);
33 let hasSideEffects = 0;
36 // 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;
130 def G_VAARG : GenericInstruction {
131 let OutOperandList = (outs type0:$val);
132 let InOperandList = (ins type1:$list, unknown:$align);
133 let hasSideEffects = 0;
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 //------------------------------------------------------------------------------
206 //------------------------------------------------------------------------------
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;
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 //------------------------------------------------------------------------------
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
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
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 //------------------------------------------------------------------------------
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;
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;
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;
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;
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;
800 // Generic atomic cmpxchg. Expects a MachineMemOperand in addition to explicit
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;
810 // Generic atomicrmw. Expects a MachineMemOperand in addition to explicit
812 class G_ATOMICRMW_OP : GenericInstruction {
813 let OutOperandList = (outs type0:$oldval);
814 let InOperandList = (ins ptype1:$addr, type0:$val);
815 let hasSideEffects = 0;
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 //------------------------------------------------------------------------------
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;
922 //------------------------------------------------------------------------------
924 //------------------------------------------------------------------------------
926 // Generic unconditional branch.
927 def G_BR : GenericInstruction {
928 let OutOperandList = (outs);
929 let InOperandList = (ins unknown:$src1);
930 let hasSideEffects = 0;
932 let isTerminator = 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;
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;
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;
960 let isTerminator = 1;
963 //------------------------------------------------------------------------------
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.