blob: e4b452e91b9da9298f064a73d5791a3e7fec147e [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 Scull5e1ddfa2018-08-14 10:06:54 +0100172//------------------------------------------------------------------------------
173// Binary ops.
174//------------------------------------------------------------------------------
175
176// Generic addition.
177def G_ADD : GenericInstruction {
178 let OutOperandList = (outs type0:$dst);
179 let InOperandList = (ins type0:$src1, type0:$src2);
180 let hasSideEffects = 0;
181 let isCommutable = 1;
182}
183
184// Generic subtraction.
185def G_SUB : GenericInstruction {
186 let OutOperandList = (outs type0:$dst);
187 let InOperandList = (ins type0:$src1, type0:$src2);
188 let hasSideEffects = 0;
189 let isCommutable = 0;
190}
191
192// Generic multiplication.
193def G_MUL : GenericInstruction {
194 let OutOperandList = (outs type0:$dst);
195 let InOperandList = (ins type0:$src1, type0:$src2);
196 let hasSideEffects = 0;
197 let isCommutable = 1;
198}
199
200// Generic signed division.
201def G_SDIV : GenericInstruction {
202 let OutOperandList = (outs type0:$dst);
203 let InOperandList = (ins type0:$src1, type0:$src2);
204 let hasSideEffects = 0;
205 let isCommutable = 0;
206}
207
208// Generic unsigned division.
209def G_UDIV : GenericInstruction {
210 let OutOperandList = (outs type0:$dst);
211 let InOperandList = (ins type0:$src1, type0:$src2);
212 let hasSideEffects = 0;
213 let isCommutable = 0;
214}
215
216// Generic signed remainder.
217def G_SREM : GenericInstruction {
218 let OutOperandList = (outs type0:$dst);
219 let InOperandList = (ins type0:$src1, type0:$src2);
220 let hasSideEffects = 0;
221 let isCommutable = 0;
222}
223
224// Generic unsigned remainder.
225def G_UREM : GenericInstruction {
226 let OutOperandList = (outs type0:$dst);
227 let InOperandList = (ins type0:$src1, type0:$src2);
228 let hasSideEffects = 0;
229 let isCommutable = 0;
230}
231
232// Generic bitwise and.
233def G_AND : GenericInstruction {
234 let OutOperandList = (outs type0:$dst);
235 let InOperandList = (ins type0:$src1, type0:$src2);
236 let hasSideEffects = 0;
237 let isCommutable = 1;
238}
239
240// Generic bitwise or.
241def G_OR : GenericInstruction {
242 let OutOperandList = (outs type0:$dst);
243 let InOperandList = (ins type0:$src1, type0:$src2);
244 let hasSideEffects = 0;
245 let isCommutable = 1;
246}
247
248// Generic bitwise xor.
249def G_XOR : GenericInstruction {
250 let OutOperandList = (outs type0:$dst);
251 let InOperandList = (ins type0:$src1, type0:$src2);
252 let hasSideEffects = 0;
253 let isCommutable = 1;
254}
255
256// Generic left-shift.
257def G_SHL : GenericInstruction {
258 let OutOperandList = (outs type0:$dst);
Andrew Walbran16937d02019-10-22 13:54:20 +0100259 let InOperandList = (ins type0:$src1, type1:$src2);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100260 let hasSideEffects = 0;
261}
262
263// Generic logical right-shift.
264def G_LSHR : GenericInstruction {
265 let OutOperandList = (outs type0:$dst);
Andrew Walbran16937d02019-10-22 13:54:20 +0100266 let InOperandList = (ins type0:$src1, type1:$src2);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100267 let hasSideEffects = 0;
268}
269
270// Generic arithmetic right-shift.
271def G_ASHR : GenericInstruction {
272 let OutOperandList = (outs type0:$dst);
Andrew Walbran16937d02019-10-22 13:54:20 +0100273 let InOperandList = (ins type0:$src1, type1:$src2);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100274 let hasSideEffects = 0;
275}
276
277// Generic integer comparison.
278def G_ICMP : GenericInstruction {
279 let OutOperandList = (outs type0:$dst);
280 let InOperandList = (ins unknown:$tst, type1:$src1, type1:$src2);
281 let hasSideEffects = 0;
282}
283
284// Generic floating-point comparison.
285def G_FCMP : GenericInstruction {
286 let OutOperandList = (outs type0:$dst);
287 let InOperandList = (ins unknown:$tst, type1:$src1, type1:$src2);
288 let hasSideEffects = 0;
289}
290
291// Generic select
292def G_SELECT : GenericInstruction {
293 let OutOperandList = (outs type0:$dst);
294 let InOperandList = (ins type1:$tst, type0:$src1, type0:$src2);
295 let hasSideEffects = 0;
296}
297
298// Generic pointer offset.
299def G_GEP : GenericInstruction {
300 let OutOperandList = (outs type0:$dst);
301 let InOperandList = (ins type0:$src1, type1:$src2);
302 let hasSideEffects = 0;
303}
304
305def G_PTR_MASK : GenericInstruction {
306 let OutOperandList = (outs type0:$dst);
307 let InOperandList = (ins type0:$src, unknown:$bits);
308 let hasSideEffects = 0;
309}
310
311//------------------------------------------------------------------------------
312// Overflow ops
313//------------------------------------------------------------------------------
314
Andrew Scull0372a572018-11-16 15:47:06 +0000315// Generic unsigned addition producing a carry flag.
316def G_UADDO : GenericInstruction {
317 let OutOperandList = (outs type0:$dst, type1:$carry_out);
318 let InOperandList = (ins type0:$src1, type0:$src2);
319 let hasSideEffects = 0;
320 let isCommutable = 1;
321}
322
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100323// Generic unsigned addition consuming and producing a carry flag.
324def G_UADDE : GenericInstruction {
325 let OutOperandList = (outs type0:$dst, type1:$carry_out);
326 let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
327 let hasSideEffects = 0;
328}
329
330// Generic signed addition producing a carry flag.
331def G_SADDO : GenericInstruction {
332 let OutOperandList = (outs type0:$dst, type1:$carry_out);
333 let InOperandList = (ins type0:$src1, type0:$src2);
334 let hasSideEffects = 0;
335 let isCommutable = 1;
336}
337
Andrew Scull0372a572018-11-16 15:47:06 +0000338// Generic signed addition consuming and producing a carry flag.
339def G_SADDE : GenericInstruction {
340 let OutOperandList = (outs type0:$dst, type1:$carry_out);
341 let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
342 let hasSideEffects = 0;
343}
344
345// Generic unsigned subtraction producing a carry flag.
346def G_USUBO : GenericInstruction {
347 let OutOperandList = (outs type0:$dst, type1:$carry_out);
348 let InOperandList = (ins type0:$src1, type0:$src2);
349 let hasSideEffects = 0;
350}
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100351// Generic unsigned subtraction consuming and producing a carry flag.
352def G_USUBE : GenericInstruction {
353 let OutOperandList = (outs type0:$dst, type1:$carry_out);
354 let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
355 let hasSideEffects = 0;
356}
357
Andrew Scull0372a572018-11-16 15:47:06 +0000358// Generic signed subtraction producing a carry flag.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100359def G_SSUBO : GenericInstruction {
360 let OutOperandList = (outs type0:$dst, type1:$carry_out);
361 let InOperandList = (ins type0:$src1, type0:$src2);
362 let hasSideEffects = 0;
363}
364
Andrew Scull0372a572018-11-16 15:47:06 +0000365// Generic signed subtraction consuming and producing a carry flag.
366def G_SSUBE : GenericInstruction {
367 let OutOperandList = (outs type0:$dst, type1:$carry_out);
368 let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
369 let hasSideEffects = 0;
370}
371
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100372// Generic unsigned multiplication producing a carry flag.
373def G_UMULO : GenericInstruction {
374 let OutOperandList = (outs type0:$dst, type1:$carry_out);
375 let InOperandList = (ins type0:$src1, type0:$src2);
376 let hasSideEffects = 0;
377 let isCommutable = 1;
378}
379
380// Generic signed multiplication producing a carry flag.
381def G_SMULO : GenericInstruction {
382 let OutOperandList = (outs type0:$dst, type1:$carry_out);
383 let InOperandList = (ins type0:$src1, type0:$src2);
384 let hasSideEffects = 0;
385 let isCommutable = 1;
386}
387
388// Multiply two numbers at twice the incoming bit width (unsigned) and return
389// the high half of the result.
390def G_UMULH : GenericInstruction {
391 let OutOperandList = (outs type0:$dst);
392 let InOperandList = (ins type0:$src1, type0:$src2);
393 let hasSideEffects = 0;
394 let isCommutable = 1;
395}
396
397// Multiply two numbers at twice the incoming bit width (signed) and return
398// the high half of the result.
399def G_SMULH : GenericInstruction {
400 let OutOperandList = (outs type0:$dst);
401 let InOperandList = (ins type0:$src1, type0:$src2);
402 let hasSideEffects = 0;
403 let isCommutable = 1;
404}
405
406//------------------------------------------------------------------------------
407// Floating Point Unary Ops.
408//------------------------------------------------------------------------------
409
410def G_FNEG : GenericInstruction {
411 let OutOperandList = (outs type0:$dst);
412 let InOperandList = (ins type0:$src);
413 let hasSideEffects = 0;
414}
415
416def G_FPEXT : GenericInstruction {
417 let OutOperandList = (outs type0:$dst);
418 let InOperandList = (ins type1:$src);
419 let hasSideEffects = 0;
420}
421
422def G_FPTRUNC : GenericInstruction {
423 let OutOperandList = (outs type0:$dst);
424 let InOperandList = (ins type1:$src);
425 let hasSideEffects = 0;
426}
427
428def G_FPTOSI : GenericInstruction {
429 let OutOperandList = (outs type0:$dst);
430 let InOperandList = (ins type1:$src);
431 let hasSideEffects = 0;
432}
433
434def G_FPTOUI : GenericInstruction {
435 let OutOperandList = (outs type0:$dst);
436 let InOperandList = (ins type1:$src);
437 let hasSideEffects = 0;
438}
439
440def G_SITOFP : GenericInstruction {
441 let OutOperandList = (outs type0:$dst);
442 let InOperandList = (ins type1:$src);
443 let hasSideEffects = 0;
444}
445
446def G_UITOFP : GenericInstruction {
447 let OutOperandList = (outs type0:$dst);
448 let InOperandList = (ins type1:$src);
449 let hasSideEffects = 0;
450}
451
452def G_FABS : GenericInstruction {
453 let OutOperandList = (outs type0:$dst);
454 let InOperandList = (ins type0:$src);
455 let hasSideEffects = 0;
456}
457
Andrew Walbran16937d02019-10-22 13:54:20 +0100458def G_FCANONICALIZE : GenericInstruction {
459 let OutOperandList = (outs type0:$dst);
460 let InOperandList = (ins type0:$src);
461 let hasSideEffects = 0;
462}
463
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100464//------------------------------------------------------------------------------
465// Floating Point Binary ops.
466//------------------------------------------------------------------------------
467
468// Generic FP addition.
469def G_FADD : GenericInstruction {
470 let OutOperandList = (outs type0:$dst);
471 let InOperandList = (ins type0:$src1, type0:$src2);
472 let hasSideEffects = 0;
473 let isCommutable = 1;
474}
475
476// Generic FP subtraction.
477def G_FSUB : GenericInstruction {
478 let OutOperandList = (outs type0:$dst);
479 let InOperandList = (ins type0:$src1, type0:$src2);
480 let hasSideEffects = 0;
481 let isCommutable = 0;
482}
483
484// Generic FP multiplication.
485def G_FMUL : GenericInstruction {
486 let OutOperandList = (outs type0:$dst);
487 let InOperandList = (ins type0:$src1, type0:$src2);
488 let hasSideEffects = 0;
489 let isCommutable = 1;
490}
491
492// Generic fused multiply-add instruction.
493// Behaves like llvm fma intrinsic ie src1 * src2 + src3
494def G_FMA : GenericInstruction {
495 let OutOperandList = (outs type0:$dst);
496 let InOperandList = (ins type0:$src1, type0:$src2, type0:$src3);
497 let hasSideEffects = 0;
498 let isCommutable = 0;
499}
500
501// Generic FP division.
502def G_FDIV : GenericInstruction {
503 let OutOperandList = (outs type0:$dst);
504 let InOperandList = (ins type0:$src1, type0:$src2);
505 let hasSideEffects = 0;
506}
507
508// Generic FP remainder.
509def G_FREM : GenericInstruction {
510 let OutOperandList = (outs type0:$dst);
511 let InOperandList = (ins type0:$src1, type0:$src2);
512 let hasSideEffects = 0;
513}
514
515// Floating point exponentiation.
516def G_FPOW : GenericInstruction {
517 let OutOperandList = (outs type0:$dst);
518 let InOperandList = (ins type0:$src1, type0:$src2);
519 let hasSideEffects = 0;
520}
521
522// Floating point base-e exponential of a value.
523def G_FEXP : GenericInstruction {
524 let OutOperandList = (outs type0:$dst);
525 let InOperandList = (ins type0:$src1);
526 let hasSideEffects = 0;
527}
528
529// Floating point base-2 exponential of a value.
530def G_FEXP2 : GenericInstruction {
531 let OutOperandList = (outs type0:$dst);
532 let InOperandList = (ins type0:$src1);
533 let hasSideEffects = 0;
534}
535
536// Floating point base-2 logarithm of a value.
537def G_FLOG : GenericInstruction {
538 let OutOperandList = (outs type0:$dst);
539 let InOperandList = (ins type0:$src1);
540 let hasSideEffects = 0;
541}
542
543// Floating point base-2 logarithm of a value.
544def G_FLOG2 : GenericInstruction {
545 let OutOperandList = (outs type0:$dst);
546 let InOperandList = (ins type0:$src1);
547 let hasSideEffects = 0;
548}
549
Andrew Walbran16937d02019-10-22 13:54:20 +0100550// Floating point base-10 logarithm of a value.
551def G_FLOG10 : GenericInstruction {
552 let OutOperandList = (outs type0:$dst);
553 let InOperandList = (ins type0:$src1);
554 let hasSideEffects = 0;
555}
556
557// Floating point ceiling of a value.
558def G_FCEIL : GenericInstruction {
559 let OutOperandList = (outs type0:$dst);
560 let InOperandList = (ins type0:$src1);
561 let hasSideEffects = 0;
562}
563
564// Floating point cosine of a value.
565def G_FCOS : GenericInstruction {
566 let OutOperandList = (outs type0:$dst);
567 let InOperandList = (ins type0:$src1);
568 let hasSideEffects = 0;
569}
570
571// Floating point sine of a value.
572def G_FSIN : GenericInstruction {
573 let OutOperandList = (outs type0:$dst);
574 let InOperandList = (ins type0:$src1);
575 let hasSideEffects = 0;
576}
577
578// Floating point square root of a value.
579// This returns NaN for negative nonzero values.
580// NOTE: Unlike libm sqrt(), this never sets errno. In all other respects it's
581// libm-conformant.
582def G_FSQRT : GenericInstruction {
583 let OutOperandList = (outs type0:$dst);
584 let InOperandList = (ins type0:$src1);
585 let hasSideEffects = 0;
586}
587
588// Floating point floor of a value.
589def G_FFLOOR : GenericInstruction {
590 let OutOperandList = (outs type0:$dst);
591 let InOperandList = (ins type0:$src1);
592 let hasSideEffects = 0;
593}
594
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100595//------------------------------------------------------------------------------
Andrew Scull0372a572018-11-16 15:47:06 +0000596// Opcodes for LLVM Intrinsics
597//------------------------------------------------------------------------------
598def G_INTRINSIC_TRUNC : GenericInstruction {
599 let OutOperandList = (outs type0:$dst);
600 let InOperandList = (ins type0:$src1);
601 let hasSideEffects = 0;
602}
603
604def G_INTRINSIC_ROUND : GenericInstruction {
605 let OutOperandList = (outs type0:$dst);
606 let InOperandList = (ins type0:$src1);
607 let hasSideEffects = 0;
608}
609
610//------------------------------------------------------------------------------
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100611// Memory ops
612//------------------------------------------------------------------------------
613
614// Generic load. Expects a MachineMemOperand in addition to explicit operands.
615def G_LOAD : GenericInstruction {
616 let OutOperandList = (outs type0:$dst);
617 let InOperandList = (ins ptype1:$addr);
618 let hasSideEffects = 0;
619 let mayLoad = 1;
620}
621
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100622// Generic sign-extended load. Expects a MachineMemOperand in addition to explicit operands.
623def G_SEXTLOAD : GenericInstruction {
624 let OutOperandList = (outs type0:$dst);
625 let InOperandList = (ins ptype1:$addr);
626 let hasSideEffects = 0;
627 let mayLoad = 1;
628}
629
630// Generic zero-extended load. Expects a MachineMemOperand in addition to explicit operands.
631def G_ZEXTLOAD : GenericInstruction {
632 let OutOperandList = (outs type0:$dst);
633 let InOperandList = (ins ptype1:$addr);
634 let hasSideEffects = 0;
635 let mayLoad = 1;
636}
637
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100638// Generic store. Expects a MachineMemOperand in addition to explicit operands.
639def G_STORE : GenericInstruction {
640 let OutOperandList = (outs);
641 let InOperandList = (ins type0:$src, ptype1:$addr);
642 let hasSideEffects = 0;
643 let mayStore = 1;
644}
645
646// Generic atomic cmpxchg with internal success check. Expects a
647// MachineMemOperand in addition to explicit operands.
648def G_ATOMIC_CMPXCHG_WITH_SUCCESS : GenericInstruction {
649 let OutOperandList = (outs type0:$oldval, type1:$success);
650 let InOperandList = (ins type2:$addr, type0:$cmpval, type0:$newval);
651 let hasSideEffects = 0;
652 let mayLoad = 1;
653 let mayStore = 1;
654}
655
656// Generic atomic cmpxchg. Expects a MachineMemOperand in addition to explicit
657// operands.
658def G_ATOMIC_CMPXCHG : GenericInstruction {
659 let OutOperandList = (outs type0:$oldval);
660 let InOperandList = (ins ptype1:$addr, type0:$cmpval, type0:$newval);
661 let hasSideEffects = 0;
662 let mayLoad = 1;
663 let mayStore = 1;
664}
665
666// Generic atomicrmw. Expects a MachineMemOperand in addition to explicit
667// operands.
668class G_ATOMICRMW_OP : GenericInstruction {
669 let OutOperandList = (outs type0:$oldval);
670 let InOperandList = (ins ptype1:$addr, type0:$val);
671 let hasSideEffects = 0;
672 let mayLoad = 1;
673 let mayStore = 1;
674}
675
676def G_ATOMICRMW_XCHG : G_ATOMICRMW_OP;
677def G_ATOMICRMW_ADD : G_ATOMICRMW_OP;
678def G_ATOMICRMW_SUB : G_ATOMICRMW_OP;
679def G_ATOMICRMW_AND : G_ATOMICRMW_OP;
680def G_ATOMICRMW_NAND : G_ATOMICRMW_OP;
681def G_ATOMICRMW_OR : G_ATOMICRMW_OP;
682def G_ATOMICRMW_XOR : G_ATOMICRMW_OP;
683def G_ATOMICRMW_MAX : G_ATOMICRMW_OP;
684def G_ATOMICRMW_MIN : G_ATOMICRMW_OP;
685def G_ATOMICRMW_UMAX : G_ATOMICRMW_OP;
686def G_ATOMICRMW_UMIN : G_ATOMICRMW_OP;
687
688//------------------------------------------------------------------------------
689// Variadic ops
690//------------------------------------------------------------------------------
691
692// Extract a register of the specified size, starting from the block given by
693// index. This will almost certainly be mapped to sub-register COPYs after
694// register banks have been selected.
695def G_EXTRACT : GenericInstruction {
696 let OutOperandList = (outs type0:$res);
697 let InOperandList = (ins type1:$src, unknown:$offset);
698 let hasSideEffects = 0;
699}
700
701// Extract multiple registers specified size, starting from blocks given by
702// indexes. This will almost certainly be mapped to sub-register COPYs after
703// register banks have been selected.
Andrew Walbran16937d02019-10-22 13:54:20 +0100704// The output operands are always ordered from lowest bits to highest:
705// %bits_0_7:(s8), %bits_8_15:(s8),
706// %bits_16_23:(s8), %bits_24_31:(s8) = G_UNMERGE_VALUES %0:(s32)
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100707def G_UNMERGE_VALUES : GenericInstruction {
708 let OutOperandList = (outs type0:$dst0, variable_ops);
709 let InOperandList = (ins type1:$src);
710 let hasSideEffects = 0;
711}
712
713// Insert a smaller register into a larger one at the specified bit-index.
714def G_INSERT : GenericInstruction {
715 let OutOperandList = (outs type0:$dst);
716 let InOperandList = (ins type0:$src, type1:$op, unknown:$offset);
717 let hasSideEffects = 0;
718}
719
Andrew Walbran16937d02019-10-22 13:54:20 +0100720// Concatenate multiple registers of the same size into a wider register.
721// The input operands are always ordered from lowest bits to highest:
722// %0:(s32) = G_MERGE_VALUES %bits_0_7:(s8), %bits_8_15:(s8),
723// %bits_16_23:(s8), %bits_24_31:(s8)
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100724def G_MERGE_VALUES : GenericInstruction {
725 let OutOperandList = (outs type0:$dst);
726 let InOperandList = (ins type1:$src0, variable_ops);
727 let hasSideEffects = 0;
728}
729
Andrew Walbran16937d02019-10-22 13:54:20 +0100730/// Create a vector from multiple scalar registers. No implicit
731/// conversion is performed (i.e. the result element type must be the
732/// same as all source operands)
733def G_BUILD_VECTOR : GenericInstruction {
734 let OutOperandList = (outs type0:$dst);
735 let InOperandList = (ins type1:$src0, variable_ops);
736 let hasSideEffects = 0;
737}
738
739/// Like G_BUILD_VECTOR, but truncates the larger operand types to fit the
740/// destination vector elt type.
741def G_BUILD_VECTOR_TRUNC : GenericInstruction {
742 let OutOperandList = (outs type0:$dst);
743 let InOperandList = (ins type1:$src0, variable_ops);
744 let hasSideEffects = 0;
745}
746
747/// Create a vector by concatenating vectors together.
748def G_CONCAT_VECTORS : GenericInstruction {
749 let OutOperandList = (outs type0:$dst);
750 let InOperandList = (ins type1:$src0, variable_ops);
751 let hasSideEffects = 0;
752}
753
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100754// Intrinsic without side effects.
755def G_INTRINSIC : GenericInstruction {
756 let OutOperandList = (outs);
757 let InOperandList = (ins unknown:$intrin, variable_ops);
758 let hasSideEffects = 0;
759}
760
761// Intrinsic with side effects.
762def G_INTRINSIC_W_SIDE_EFFECTS : GenericInstruction {
763 let OutOperandList = (outs);
764 let InOperandList = (ins unknown:$intrin, variable_ops);
765 let hasSideEffects = 1;
766 let mayLoad = 1;
767 let mayStore = 1;
768}
769
770//------------------------------------------------------------------------------
771// Branches.
772//------------------------------------------------------------------------------
773
774// Generic unconditional branch.
775def G_BR : GenericInstruction {
776 let OutOperandList = (outs);
777 let InOperandList = (ins unknown:$src1);
778 let hasSideEffects = 0;
779 let isBranch = 1;
780 let isTerminator = 1;
781 let isBarrier = 1;
782}
783
784// Generic conditional branch.
785def G_BRCOND : GenericInstruction {
786 let OutOperandList = (outs);
787 let InOperandList = (ins type0:$tst, unknown:$truebb);
788 let hasSideEffects = 0;
789 let isBranch = 1;
790 let isTerminator = 1;
791}
792
793// Generic indirect branch.
794def G_BRINDIRECT : GenericInstruction {
795 let OutOperandList = (outs);
796 let InOperandList = (ins type0:$src1);
797 let hasSideEffects = 0;
798 let isBranch = 1;
799 let isTerminator = 1;
800}
801
802//------------------------------------------------------------------------------
803// Vector ops
804//------------------------------------------------------------------------------
805
806// Generic insertelement.
807def G_INSERT_VECTOR_ELT : GenericInstruction {
808 let OutOperandList = (outs type0:$dst);
809 let InOperandList = (ins type0:$src, type1:$elt, type2:$idx);
810 let hasSideEffects = 0;
811}
812
813// Generic extractelement.
814def G_EXTRACT_VECTOR_ELT : GenericInstruction {
815 let OutOperandList = (outs type0:$dst);
816 let InOperandList = (ins type1:$src, type2:$idx);
817 let hasSideEffects = 0;
818}
819
820// Generic shufflevector.
821def G_SHUFFLE_VECTOR: GenericInstruction {
822 let OutOperandList = (outs type0:$dst);
823 let InOperandList = (ins type1:$v1, type1:$v2, type2:$mask);
824 let hasSideEffects = 0;
825}
826
827// TODO: Add the other generic opcodes.