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_FRAME_INDEX : Instruction {
53 let OutOperandList = (outs type0:$dst);
54 let InOperandList = (ins unknown:$src2);
55 let hasSideEffects = 0;
58 def G_GLOBAL_VALUE : Instruction {
59 let OutOperandList = (outs type0:$dst);
60 let InOperandList = (ins unknown:$src);
61 let hasSideEffects = 0;
64 def G_INTTOPTR : Instruction {
65 let OutOperandList = (outs type0:$dst);
66 let InOperandList = (ins type1:$src);
67 let hasSideEffects = 0;
70 def G_PTRTOINT : Instruction {
71 let OutOperandList = (outs type0:$dst);
72 let InOperandList = (ins type1:$src);
73 let hasSideEffects = 0;
76 def G_BITCAST : Instruction {
77 let OutOperandList = (outs type0:$dst);
78 let InOperandList = (ins type1:$src);
79 let hasSideEffects = 0;
82 def G_CONSTANT : Instruction {
83 let OutOperandList = (outs type0:$dst);
84 let InOperandList = (ins unknown:$imm);
85 let hasSideEffects = 0;
88 def G_FCONSTANT : Instruction {
89 let OutOperandList = (outs type0:$dst);
90 let InOperandList = (ins unknown:$imm);
91 let hasSideEffects = 0;
94 def G_VASTART : Instruction {
95 let OutOperandList = (outs);
96 let InOperandList = (ins type0:$list);
97 let hasSideEffects = 0;
101 def G_VAARG : Instruction {
102 let OutOperandList = (outs type0:$val);
103 let InOperandList = (ins type1:$list, unknown:$align);
104 let hasSideEffects = 0;
109 //------------------------------------------------------------------------------
111 //------------------------------------------------------------------------------
114 def G_ADD : Instruction {
115 let OutOperandList = (outs type0:$dst);
116 let InOperandList = (ins type0:$src1, type0:$src2);
117 let hasSideEffects = 0;
118 let isCommutable = 1;
121 // Generic subtraction.
122 def G_SUB : Instruction {
123 let OutOperandList = (outs type0:$dst);
124 let InOperandList = (ins type0:$src1, type0:$src2);
125 let hasSideEffects = 0;
126 let isCommutable = 0;
129 // Generic multiplication.
130 def G_MUL : Instruction {
131 let OutOperandList = (outs type0:$dst);
132 let InOperandList = (ins type0:$src1, type0:$src2);
133 let hasSideEffects = 0;
134 let isCommutable = 1;
137 // Generic signed division.
138 def G_SDIV : Instruction {
139 let OutOperandList = (outs type0:$dst);
140 let InOperandList = (ins type0:$src1, type0:$src2);
141 let hasSideEffects = 0;
142 let isCommutable = 0;
145 // Generic unsigned division.
146 def G_UDIV : Instruction {
147 let OutOperandList = (outs type0:$dst);
148 let InOperandList = (ins type0:$src1, type0:$src2);
149 let hasSideEffects = 0;
150 let isCommutable = 0;
153 // Generic signed remainder.
154 def G_SREM : Instruction {
155 let OutOperandList = (outs type0:$dst);
156 let InOperandList = (ins type0:$src1, type0:$src2);
157 let hasSideEffects = 0;
158 let isCommutable = 0;
161 // Generic unsigned remainder.
162 def G_UREM : Instruction {
163 let OutOperandList = (outs type0:$dst);
164 let InOperandList = (ins type0:$src1, type0:$src2);
165 let hasSideEffects = 0;
166 let isCommutable = 0;
169 // Generic bitwise and.
170 def G_AND : Instruction {
171 let OutOperandList = (outs type0:$dst);
172 let InOperandList = (ins type0:$src1, type0:$src2);
173 let hasSideEffects = 0;
174 let isCommutable = 1;
177 // Generic bitwise or.
178 def G_OR : Instruction {
179 let OutOperandList = (outs type0:$dst);
180 let InOperandList = (ins type0:$src1, type0:$src2);
181 let hasSideEffects = 0;
182 let isCommutable = 1;
185 // Generic bitwise xor.
186 def G_XOR : Instruction {
187 let OutOperandList = (outs type0:$dst);
188 let InOperandList = (ins type0:$src1, type0:$src2);
189 let hasSideEffects = 0;
190 let isCommutable = 1;
193 // Generic left-shift.
194 def G_SHL : Instruction {
195 let OutOperandList = (outs type0:$dst);
196 let InOperandList = (ins type0:$src1, type0:$src2);
197 let hasSideEffects = 0;
200 // Generic logical right-shift.
201 def G_LSHR : Instruction {
202 let OutOperandList = (outs type0:$dst);
203 let InOperandList = (ins type0:$src1, type0:$src2);
204 let hasSideEffects = 0;
207 // Generic arithmetic right-shift.
208 def G_ASHR : Instruction {
209 let OutOperandList = (outs type0:$dst);
210 let InOperandList = (ins type0:$src1, type0:$src2);
211 let hasSideEffects = 0;
214 // Generic integer comparison.
215 def G_ICMP : Instruction {
216 let OutOperandList = (outs type0:$dst);
217 let InOperandList = (ins unknown:$tst, type1:$src1, type1:$src2);
218 let hasSideEffects = 0;
221 // Generic floating-point comparison.
222 def G_FCMP : Instruction {
223 let OutOperandList = (outs type0:$dst);
224 let InOperandList = (ins unknown:$tst, type1:$src1, type1:$src2);
225 let hasSideEffects = 0;
229 def G_SELECT : Instruction {
230 let OutOperandList = (outs type0:$dst);
231 let InOperandList = (ins type1:$tst, type0:$src1, type0:$src2);
232 let hasSideEffects = 0;
235 // Generic pointer offset.
236 def G_GEP : Instruction {
237 let OutOperandList = (outs type0:$dst);
238 let InOperandList = (ins type0:$src1, type1:$src2);
239 let hasSideEffects = 0;
242 def G_PTR_MASK : Instruction {
243 let OutOperandList = (outs type0:$dst);
244 let InOperandList = (ins type0:$src, unknown:$bits);
245 let hasSideEffects = 0;
248 //------------------------------------------------------------------------------
250 //------------------------------------------------------------------------------
252 // Generic unsigned addition consuming and producing a carry flag.
253 def G_UADDE : Instruction {
254 let OutOperandList = (outs type0:$dst, type1:$carry_out);
255 let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
256 let hasSideEffects = 0;
259 // Generic signed addition producing a carry flag.
260 def G_SADDO : Instruction {
261 let OutOperandList = (outs type0:$dst, type1:$carry_out);
262 let InOperandList = (ins type0:$src1, type0:$src2);
263 let hasSideEffects = 0;
264 let isCommutable = 1;
267 // Generic unsigned subtraction consuming and producing a carry flag.
268 def G_USUBE : Instruction {
269 let OutOperandList = (outs type0:$dst, type1:$carry_out);
270 let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
271 let hasSideEffects = 0;
274 // Generic unsigned subtraction producing a carry flag.
275 def G_SSUBO : Instruction {
276 let OutOperandList = (outs type0:$dst, type1:$carry_out);
277 let InOperandList = (ins type0:$src1, type0:$src2);
278 let hasSideEffects = 0;
281 // Generic unsigned multiplication producing a carry flag.
282 def G_UMULO : Instruction {
283 let OutOperandList = (outs type0:$dst, type1:$carry_out);
284 let InOperandList = (ins type0:$src1, type0:$src2);
285 let hasSideEffects = 0;
286 let isCommutable = 1;
289 // Generic signed multiplication producing a carry flag.
290 def G_SMULO : Instruction {
291 let OutOperandList = (outs type0:$dst, type1:$carry_out);
292 let InOperandList = (ins type0:$src1, type0:$src2);
293 let hasSideEffects = 0;
294 let isCommutable = 1;
297 // Multiply two numbers at twice the incoming bit width (unsigned) and return
298 // the high half of the result.
299 def G_UMULH : Instruction {
300 let OutOperandList = (outs type0:$dst);
301 let InOperandList = (ins type0:$src1, type0:$src2);
302 let hasSideEffects = 0;
303 let isCommutable = 1;
306 // Multiply two numbers at twice the incoming bit width (signed) and return
307 // the high half of the result.
308 def G_SMULH : Instruction {
309 let OutOperandList = (outs type0:$dst);
310 let InOperandList = (ins type0:$src1, type0:$src2);
311 let hasSideEffects = 0;
312 let isCommutable = 1;
315 //------------------------------------------------------------------------------
316 // Floating Point Unary Ops.
317 //------------------------------------------------------------------------------
319 def G_FNEG : Instruction {
320 let OutOperandList = (outs type0:$dst);
321 let InOperandList = (ins type0:$src);
322 let hasSideEffects = 0;
325 def G_FPEXT : Instruction {
326 let OutOperandList = (outs type0:$dst);
327 let InOperandList = (ins type1:$src);
328 let hasSideEffects = 0;
331 def G_FPTRUNC : Instruction {
332 let OutOperandList = (outs type0:$dst);
333 let InOperandList = (ins type1:$src);
334 let hasSideEffects = 0;
337 def G_FPTOSI : Instruction {
338 let OutOperandList = (outs type0:$dst);
339 let InOperandList = (ins type1:$src);
340 let hasSideEffects = 0;
343 def G_FPTOUI : Instruction {
344 let OutOperandList = (outs type0:$dst);
345 let InOperandList = (ins type1:$src);
346 let hasSideEffects = 0;
349 def G_SITOFP : Instruction {
350 let OutOperandList = (outs type0:$dst);
351 let InOperandList = (ins type1:$src);
352 let hasSideEffects = 0;
355 def G_UITOFP : Instruction {
356 let OutOperandList = (outs type0:$dst);
357 let InOperandList = (ins type1:$src);
358 let hasSideEffects = 0;
361 //------------------------------------------------------------------------------
362 // Floating Point Binary ops.
363 //------------------------------------------------------------------------------
365 // Generic FP addition.
366 def G_FADD : Instruction {
367 let OutOperandList = (outs type0:$dst);
368 let InOperandList = (ins type0:$src1, type0:$src2);
369 let hasSideEffects = 0;
370 let isCommutable = 1;
373 // Generic FP subtraction.
374 def G_FSUB : Instruction {
375 let OutOperandList = (outs type0:$dst);
376 let InOperandList = (ins type0:$src1, type0:$src2);
377 let hasSideEffects = 0;
378 let isCommutable = 0;
381 // Generic FP multiplication.
382 def G_FMUL : Instruction {
383 let OutOperandList = (outs type0:$dst);
384 let InOperandList = (ins type0:$src1, type0:$src2);
385 let hasSideEffects = 0;
386 let isCommutable = 1;
389 // Generic FP division.
390 def G_FDIV : Instruction {
391 let OutOperandList = (outs type0:$dst);
392 let InOperandList = (ins type0:$src1, type0:$src2);
393 let hasSideEffects = 0;
396 // Generic FP remainder.
397 def G_FREM : Instruction {
398 let OutOperandList = (outs type0:$dst);
399 let InOperandList = (ins type0:$src1, type0:$src2);
400 let hasSideEffects = 0;
403 // Floating point exponentiation.
404 def G_FPOW : Instruction {
405 let OutOperandList = (outs type0:$dst);
406 let InOperandList = (ins type0:$src1, type0:$src2);
407 let hasSideEffects = 0;
410 //------------------------------------------------------------------------------
412 //------------------------------------------------------------------------------
414 // Generic load. Expects a MachineMemOperand in addition to explicit operands.
415 def G_LOAD : Instruction {
416 let OutOperandList = (outs type0:$dst);
417 let InOperandList = (ins type1:$addr);
418 let hasSideEffects = 0;
422 // Generic store. Expects a MachineMemOperand in addition to explicit operands.
423 def G_STORE : Instruction {
424 let OutOperandList = (outs);
425 let InOperandList = (ins type0:$src, type1:$addr);
426 let hasSideEffects = 0;
430 //------------------------------------------------------------------------------
432 //------------------------------------------------------------------------------
434 // Extract multiple registers specified size, starting from blocks given by
435 // indexes. This will almost certainly be mapped to sub-register COPYs after
436 // register banks have been selected.
437 def G_EXTRACT : Instruction {
438 let OutOperandList = (outs type0:$res);
439 let InOperandList = (ins type1:$src, unknown:$offset);
440 let hasSideEffects = 0;
443 // Extract multiple registers specified size, starting from blocks given by
444 // indexes. This will almost certainly be mapped to sub-register COPYs after
445 // register banks have been selected.
446 def G_UNMERGE_VALUES : Instruction {
447 let OutOperandList = (outs);
448 let InOperandList = (ins variable_ops);
449 let hasSideEffects = 0;
452 // Insert a smaller register into a larger one at the specified bit-index.
453 def G_INSERT : Instruction {
454 let OutOperandList = (outs type0:$dst);
455 let InOperandList = (ins type0:$src, type1:$op, unknown:$offset);
456 let hasSideEffects = 0;
459 // Combine a sequence of generic vregs into a single larger value (starting at
460 // bit 0). Essentially a G_INSERT where $src is an IMPLICIT_DEF, but it's so
461 // important to legalization it probably deserves its own instruction.
462 def G_SEQUENCE : Instruction {
463 let OutOperandList = (outs type0:$dst);
464 let InOperandList = (ins variable_ops);
465 let hasSideEffects = 0;
468 def G_MERGE_VALUES : Instruction {
469 let OutOperandList = (outs type0:$dst);
470 let InOperandList = (ins variable_ops);
471 let hasSideEffects = 0;
474 // Intrinsic without side effects.
475 def G_INTRINSIC : Instruction {
476 let OutOperandList = (outs);
477 let InOperandList = (ins unknown:$intrin, variable_ops);
478 let hasSideEffects = 0;
481 // Intrinsic with side effects.
482 def G_INTRINSIC_W_SIDE_EFFECTS : Instruction {
483 let OutOperandList = (outs);
484 let InOperandList = (ins unknown:$intrin, variable_ops);
485 let hasSideEffects = 1;
490 //------------------------------------------------------------------------------
492 //------------------------------------------------------------------------------
494 // Generic unconditional branch.
495 def G_BR : Instruction {
496 let OutOperandList = (outs);
497 let InOperandList = (ins unknown:$src1);
498 let hasSideEffects = 0;
500 let isTerminator = 1;
504 // Generic conditional branch.
505 def G_BRCOND : Instruction {
506 let OutOperandList = (outs);
507 let InOperandList = (ins type0:$tst, unknown:$truebb);
508 let hasSideEffects = 0;
510 let isTerminator = 1;
513 // Generic indirect branch.
514 def G_BRINDIRECT : Instruction {
515 let OutOperandList = (outs);
516 let InOperandList = (ins type0:$src1);
517 let hasSideEffects = 0;
519 let isTerminator = 1;
522 //------------------------------------------------------------------------------
524 //------------------------------------------------------------------------------
526 // Generic insertelement.
527 def G_INSERT_VECTOR_ELT : Instruction {
528 let OutOperandList = (outs type0:$dst);
529 let InOperandList = (ins type0:$src, type1:$elt, type2:$idx);
530 let hasSideEffects = 0;
533 // Generic extractelement.
534 def G_EXTRACT_VECTOR_ELT : Instruction {
535 let OutOperandList = (outs type0:$dst);
536 let InOperandList = (ins type1:$src, type2:$idx);
537 let hasSideEffects = 0;
540 // Generic shufflevector.
541 def G_SHUFFLE_VECTOR: Instruction {
542 let OutOperandList = (outs type0:$dst);
543 let InOperandList = (ins type1:$v1, type1:$v2, type2:$mask);
544 let hasSideEffects = 0;
547 // TODO: Add the other generic opcodes.