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 {
19 let isPreISelOpcode = true;
22 // Provide a variant of an instruction with the same operands, but
23 // different instruction flags. This is intended to provide a
24 // convenient way to define strict floating point variants of ordinary
25 // floating point instructions.
26 class ConstrainedIntruction<GenericInstruction baseInst> :
28 let OutOperandList = baseInst.OutOperandList;
29 let InOperandList = baseInst.InOperandList;
30 let isCommutable = baseInst.isCommutable;
32 // TODO: Do we need a better way to mark reads from FP mode than
34 let hasSideEffects = true;
35 let mayRaiseFPException = true;
38 // Extend the underlying scalar type of an operation, leaving the high bits
40 def G_ANYEXT : GenericInstruction {
41 let OutOperandList = (outs type0:$dst);
42 let InOperandList = (ins type1:$src);
43 let hasSideEffects = false;
46 // Sign extend the underlying scalar type of an operation, copying the sign bit
47 // into the newly-created space.
48 def G_SEXT : GenericInstruction {
49 let OutOperandList = (outs type0:$dst);
50 let InOperandList = (ins type1:$src);
51 let hasSideEffects = false;
54 // Sign extend the a value from an arbitrary bit position, copying the sign bit
55 // into all bits above it. This is equivalent to a shl + ashr pair with an
56 // appropriate shift amount. $sz is an immediate (MachineOperand::isImm()
57 // returns true) to allow targets to have some bitwidths legal and others
58 // lowered. This opcode is particularly useful if the target has sign-extension
59 // instructions that are cheaper than the constituent shifts as the optimizer is
60 // able to make decisions on whether it's better to hang on to the G_SEXT_INREG
61 // or to lower it and optimize the individual shifts.
62 def G_SEXT_INREG : GenericInstruction {
63 let OutOperandList = (outs type0:$dst);
64 let InOperandList = (ins type0:$src, untyped_imm_0:$sz);
65 let hasSideEffects = false;
68 // Zero extend the underlying scalar type of an operation, putting zero bits
69 // into the newly-created space.
70 def G_ZEXT : GenericInstruction {
71 let OutOperandList = (outs type0:$dst);
72 let InOperandList = (ins type1:$src);
73 let hasSideEffects = false;
77 // Truncate the underlying scalar type of an operation. This is equivalent to
78 // G_EXTRACT for scalar types, but acts elementwise on vectors.
79 def G_TRUNC : GenericInstruction {
80 let OutOperandList = (outs type0:$dst);
81 let InOperandList = (ins type1:$src);
82 let hasSideEffects = false;
85 def G_IMPLICIT_DEF : GenericInstruction {
86 let OutOperandList = (outs type0:$dst);
87 let InOperandList = (ins);
88 let hasSideEffects = false;
91 def G_PHI : GenericInstruction {
92 let OutOperandList = (outs type0:$dst);
93 let InOperandList = (ins variable_ops);
94 let hasSideEffects = false;
97 def G_FRAME_INDEX : GenericInstruction {
98 let OutOperandList = (outs type0:$dst);
99 let InOperandList = (ins unknown:$src2);
100 let hasSideEffects = false;
103 def G_GLOBAL_VALUE : GenericInstruction {
104 let OutOperandList = (outs type0:$dst);
105 let InOperandList = (ins unknown:$src);
106 let hasSideEffects = false;
109 def G_INTTOPTR : GenericInstruction {
110 let OutOperandList = (outs type0:$dst);
111 let InOperandList = (ins type1:$src);
112 let hasSideEffects = false;
115 def G_PTRTOINT : GenericInstruction {
116 let OutOperandList = (outs type0:$dst);
117 let InOperandList = (ins type1:$src);
118 let hasSideEffects = false;
121 def G_BITCAST : GenericInstruction {
122 let OutOperandList = (outs type0:$dst);
123 let InOperandList = (ins type1:$src);
124 let hasSideEffects = false;
127 // Only supports scalar result types
128 def G_CONSTANT : GenericInstruction {
129 let OutOperandList = (outs type0:$dst);
130 let InOperandList = (ins unknown:$imm);
131 let hasSideEffects = false;
134 // Only supports scalar result types
135 def G_FCONSTANT : GenericInstruction {
136 let OutOperandList = (outs type0:$dst);
137 let InOperandList = (ins unknown:$imm);
138 let hasSideEffects = false;
141 def G_VASTART : GenericInstruction {
142 let OutOperandList = (outs);
143 let InOperandList = (ins type0:$list);
144 let hasSideEffects = false;
148 def G_VAARG : GenericInstruction {
149 let OutOperandList = (outs type0:$val);
150 let InOperandList = (ins type1:$list, unknown:$align);
151 let hasSideEffects = false;
156 def G_CTLZ : GenericInstruction {
157 let OutOperandList = (outs type0:$dst);
158 let InOperandList = (ins type1:$src);
159 let hasSideEffects = false;
162 def G_CTLZ_ZERO_UNDEF : GenericInstruction {
163 let OutOperandList = (outs type0:$dst);
164 let InOperandList = (ins type1:$src);
165 let hasSideEffects = false;
168 def G_CTTZ : GenericInstruction {
169 let OutOperandList = (outs type0:$dst);
170 let InOperandList = (ins type1:$src);
171 let hasSideEffects = false;
174 def G_CTTZ_ZERO_UNDEF : GenericInstruction {
175 let OutOperandList = (outs type0:$dst);
176 let InOperandList = (ins type1:$src);
177 let hasSideEffects = false;
180 def G_CTPOP : GenericInstruction {
181 let OutOperandList = (outs type0:$dst);
182 let InOperandList = (ins type1:$src);
183 let hasSideEffects = false;
186 def G_BSWAP : GenericInstruction {
187 let OutOperandList = (outs type0:$dst);
188 let InOperandList = (ins type0:$src);
189 let hasSideEffects = false;
192 def G_BITREVERSE : GenericInstruction {
193 let OutOperandList = (outs type0:$dst);
194 let InOperandList = (ins type0:$src);
195 let hasSideEffects = false;
198 def G_ADDRSPACE_CAST : GenericInstruction {
199 let OutOperandList = (outs type0:$dst);
200 let InOperandList = (ins type1:$src);
201 let hasSideEffects = false;
204 def G_BLOCK_ADDR : GenericInstruction {
205 let OutOperandList = (outs type0:$dst);
206 let InOperandList = (ins unknown:$ba);
207 let hasSideEffects = false;
210 def G_JUMP_TABLE : GenericInstruction {
211 let OutOperandList = (outs type0:$dst);
212 let InOperandList = (ins unknown:$jti);
213 let hasSideEffects = false;
216 def G_DYN_STACKALLOC : GenericInstruction {
217 let OutOperandList = (outs ptype0:$dst);
218 let InOperandList = (ins type1:$size, i32imm:$align);
219 let hasSideEffects = true;
222 def G_FREEZE : GenericInstruction {
223 let OutOperandList = (outs type0:$dst);
224 let InOperandList = (ins type0:$src);
225 let hasSideEffects = false;
228 def G_LROUND: GenericInstruction {
229 let OutOperandList = (outs type0:$dst);
230 let InOperandList = (ins type1:$src);
231 let hasSideEffects = false;
234 def G_LLROUND: GenericInstruction {
235 let OutOperandList = (outs type0:$dst);
236 let InOperandList = (ins type1:$src);
237 let hasSideEffects = false;
240 //------------------------------------------------------------------------------
242 //------------------------------------------------------------------------------
245 def G_ADD : GenericInstruction {
246 let OutOperandList = (outs type0:$dst);
247 let InOperandList = (ins type0:$src1, type0:$src2);
248 let hasSideEffects = false;
249 let isCommutable = true;
252 // Generic subtraction.
253 def G_SUB : GenericInstruction {
254 let OutOperandList = (outs type0:$dst);
255 let InOperandList = (ins type0:$src1, type0:$src2);
256 let hasSideEffects = false;
257 let isCommutable = false;
260 // Generic multiplication.
261 def G_MUL : GenericInstruction {
262 let OutOperandList = (outs type0:$dst);
263 let InOperandList = (ins type0:$src1, type0:$src2);
264 let hasSideEffects = false;
265 let isCommutable = true;
268 // Generic signed division.
269 def G_SDIV : GenericInstruction {
270 let OutOperandList = (outs type0:$dst);
271 let InOperandList = (ins type0:$src1, type0:$src2);
272 let hasSideEffects = false;
273 let isCommutable = false;
276 // Generic unsigned division.
277 def G_UDIV : GenericInstruction {
278 let OutOperandList = (outs type0:$dst);
279 let InOperandList = (ins type0:$src1, type0:$src2);
280 let hasSideEffects = false;
281 let isCommutable = false;
284 // Generic signed remainder.
285 def G_SREM : GenericInstruction {
286 let OutOperandList = (outs type0:$dst);
287 let InOperandList = (ins type0:$src1, type0:$src2);
288 let hasSideEffects = false;
289 let isCommutable = false;
292 // Generic unsigned remainder.
293 def G_UREM : GenericInstruction {
294 let OutOperandList = (outs type0:$dst);
295 let InOperandList = (ins type0:$src1, type0:$src2);
296 let hasSideEffects = false;
297 let isCommutable = false;
300 // Generic signed division and remainder.
301 def G_SDIVREM : GenericInstruction {
302 let OutOperandList = (outs type0:$div, type0:$rem);
303 let InOperandList = (ins type0:$src1, type0:$src2);
304 let hasSideEffects = false;
305 let isCommutable = false;
308 // Generic unsigned division and remainder.
309 def G_UDIVREM : GenericInstruction {
310 let OutOperandList = (outs type0:$div, type0:$rem);
311 let InOperandList = (ins type0:$src1, type0:$src2);
312 let hasSideEffects = false;
313 let isCommutable = false;
316 // Generic bitwise and.
317 def G_AND : GenericInstruction {
318 let OutOperandList = (outs type0:$dst);
319 let InOperandList = (ins type0:$src1, type0:$src2);
320 let hasSideEffects = false;
321 let isCommutable = true;
324 // Generic bitwise or.
325 def G_OR : GenericInstruction {
326 let OutOperandList = (outs type0:$dst);
327 let InOperandList = (ins type0:$src1, type0:$src2);
328 let hasSideEffects = false;
329 let isCommutable = true;
332 // Generic bitwise xor.
333 def G_XOR : GenericInstruction {
334 let OutOperandList = (outs type0:$dst);
335 let InOperandList = (ins type0:$src1, type0:$src2);
336 let hasSideEffects = false;
337 let isCommutable = true;
340 // Generic left-shift.
341 def G_SHL : GenericInstruction {
342 let OutOperandList = (outs type0:$dst);
343 let InOperandList = (ins type0:$src1, type1:$src2);
344 let hasSideEffects = false;
347 // Generic logical right-shift.
348 def G_LSHR : GenericInstruction {
349 let OutOperandList = (outs type0:$dst);
350 let InOperandList = (ins type0:$src1, type1:$src2);
351 let hasSideEffects = false;
354 // Generic arithmetic right-shift.
355 def G_ASHR : GenericInstruction {
356 let OutOperandList = (outs type0:$dst);
357 let InOperandList = (ins type0:$src1, type1:$src2);
358 let hasSideEffects = false;
361 /// Funnel 'double' shifts take 3 operands, 2 inputs and the shift amount.
362 /// fshl(X,Y,Z): (X << (Z % bitwidth)) | (Y >> (bitwidth - (Z % bitwidth)))
363 def G_FSHL : GenericInstruction {
364 let OutOperandList = (outs type0:$dst);
365 let InOperandList = (ins type0:$src1, type0:$src2, type1:$src3);
366 let hasSideEffects = false;
369 /// Funnel 'double' shifts take 3 operands, 2 inputs and the shift amount.
370 /// fshr(X,Y,Z): (X << (bitwidth - (Z % bitwidth))) | (Y >> (Z % bitwidth))
371 def G_FSHR : GenericInstruction {
372 let OutOperandList = (outs type0:$dst);
373 let InOperandList = (ins type0:$src1, type0:$src2, type1:$src3);
374 let hasSideEffects = false;
377 /// Rotate bits right.
378 def G_ROTR : GenericInstruction {
379 let OutOperandList = (outs type0:$dst);
380 let InOperandList = (ins type0:$src1, type1:$src2);
381 let hasSideEffects = false;
384 /// Rotate bits left.
385 def G_ROTL : GenericInstruction {
386 let OutOperandList = (outs type0:$dst);
387 let InOperandList = (ins type0:$src1, type1:$src2);
388 let hasSideEffects = false;
391 // Generic integer comparison.
392 def G_ICMP : GenericInstruction {
393 let OutOperandList = (outs type0:$dst);
394 let InOperandList = (ins unknown:$tst, type1:$src1, type1:$src2);
395 let hasSideEffects = false;
398 // Generic floating-point comparison.
399 def G_FCMP : GenericInstruction {
400 let OutOperandList = (outs type0:$dst);
401 let InOperandList = (ins unknown:$tst, type1:$src1, type1:$src2);
402 let hasSideEffects = false;
406 def G_SELECT : GenericInstruction {
407 let OutOperandList = (outs type0:$dst);
408 let InOperandList = (ins type1:$tst, type0:$src1, type0:$src2);
409 let hasSideEffects = false;
412 // Generic pointer offset.
413 def G_PTR_ADD : GenericInstruction {
414 let OutOperandList = (outs type0:$dst);
415 let InOperandList = (ins type0:$src1, type1:$src2);
416 let hasSideEffects = false;
419 // Generic pointer mask. type1 should be an integer with the same
420 // bitwidth as the pointer type.
421 def G_PTRMASK : GenericInstruction {
422 let OutOperandList = (outs ptype0:$dst);
423 let InOperandList = (ins ptype0:$src, type1:$bits);
424 let hasSideEffects = false;
427 // Generic signed integer minimum.
428 def G_SMIN : GenericInstruction {
429 let OutOperandList = (outs type0:$dst);
430 let InOperandList = (ins type0:$src1, type0:$src2);
431 let hasSideEffects = false;
432 let isCommutable = true;
435 // Generic signed integer maximum.
436 def G_SMAX : GenericInstruction {
437 let OutOperandList = (outs type0:$dst);
438 let InOperandList = (ins type0:$src1, type0:$src2);
439 let hasSideEffects = false;
440 let isCommutable = true;
443 // Generic unsigned integer minimum.
444 def G_UMIN : GenericInstruction {
445 let OutOperandList = (outs type0:$dst);
446 let InOperandList = (ins type0:$src1, type0:$src2);
447 let hasSideEffects = false;
448 let isCommutable = true;
451 // Generic unsigned integer maximum.
452 def G_UMAX : GenericInstruction {
453 let OutOperandList = (outs type0:$dst);
454 let InOperandList = (ins type0:$src1, type0:$src2);
455 let hasSideEffects = false;
456 let isCommutable = true;
459 // Generic integer absolute value.
460 def G_ABS : GenericInstruction {
461 let OutOperandList = (outs type0:$dst);
462 let InOperandList = (ins type0:$src);
463 let hasSideEffects = false;
466 //------------------------------------------------------------------------------
468 //------------------------------------------------------------------------------
470 // Generic unsigned addition producing a carry flag.
471 def G_UADDO : GenericInstruction {
472 let OutOperandList = (outs type0:$dst, type1:$carry_out);
473 let InOperandList = (ins type0:$src1, type0:$src2);
474 let hasSideEffects = false;
475 let isCommutable = true;
478 // Generic unsigned addition consuming and producing a carry flag.
479 def G_UADDE : GenericInstruction {
480 let OutOperandList = (outs type0:$dst, type1:$carry_out);
481 let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
482 let hasSideEffects = false;
485 // Generic signed addition producing a carry flag.
486 def G_SADDO : GenericInstruction {
487 let OutOperandList = (outs type0:$dst, type1:$carry_out);
488 let InOperandList = (ins type0:$src1, type0:$src2);
489 let hasSideEffects = false;
490 let isCommutable = true;
493 // Generic signed addition consuming and producing a carry flag.
494 def G_SADDE : GenericInstruction {
495 let OutOperandList = (outs type0:$dst, type1:$carry_out);
496 let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
497 let hasSideEffects = false;
500 // Generic unsigned subtraction producing a carry flag.
501 def G_USUBO : GenericInstruction {
502 let OutOperandList = (outs type0:$dst, type1:$carry_out);
503 let InOperandList = (ins type0:$src1, type0:$src2);
504 let hasSideEffects = false;
506 // Generic unsigned subtraction consuming and producing a carry flag.
507 def G_USUBE : GenericInstruction {
508 let OutOperandList = (outs type0:$dst, type1:$carry_out);
509 let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
510 let hasSideEffects = false;
513 // Generic signed subtraction producing a carry flag.
514 def G_SSUBO : GenericInstruction {
515 let OutOperandList = (outs type0:$dst, type1:$carry_out);
516 let InOperandList = (ins type0:$src1, type0:$src2);
517 let hasSideEffects = false;
520 // Generic signed subtraction consuming and producing a carry flag.
521 def G_SSUBE : GenericInstruction {
522 let OutOperandList = (outs type0:$dst, type1:$carry_out);
523 let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
524 let hasSideEffects = false;
527 // Generic unsigned multiplication producing a carry flag.
528 def G_UMULO : GenericInstruction {
529 let OutOperandList = (outs type0:$dst, type1:$carry_out);
530 let InOperandList = (ins type0:$src1, type0:$src2);
531 let hasSideEffects = false;
532 let isCommutable = true;
535 // Generic signed multiplication producing a carry flag.
536 def G_SMULO : GenericInstruction {
537 let OutOperandList = (outs type0:$dst, type1:$carry_out);
538 let InOperandList = (ins type0:$src1, type0:$src2);
539 let hasSideEffects = false;
540 let isCommutable = true;
543 // Multiply two numbers at twice the incoming bit width (unsigned) and return
544 // the high half of the result.
545 def G_UMULH : GenericInstruction {
546 let OutOperandList = (outs type0:$dst);
547 let InOperandList = (ins type0:$src1, type0:$src2);
548 let hasSideEffects = false;
549 let isCommutable = true;
552 // Multiply two numbers at twice the incoming bit width (signed) and return
553 // the high half of the result.
554 def G_SMULH : GenericInstruction {
555 let OutOperandList = (outs type0:$dst);
556 let InOperandList = (ins type0:$src1, type0:$src2);
557 let hasSideEffects = false;
558 let isCommutable = true;
561 //------------------------------------------------------------------------------
563 //------------------------------------------------------------------------------
565 // Generic saturating unsigned addition.
566 def G_UADDSAT : GenericInstruction {
567 let OutOperandList = (outs type0:$dst);
568 let InOperandList = (ins type0:$src1, type0:$src2);
569 let hasSideEffects = false;
570 let isCommutable = true;
573 // Generic saturating signed addition.
574 def G_SADDSAT : GenericInstruction {
575 let OutOperandList = (outs type0:$dst);
576 let InOperandList = (ins type0:$src1, type0:$src2);
577 let hasSideEffects = false;
578 let isCommutable = true;
581 // Generic saturating unsigned subtraction.
582 def G_USUBSAT : GenericInstruction {
583 let OutOperandList = (outs type0:$dst);
584 let InOperandList = (ins type0:$src1, type0:$src2);
585 let hasSideEffects = false;
586 let isCommutable = false;
589 // Generic saturating signed subtraction.
590 def G_SSUBSAT : GenericInstruction {
591 let OutOperandList = (outs type0:$dst);
592 let InOperandList = (ins type0:$src1, type0:$src2);
593 let hasSideEffects = false;
594 let isCommutable = false;
597 // Generic saturating unsigned left shift.
598 def G_USHLSAT : GenericInstruction {
599 let OutOperandList = (outs type0:$dst);
600 let InOperandList = (ins type0:$src1, type1:$src2);
601 let hasSideEffects = false;
602 let isCommutable = false;
605 // Generic saturating signed left shift.
606 def G_SSHLSAT : GenericInstruction {
607 let OutOperandList = (outs type0:$dst);
608 let InOperandList = (ins type0:$src1, type1:$src2);
609 let hasSideEffects = false;
610 let isCommutable = false;
613 /// RESULT = [US]MULFIX(LHS, RHS, SCALE) - Perform fixed point
614 /// multiplication on 2 integers with the same width and scale. SCALE
615 /// represents the scale of both operands as fixed point numbers. This
616 /// SCALE parameter must be a constant integer. A scale of zero is
617 /// effectively performing multiplication on 2 integers.
618 def G_SMULFIX : GenericInstruction {
619 let OutOperandList = (outs type0:$dst);
620 let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
621 let hasSideEffects = false;
622 let isCommutable = true;
625 def G_UMULFIX : GenericInstruction {
626 let OutOperandList = (outs type0:$dst);
627 let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
628 let hasSideEffects = false;
629 let isCommutable = true;
632 /// Same as the corresponding unsaturated fixed point instructions, but the
633 /// result is clamped between the min and max values representable by the
634 /// bits of the first 2 operands.
635 def G_SMULFIXSAT : GenericInstruction {
636 let OutOperandList = (outs type0:$dst);
637 let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
638 let hasSideEffects = false;
639 let isCommutable = true;
642 def G_UMULFIXSAT : GenericInstruction {
643 let OutOperandList = (outs type0:$dst);
644 let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
645 let hasSideEffects = false;
646 let isCommutable = true;
649 /// RESULT = [US]DIVFIX(LHS, RHS, SCALE) - Perform fixed point division on
650 /// 2 integers with the same width and scale. SCALE represents the scale
651 /// of both operands as fixed point numbers. This SCALE parameter must be a
652 /// constant integer.
653 def G_SDIVFIX : GenericInstruction {
654 let OutOperandList = (outs type0:$dst);
655 let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
656 let hasSideEffects = false;
657 let isCommutable = false;
660 def G_UDIVFIX : GenericInstruction {
661 let OutOperandList = (outs type0:$dst);
662 let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
663 let hasSideEffects = false;
664 let isCommutable = false;
667 /// Same as the corresponding unsaturated fixed point instructions,
668 /// but the result is clamped between the min and max values
669 /// representable by the bits of the first 2 operands.
670 def G_SDIVFIXSAT : GenericInstruction {
671 let OutOperandList = (outs type0:$dst);
672 let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
673 let hasSideEffects = false;
674 let isCommutable = false;
677 def G_UDIVFIXSAT : GenericInstruction {
678 let OutOperandList = (outs type0:$dst);
679 let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
680 let hasSideEffects = false;
681 let isCommutable = false;
684 //------------------------------------------------------------------------------
685 // Floating Point Unary Ops.
686 //------------------------------------------------------------------------------
688 def G_FNEG : GenericInstruction {
689 let OutOperandList = (outs type0:$dst);
690 let InOperandList = (ins type0:$src);
691 let hasSideEffects = false;
694 def G_FPEXT : GenericInstruction {
695 let OutOperandList = (outs type0:$dst);
696 let InOperandList = (ins type1:$src);
697 let hasSideEffects = false;
700 def G_FPTRUNC : GenericInstruction {
701 let OutOperandList = (outs type0:$dst);
702 let InOperandList = (ins type1:$src);
703 let hasSideEffects = false;
706 def G_FPTOSI : GenericInstruction {
707 let OutOperandList = (outs type0:$dst);
708 let InOperandList = (ins type1:$src);
709 let hasSideEffects = false;
712 def G_FPTOUI : GenericInstruction {
713 let OutOperandList = (outs type0:$dst);
714 let InOperandList = (ins type1:$src);
715 let hasSideEffects = false;
718 def G_SITOFP : GenericInstruction {
719 let OutOperandList = (outs type0:$dst);
720 let InOperandList = (ins type1:$src);
721 let hasSideEffects = false;
724 def G_UITOFP : GenericInstruction {
725 let OutOperandList = (outs type0:$dst);
726 let InOperandList = (ins type1:$src);
727 let hasSideEffects = false;
730 def G_FABS : GenericInstruction {
731 let OutOperandList = (outs type0:$dst);
732 let InOperandList = (ins type0:$src);
733 let hasSideEffects = false;
736 def G_FCOPYSIGN : GenericInstruction {
737 let OutOperandList = (outs type0:$dst);
738 let InOperandList = (ins type0:$src0, type1:$src1);
739 let hasSideEffects = false;
742 def G_FCANONICALIZE : GenericInstruction {
743 let OutOperandList = (outs type0:$dst);
744 let InOperandList = (ins type0:$src);
745 let hasSideEffects = false;
748 // FMINNUM/FMAXNUM - Perform floating-point minimum or maximum on two
751 // In the case where a single input is a NaN (either signaling or quiet),
752 // the non-NaN input is returned.
754 // The return value of (FMINNUM 0.0, -0.0) could be either 0.0 or -0.0.
755 def G_FMINNUM : GenericInstruction {
756 let OutOperandList = (outs type0:$dst);
757 let InOperandList = (ins type0:$src1, type0:$src2);
758 let hasSideEffects = false;
759 let isCommutable = true;
762 def G_FMAXNUM : GenericInstruction {
763 let OutOperandList = (outs type0:$dst);
764 let InOperandList = (ins type0:$src1, type0:$src2);
765 let hasSideEffects = false;
766 let isCommutable = true;
769 // FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimum or maximum on
770 // two values, following the IEEE-754 2008 definition. This differs from
771 // FMINNUM/FMAXNUM in the handling of signaling NaNs. If one input is a
772 // signaling NaN, returns a quiet NaN.
773 def G_FMINNUM_IEEE : GenericInstruction {
774 let OutOperandList = (outs type0:$dst);
775 let InOperandList = (ins type0:$src1, type0:$src2);
776 let hasSideEffects = false;
777 let isCommutable = true;
780 def G_FMAXNUM_IEEE : GenericInstruction {
781 let OutOperandList = (outs type0:$dst);
782 let InOperandList = (ins type0:$src1, type0:$src2);
783 let hasSideEffects = false;
784 let isCommutable = true;
787 // FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0
788 // as less than 0.0. While FMINNUM_IEEE/FMAXNUM_IEEE follow IEEE 754-2008
789 // semantics, FMINIMUM/FMAXIMUM follow IEEE 754-2018 draft semantics.
790 def G_FMINIMUM : GenericInstruction {
791 let OutOperandList = (outs type0:$dst);
792 let InOperandList = (ins type0:$src1, type0:$src2);
793 let hasSideEffects = false;
794 let isCommutable = true;
797 def G_FMAXIMUM : GenericInstruction {
798 let OutOperandList = (outs type0:$dst);
799 let InOperandList = (ins type0:$src1, type0:$src2);
800 let hasSideEffects = false;
801 let isCommutable = true;
804 //------------------------------------------------------------------------------
805 // Floating Point Binary ops.
806 //------------------------------------------------------------------------------
808 // Generic FP addition.
809 def G_FADD : GenericInstruction {
810 let OutOperandList = (outs type0:$dst);
811 let InOperandList = (ins type0:$src1, type0:$src2);
812 let hasSideEffects = false;
813 let isCommutable = true;
816 // Generic FP subtraction.
817 def G_FSUB : GenericInstruction {
818 let OutOperandList = (outs type0:$dst);
819 let InOperandList = (ins type0:$src1, type0:$src2);
820 let hasSideEffects = false;
821 let isCommutable = false;
824 // Generic FP multiplication.
825 def G_FMUL : GenericInstruction {
826 let OutOperandList = (outs type0:$dst);
827 let InOperandList = (ins type0:$src1, type0:$src2);
828 let hasSideEffects = false;
829 let isCommutable = true;
832 // Generic fused multiply-add instruction.
833 // Behaves like llvm fma intrinsic ie src1 * src2 + src3
834 def G_FMA : GenericInstruction {
835 let OutOperandList = (outs type0:$dst);
836 let InOperandList = (ins type0:$src1, type0:$src2, type0:$src3);
837 let hasSideEffects = false;
838 let isCommutable = false;
841 /// Generic FP multiply and add. Perform a * b + c, while getting the
842 /// same result as the separately rounded operations, unlike G_FMA.
843 def G_FMAD : GenericInstruction {
844 let OutOperandList = (outs type0:$dst);
845 let InOperandList = (ins type0:$src1, type0:$src2, type0:$src3);
846 let hasSideEffects = false;
847 let isCommutable = false;
850 // Generic FP division.
851 def G_FDIV : GenericInstruction {
852 let OutOperandList = (outs type0:$dst);
853 let InOperandList = (ins type0:$src1, type0:$src2);
854 let hasSideEffects = false;
857 // Generic FP remainder.
858 def G_FREM : GenericInstruction {
859 let OutOperandList = (outs type0:$dst);
860 let InOperandList = (ins type0:$src1, type0:$src2);
861 let hasSideEffects = false;
864 // Floating point exponentiation.
865 def G_FPOW : GenericInstruction {
866 let OutOperandList = (outs type0:$dst);
867 let InOperandList = (ins type0:$src1, type0:$src2);
868 let hasSideEffects = false;
871 // Floating point exponentiation, with an integer power.
872 def G_FPOWI : GenericInstruction {
873 let OutOperandList = (outs type0:$dst);
874 let InOperandList = (ins type0:$src0, type1:$src1);
875 let hasSideEffects = false;
878 // Floating point base-e exponential of a value.
879 def G_FEXP : GenericInstruction {
880 let OutOperandList = (outs type0:$dst);
881 let InOperandList = (ins type0:$src1);
882 let hasSideEffects = false;
885 // Floating point base-2 exponential of a value.
886 def G_FEXP2 : GenericInstruction {
887 let OutOperandList = (outs type0:$dst);
888 let InOperandList = (ins type0:$src1);
889 let hasSideEffects = false;
892 // Floating point base-e logarithm of a value.
893 def G_FLOG : GenericInstruction {
894 let OutOperandList = (outs type0:$dst);
895 let InOperandList = (ins type0:$src1);
896 let hasSideEffects = false;
899 // Floating point base-2 logarithm of a value.
900 def G_FLOG2 : GenericInstruction {
901 let OutOperandList = (outs type0:$dst);
902 let InOperandList = (ins type0:$src1);
903 let hasSideEffects = false;
906 // Floating point base-10 logarithm of a value.
907 def G_FLOG10 : GenericInstruction {
908 let OutOperandList = (outs type0:$dst);
909 let InOperandList = (ins type0:$src1);
910 let hasSideEffects = false;
913 // Floating point ceiling of a value.
914 def G_FCEIL : GenericInstruction {
915 let OutOperandList = (outs type0:$dst);
916 let InOperandList = (ins type0:$src1);
917 let hasSideEffects = false;
920 // Floating point cosine of a value.
921 def G_FCOS : GenericInstruction {
922 let OutOperandList = (outs type0:$dst);
923 let InOperandList = (ins type0:$src1);
924 let hasSideEffects = false;
927 // Floating point sine of a value.
928 def G_FSIN : GenericInstruction {
929 let OutOperandList = (outs type0:$dst);
930 let InOperandList = (ins type0:$src1);
931 let hasSideEffects = false;
934 // Floating point square root of a value.
935 // This returns NaN for negative nonzero values.
936 // NOTE: Unlike libm sqrt(), this never sets errno. In all other respects it's
938 def G_FSQRT : GenericInstruction {
939 let OutOperandList = (outs type0:$dst);
940 let InOperandList = (ins type0:$src1);
941 let hasSideEffects = false;
944 // Floating point floor of a value.
945 def G_FFLOOR : GenericInstruction {
946 let OutOperandList = (outs type0:$dst);
947 let InOperandList = (ins type0:$src1);
948 let hasSideEffects = false;
951 // Floating point round to next integer.
952 def G_FRINT : GenericInstruction {
953 let OutOperandList = (outs type0:$dst);
954 let InOperandList = (ins type0:$src1);
955 let hasSideEffects = false;
958 // Floating point round to the nearest integer.
959 def G_FNEARBYINT : GenericInstruction {
960 let OutOperandList = (outs type0:$dst);
961 let InOperandList = (ins type0:$src1);
962 let hasSideEffects = false;
965 //------------------------------------------------------------------------------
966 // Opcodes for LLVM Intrinsics
967 //------------------------------------------------------------------------------
968 def G_INTRINSIC_TRUNC : GenericInstruction {
969 let OutOperandList = (outs type0:$dst);
970 let InOperandList = (ins type0:$src1);
971 let hasSideEffects = false;
974 def G_INTRINSIC_ROUND : GenericInstruction {
975 let OutOperandList = (outs type0:$dst);
976 let InOperandList = (ins type0:$src1);
977 let hasSideEffects = false;
980 def G_INTRINSIC_LRINT : GenericInstruction {
981 let OutOperandList = (outs type0:$dst);
982 let InOperandList = (ins type1:$src);
983 let hasSideEffects = false;
986 def G_INTRINSIC_ROUNDEVEN : GenericInstruction {
987 let OutOperandList = (outs type0:$dst);
988 let InOperandList = (ins type0:$src1);
989 let hasSideEffects = false;
992 def G_READCYCLECOUNTER : GenericInstruction {
993 let OutOperandList = (outs type0:$dst);
994 let InOperandList = (ins);
995 let hasSideEffects = true;
998 //------------------------------------------------------------------------------
1000 //------------------------------------------------------------------------------
1002 // Generic load. Expects a MachineMemOperand in addition to explicit
1003 // operands. If the result size is larger than the memory size, the
1004 // high bits are undefined. If the result is a vector type and larger
1005 // than the memory size, the high elements are undefined (i.e. this is
1006 // not a per-element, vector anyextload)
1007 def G_LOAD : GenericInstruction {
1008 let OutOperandList = (outs type0:$dst);
1009 let InOperandList = (ins ptype1:$addr);
1010 let hasSideEffects = false;
1014 // Generic sign-extended load. Expects a MachineMemOperand in addition to explicit operands.
1015 def G_SEXTLOAD : GenericInstruction {
1016 let OutOperandList = (outs type0:$dst);
1017 let InOperandList = (ins ptype1:$addr);
1018 let hasSideEffects = false;
1022 // Generic zero-extended load. Expects a MachineMemOperand in addition to explicit operands.
1023 def G_ZEXTLOAD : GenericInstruction {
1024 let OutOperandList = (outs type0:$dst);
1025 let InOperandList = (ins ptype1:$addr);
1026 let hasSideEffects = false;
1030 // Generic indexed load. Combines a GEP with a load. $newaddr is set to $base + $offset.
1031 // If $am is 0 (post-indexed), then the value is loaded from $base; if $am is 1 (pre-indexed)
1032 // then the value is loaded from $newaddr.
1033 def G_INDEXED_LOAD : GenericInstruction {
1034 let OutOperandList = (outs type0:$dst, ptype1:$newaddr);
1035 let InOperandList = (ins ptype1:$base, type2:$offset, unknown:$am);
1036 let hasSideEffects = false;
1040 // Same as G_INDEXED_LOAD except that the load performed is sign-extending, as with G_SEXTLOAD.
1041 def G_INDEXED_SEXTLOAD : GenericInstruction {
1042 let OutOperandList = (outs type0:$dst, ptype1:$newaddr);
1043 let InOperandList = (ins ptype1:$base, type2:$offset, unknown:$am);
1044 let hasSideEffects = false;
1048 // Same as G_INDEXED_LOAD except that the load performed is zero-extending, as with G_ZEXTLOAD.
1049 def G_INDEXED_ZEXTLOAD : GenericInstruction {
1050 let OutOperandList = (outs type0:$dst, ptype1:$newaddr);
1051 let InOperandList = (ins ptype1:$base, type2:$offset, unknown:$am);
1052 let hasSideEffects = false;
1056 // Generic store. Expects a MachineMemOperand in addition to explicit operands.
1057 def G_STORE : GenericInstruction {
1058 let OutOperandList = (outs);
1059 let InOperandList = (ins type0:$src, ptype1:$addr);
1060 let hasSideEffects = false;
1061 let mayStore = true;
1064 // Combines a store with a GEP. See description of G_INDEXED_LOAD for indexing behaviour.
1065 def G_INDEXED_STORE : GenericInstruction {
1066 let OutOperandList = (outs ptype0:$newaddr);
1067 let InOperandList = (ins type1:$src, ptype0:$base, ptype2:$offset,
1069 let hasSideEffects = false;
1070 let mayStore = true;
1073 // Generic atomic cmpxchg with internal success check. Expects a
1074 // MachineMemOperand in addition to explicit operands.
1075 def G_ATOMIC_CMPXCHG_WITH_SUCCESS : GenericInstruction {
1076 let OutOperandList = (outs type0:$oldval, type1:$success);
1077 let InOperandList = (ins type2:$addr, type0:$cmpval, type0:$newval);
1078 let hasSideEffects = false;
1080 let mayStore = true;
1083 // Generic atomic cmpxchg. Expects a MachineMemOperand in addition to explicit
1085 def G_ATOMIC_CMPXCHG : GenericInstruction {
1086 let OutOperandList = (outs type0:$oldval);
1087 let InOperandList = (ins ptype1:$addr, type0:$cmpval, type0:$newval);
1088 let hasSideEffects = false;
1090 let mayStore = true;
1093 // Generic atomicrmw. Expects a MachineMemOperand in addition to explicit
1095 class G_ATOMICRMW_OP : GenericInstruction {
1096 let OutOperandList = (outs type0:$oldval);
1097 let InOperandList = (ins ptype1:$addr, type0:$val);
1098 let hasSideEffects = false;
1100 let mayStore = true;
1103 def G_ATOMICRMW_XCHG : G_ATOMICRMW_OP;
1104 def G_ATOMICRMW_ADD : G_ATOMICRMW_OP;
1105 def G_ATOMICRMW_SUB : G_ATOMICRMW_OP;
1106 def G_ATOMICRMW_AND : G_ATOMICRMW_OP;
1107 def G_ATOMICRMW_NAND : G_ATOMICRMW_OP;
1108 def G_ATOMICRMW_OR : G_ATOMICRMW_OP;
1109 def G_ATOMICRMW_XOR : G_ATOMICRMW_OP;
1110 def G_ATOMICRMW_MAX : G_ATOMICRMW_OP;
1111 def G_ATOMICRMW_MIN : G_ATOMICRMW_OP;
1112 def G_ATOMICRMW_UMAX : G_ATOMICRMW_OP;
1113 def G_ATOMICRMW_UMIN : G_ATOMICRMW_OP;
1114 def G_ATOMICRMW_FADD : G_ATOMICRMW_OP;
1115 def G_ATOMICRMW_FSUB : G_ATOMICRMW_OP;
1117 def G_FENCE : GenericInstruction {
1118 let OutOperandList = (outs);
1119 let InOperandList = (ins i32imm:$ordering, i32imm:$scope);
1120 let hasSideEffects = true;
1123 //------------------------------------------------------------------------------
1125 //------------------------------------------------------------------------------
1127 // Extract a register of the specified size, starting from the block given by
1128 // index. This will almost certainly be mapped to sub-register COPYs after
1129 // register banks have been selected.
1130 def G_EXTRACT : GenericInstruction {
1131 let OutOperandList = (outs type0:$res);
1132 let InOperandList = (ins type1:$src, untyped_imm_0:$offset);
1133 let hasSideEffects = false;
1136 // Extract multiple registers specified size, starting from blocks given by
1137 // indexes. This will almost certainly be mapped to sub-register COPYs after
1138 // register banks have been selected.
1139 // The output operands are always ordered from lowest bits to highest:
1140 // %bits_0_7:(s8), %bits_8_15:(s8),
1141 // %bits_16_23:(s8), %bits_24_31:(s8) = G_UNMERGE_VALUES %0:(s32)
1142 def G_UNMERGE_VALUES : GenericInstruction {
1143 let OutOperandList = (outs type0:$dst0, variable_ops);
1144 let InOperandList = (ins type1:$src);
1145 let hasSideEffects = false;
1148 // Insert a smaller register into a larger one at the specified bit-index.
1149 def G_INSERT : GenericInstruction {
1150 let OutOperandList = (outs type0:$dst);
1151 let InOperandList = (ins type0:$src, type1:$op, untyped_imm_0:$offset);
1152 let hasSideEffects = false;
1155 // Concatenate multiple registers of the same size into a wider register.
1156 // The input operands are always ordered from lowest bits to highest:
1157 // %0:(s32) = G_MERGE_VALUES %bits_0_7:(s8), %bits_8_15:(s8),
1158 // %bits_16_23:(s8), %bits_24_31:(s8)
1159 def G_MERGE_VALUES : GenericInstruction {
1160 let OutOperandList = (outs type0:$dst);
1161 let InOperandList = (ins type1:$src0, variable_ops);
1162 let hasSideEffects = false;
1165 /// Create a vector from multiple scalar registers. No implicit
1166 /// conversion is performed (i.e. the result element type must be the
1167 /// same as all source operands)
1168 def G_BUILD_VECTOR : GenericInstruction {
1169 let OutOperandList = (outs type0:$dst);
1170 let InOperandList = (ins type1:$src0, variable_ops);
1171 let hasSideEffects = false;
1174 /// Like G_BUILD_VECTOR, but truncates the larger operand types to fit the
1175 /// destination vector elt type.
1176 def G_BUILD_VECTOR_TRUNC : GenericInstruction {
1177 let OutOperandList = (outs type0:$dst);
1178 let InOperandList = (ins type1:$src0, variable_ops);
1179 let hasSideEffects = false;
1182 /// Create a vector by concatenating vectors together.
1183 def G_CONCAT_VECTORS : GenericInstruction {
1184 let OutOperandList = (outs type0:$dst);
1185 let InOperandList = (ins type1:$src0, variable_ops);
1186 let hasSideEffects = false;
1189 // Intrinsic without side effects.
1190 def G_INTRINSIC : GenericInstruction {
1191 let OutOperandList = (outs);
1192 let InOperandList = (ins unknown:$intrin, variable_ops);
1193 let hasSideEffects = false;
1195 // Conservatively assume this is convergent. If there turnes out to
1196 // be a need, there should be separate convergent intrinsic opcodes.
1197 let isConvergent = 1;
1200 // Intrinsic with side effects.
1201 def G_INTRINSIC_W_SIDE_EFFECTS : GenericInstruction {
1202 let OutOperandList = (outs);
1203 let InOperandList = (ins unknown:$intrin, variable_ops);
1204 let hasSideEffects = true;
1206 let mayStore = true;
1208 // Conservatively assume this is convergent. If there turnes out to
1209 // be a need, there should be separate convergent intrinsic opcodes.
1210 let isConvergent = true;
1213 //------------------------------------------------------------------------------
1215 //------------------------------------------------------------------------------
1217 // Generic unconditional branch.
1218 def G_BR : GenericInstruction {
1219 let OutOperandList = (outs);
1220 let InOperandList = (ins unknown:$src1);
1221 let hasSideEffects = false;
1222 let isBranch = true;
1223 let isTerminator = true;
1224 let isBarrier = true;
1227 // Generic conditional branch.
1228 def G_BRCOND : GenericInstruction {
1229 let OutOperandList = (outs);
1230 let InOperandList = (ins type0:$tst, unknown:$truebb);
1231 let hasSideEffects = false;
1232 let isBranch = true;
1233 let isTerminator = true;
1236 // Generic indirect branch.
1237 def G_BRINDIRECT : GenericInstruction {
1238 let OutOperandList = (outs);
1239 let InOperandList = (ins type0:$src1);
1240 let hasSideEffects = false;
1241 let isBranch = true;
1242 let isTerminator = true;
1243 let isBarrier = true;
1244 let isIndirectBranch = true;
1247 // Generic branch to jump table entry
1248 def G_BRJT : GenericInstruction {
1249 let OutOperandList = (outs);
1250 let InOperandList = (ins ptype0:$tbl, unknown:$jti, type1:$idx);
1251 let hasSideEffects = false;
1252 let isBranch = true;
1253 let isTerminator = true;
1254 let isBarrier = true;
1255 let isIndirectBranch = true;
1258 def G_READ_REGISTER : GenericInstruction {
1259 let OutOperandList = (outs type0:$dst);
1260 let InOperandList = (ins unknown:$register);
1261 let hasSideEffects = true;
1263 // Assume convergent. It's probably not worth the effort of somehow
1264 // modeling convergent and nonconvergent register accesses.
1265 let isConvergent = true;
1268 def G_WRITE_REGISTER : GenericInstruction {
1269 let OutOperandList = (outs);
1270 let InOperandList = (ins unknown:$register, type0:$value);
1271 let hasSideEffects = true;
1273 // Assume convergent. It's probably not worth the effort of somehow
1274 // modeling convergent and nonconvergent register accesses.
1275 let isConvergent = true;
1278 //------------------------------------------------------------------------------
1280 //------------------------------------------------------------------------------
1282 // Generic insertelement.
1283 def G_INSERT_VECTOR_ELT : GenericInstruction {
1284 let OutOperandList = (outs type0:$dst);
1285 let InOperandList = (ins type0:$src, type1:$elt, type2:$idx);
1286 let hasSideEffects = false;
1289 // Generic extractelement.
1290 def G_EXTRACT_VECTOR_ELT : GenericInstruction {
1291 let OutOperandList = (outs type0:$dst);
1292 let InOperandList = (ins type1:$src, type2:$idx);
1293 let hasSideEffects = false;
1296 // Generic shufflevector.
1298 // The mask operand should be an IR Constant which exactly matches the
1299 // corresponding mask for the IR shufflevector instruction.
1300 def G_SHUFFLE_VECTOR: GenericInstruction {
1301 let OutOperandList = (outs type0:$dst);
1302 let InOperandList = (ins type1:$v1, type1:$v2, unknown:$mask);
1303 let hasSideEffects = false;
1306 //------------------------------------------------------------------------------
1307 // Vector reductions
1308 //------------------------------------------------------------------------------
1310 class VectorReduction : GenericInstruction {
1311 let OutOperandList = (outs type0:$dst);
1312 let InOperandList = (ins type1:$v);
1313 let hasSideEffects = false;
1316 def G_VECREDUCE_SEQ_FADD : GenericInstruction {
1317 let OutOperandList = (outs type0:$dst);
1318 let InOperandList = (ins type1:$acc, type2:$v);
1319 let hasSideEffects = false;
1322 def G_VECREDUCE_SEQ_FMUL : GenericInstruction {
1323 let OutOperandList = (outs type0:$dst);
1324 let InOperandList = (ins type1:$acc, type2:$v);
1325 let hasSideEffects = false;
1328 def G_VECREDUCE_FADD : VectorReduction;
1329 def G_VECREDUCE_FMUL : VectorReduction;
1331 def G_VECREDUCE_FMAX : VectorReduction;
1332 def G_VECREDUCE_FMIN : VectorReduction;
1334 def G_VECREDUCE_ADD : VectorReduction;
1335 def G_VECREDUCE_MUL : VectorReduction;
1336 def G_VECREDUCE_AND : VectorReduction;
1337 def G_VECREDUCE_OR : VectorReduction;
1338 def G_VECREDUCE_XOR : VectorReduction;
1339 def G_VECREDUCE_SMAX : VectorReduction;
1340 def G_VECREDUCE_SMIN : VectorReduction;
1341 def G_VECREDUCE_UMAX : VectorReduction;
1342 def G_VECREDUCE_UMIN : VectorReduction;
1344 //------------------------------------------------------------------------------
1345 // Constrained floating point ops
1346 //------------------------------------------------------------------------------
1348 def G_STRICT_FADD : ConstrainedIntruction<G_FADD>;
1349 def G_STRICT_FSUB : ConstrainedIntruction<G_FSUB>;
1350 def G_STRICT_FMUL : ConstrainedIntruction<G_FMUL>;
1351 def G_STRICT_FDIV : ConstrainedIntruction<G_FDIV>;
1352 def G_STRICT_FREM : ConstrainedIntruction<G_FREM>;
1353 def G_STRICT_FMA : ConstrainedIntruction<G_FMA>;
1354 def G_STRICT_FSQRT : ConstrainedIntruction<G_FSQRT>;
1356 //------------------------------------------------------------------------------
1357 // Memory intrinsics
1358 //------------------------------------------------------------------------------
1360 def G_MEMCPY : GenericInstruction {
1361 let OutOperandList = (outs);
1362 let InOperandList = (ins ptype0:$dst_addr, ptype1:$src_addr, type2:$size, untyped_imm_0:$tailcall);
1363 let hasSideEffects = false;
1365 let mayStore = true;
1368 def G_MEMCPY_INLINE : GenericInstruction {
1369 let OutOperandList = (outs);
1370 let InOperandList = (ins ptype0:$dst_addr, ptype1:$src_addr, type2:$size);
1371 let hasSideEffects = false;
1373 let mayStore = true;
1376 def G_MEMMOVE : GenericInstruction {
1377 let OutOperandList = (outs);
1378 let InOperandList = (ins ptype0:$dst_addr, ptype1:$src_addr, type2:$size, untyped_imm_0:$tailcall);
1379 let hasSideEffects = false;
1381 let mayStore = true;
1384 def G_MEMSET : GenericInstruction {
1385 let OutOperandList = (outs);
1386 let InOperandList = (ins ptype0:$dst_addr, type1:$value, type2:$size, untyped_imm_0:$tailcall);
1387 let hasSideEffects = false;
1388 let mayStore = true;
1391 def G_BZERO : GenericInstruction {
1392 let OutOperandList = (outs);
1393 let InOperandList = (ins ptype0:$dst_addr, type1:$size, untyped_imm_0:$tailcall);
1394 let hasSideEffects = false;
1395 let mayStore = true;
1398 //------------------------------------------------------------------------------
1399 // Bitfield extraction.
1400 //------------------------------------------------------------------------------
1402 // Generic signed bitfield extraction. The operands are in the range
1403 // 0 <= lsb < lsb + width <= src bitwidth, where all values are unsigned.
1404 def G_SBFX : GenericInstruction {
1405 let OutOperandList = (outs type0:$dst);
1406 let InOperandList = (ins type0:$src, type1:$lsb, type1:$width);
1407 let hasSideEffects = false;
1410 // Generic unsigned bitfield extraction. The operands are in the range
1411 // 0 <= lsb < lsb + width <= src bitwidth, where all values are unsigned.
1412 def G_UBFX : GenericInstruction {
1413 let OutOperandList = (outs type0:$dst);
1414 let InOperandList = (ins type0:$src, type1:$lsb, type1:$width);
1415 let hasSideEffects = false;
1418 //------------------------------------------------------------------------------
1419 // Optimization hints
1420 //------------------------------------------------------------------------------
1422 // Asserts that an operation has already been zero-extended from a specific
1424 def G_ASSERT_ZEXT : GenericInstruction {
1425 let OutOperandList = (outs type0:$dst);
1426 let InOperandList = (ins type0:$src, untyped_imm_0:$sz);
1427 let hasSideEffects = false;
1430 // Asserts that an operation has already been sign-extended from a specific
1432 def G_ASSERT_SEXT : GenericInstruction {
1433 let OutOperandList = (outs type0:$dst);
1434 let InOperandList = (ins type0:$src, untyped_imm_0:$sz);
1435 let hasSideEffects = false;
1438 // Asserts that a value has at least the given alignment.
1439 def G_ASSERT_ALIGN : GenericInstruction {
1440 let OutOperandList = (outs type0:$dst);
1441 let InOperandList = (ins type0:$src, untyped_imm_0:$align);
1442 let hasSideEffects = false;