]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/Target/GenericOpcodes.td
Merge ^/head r316992 through r317215.
[FreeBSD/FreeBSD.git] / contrib / llvm / include / llvm / Target / GenericOpcodes.td
1 //===-- 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
19 // Extend the underlying scalar type of an operation, leaving the high bits
20 // unspecified.
21 def G_ANYEXT : Instruction {
22   let OutOperandList = (outs type0:$dst);
23   let InOperandList = (ins type1:$src);
24   let hasSideEffects = 0;
25 }
26
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;
33 }
34
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;
41 }
42
43
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;
50 }
51
52 def G_FRAME_INDEX : Instruction {
53   let OutOperandList = (outs type0:$dst);
54   let InOperandList = (ins unknown:$src2);
55   let hasSideEffects = 0;
56 }
57
58 def G_GLOBAL_VALUE : Instruction {
59   let OutOperandList = (outs type0:$dst);
60   let InOperandList = (ins unknown:$src);
61   let hasSideEffects = 0;
62 }
63
64 def G_INTTOPTR : Instruction {
65   let OutOperandList = (outs type0:$dst);
66   let InOperandList = (ins type1:$src);
67   let hasSideEffects = 0;
68 }
69
70 def G_PTRTOINT : Instruction {
71   let OutOperandList = (outs type0:$dst);
72   let InOperandList = (ins type1:$src);
73   let hasSideEffects = 0;
74 }
75
76 def G_BITCAST : Instruction {
77   let OutOperandList = (outs type0:$dst);
78   let InOperandList = (ins type1:$src);
79   let hasSideEffects = 0;
80 }
81
82 def G_CONSTANT : Instruction {
83   let OutOperandList = (outs type0:$dst);
84   let InOperandList = (ins unknown:$imm);
85   let hasSideEffects = 0;
86 }
87
88 def G_FCONSTANT : Instruction {
89   let OutOperandList = (outs type0:$dst);
90   let InOperandList = (ins unknown:$imm);
91   let hasSideEffects = 0;
92 }
93
94 def G_VASTART : Instruction {
95   let OutOperandList = (outs);
96   let InOperandList = (ins type0:$list);
97   let hasSideEffects = 0;
98   let mayStore = 1;
99 }
100
101 def G_VAARG : Instruction {
102   let OutOperandList = (outs type0:$val);
103   let InOperandList = (ins type1:$list, unknown:$align);
104   let hasSideEffects = 0;
105   let mayLoad = 1;
106   let mayStore = 1;
107 }
108
109 //------------------------------------------------------------------------------
110 // Binary ops.
111 //------------------------------------------------------------------------------
112
113 // Generic addition.
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;
119 }
120
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;
127 }
128
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;
135 }
136
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;
143 }
144
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;
151 }
152
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;
159 }
160
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;
167 }
168
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;
175 }
176
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;
183 }
184
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;
191 }
192
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;
198 }
199
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;
205 }
206
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;
212 }
213
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;
219 }
220
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;
226 }
227
228 // Generic select
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;
233 }
234
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;
240 }
241
242 def G_PTR_MASK : Instruction {
243   let OutOperandList = (outs type0:$dst);
244   let InOperandList = (ins type0:$src, unknown:$bits);
245   let hasSideEffects = 0;
246 }
247
248 //------------------------------------------------------------------------------
249 // Overflow ops
250 //------------------------------------------------------------------------------
251
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;
257 }
258
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;
265 }
266
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;
272 }
273
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;
279 }
280
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;
287 }
288
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;
295 }
296
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;
304 }
305
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;
313 }
314
315 //------------------------------------------------------------------------------
316 // Floating Point Unary Ops.
317 //------------------------------------------------------------------------------
318
319 def G_FNEG : Instruction {
320   let OutOperandList = (outs type0:$dst);
321   let InOperandList = (ins type0:$src);
322   let hasSideEffects = 0;
323 }
324
325 def G_FPEXT : Instruction {
326   let OutOperandList = (outs type0:$dst);
327   let InOperandList = (ins type1:$src);
328   let hasSideEffects = 0;
329 }
330
331 def G_FPTRUNC : Instruction {
332   let OutOperandList = (outs type0:$dst);
333   let InOperandList = (ins type1:$src);
334   let hasSideEffects = 0;
335 }
336
337 def G_FPTOSI : Instruction {
338   let OutOperandList = (outs type0:$dst);
339   let InOperandList = (ins type1:$src);
340   let hasSideEffects = 0;
341 }
342
343 def G_FPTOUI : Instruction {
344   let OutOperandList = (outs type0:$dst);
345   let InOperandList = (ins type1:$src);
346   let hasSideEffects = 0;
347 }
348
349 def G_SITOFP : Instruction {
350   let OutOperandList = (outs type0:$dst);
351   let InOperandList = (ins type1:$src);
352   let hasSideEffects = 0;
353 }
354
355 def G_UITOFP : Instruction {
356   let OutOperandList = (outs type0:$dst);
357   let InOperandList = (ins type1:$src);
358   let hasSideEffects = 0;
359 }
360
361 //------------------------------------------------------------------------------
362 // Floating Point Binary ops.
363 //------------------------------------------------------------------------------
364
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;
371 }
372
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;
379 }
380
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;
387 }
388
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;
394 }
395
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;
401 }
402
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;
408 }
409
410 //------------------------------------------------------------------------------
411 // Memory ops
412 //------------------------------------------------------------------------------
413
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;
419   let mayLoad = 1;
420 }
421
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;
427   let mayStore = 1;
428 }
429
430 //------------------------------------------------------------------------------
431 // Variadic ops
432 //------------------------------------------------------------------------------
433
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;
441 }
442
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;
450 }
451
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;
457 }
458
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;
466 }
467
468 def G_MERGE_VALUES : Instruction {
469   let OutOperandList = (outs type0:$dst);
470   let InOperandList = (ins variable_ops);
471   let hasSideEffects = 0;
472 }
473
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;
479 }
480
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;
486   let mayLoad = 1;
487   let mayStore = 1;
488 }
489
490 //------------------------------------------------------------------------------
491 // Branches.
492 //------------------------------------------------------------------------------
493
494 // Generic unconditional branch.
495 def G_BR : Instruction {
496   let OutOperandList = (outs);
497   let InOperandList = (ins unknown:$src1);
498   let hasSideEffects = 0;
499   let isBranch = 1;
500   let isTerminator = 1;
501   let isBarrier = 1;
502 }
503
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;
509   let isBranch = 1;
510   let isTerminator = 1;
511 }
512
513 // Generic indirect branch.
514 def G_BRINDIRECT : Instruction {
515   let OutOperandList = (outs);
516   let InOperandList = (ins type0:$src1);
517   let hasSideEffects = 0;
518   let isBranch = 1;
519   let isTerminator = 1;
520 }
521
522 //------------------------------------------------------------------------------
523 // Vector ops
524 //------------------------------------------------------------------------------
525
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;
531 }
532
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;
538 }
539
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;
545 }
546
547 // TODO: Add the other generic opcodes.