1 //===-- GenericOpcodes.td - Opcodes used with GlobalISel ---*- tablegen -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the generic opcodes used with GlobalISel.
11 // After instruction selection, these opcodes should not appear.
13 //===----------------------------------------------------------------------===//
15 //------------------------------------------------------------------------------
17 //------------------------------------------------------------------------------
19 // Extend the underlying scalar type of an operation, leaving the high bits
21 def G_ANYEXT : Instruction {
22 let OutOperandList = (outs type0:$dst);
23 let InOperandList = (ins type1:$src);
24 let hasSideEffects = 0;
27 // Sign extend the underlying scalar type of an operation, copying the sign bit
28 // into the newly-created space.
29 def G_SEXT : Instruction {
30 let OutOperandList = (outs type0:$dst);
31 let InOperandList = (ins type1:$src);
32 let hasSideEffects = 0;
35 // Zero extend the underlying scalar type of an operation, putting zero bits
36 // into the newly-created space.
37 def G_ZEXT : Instruction {
38 let OutOperandList = (outs type0:$dst);
39 let InOperandList = (ins type1:$src);
40 let hasSideEffects = 0;
44 // Truncate the underlying scalar type of an operation. This is equivalent to
45 // G_EXTRACT for scalar types, but acts elementwise on vectors.
46 def G_TRUNC : Instruction {
47 let OutOperandList = (outs type0:$dst);
48 let InOperandList = (ins type1:$src);
49 let hasSideEffects = 0;
52 def G_IMPLICIT_DEF : Instruction {
53 let OutOperandList = (outs type0:$dst);
54 let InOperandList = (ins);
55 let hasSideEffects = 0;
58 def G_FRAME_INDEX : Instruction {
59 let OutOperandList = (outs type0:$dst);
60 let InOperandList = (ins unknown:$src2);
61 let hasSideEffects = 0;
64 def G_GLOBAL_VALUE : Instruction {
65 let OutOperandList = (outs type0:$dst);
66 let InOperandList = (ins unknown:$src);
67 let hasSideEffects = 0;
70 def G_INTTOPTR : Instruction {
71 let OutOperandList = (outs type0:$dst);
72 let InOperandList = (ins type1:$src);
73 let hasSideEffects = 0;
76 def G_PTRTOINT : Instruction {
77 let OutOperandList = (outs type0:$dst);
78 let InOperandList = (ins type1:$src);
79 let hasSideEffects = 0;
82 def G_BITCAST : Instruction {
83 let OutOperandList = (outs type0:$dst);
84 let InOperandList = (ins type1:$src);
85 let hasSideEffects = 0;
88 def G_CONSTANT : Instruction {
89 let OutOperandList = (outs type0:$dst);
90 let InOperandList = (ins unknown:$imm);
91 let hasSideEffects = 0;
94 def G_FCONSTANT : Instruction {
95 let OutOperandList = (outs type0:$dst);
96 let InOperandList = (ins unknown:$imm);
97 let hasSideEffects = 0;
100 def G_VASTART : Instruction {
101 let OutOperandList = (outs);
102 let InOperandList = (ins type0:$list);
103 let hasSideEffects = 0;
107 def G_VAARG : Instruction {
108 let OutOperandList = (outs type0:$val);
109 let InOperandList = (ins type1:$list, unknown:$align);
110 let hasSideEffects = 0;
115 //------------------------------------------------------------------------------
117 //------------------------------------------------------------------------------
120 def G_ADD : Instruction {
121 let OutOperandList = (outs type0:$dst);
122 let InOperandList = (ins type0:$src1, type0:$src2);
123 let hasSideEffects = 0;
124 let isCommutable = 1;
127 // Generic subtraction.
128 def G_SUB : Instruction {
129 let OutOperandList = (outs type0:$dst);
130 let InOperandList = (ins type0:$src1, type0:$src2);
131 let hasSideEffects = 0;
132 let isCommutable = 0;
135 // Generic multiplication.
136 def G_MUL : Instruction {
137 let OutOperandList = (outs type0:$dst);
138 let InOperandList = (ins type0:$src1, type0:$src2);
139 let hasSideEffects = 0;
140 let isCommutable = 1;
143 // Generic signed division.
144 def G_SDIV : Instruction {
145 let OutOperandList = (outs type0:$dst);
146 let InOperandList = (ins type0:$src1, type0:$src2);
147 let hasSideEffects = 0;
148 let isCommutable = 0;
151 // Generic unsigned division.
152 def G_UDIV : Instruction {
153 let OutOperandList = (outs type0:$dst);
154 let InOperandList = (ins type0:$src1, type0:$src2);
155 let hasSideEffects = 0;
156 let isCommutable = 0;
159 // Generic signed remainder.
160 def G_SREM : Instruction {
161 let OutOperandList = (outs type0:$dst);
162 let InOperandList = (ins type0:$src1, type0:$src2);
163 let hasSideEffects = 0;
164 let isCommutable = 0;
167 // Generic unsigned remainder.
168 def G_UREM : Instruction {
169 let OutOperandList = (outs type0:$dst);
170 let InOperandList = (ins type0:$src1, type0:$src2);
171 let hasSideEffects = 0;
172 let isCommutable = 0;
175 // Generic bitwise and.
176 def G_AND : Instruction {
177 let OutOperandList = (outs type0:$dst);
178 let InOperandList = (ins type0:$src1, type0:$src2);
179 let hasSideEffects = 0;
180 let isCommutable = 1;
183 // Generic bitwise or.
184 def G_OR : Instruction {
185 let OutOperandList = (outs type0:$dst);
186 let InOperandList = (ins type0:$src1, type0:$src2);
187 let hasSideEffects = 0;
188 let isCommutable = 1;
191 // Generic bitwise xor.
192 def G_XOR : Instruction {
193 let OutOperandList = (outs type0:$dst);
194 let InOperandList = (ins type0:$src1, type0:$src2);
195 let hasSideEffects = 0;
196 let isCommutable = 1;
199 // Generic left-shift.
200 def G_SHL : Instruction {
201 let OutOperandList = (outs type0:$dst);
202 let InOperandList = (ins type0:$src1, type0:$src2);
203 let hasSideEffects = 0;
206 // Generic logical right-shift.
207 def G_LSHR : Instruction {
208 let OutOperandList = (outs type0:$dst);
209 let InOperandList = (ins type0:$src1, type0:$src2);
210 let hasSideEffects = 0;
213 // Generic arithmetic right-shift.
214 def G_ASHR : Instruction {
215 let OutOperandList = (outs type0:$dst);
216 let InOperandList = (ins type0:$src1, type0:$src2);
217 let hasSideEffects = 0;
220 // Generic integer comparison.
221 def G_ICMP : Instruction {
222 let OutOperandList = (outs type0:$dst);
223 let InOperandList = (ins unknown:$tst, type1:$src1, type1:$src2);
224 let hasSideEffects = 0;
227 // Generic floating-point comparison.
228 def G_FCMP : Instruction {
229 let OutOperandList = (outs type0:$dst);
230 let InOperandList = (ins unknown:$tst, type1:$src1, type1:$src2);
231 let hasSideEffects = 0;
235 def G_SELECT : Instruction {
236 let OutOperandList = (outs type0:$dst);
237 let InOperandList = (ins type1:$tst, type0:$src1, type0:$src2);
238 let hasSideEffects = 0;
241 // Generic pointer offset.
242 def G_GEP : Instruction {
243 let OutOperandList = (outs type0:$dst);
244 let InOperandList = (ins type0:$src1, type1:$src2);
245 let hasSideEffects = 0;
248 def G_PTR_MASK : Instruction {
249 let OutOperandList = (outs type0:$dst);
250 let InOperandList = (ins type0:$src, unknown:$bits);
251 let hasSideEffects = 0;
254 //------------------------------------------------------------------------------
256 //------------------------------------------------------------------------------
258 // Generic unsigned addition consuming and producing a carry flag.
259 def G_UADDE : Instruction {
260 let OutOperandList = (outs type0:$dst, type1:$carry_out);
261 let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
262 let hasSideEffects = 0;
265 // Generic signed addition producing a carry flag.
266 def G_SADDO : Instruction {
267 let OutOperandList = (outs type0:$dst, type1:$carry_out);
268 let InOperandList = (ins type0:$src1, type0:$src2);
269 let hasSideEffects = 0;
270 let isCommutable = 1;
273 // Generic unsigned subtraction consuming and producing a carry flag.
274 def G_USUBE : Instruction {
275 let OutOperandList = (outs type0:$dst, type1:$carry_out);
276 let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
277 let hasSideEffects = 0;
280 // Generic unsigned subtraction producing a carry flag.
281 def G_SSUBO : Instruction {
282 let OutOperandList = (outs type0:$dst, type1:$carry_out);
283 let InOperandList = (ins type0:$src1, type0:$src2);
284 let hasSideEffects = 0;
287 // Generic unsigned multiplication producing a carry flag.
288 def G_UMULO : Instruction {
289 let OutOperandList = (outs type0:$dst, type1:$carry_out);
290 let InOperandList = (ins type0:$src1, type0:$src2);
291 let hasSideEffects = 0;
292 let isCommutable = 1;
295 // Generic signed multiplication producing a carry flag.
296 def G_SMULO : Instruction {
297 let OutOperandList = (outs type0:$dst, type1:$carry_out);
298 let InOperandList = (ins type0:$src1, type0:$src2);
299 let hasSideEffects = 0;
300 let isCommutable = 1;
303 // Multiply two numbers at twice the incoming bit width (unsigned) and return
304 // the high half of the result.
305 def G_UMULH : Instruction {
306 let OutOperandList = (outs type0:$dst);
307 let InOperandList = (ins type0:$src1, type0:$src2);
308 let hasSideEffects = 0;
309 let isCommutable = 1;
312 // Multiply two numbers at twice the incoming bit width (signed) and return
313 // the high half of the result.
314 def G_SMULH : Instruction {
315 let OutOperandList = (outs type0:$dst);
316 let InOperandList = (ins type0:$src1, type0:$src2);
317 let hasSideEffects = 0;
318 let isCommutable = 1;
321 //------------------------------------------------------------------------------
322 // Floating Point Unary Ops.
323 //------------------------------------------------------------------------------
325 def G_FNEG : Instruction {
326 let OutOperandList = (outs type0:$dst);
327 let InOperandList = (ins type0:$src);
328 let hasSideEffects = 0;
331 def G_FPEXT : Instruction {
332 let OutOperandList = (outs type0:$dst);
333 let InOperandList = (ins type1:$src);
334 let hasSideEffects = 0;
337 def G_FPTRUNC : Instruction {
338 let OutOperandList = (outs type0:$dst);
339 let InOperandList = (ins type1:$src);
340 let hasSideEffects = 0;
343 def G_FPTOSI : Instruction {
344 let OutOperandList = (outs type0:$dst);
345 let InOperandList = (ins type1:$src);
346 let hasSideEffects = 0;
349 def G_FPTOUI : Instruction {
350 let OutOperandList = (outs type0:$dst);
351 let InOperandList = (ins type1:$src);
352 let hasSideEffects = 0;
355 def G_SITOFP : Instruction {
356 let OutOperandList = (outs type0:$dst);
357 let InOperandList = (ins type1:$src);
358 let hasSideEffects = 0;
361 def G_UITOFP : Instruction {
362 let OutOperandList = (outs type0:$dst);
363 let InOperandList = (ins type1:$src);
364 let hasSideEffects = 0;
367 //------------------------------------------------------------------------------
368 // Floating Point Binary ops.
369 //------------------------------------------------------------------------------
371 // Generic FP addition.
372 def G_FADD : Instruction {
373 let OutOperandList = (outs type0:$dst);
374 let InOperandList = (ins type0:$src1, type0:$src2);
375 let hasSideEffects = 0;
376 let isCommutable = 1;
379 // Generic FP subtraction.
380 def G_FSUB : Instruction {
381 let OutOperandList = (outs type0:$dst);
382 let InOperandList = (ins type0:$src1, type0:$src2);
383 let hasSideEffects = 0;
384 let isCommutable = 0;
387 // Generic FP multiplication.
388 def G_FMUL : Instruction {
389 let OutOperandList = (outs type0:$dst);
390 let InOperandList = (ins type0:$src1, type0:$src2);
391 let hasSideEffects = 0;
392 let isCommutable = 1;
395 // Generic fused multiply-add instruction.
396 // Behaves like llvm fma intrinsic ie src1 * src2 + src3
397 def G_FMA : Instruction {
398 let OutOperandList = (outs type0:$dst);
399 let InOperandList = (ins type0:$src1, type0:$src2, type0:$src3);
400 let hasSideEffects = 0;
401 let isCommutable = 0;
404 // Generic FP division.
405 def G_FDIV : Instruction {
406 let OutOperandList = (outs type0:$dst);
407 let InOperandList = (ins type0:$src1, type0:$src2);
408 let hasSideEffects = 0;
411 // Generic FP remainder.
412 def G_FREM : Instruction {
413 let OutOperandList = (outs type0:$dst);
414 let InOperandList = (ins type0:$src1, type0:$src2);
415 let hasSideEffects = 0;
418 // Floating point exponentiation.
419 def G_FPOW : Instruction {
420 let OutOperandList = (outs type0:$dst);
421 let InOperandList = (ins type0:$src1, type0:$src2);
422 let hasSideEffects = 0;
425 // Floating point base-e exponential of a value.
426 def G_FEXP : Instruction {
427 let OutOperandList = (outs type0:$dst);
428 let InOperandList = (ins type0:$src1);
429 let hasSideEffects = 0;
432 // Floating point base-2 exponential of a value.
433 def G_FEXP2 : Instruction {
434 let OutOperandList = (outs type0:$dst);
435 let InOperandList = (ins type0:$src1);
436 let hasSideEffects = 0;
439 // Floating point base-2 logarithm of a value.
440 def G_FLOG : Instruction {
441 let OutOperandList = (outs type0:$dst);
442 let InOperandList = (ins type0:$src1);
443 let hasSideEffects = 0;
446 // Floating point base-2 logarithm of a value.
447 def G_FLOG2 : Instruction {
448 let OutOperandList = (outs type0:$dst);
449 let InOperandList = (ins type0:$src1);
450 let hasSideEffects = 0;
453 //------------------------------------------------------------------------------
455 //------------------------------------------------------------------------------
457 // Generic load. Expects a MachineMemOperand in addition to explicit operands.
458 def G_LOAD : Instruction {
459 let OutOperandList = (outs type0:$dst);
460 let InOperandList = (ins type1:$addr);
461 let hasSideEffects = 0;
465 // Generic store. Expects a MachineMemOperand in addition to explicit operands.
466 def G_STORE : Instruction {
467 let OutOperandList = (outs);
468 let InOperandList = (ins type0:$src, type1:$addr);
469 let hasSideEffects = 0;
473 //------------------------------------------------------------------------------
475 //------------------------------------------------------------------------------
477 // Extract multiple registers specified size, starting from blocks given by
478 // indexes. This will almost certainly be mapped to sub-register COPYs after
479 // register banks have been selected.
480 def G_EXTRACT : Instruction {
481 let OutOperandList = (outs type0:$res);
482 let InOperandList = (ins type1:$src, unknown:$offset);
483 let hasSideEffects = 0;
486 // Extract multiple registers specified size, starting from blocks given by
487 // indexes. This will almost certainly be mapped to sub-register COPYs after
488 // register banks have been selected.
489 def G_UNMERGE_VALUES : Instruction {
490 let OutOperandList = (outs);
491 let InOperandList = (ins variable_ops);
492 let hasSideEffects = 0;
495 // Insert a smaller register into a larger one at the specified bit-index.
496 def G_INSERT : Instruction {
497 let OutOperandList = (outs type0:$dst);
498 let InOperandList = (ins type0:$src, type1:$op, unknown:$offset);
499 let hasSideEffects = 0;
502 def G_MERGE_VALUES : Instruction {
503 let OutOperandList = (outs type0:$dst);
504 let InOperandList = (ins variable_ops);
505 let hasSideEffects = 0;
508 // Intrinsic without side effects.
509 def G_INTRINSIC : Instruction {
510 let OutOperandList = (outs);
511 let InOperandList = (ins unknown:$intrin, variable_ops);
512 let hasSideEffects = 0;
515 // Intrinsic with side effects.
516 def G_INTRINSIC_W_SIDE_EFFECTS : Instruction {
517 let OutOperandList = (outs);
518 let InOperandList = (ins unknown:$intrin, variable_ops);
519 let hasSideEffects = 1;
524 //------------------------------------------------------------------------------
526 //------------------------------------------------------------------------------
528 // Generic unconditional branch.
529 def G_BR : Instruction {
530 let OutOperandList = (outs);
531 let InOperandList = (ins unknown:$src1);
532 let hasSideEffects = 0;
534 let isTerminator = 1;
538 // Generic conditional branch.
539 def G_BRCOND : Instruction {
540 let OutOperandList = (outs);
541 let InOperandList = (ins type0:$tst, unknown:$truebb);
542 let hasSideEffects = 0;
544 let isTerminator = 1;
547 // Generic indirect branch.
548 def G_BRINDIRECT : Instruction {
549 let OutOperandList = (outs);
550 let InOperandList = (ins type0:$src1);
551 let hasSideEffects = 0;
553 let isTerminator = 1;
556 //------------------------------------------------------------------------------
558 //------------------------------------------------------------------------------
560 // Generic insertelement.
561 def G_INSERT_VECTOR_ELT : Instruction {
562 let OutOperandList = (outs type0:$dst);
563 let InOperandList = (ins type0:$src, type1:$elt, type2:$idx);
564 let hasSideEffects = 0;
567 // Generic extractelement.
568 def G_EXTRACT_VECTOR_ELT : Instruction {
569 let OutOperandList = (outs type0:$dst);
570 let InOperandList = (ins type1:$src, type2:$idx);
571 let hasSideEffects = 0;
574 // Generic shufflevector.
575 def G_SHUFFLE_VECTOR: Instruction {
576 let OutOperandList = (outs type0:$dst);
577 let InOperandList = (ins type1:$v1, type1:$v2, type2:$mask);
578 let hasSideEffects = 0;
581 // TODO: Add the other generic opcodes.