blob: 11fbf621154c20ef7b67547e1c6452b92230ef6f [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===-- GenericOpcodes.td - Opcodes used with GlobalISel ---*- tablegen -*-===//
2//
Andrew Walbran16937d02019-10-22 13:54:20 +01003// 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
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01006//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the generic opcodes used with GlobalISel.
10// After instruction selection, these opcodes should not appear.
11//
12//===----------------------------------------------------------------------===//
13
14//------------------------------------------------------------------------------
15// Unary ops.
16//------------------------------------------------------------------------------
17
18class GenericInstruction : StandardPseudoInstruction;
19
20// Extend the underlying scalar type of an operation, leaving the high bits
21// unspecified.
22def G_ANYEXT : GenericInstruction {
23 let OutOperandList = (outs type0:$dst);
24 let InOperandList = (ins type1:$src);
25 let hasSideEffects = 0;
26}
27
28// Sign extend the underlying scalar type of an operation, copying the sign bit
29// into the newly-created space.
30def G_SEXT : GenericInstruction {
31 let OutOperandList = (outs type0:$dst);
32 let InOperandList = (ins type1:$src);
33 let hasSideEffects = 0;
34}
35
36// Zero extend the underlying scalar type of an operation, putting zero bits
37// into the newly-created space.
38def G_ZEXT : GenericInstruction {
39 let OutOperandList = (outs type0:$dst);
40 let InOperandList = (ins type1:$src);
41 let hasSideEffects = 0;
42}
43
44
45// Truncate the underlying scalar type of an operation. This is equivalent to
46// G_EXTRACT for scalar types, but acts elementwise on vectors.
47def G_TRUNC : GenericInstruction {
48 let OutOperandList = (outs type0:$dst);
49 let InOperandList = (ins type1:$src);
50 let hasSideEffects = 0;
51}
52
53def G_IMPLICIT_DEF : GenericInstruction {
54 let OutOperandList = (outs type0:$dst);
55 let InOperandList = (ins);
56 let hasSideEffects = 0;
57}
58
59def G_PHI : GenericInstruction {
60 let OutOperandList = (outs type0:$dst);
61 let InOperandList = (ins variable_ops);
62 let hasSideEffects = 0;
63}
64
65def G_FRAME_INDEX : GenericInstruction {
66 let OutOperandList = (outs type0:$dst);
67 let InOperandList = (ins unknown:$src2);
68 let hasSideEffects = 0;
69}
70
71def G_GLOBAL_VALUE : GenericInstruction {
72 let OutOperandList = (outs type0:$dst);
73 let InOperandList = (ins unknown:$src);
74 let hasSideEffects = 0;
75}
76
77def G_INTTOPTR : GenericInstruction {
78 let OutOperandList = (outs type0:$dst);
79 let InOperandList = (ins type1:$src);
80 let hasSideEffects = 0;
81}
82
83def G_PTRTOINT : GenericInstruction {
84 let OutOperandList = (outs type0:$dst);
85 let InOperandList = (ins type1:$src);
86 let hasSideEffects = 0;
87}
88
89def G_BITCAST : GenericInstruction {
90 let OutOperandList = (outs type0:$dst);
91 let InOperandList = (ins type1:$src);
92 let hasSideEffects = 0;
93}
94
Andrew Walbran16937d02019-10-22 13:54:20 +010095// Only supports scalar result types
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010096def G_CONSTANT : GenericInstruction {
97 let OutOperandList = (outs type0:$dst);
98 let InOperandList = (ins unknown:$imm);
99 let hasSideEffects = 0;
100}
101
Andrew Walbran16937d02019-10-22 13:54:20 +0100102// Only supports scalar result types
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100103def G_FCONSTANT : GenericInstruction {
104 let OutOperandList = (outs type0:$dst);
105 let InOperandList = (ins unknown:$imm);
106 let hasSideEffects = 0;
107}
108
109def G_VASTART : GenericInstruction {
110 let OutOperandList = (outs);
111 let InOperandList = (ins type0:$list);
112 let hasSideEffects = 0;
113 let mayStore = 1;
114}
115
116def 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;
122}
123
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100124def G_CTLZ : GenericInstruction {
125 let OutOperandList = (outs type0:$dst);
Andrew Walbran16937d02019-10-22 13:54:20 +0100126 let InOperandList = (ins type1:$src);
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100127 let hasSideEffects = 0;
128}
129
130def G_CTLZ_ZERO_UNDEF : GenericInstruction {
131 let OutOperandList = (outs type0:$dst);
Andrew Walbran16937d02019-10-22 13:54:20 +0100132 let InOperandList = (ins type1:$src);
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100133 let hasSideEffects = 0;
134}
135
136def G_CTTZ : GenericInstruction {
137 let OutOperandList = (outs type0:$dst);
Andrew Walbran16937d02019-10-22 13:54:20 +0100138 let InOperandList = (ins type1:$src);
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100139 let hasSideEffects = 0;
140}
141
142def G_CTTZ_ZERO_UNDEF : GenericInstruction {
143 let OutOperandList = (outs type0:$dst);
Andrew Walbran16937d02019-10-22 13:54:20 +0100144 let InOperandList = (ins type1:$src);
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100145 let hasSideEffects = 0;
146}
147
148def G_CTPOP : GenericInstruction {
149 let OutOperandList = (outs type0:$dst);
Andrew Walbran16937d02019-10-22 13:54:20 +0100150 let InOperandList = (ins type1:$src);
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100151 let hasSideEffects = 0;
152}
153
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100154def G_BSWAP : GenericInstruction {
155 let OutOperandList = (outs type0:$dst);
156 let InOperandList = (ins type0:$src);
157 let hasSideEffects = 0;
158}
159
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100160def G_ADDRSPACE_CAST : GenericInstruction {
161 let OutOperandList = (outs type0:$dst);
162 let InOperandList = (ins type1:$src);
163 let hasSideEffects = 0;
164}
165
166def G_BLOCK_ADDR : GenericInstruction {
167 let OutOperandList = (outs type0:$dst);
168 let InOperandList = (ins unknown:$ba);
169 let hasSideEffects = 0;
170}
171
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100172def G_JUMP_TABLE : GenericInstruction {
173 let OutOperandList = (outs type0:$dst);
174 let InOperandList = (ins unknown:$jti);
175 let hasSideEffects = 0;
176}
177
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100178//------------------------------------------------------------------------------
179// Binary ops.
180//------------------------------------------------------------------------------
181
182// Generic addition.
183def G_ADD : GenericInstruction {
184 let OutOperandList = (outs type0:$dst);
185 let InOperandList = (ins type0:$src1, type0:$src2);
186 let hasSideEffects = 0;
187 let isCommutable = 1;
188}
189
190// Generic subtraction.
191def G_SUB : GenericInstruction {
192 let OutOperandList = (outs type0:$dst);
193 let InOperandList = (ins type0:$src1, type0:$src2);
194 let hasSideEffects = 0;
195 let isCommutable = 0;
196}
197
198// Generic multiplication.
199def G_MUL : GenericInstruction {
200 let OutOperandList = (outs type0:$dst);
201 let InOperandList = (ins type0:$src1, type0:$src2);
202 let hasSideEffects = 0;
203 let isCommutable = 1;
204}
205
206// Generic signed division.
207def G_SDIV : GenericInstruction {
208 let OutOperandList = (outs type0:$dst);
209 let InOperandList = (ins type0:$src1, type0:$src2);
210 let hasSideEffects = 0;
211 let isCommutable = 0;
212}
213
214// Generic unsigned division.
215def G_UDIV : GenericInstruction {
216 let OutOperandList = (outs type0:$dst);
217 let InOperandList = (ins type0:$src1, type0:$src2);
218 let hasSideEffects = 0;
219 let isCommutable = 0;
220}
221
222// Generic signed remainder.
223def G_SREM : GenericInstruction {
224 let OutOperandList = (outs type0:$dst);
225 let InOperandList = (ins type0:$src1, type0:$src2);
226 let hasSideEffects = 0;
227 let isCommutable = 0;
228}
229
230// Generic unsigned remainder.
231def G_UREM : GenericInstruction {
232 let OutOperandList = (outs type0:$dst);
233 let InOperandList = (ins type0:$src1, type0:$src2);
234 let hasSideEffects = 0;
235 let isCommutable = 0;
236}
237
238// Generic bitwise and.
239def G_AND : GenericInstruction {
240 let OutOperandList = (outs type0:$dst);
241 let InOperandList = (ins type0:$src1, type0:$src2);
242 let hasSideEffects = 0;
243 let isCommutable = 1;
244}
245
246// Generic bitwise or.
247def G_OR : GenericInstruction {
248 let OutOperandList = (outs type0:$dst);
249 let InOperandList = (ins type0:$src1, type0:$src2);
250 let hasSideEffects = 0;
251 let isCommutable = 1;
252}
253
254// Generic bitwise xor.
255def G_XOR : GenericInstruction {
256 let OutOperandList = (outs type0:$dst);
257 let InOperandList = (ins type0:$src1, type0:$src2);
258 let hasSideEffects = 0;
259 let isCommutable = 1;
260}
261
262// Generic left-shift.
263def G_SHL : GenericInstruction {
264 let OutOperandList = (outs type0:$dst);
Andrew Walbran16937d02019-10-22 13:54:20 +0100265 let InOperandList = (ins type0:$src1, type1:$src2);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100266 let hasSideEffects = 0;
267}
268
269// Generic logical right-shift.
270def G_LSHR : GenericInstruction {
271 let OutOperandList = (outs type0:$dst);
Andrew Walbran16937d02019-10-22 13:54:20 +0100272 let InOperandList = (ins type0:$src1, type1:$src2);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100273 let hasSideEffects = 0;
274}
275
276// Generic arithmetic right-shift.
277def G_ASHR : GenericInstruction {
278 let OutOperandList = (outs type0:$dst);
Andrew Walbran16937d02019-10-22 13:54:20 +0100279 let InOperandList = (ins type0:$src1, type1:$src2);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100280 let hasSideEffects = 0;
281}
282
283// Generic integer comparison.
284def G_ICMP : GenericInstruction {
285 let OutOperandList = (outs type0:$dst);
286 let InOperandList = (ins unknown:$tst, type1:$src1, type1:$src2);
287 let hasSideEffects = 0;
288}
289
290// Generic floating-point comparison.
291def G_FCMP : GenericInstruction {
292 let OutOperandList = (outs type0:$dst);
293 let InOperandList = (ins unknown:$tst, type1:$src1, type1:$src2);
294 let hasSideEffects = 0;
295}
296
297// Generic select
298def G_SELECT : GenericInstruction {
299 let OutOperandList = (outs type0:$dst);
300 let InOperandList = (ins type1:$tst, type0:$src1, type0:$src2);
301 let hasSideEffects = 0;
302}
303
304// Generic pointer offset.
305def G_GEP : GenericInstruction {
306 let OutOperandList = (outs type0:$dst);
307 let InOperandList = (ins type0:$src1, type1:$src2);
308 let hasSideEffects = 0;
309}
310
311def G_PTR_MASK : GenericInstruction {
312 let OutOperandList = (outs type0:$dst);
313 let InOperandList = (ins type0:$src, unknown:$bits);
314 let hasSideEffects = 0;
315}
316
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100317// Generic signed integer minimum.
318def G_SMIN : GenericInstruction {
319 let OutOperandList = (outs type0:$dst);
320 let InOperandList = (ins type0:$src1, type0:$src2);
321 let hasSideEffects = 0;
322 let isCommutable = 1;
323}
324
325// Generic signed integer maximum.
326def G_SMAX : GenericInstruction {
327 let OutOperandList = (outs type0:$dst);
328 let InOperandList = (ins type0:$src1, type0:$src2);
329 let hasSideEffects = 0;
330 let isCommutable = 1;
331}
332
333// Generic unsigned integer minimum.
334def G_UMIN : GenericInstruction {
335 let OutOperandList = (outs type0:$dst);
336 let InOperandList = (ins type0:$src1, type0:$src2);
337 let hasSideEffects = 0;
338 let isCommutable = 1;
339}
340
341// Generic unsigned integer maximum.
342def G_UMAX : GenericInstruction {
343 let OutOperandList = (outs type0:$dst);
344 let InOperandList = (ins type0:$src1, type0:$src2);
345 let hasSideEffects = 0;
346 let isCommutable = 1;
347}
348
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100349//------------------------------------------------------------------------------
350// Overflow ops
351//------------------------------------------------------------------------------
352
Andrew Scull0372a572018-11-16 15:47:06 +0000353// Generic unsigned addition producing a carry flag.
354def G_UADDO : GenericInstruction {
355 let OutOperandList = (outs type0:$dst, type1:$carry_out);
356 let InOperandList = (ins type0:$src1, type0:$src2);
357 let hasSideEffects = 0;
358 let isCommutable = 1;
359}
360
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100361// Generic unsigned addition consuming and producing a carry flag.
362def G_UADDE : GenericInstruction {
363 let OutOperandList = (outs type0:$dst, type1:$carry_out);
364 let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
365 let hasSideEffects = 0;
366}
367
368// Generic signed addition producing a carry flag.
369def G_SADDO : GenericInstruction {
370 let OutOperandList = (outs type0:$dst, type1:$carry_out);
371 let InOperandList = (ins type0:$src1, type0:$src2);
372 let hasSideEffects = 0;
373 let isCommutable = 1;
374}
375
Andrew Scull0372a572018-11-16 15:47:06 +0000376// Generic signed addition consuming and producing a carry flag.
377def G_SADDE : GenericInstruction {
378 let OutOperandList = (outs type0:$dst, type1:$carry_out);
379 let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
380 let hasSideEffects = 0;
381}
382
383// Generic unsigned subtraction producing a carry flag.
384def G_USUBO : GenericInstruction {
385 let OutOperandList = (outs type0:$dst, type1:$carry_out);
386 let InOperandList = (ins type0:$src1, type0:$src2);
387 let hasSideEffects = 0;
388}
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100389// Generic unsigned subtraction consuming and producing a carry flag.
390def G_USUBE : GenericInstruction {
391 let OutOperandList = (outs type0:$dst, type1:$carry_out);
392 let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
393 let hasSideEffects = 0;
394}
395
Andrew Scull0372a572018-11-16 15:47:06 +0000396// Generic signed subtraction producing a carry flag.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100397def G_SSUBO : GenericInstruction {
398 let OutOperandList = (outs type0:$dst, type1:$carry_out);
399 let InOperandList = (ins type0:$src1, type0:$src2);
400 let hasSideEffects = 0;
401}
402
Andrew Scull0372a572018-11-16 15:47:06 +0000403// Generic signed subtraction consuming and producing a carry flag.
404def G_SSUBE : GenericInstruction {
405 let OutOperandList = (outs type0:$dst, type1:$carry_out);
406 let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
407 let hasSideEffects = 0;
408}
409
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100410// Generic unsigned multiplication producing a carry flag.
411def G_UMULO : GenericInstruction {
412 let OutOperandList = (outs type0:$dst, type1:$carry_out);
413 let InOperandList = (ins type0:$src1, type0:$src2);
414 let hasSideEffects = 0;
415 let isCommutable = 1;
416}
417
418// Generic signed multiplication producing a carry flag.
419def G_SMULO : GenericInstruction {
420 let OutOperandList = (outs type0:$dst, type1:$carry_out);
421 let InOperandList = (ins type0:$src1, type0:$src2);
422 let hasSideEffects = 0;
423 let isCommutable = 1;
424}
425
426// Multiply two numbers at twice the incoming bit width (unsigned) and return
427// the high half of the result.
428def G_UMULH : GenericInstruction {
429 let OutOperandList = (outs type0:$dst);
430 let InOperandList = (ins type0:$src1, type0:$src2);
431 let hasSideEffects = 0;
432 let isCommutable = 1;
433}
434
435// Multiply two numbers at twice the incoming bit width (signed) and return
436// the high half of the result.
437def G_SMULH : GenericInstruction {
438 let OutOperandList = (outs type0:$dst);
439 let InOperandList = (ins type0:$src1, type0:$src2);
440 let hasSideEffects = 0;
441 let isCommutable = 1;
442}
443
444//------------------------------------------------------------------------------
445// Floating Point Unary Ops.
446//------------------------------------------------------------------------------
447
448def G_FNEG : GenericInstruction {
449 let OutOperandList = (outs type0:$dst);
450 let InOperandList = (ins type0:$src);
451 let hasSideEffects = 0;
452}
453
454def G_FPEXT : GenericInstruction {
455 let OutOperandList = (outs type0:$dst);
456 let InOperandList = (ins type1:$src);
457 let hasSideEffects = 0;
458}
459
460def G_FPTRUNC : GenericInstruction {
461 let OutOperandList = (outs type0:$dst);
462 let InOperandList = (ins type1:$src);
463 let hasSideEffects = 0;
464}
465
466def G_FPTOSI : GenericInstruction {
467 let OutOperandList = (outs type0:$dst);
468 let InOperandList = (ins type1:$src);
469 let hasSideEffects = 0;
470}
471
472def G_FPTOUI : GenericInstruction {
473 let OutOperandList = (outs type0:$dst);
474 let InOperandList = (ins type1:$src);
475 let hasSideEffects = 0;
476}
477
478def G_SITOFP : GenericInstruction {
479 let OutOperandList = (outs type0:$dst);
480 let InOperandList = (ins type1:$src);
481 let hasSideEffects = 0;
482}
483
484def G_UITOFP : GenericInstruction {
485 let OutOperandList = (outs type0:$dst);
486 let InOperandList = (ins type1:$src);
487 let hasSideEffects = 0;
488}
489
490def G_FABS : GenericInstruction {
491 let OutOperandList = (outs type0:$dst);
492 let InOperandList = (ins type0:$src);
493 let hasSideEffects = 0;
494}
495
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100496def G_FCOPYSIGN : GenericInstruction {
497 let OutOperandList = (outs type0:$dst);
498 let InOperandList = (ins type0:$src0, type1:$src1);
499 let hasSideEffects = 0;
500}
501
Andrew Walbran16937d02019-10-22 13:54:20 +0100502def G_FCANONICALIZE : GenericInstruction {
503 let OutOperandList = (outs type0:$dst);
504 let InOperandList = (ins type0:$src);
505 let hasSideEffects = 0;
506}
507
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100508//------------------------------------------------------------------------------
509// Floating Point Binary ops.
510//------------------------------------------------------------------------------
511
512// Generic FP addition.
513def G_FADD : GenericInstruction {
514 let OutOperandList = (outs type0:$dst);
515 let InOperandList = (ins type0:$src1, type0:$src2);
516 let hasSideEffects = 0;
517 let isCommutable = 1;
518}
519
520// Generic FP subtraction.
521def G_FSUB : GenericInstruction {
522 let OutOperandList = (outs type0:$dst);
523 let InOperandList = (ins type0:$src1, type0:$src2);
524 let hasSideEffects = 0;
525 let isCommutable = 0;
526}
527
528// Generic FP multiplication.
529def G_FMUL : GenericInstruction {
530 let OutOperandList = (outs type0:$dst);
531 let InOperandList = (ins type0:$src1, type0:$src2);
532 let hasSideEffects = 0;
533 let isCommutable = 1;
534}
535
536// Generic fused multiply-add instruction.
537// Behaves like llvm fma intrinsic ie src1 * src2 + src3
538def G_FMA : GenericInstruction {
539 let OutOperandList = (outs type0:$dst);
540 let InOperandList = (ins type0:$src1, type0:$src2, type0:$src3);
541 let hasSideEffects = 0;
542 let isCommutable = 0;
543}
544
545// Generic FP division.
546def G_FDIV : GenericInstruction {
547 let OutOperandList = (outs type0:$dst);
548 let InOperandList = (ins type0:$src1, type0:$src2);
549 let hasSideEffects = 0;
550}
551
552// Generic FP remainder.
553def G_FREM : GenericInstruction {
554 let OutOperandList = (outs type0:$dst);
555 let InOperandList = (ins type0:$src1, type0:$src2);
556 let hasSideEffects = 0;
557}
558
559// Floating point exponentiation.
560def G_FPOW : GenericInstruction {
561 let OutOperandList = (outs type0:$dst);
562 let InOperandList = (ins type0:$src1, type0:$src2);
563 let hasSideEffects = 0;
564}
565
566// Floating point base-e exponential of a value.
567def G_FEXP : GenericInstruction {
568 let OutOperandList = (outs type0:$dst);
569 let InOperandList = (ins type0:$src1);
570 let hasSideEffects = 0;
571}
572
573// Floating point base-2 exponential of a value.
574def G_FEXP2 : GenericInstruction {
575 let OutOperandList = (outs type0:$dst);
576 let InOperandList = (ins type0:$src1);
577 let hasSideEffects = 0;
578}
579
580// Floating point base-2 logarithm of a value.
581def G_FLOG : GenericInstruction {
582 let OutOperandList = (outs type0:$dst);
583 let InOperandList = (ins type0:$src1);
584 let hasSideEffects = 0;
585}
586
587// Floating point base-2 logarithm of a value.
588def G_FLOG2 : GenericInstruction {
589 let OutOperandList = (outs type0:$dst);
590 let InOperandList = (ins type0:$src1);
591 let hasSideEffects = 0;
592}
593
Andrew Walbran16937d02019-10-22 13:54:20 +0100594// Floating point base-10 logarithm of a value.
595def G_FLOG10 : GenericInstruction {
596 let OutOperandList = (outs type0:$dst);
597 let InOperandList = (ins type0:$src1);
598 let hasSideEffects = 0;
599}
600
601// Floating point ceiling of a value.
602def G_FCEIL : GenericInstruction {
603 let OutOperandList = (outs type0:$dst);
604 let InOperandList = (ins type0:$src1);
605 let hasSideEffects = 0;
606}
607
608// Floating point cosine of a value.
609def G_FCOS : GenericInstruction {
610 let OutOperandList = (outs type0:$dst);
611 let InOperandList = (ins type0:$src1);
612 let hasSideEffects = 0;
613}
614
615// Floating point sine of a value.
616def G_FSIN : GenericInstruction {
617 let OutOperandList = (outs type0:$dst);
618 let InOperandList = (ins type0:$src1);
619 let hasSideEffects = 0;
620}
621
622// Floating point square root of a value.
623// This returns NaN for negative nonzero values.
624// NOTE: Unlike libm sqrt(), this never sets errno. In all other respects it's
625// libm-conformant.
626def G_FSQRT : GenericInstruction {
627 let OutOperandList = (outs type0:$dst);
628 let InOperandList = (ins type0:$src1);
629 let hasSideEffects = 0;
630}
631
632// Floating point floor of a value.
633def G_FFLOOR : GenericInstruction {
634 let OutOperandList = (outs type0:$dst);
635 let InOperandList = (ins type0:$src1);
636 let hasSideEffects = 0;
637}
638
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100639// Floating point round to next integer.
640def G_FRINT : GenericInstruction {
641 let OutOperandList = (outs type0:$dst);
642 let InOperandList = (ins type0:$src1);
643 let hasSideEffects = 0;
644}
645
646// Floating point round to the nearest integer.
647def G_FNEARBYINT : GenericInstruction {
648 let OutOperandList = (outs type0:$dst);
649 let InOperandList = (ins type0:$src1);
650 let hasSideEffects = 0;
651}
652
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100653//------------------------------------------------------------------------------
Andrew Scull0372a572018-11-16 15:47:06 +0000654// Opcodes for LLVM Intrinsics
655//------------------------------------------------------------------------------
656def G_INTRINSIC_TRUNC : GenericInstruction {
657 let OutOperandList = (outs type0:$dst);
658 let InOperandList = (ins type0:$src1);
659 let hasSideEffects = 0;
660}
661
662def G_INTRINSIC_ROUND : GenericInstruction {
663 let OutOperandList = (outs type0:$dst);
664 let InOperandList = (ins type0:$src1);
665 let hasSideEffects = 0;
666}
667
668//------------------------------------------------------------------------------
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100669// Memory ops
670//------------------------------------------------------------------------------
671
672// Generic load. Expects a MachineMemOperand in addition to explicit operands.
673def G_LOAD : GenericInstruction {
674 let OutOperandList = (outs type0:$dst);
675 let InOperandList = (ins ptype1:$addr);
676 let hasSideEffects = 0;
677 let mayLoad = 1;
678}
679
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100680// Generic sign-extended load. Expects a MachineMemOperand in addition to explicit operands.
681def G_SEXTLOAD : GenericInstruction {
682 let OutOperandList = (outs type0:$dst);
683 let InOperandList = (ins ptype1:$addr);
684 let hasSideEffects = 0;
685 let mayLoad = 1;
686}
687
688// Generic zero-extended load. Expects a MachineMemOperand in addition to explicit operands.
689def G_ZEXTLOAD : GenericInstruction {
690 let OutOperandList = (outs type0:$dst);
691 let InOperandList = (ins ptype1:$addr);
692 let hasSideEffects = 0;
693 let mayLoad = 1;
694}
695
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100696// Generic store. Expects a MachineMemOperand in addition to explicit operands.
697def G_STORE : GenericInstruction {
698 let OutOperandList = (outs);
699 let InOperandList = (ins type0:$src, ptype1:$addr);
700 let hasSideEffects = 0;
701 let mayStore = 1;
702}
703
704// Generic atomic cmpxchg with internal success check. Expects a
705// MachineMemOperand in addition to explicit operands.
706def G_ATOMIC_CMPXCHG_WITH_SUCCESS : GenericInstruction {
707 let OutOperandList = (outs type0:$oldval, type1:$success);
708 let InOperandList = (ins type2:$addr, type0:$cmpval, type0:$newval);
709 let hasSideEffects = 0;
710 let mayLoad = 1;
711 let mayStore = 1;
712}
713
714// Generic atomic cmpxchg. Expects a MachineMemOperand in addition to explicit
715// operands.
716def G_ATOMIC_CMPXCHG : GenericInstruction {
717 let OutOperandList = (outs type0:$oldval);
718 let InOperandList = (ins ptype1:$addr, type0:$cmpval, type0:$newval);
719 let hasSideEffects = 0;
720 let mayLoad = 1;
721 let mayStore = 1;
722}
723
724// Generic atomicrmw. Expects a MachineMemOperand in addition to explicit
725// operands.
726class G_ATOMICRMW_OP : GenericInstruction {
727 let OutOperandList = (outs type0:$oldval);
728 let InOperandList = (ins ptype1:$addr, type0:$val);
729 let hasSideEffects = 0;
730 let mayLoad = 1;
731 let mayStore = 1;
732}
733
734def G_ATOMICRMW_XCHG : G_ATOMICRMW_OP;
735def G_ATOMICRMW_ADD : G_ATOMICRMW_OP;
736def G_ATOMICRMW_SUB : G_ATOMICRMW_OP;
737def G_ATOMICRMW_AND : G_ATOMICRMW_OP;
738def G_ATOMICRMW_NAND : G_ATOMICRMW_OP;
739def G_ATOMICRMW_OR : G_ATOMICRMW_OP;
740def G_ATOMICRMW_XOR : G_ATOMICRMW_OP;
741def G_ATOMICRMW_MAX : G_ATOMICRMW_OP;
742def G_ATOMICRMW_MIN : G_ATOMICRMW_OP;
743def G_ATOMICRMW_UMAX : G_ATOMICRMW_OP;
744def G_ATOMICRMW_UMIN : G_ATOMICRMW_OP;
745
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100746def G_FENCE : GenericInstruction {
747 let OutOperandList = (outs);
748 let InOperandList = (ins i32imm:$ordering, i32imm:$scope);
749 let hasSideEffects = 1;
750}
751
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100752//------------------------------------------------------------------------------
753// Variadic ops
754//------------------------------------------------------------------------------
755
756// Extract a register of the specified size, starting from the block given by
757// index. This will almost certainly be mapped to sub-register COPYs after
758// register banks have been selected.
759def G_EXTRACT : GenericInstruction {
760 let OutOperandList = (outs type0:$res);
761 let InOperandList = (ins type1:$src, unknown:$offset);
762 let hasSideEffects = 0;
763}
764
765// Extract multiple registers specified size, starting from blocks given by
766// indexes. This will almost certainly be mapped to sub-register COPYs after
767// register banks have been selected.
Andrew Walbran16937d02019-10-22 13:54:20 +0100768// The output operands are always ordered from lowest bits to highest:
769// %bits_0_7:(s8), %bits_8_15:(s8),
770// %bits_16_23:(s8), %bits_24_31:(s8) = G_UNMERGE_VALUES %0:(s32)
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100771def G_UNMERGE_VALUES : GenericInstruction {
772 let OutOperandList = (outs type0:$dst0, variable_ops);
773 let InOperandList = (ins type1:$src);
774 let hasSideEffects = 0;
775}
776
777// Insert a smaller register into a larger one at the specified bit-index.
778def G_INSERT : GenericInstruction {
779 let OutOperandList = (outs type0:$dst);
780 let InOperandList = (ins type0:$src, type1:$op, unknown:$offset);
781 let hasSideEffects = 0;
782}
783
Andrew Walbran16937d02019-10-22 13:54:20 +0100784// Concatenate multiple registers of the same size into a wider register.
785// The input operands are always ordered from lowest bits to highest:
786// %0:(s32) = G_MERGE_VALUES %bits_0_7:(s8), %bits_8_15:(s8),
787// %bits_16_23:(s8), %bits_24_31:(s8)
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100788def G_MERGE_VALUES : GenericInstruction {
789 let OutOperandList = (outs type0:$dst);
790 let InOperandList = (ins type1:$src0, variable_ops);
791 let hasSideEffects = 0;
792}
793
Andrew Walbran16937d02019-10-22 13:54:20 +0100794/// Create a vector from multiple scalar registers. No implicit
795/// conversion is performed (i.e. the result element type must be the
796/// same as all source operands)
797def G_BUILD_VECTOR : GenericInstruction {
798 let OutOperandList = (outs type0:$dst);
799 let InOperandList = (ins type1:$src0, variable_ops);
800 let hasSideEffects = 0;
801}
802
803/// Like G_BUILD_VECTOR, but truncates the larger operand types to fit the
804/// destination vector elt type.
805def G_BUILD_VECTOR_TRUNC : GenericInstruction {
806 let OutOperandList = (outs type0:$dst);
807 let InOperandList = (ins type1:$src0, variable_ops);
808 let hasSideEffects = 0;
809}
810
811/// Create a vector by concatenating vectors together.
812def G_CONCAT_VECTORS : GenericInstruction {
813 let OutOperandList = (outs type0:$dst);
814 let InOperandList = (ins type1:$src0, variable_ops);
815 let hasSideEffects = 0;
816}
817
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100818// Intrinsic without side effects.
819def G_INTRINSIC : GenericInstruction {
820 let OutOperandList = (outs);
821 let InOperandList = (ins unknown:$intrin, variable_ops);
822 let hasSideEffects = 0;
823}
824
825// Intrinsic with side effects.
826def G_INTRINSIC_W_SIDE_EFFECTS : GenericInstruction {
827 let OutOperandList = (outs);
828 let InOperandList = (ins unknown:$intrin, variable_ops);
829 let hasSideEffects = 1;
830 let mayLoad = 1;
831 let mayStore = 1;
832}
833
834//------------------------------------------------------------------------------
835// Branches.
836//------------------------------------------------------------------------------
837
838// Generic unconditional branch.
839def G_BR : GenericInstruction {
840 let OutOperandList = (outs);
841 let InOperandList = (ins unknown:$src1);
842 let hasSideEffects = 0;
843 let isBranch = 1;
844 let isTerminator = 1;
845 let isBarrier = 1;
846}
847
848// Generic conditional branch.
849def G_BRCOND : GenericInstruction {
850 let OutOperandList = (outs);
851 let InOperandList = (ins type0:$tst, unknown:$truebb);
852 let hasSideEffects = 0;
853 let isBranch = 1;
854 let isTerminator = 1;
855}
856
857// Generic indirect branch.
858def G_BRINDIRECT : GenericInstruction {
859 let OutOperandList = (outs);
860 let InOperandList = (ins type0:$src1);
861 let hasSideEffects = 0;
862 let isBranch = 1;
863 let isTerminator = 1;
864}
865
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100866// Generic branch to jump table entry
867def G_BRJT : GenericInstruction {
868 let OutOperandList = (outs);
869 let InOperandList = (ins ptype0:$tbl, unknown:$jti, type1:$idx);
870 let hasSideEffects = 0;
871 let isBranch = 1;
872 let isTerminator = 1;
873}
874
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100875//------------------------------------------------------------------------------
876// Vector ops
877//------------------------------------------------------------------------------
878
879// Generic insertelement.
880def G_INSERT_VECTOR_ELT : GenericInstruction {
881 let OutOperandList = (outs type0:$dst);
882 let InOperandList = (ins type0:$src, type1:$elt, type2:$idx);
883 let hasSideEffects = 0;
884}
885
886// Generic extractelement.
887def G_EXTRACT_VECTOR_ELT : GenericInstruction {
888 let OutOperandList = (outs type0:$dst);
889 let InOperandList = (ins type1:$src, type2:$idx);
890 let hasSideEffects = 0;
891}
892
893// Generic shufflevector.
894def G_SHUFFLE_VECTOR: GenericInstruction {
895 let OutOperandList = (outs type0:$dst);
896 let InOperandList = (ins type1:$v1, type1:$v2, type2:$mask);
897 let hasSideEffects = 0;
898}
899
900// TODO: Add the other generic opcodes.