blob: 1af6a9ab9f257fd62cf1c19e39862462ed26bba0 [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===-- GenericOpcodes.td - Opcodes used with GlobalISel ---*- tablegen -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the generic opcodes used with GlobalISel.
11// After instruction selection, these opcodes should not appear.
12//
13//===----------------------------------------------------------------------===//
14
15//------------------------------------------------------------------------------
16// Unary ops.
17//------------------------------------------------------------------------------
18
19class GenericInstruction : StandardPseudoInstruction;
20
21// Extend the underlying scalar type of an operation, leaving the high bits
22// unspecified.
23def G_ANYEXT : GenericInstruction {
24 let OutOperandList = (outs type0:$dst);
25 let InOperandList = (ins type1:$src);
26 let hasSideEffects = 0;
27}
28
29// Sign extend the underlying scalar type of an operation, copying the sign bit
30// into the newly-created space.
31def G_SEXT : GenericInstruction {
32 let OutOperandList = (outs type0:$dst);
33 let InOperandList = (ins type1:$src);
34 let hasSideEffects = 0;
35}
36
37// Zero extend the underlying scalar type of an operation, putting zero bits
38// into the newly-created space.
39def G_ZEXT : GenericInstruction {
40 let OutOperandList = (outs type0:$dst);
41 let InOperandList = (ins type1:$src);
42 let hasSideEffects = 0;
43}
44
45
46// Truncate the underlying scalar type of an operation. This is equivalent to
47// G_EXTRACT for scalar types, but acts elementwise on vectors.
48def G_TRUNC : GenericInstruction {
49 let OutOperandList = (outs type0:$dst);
50 let InOperandList = (ins type1:$src);
51 let hasSideEffects = 0;
52}
53
54def G_IMPLICIT_DEF : GenericInstruction {
55 let OutOperandList = (outs type0:$dst);
56 let InOperandList = (ins);
57 let hasSideEffects = 0;
58}
59
60def G_PHI : GenericInstruction {
61 let OutOperandList = (outs type0:$dst);
62 let InOperandList = (ins variable_ops);
63 let hasSideEffects = 0;
64}
65
66def G_FRAME_INDEX : GenericInstruction {
67 let OutOperandList = (outs type0:$dst);
68 let InOperandList = (ins unknown:$src2);
69 let hasSideEffects = 0;
70}
71
72def G_GLOBAL_VALUE : GenericInstruction {
73 let OutOperandList = (outs type0:$dst);
74 let InOperandList = (ins unknown:$src);
75 let hasSideEffects = 0;
76}
77
78def G_INTTOPTR : GenericInstruction {
79 let OutOperandList = (outs type0:$dst);
80 let InOperandList = (ins type1:$src);
81 let hasSideEffects = 0;
82}
83
84def G_PTRTOINT : GenericInstruction {
85 let OutOperandList = (outs type0:$dst);
86 let InOperandList = (ins type1:$src);
87 let hasSideEffects = 0;
88}
89
90def G_BITCAST : GenericInstruction {
91 let OutOperandList = (outs type0:$dst);
92 let InOperandList = (ins type1:$src);
93 let hasSideEffects = 0;
94}
95
96def G_CONSTANT : GenericInstruction {
97 let OutOperandList = (outs type0:$dst);
98 let InOperandList = (ins unknown:$imm);
99 let hasSideEffects = 0;
100}
101
102def G_FCONSTANT : GenericInstruction {
103 let OutOperandList = (outs type0:$dst);
104 let InOperandList = (ins unknown:$imm);
105 let hasSideEffects = 0;
106}
107
108def G_VASTART : GenericInstruction {
109 let OutOperandList = (outs);
110 let InOperandList = (ins type0:$list);
111 let hasSideEffects = 0;
112 let mayStore = 1;
113}
114
115def G_VAARG : GenericInstruction {
116 let OutOperandList = (outs type0:$val);
117 let InOperandList = (ins type1:$list, unknown:$align);
118 let hasSideEffects = 0;
119 let mayLoad = 1;
120 let mayStore = 1;
121}
122
123def G_BSWAP : GenericInstruction {
124 let OutOperandList = (outs type0:$dst);
125 let InOperandList = (ins type0:$src);
126 let hasSideEffects = 0;
127}
128
129//------------------------------------------------------------------------------
130// Binary ops.
131//------------------------------------------------------------------------------
132
133// Generic addition.
134def G_ADD : GenericInstruction {
135 let OutOperandList = (outs type0:$dst);
136 let InOperandList = (ins type0:$src1, type0:$src2);
137 let hasSideEffects = 0;
138 let isCommutable = 1;
139}
140
141// Generic subtraction.
142def G_SUB : GenericInstruction {
143 let OutOperandList = (outs type0:$dst);
144 let InOperandList = (ins type0:$src1, type0:$src2);
145 let hasSideEffects = 0;
146 let isCommutable = 0;
147}
148
149// Generic multiplication.
150def G_MUL : GenericInstruction {
151 let OutOperandList = (outs type0:$dst);
152 let InOperandList = (ins type0:$src1, type0:$src2);
153 let hasSideEffects = 0;
154 let isCommutable = 1;
155}
156
157// Generic signed division.
158def G_SDIV : GenericInstruction {
159 let OutOperandList = (outs type0:$dst);
160 let InOperandList = (ins type0:$src1, type0:$src2);
161 let hasSideEffects = 0;
162 let isCommutable = 0;
163}
164
165// Generic unsigned division.
166def G_UDIV : GenericInstruction {
167 let OutOperandList = (outs type0:$dst);
168 let InOperandList = (ins type0:$src1, type0:$src2);
169 let hasSideEffects = 0;
170 let isCommutable = 0;
171}
172
173// Generic signed remainder.
174def G_SREM : GenericInstruction {
175 let OutOperandList = (outs type0:$dst);
176 let InOperandList = (ins type0:$src1, type0:$src2);
177 let hasSideEffects = 0;
178 let isCommutable = 0;
179}
180
181// Generic unsigned remainder.
182def G_UREM : GenericInstruction {
183 let OutOperandList = (outs type0:$dst);
184 let InOperandList = (ins type0:$src1, type0:$src2);
185 let hasSideEffects = 0;
186 let isCommutable = 0;
187}
188
189// Generic bitwise and.
190def G_AND : GenericInstruction {
191 let OutOperandList = (outs type0:$dst);
192 let InOperandList = (ins type0:$src1, type0:$src2);
193 let hasSideEffects = 0;
194 let isCommutable = 1;
195}
196
197// Generic bitwise or.
198def G_OR : GenericInstruction {
199 let OutOperandList = (outs type0:$dst);
200 let InOperandList = (ins type0:$src1, type0:$src2);
201 let hasSideEffects = 0;
202 let isCommutable = 1;
203}
204
205// Generic bitwise xor.
206def G_XOR : GenericInstruction {
207 let OutOperandList = (outs type0:$dst);
208 let InOperandList = (ins type0:$src1, type0:$src2);
209 let hasSideEffects = 0;
210 let isCommutable = 1;
211}
212
213// Generic left-shift.
214def G_SHL : GenericInstruction {
215 let OutOperandList = (outs type0:$dst);
216 let InOperandList = (ins type0:$src1, type0:$src2);
217 let hasSideEffects = 0;
218}
219
220// Generic logical right-shift.
221def G_LSHR : GenericInstruction {
222 let OutOperandList = (outs type0:$dst);
223 let InOperandList = (ins type0:$src1, type0:$src2);
224 let hasSideEffects = 0;
225}
226
227// Generic arithmetic right-shift.
228def G_ASHR : GenericInstruction {
229 let OutOperandList = (outs type0:$dst);
230 let InOperandList = (ins type0:$src1, type0:$src2);
231 let hasSideEffects = 0;
232}
233
234// Generic integer comparison.
235def G_ICMP : GenericInstruction {
236 let OutOperandList = (outs type0:$dst);
237 let InOperandList = (ins unknown:$tst, type1:$src1, type1:$src2);
238 let hasSideEffects = 0;
239}
240
241// Generic floating-point comparison.
242def G_FCMP : GenericInstruction {
243 let OutOperandList = (outs type0:$dst);
244 let InOperandList = (ins unknown:$tst, type1:$src1, type1:$src2);
245 let hasSideEffects = 0;
246}
247
248// Generic select
249def G_SELECT : GenericInstruction {
250 let OutOperandList = (outs type0:$dst);
251 let InOperandList = (ins type1:$tst, type0:$src1, type0:$src2);
252 let hasSideEffects = 0;
253}
254
255// Generic pointer offset.
256def G_GEP : GenericInstruction {
257 let OutOperandList = (outs type0:$dst);
258 let InOperandList = (ins type0:$src1, type1:$src2);
259 let hasSideEffects = 0;
260}
261
262def G_PTR_MASK : GenericInstruction {
263 let OutOperandList = (outs type0:$dst);
264 let InOperandList = (ins type0:$src, unknown:$bits);
265 let hasSideEffects = 0;
266}
267
268//------------------------------------------------------------------------------
269// Overflow ops
270//------------------------------------------------------------------------------
271
272// Generic unsigned addition consuming and producing a carry flag.
273def G_UADDE : GenericInstruction {
274 let OutOperandList = (outs type0:$dst, type1:$carry_out);
275 let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
276 let hasSideEffects = 0;
277}
278
279// Generic signed addition producing a carry flag.
280def G_SADDO : GenericInstruction {
281 let OutOperandList = (outs type0:$dst, type1:$carry_out);
282 let InOperandList = (ins type0:$src1, type0:$src2);
283 let hasSideEffects = 0;
284 let isCommutable = 1;
285}
286
287// Generic unsigned subtraction consuming and producing a carry flag.
288def G_USUBE : GenericInstruction {
289 let OutOperandList = (outs type0:$dst, type1:$carry_out);
290 let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
291 let hasSideEffects = 0;
292}
293
294// Generic unsigned subtraction producing a carry flag.
295def G_SSUBO : GenericInstruction {
296 let OutOperandList = (outs type0:$dst, type1:$carry_out);
297 let InOperandList = (ins type0:$src1, type0:$src2);
298 let hasSideEffects = 0;
299}
300
301// Generic unsigned multiplication producing a carry flag.
302def G_UMULO : GenericInstruction {
303 let OutOperandList = (outs type0:$dst, type1:$carry_out);
304 let InOperandList = (ins type0:$src1, type0:$src2);
305 let hasSideEffects = 0;
306 let isCommutable = 1;
307}
308
309// Generic signed multiplication producing a carry flag.
310def G_SMULO : GenericInstruction {
311 let OutOperandList = (outs type0:$dst, type1:$carry_out);
312 let InOperandList = (ins type0:$src1, type0:$src2);
313 let hasSideEffects = 0;
314 let isCommutable = 1;
315}
316
317// Multiply two numbers at twice the incoming bit width (unsigned) and return
318// the high half of the result.
319def G_UMULH : GenericInstruction {
320 let OutOperandList = (outs type0:$dst);
321 let InOperandList = (ins type0:$src1, type0:$src2);
322 let hasSideEffects = 0;
323 let isCommutable = 1;
324}
325
326// Multiply two numbers at twice the incoming bit width (signed) and return
327// the high half of the result.
328def G_SMULH : GenericInstruction {
329 let OutOperandList = (outs type0:$dst);
330 let InOperandList = (ins type0:$src1, type0:$src2);
331 let hasSideEffects = 0;
332 let isCommutable = 1;
333}
334
335//------------------------------------------------------------------------------
336// Floating Point Unary Ops.
337//------------------------------------------------------------------------------
338
339def G_FNEG : GenericInstruction {
340 let OutOperandList = (outs type0:$dst);
341 let InOperandList = (ins type0:$src);
342 let hasSideEffects = 0;
343}
344
345def G_FPEXT : GenericInstruction {
346 let OutOperandList = (outs type0:$dst);
347 let InOperandList = (ins type1:$src);
348 let hasSideEffects = 0;
349}
350
351def G_FPTRUNC : GenericInstruction {
352 let OutOperandList = (outs type0:$dst);
353 let InOperandList = (ins type1:$src);
354 let hasSideEffects = 0;
355}
356
357def G_FPTOSI : GenericInstruction {
358 let OutOperandList = (outs type0:$dst);
359 let InOperandList = (ins type1:$src);
360 let hasSideEffects = 0;
361}
362
363def G_FPTOUI : GenericInstruction {
364 let OutOperandList = (outs type0:$dst);
365 let InOperandList = (ins type1:$src);
366 let hasSideEffects = 0;
367}
368
369def G_SITOFP : GenericInstruction {
370 let OutOperandList = (outs type0:$dst);
371 let InOperandList = (ins type1:$src);
372 let hasSideEffects = 0;
373}
374
375def G_UITOFP : GenericInstruction {
376 let OutOperandList = (outs type0:$dst);
377 let InOperandList = (ins type1:$src);
378 let hasSideEffects = 0;
379}
380
381def G_FABS : GenericInstruction {
382 let OutOperandList = (outs type0:$dst);
383 let InOperandList = (ins type0:$src);
384 let hasSideEffects = 0;
385}
386
387//------------------------------------------------------------------------------
388// Floating Point Binary ops.
389//------------------------------------------------------------------------------
390
391// Generic FP addition.
392def G_FADD : GenericInstruction {
393 let OutOperandList = (outs type0:$dst);
394 let InOperandList = (ins type0:$src1, type0:$src2);
395 let hasSideEffects = 0;
396 let isCommutable = 1;
397}
398
399// Generic FP subtraction.
400def G_FSUB : GenericInstruction {
401 let OutOperandList = (outs type0:$dst);
402 let InOperandList = (ins type0:$src1, type0:$src2);
403 let hasSideEffects = 0;
404 let isCommutable = 0;
405}
406
407// Generic FP multiplication.
408def G_FMUL : GenericInstruction {
409 let OutOperandList = (outs type0:$dst);
410 let InOperandList = (ins type0:$src1, type0:$src2);
411 let hasSideEffects = 0;
412 let isCommutable = 1;
413}
414
415// Generic fused multiply-add instruction.
416// Behaves like llvm fma intrinsic ie src1 * src2 + src3
417def G_FMA : GenericInstruction {
418 let OutOperandList = (outs type0:$dst);
419 let InOperandList = (ins type0:$src1, type0:$src2, type0:$src3);
420 let hasSideEffects = 0;
421 let isCommutable = 0;
422}
423
424// Generic FP division.
425def G_FDIV : GenericInstruction {
426 let OutOperandList = (outs type0:$dst);
427 let InOperandList = (ins type0:$src1, type0:$src2);
428 let hasSideEffects = 0;
429}
430
431// Generic FP remainder.
432def G_FREM : GenericInstruction {
433 let OutOperandList = (outs type0:$dst);
434 let InOperandList = (ins type0:$src1, type0:$src2);
435 let hasSideEffects = 0;
436}
437
438// Floating point exponentiation.
439def G_FPOW : GenericInstruction {
440 let OutOperandList = (outs type0:$dst);
441 let InOperandList = (ins type0:$src1, type0:$src2);
442 let hasSideEffects = 0;
443}
444
445// Floating point base-e exponential of a value.
446def G_FEXP : GenericInstruction {
447 let OutOperandList = (outs type0:$dst);
448 let InOperandList = (ins type0:$src1);
449 let hasSideEffects = 0;
450}
451
452// Floating point base-2 exponential of a value.
453def G_FEXP2 : GenericInstruction {
454 let OutOperandList = (outs type0:$dst);
455 let InOperandList = (ins type0:$src1);
456 let hasSideEffects = 0;
457}
458
459// Floating point base-2 logarithm of a value.
460def G_FLOG : GenericInstruction {
461 let OutOperandList = (outs type0:$dst);
462 let InOperandList = (ins type0:$src1);
463 let hasSideEffects = 0;
464}
465
466// Floating point base-2 logarithm of a value.
467def G_FLOG2 : GenericInstruction {
468 let OutOperandList = (outs type0:$dst);
469 let InOperandList = (ins type0:$src1);
470 let hasSideEffects = 0;
471}
472
473//------------------------------------------------------------------------------
474// Memory ops
475//------------------------------------------------------------------------------
476
477// Generic load. Expects a MachineMemOperand in addition to explicit operands.
478def G_LOAD : GenericInstruction {
479 let OutOperandList = (outs type0:$dst);
480 let InOperandList = (ins ptype1:$addr);
481 let hasSideEffects = 0;
482 let mayLoad = 1;
483}
484
485// Generic store. Expects a MachineMemOperand in addition to explicit operands.
486def G_STORE : GenericInstruction {
487 let OutOperandList = (outs);
488 let InOperandList = (ins type0:$src, ptype1:$addr);
489 let hasSideEffects = 0;
490 let mayStore = 1;
491}
492
493// Generic atomic cmpxchg with internal success check. Expects a
494// MachineMemOperand in addition to explicit operands.
495def G_ATOMIC_CMPXCHG_WITH_SUCCESS : GenericInstruction {
496 let OutOperandList = (outs type0:$oldval, type1:$success);
497 let InOperandList = (ins type2:$addr, type0:$cmpval, type0:$newval);
498 let hasSideEffects = 0;
499 let mayLoad = 1;
500 let mayStore = 1;
501}
502
503// Generic atomic cmpxchg. Expects a MachineMemOperand in addition to explicit
504// operands.
505def G_ATOMIC_CMPXCHG : GenericInstruction {
506 let OutOperandList = (outs type0:$oldval);
507 let InOperandList = (ins ptype1:$addr, type0:$cmpval, type0:$newval);
508 let hasSideEffects = 0;
509 let mayLoad = 1;
510 let mayStore = 1;
511}
512
513// Generic atomicrmw. Expects a MachineMemOperand in addition to explicit
514// operands.
515class G_ATOMICRMW_OP : GenericInstruction {
516 let OutOperandList = (outs type0:$oldval);
517 let InOperandList = (ins ptype1:$addr, type0:$val);
518 let hasSideEffects = 0;
519 let mayLoad = 1;
520 let mayStore = 1;
521}
522
523def G_ATOMICRMW_XCHG : G_ATOMICRMW_OP;
524def G_ATOMICRMW_ADD : G_ATOMICRMW_OP;
525def G_ATOMICRMW_SUB : G_ATOMICRMW_OP;
526def G_ATOMICRMW_AND : G_ATOMICRMW_OP;
527def G_ATOMICRMW_NAND : G_ATOMICRMW_OP;
528def G_ATOMICRMW_OR : G_ATOMICRMW_OP;
529def G_ATOMICRMW_XOR : G_ATOMICRMW_OP;
530def G_ATOMICRMW_MAX : G_ATOMICRMW_OP;
531def G_ATOMICRMW_MIN : G_ATOMICRMW_OP;
532def G_ATOMICRMW_UMAX : G_ATOMICRMW_OP;
533def G_ATOMICRMW_UMIN : G_ATOMICRMW_OP;
534
535//------------------------------------------------------------------------------
536// Variadic ops
537//------------------------------------------------------------------------------
538
539// Extract a register of the specified size, starting from the block given by
540// index. This will almost certainly be mapped to sub-register COPYs after
541// register banks have been selected.
542def G_EXTRACT : GenericInstruction {
543 let OutOperandList = (outs type0:$res);
544 let InOperandList = (ins type1:$src, unknown:$offset);
545 let hasSideEffects = 0;
546}
547
548// Extract multiple registers specified size, starting from blocks given by
549// indexes. This will almost certainly be mapped to sub-register COPYs after
550// register banks have been selected.
551def G_UNMERGE_VALUES : GenericInstruction {
552 let OutOperandList = (outs type0:$dst0, variable_ops);
553 let InOperandList = (ins type1:$src);
554 let hasSideEffects = 0;
555}
556
557// Insert a smaller register into a larger one at the specified bit-index.
558def G_INSERT : GenericInstruction {
559 let OutOperandList = (outs type0:$dst);
560 let InOperandList = (ins type0:$src, type1:$op, unknown:$offset);
561 let hasSideEffects = 0;
562}
563
564/// Concatenate multiple registers of the same size into a wider register.
565def G_MERGE_VALUES : GenericInstruction {
566 let OutOperandList = (outs type0:$dst);
567 let InOperandList = (ins type1:$src0, variable_ops);
568 let hasSideEffects = 0;
569}
570
571// Intrinsic without side effects.
572def G_INTRINSIC : GenericInstruction {
573 let OutOperandList = (outs);
574 let InOperandList = (ins unknown:$intrin, variable_ops);
575 let hasSideEffects = 0;
576}
577
578// Intrinsic with side effects.
579def G_INTRINSIC_W_SIDE_EFFECTS : GenericInstruction {
580 let OutOperandList = (outs);
581 let InOperandList = (ins unknown:$intrin, variable_ops);
582 let hasSideEffects = 1;
583 let mayLoad = 1;
584 let mayStore = 1;
585}
586
587//------------------------------------------------------------------------------
588// Branches.
589//------------------------------------------------------------------------------
590
591// Generic unconditional branch.
592def G_BR : GenericInstruction {
593 let OutOperandList = (outs);
594 let InOperandList = (ins unknown:$src1);
595 let hasSideEffects = 0;
596 let isBranch = 1;
597 let isTerminator = 1;
598 let isBarrier = 1;
599}
600
601// Generic conditional branch.
602def G_BRCOND : GenericInstruction {
603 let OutOperandList = (outs);
604 let InOperandList = (ins type0:$tst, unknown:$truebb);
605 let hasSideEffects = 0;
606 let isBranch = 1;
607 let isTerminator = 1;
608}
609
610// Generic indirect branch.
611def G_BRINDIRECT : GenericInstruction {
612 let OutOperandList = (outs);
613 let InOperandList = (ins type0:$src1);
614 let hasSideEffects = 0;
615 let isBranch = 1;
616 let isTerminator = 1;
617}
618
619//------------------------------------------------------------------------------
620// Vector ops
621//------------------------------------------------------------------------------
622
623// Generic insertelement.
624def G_INSERT_VECTOR_ELT : GenericInstruction {
625 let OutOperandList = (outs type0:$dst);
626 let InOperandList = (ins type0:$src, type1:$elt, type2:$idx);
627 let hasSideEffects = 0;
628}
629
630// Generic extractelement.
631def G_EXTRACT_VECTOR_ELT : GenericInstruction {
632 let OutOperandList = (outs type0:$dst);
633 let InOperandList = (ins type1:$src, type2:$idx);
634 let hasSideEffects = 0;
635}
636
637// Generic shufflevector.
638def G_SHUFFLE_VECTOR: GenericInstruction {
639 let OutOperandList = (outs type0:$dst);
640 let InOperandList = (ins type1:$v1, type1:$v2, type2:$mask);
641 let hasSideEffects = 0;
642}
643
644// TODO: Add the other generic opcodes.