]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/Target/GenericOpcodes.td
Copy libevent sources to contrib
[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 class GenericInstruction : StandardPseudoInstruction;
20
21 // Extend the underlying scalar type of an operation, leaving the high bits
22 // unspecified.
23 def 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.
31 def 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.
39 def 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.
48 def G_TRUNC : GenericInstruction {
49   let OutOperandList = (outs type0:$dst);
50   let InOperandList = (ins type1:$src);
51   let hasSideEffects = 0;
52 }
53
54 def G_IMPLICIT_DEF : GenericInstruction {
55   let OutOperandList = (outs type0:$dst);
56   let InOperandList = (ins);
57   let hasSideEffects = 0;
58 }
59
60 def G_PHI : GenericInstruction {
61   let OutOperandList = (outs type0:$dst);
62   let InOperandList = (ins variable_ops);
63   let hasSideEffects = 0;
64 }
65
66 def G_FRAME_INDEX : GenericInstruction {
67   let OutOperandList = (outs type0:$dst);
68   let InOperandList = (ins unknown:$src2);
69   let hasSideEffects = 0;
70 }
71
72 def G_GLOBAL_VALUE : GenericInstruction {
73   let OutOperandList = (outs type0:$dst);
74   let InOperandList = (ins unknown:$src);
75   let hasSideEffects = 0;
76 }
77
78 def G_INTTOPTR : GenericInstruction {
79   let OutOperandList = (outs type0:$dst);
80   let InOperandList = (ins type1:$src);
81   let hasSideEffects = 0;
82 }
83
84 def G_PTRTOINT : GenericInstruction {
85   let OutOperandList = (outs type0:$dst);
86   let InOperandList = (ins type1:$src);
87   let hasSideEffects = 0;
88 }
89
90 def G_BITCAST : GenericInstruction {
91   let OutOperandList = (outs type0:$dst);
92   let InOperandList = (ins type1:$src);
93   let hasSideEffects = 0;
94 }
95
96 def G_CONSTANT : GenericInstruction {
97   let OutOperandList = (outs type0:$dst);
98   let InOperandList = (ins unknown:$imm);
99   let hasSideEffects = 0;
100 }
101
102 def G_FCONSTANT : GenericInstruction {
103   let OutOperandList = (outs type0:$dst);
104   let InOperandList = (ins unknown:$imm);
105   let hasSideEffects = 0;
106 }
107
108 def G_VASTART : GenericInstruction {
109   let OutOperandList = (outs);
110   let InOperandList = (ins type0:$list);
111   let hasSideEffects = 0;
112   let mayStore = 1;
113 }
114
115 def 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
123 def 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.
134 def 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.
142 def 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.
150 def 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.
158 def 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.
166 def 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.
174 def 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.
182 def 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.
190 def 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.
198 def 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.
206 def 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.
214 def 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.
221 def 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.
228 def 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.
235 def 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.
242 def 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
249 def 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.
256 def G_GEP : GenericInstruction {
257   let OutOperandList = (outs type0:$dst);
258   let InOperandList = (ins type0:$src1, type1:$src2);
259   let hasSideEffects = 0;
260 }
261
262 def 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.
273 def 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.
280 def 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.
288 def 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.
295 def 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.
302 def 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.
310 def 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.
319 def 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.
328 def 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
339 def G_FNEG : GenericInstruction {
340   let OutOperandList = (outs type0:$dst);
341   let InOperandList = (ins type0:$src);
342   let hasSideEffects = 0;
343 }
344
345 def G_FPEXT : GenericInstruction {
346   let OutOperandList = (outs type0:$dst);
347   let InOperandList = (ins type1:$src);
348   let hasSideEffects = 0;
349 }
350
351 def G_FPTRUNC : GenericInstruction {
352   let OutOperandList = (outs type0:$dst);
353   let InOperandList = (ins type1:$src);
354   let hasSideEffects = 0;
355 }
356
357 def G_FPTOSI : GenericInstruction {
358   let OutOperandList = (outs type0:$dst);
359   let InOperandList = (ins type1:$src);
360   let hasSideEffects = 0;
361 }
362
363 def G_FPTOUI : GenericInstruction {
364   let OutOperandList = (outs type0:$dst);
365   let InOperandList = (ins type1:$src);
366   let hasSideEffects = 0;
367 }
368
369 def G_SITOFP : GenericInstruction {
370   let OutOperandList = (outs type0:$dst);
371   let InOperandList = (ins type1:$src);
372   let hasSideEffects = 0;
373 }
374
375 def G_UITOFP : GenericInstruction {
376   let OutOperandList = (outs type0:$dst);
377   let InOperandList = (ins type1:$src);
378   let hasSideEffects = 0;
379 }
380
381 //------------------------------------------------------------------------------
382 // Floating Point Binary ops.
383 //------------------------------------------------------------------------------
384
385 // Generic FP addition.
386 def G_FADD : GenericInstruction {
387   let OutOperandList = (outs type0:$dst);
388   let InOperandList = (ins type0:$src1, type0:$src2);
389   let hasSideEffects = 0;
390   let isCommutable = 1;
391 }
392
393 // Generic FP subtraction.
394 def G_FSUB : GenericInstruction {
395   let OutOperandList = (outs type0:$dst);
396   let InOperandList = (ins type0:$src1, type0:$src2);
397   let hasSideEffects = 0;
398   let isCommutable = 0;
399 }
400
401 // Generic FP multiplication.
402 def G_FMUL : GenericInstruction {
403   let OutOperandList = (outs type0:$dst);
404   let InOperandList = (ins type0:$src1, type0:$src2);
405   let hasSideEffects = 0;
406   let isCommutable = 1;
407 }
408
409 // Generic fused multiply-add instruction.
410 // Behaves like llvm fma intrinsic ie src1 * src2 + src3
411 def G_FMA : GenericInstruction {
412   let OutOperandList = (outs type0:$dst);
413   let InOperandList = (ins type0:$src1, type0:$src2, type0:$src3);
414   let hasSideEffects = 0;
415   let isCommutable = 0;
416 }
417
418 // Generic FP division.
419 def G_FDIV : GenericInstruction {
420   let OutOperandList = (outs type0:$dst);
421   let InOperandList = (ins type0:$src1, type0:$src2);
422   let hasSideEffects = 0;
423 }
424
425 // Generic FP remainder.
426 def G_FREM : GenericInstruction {
427   let OutOperandList = (outs type0:$dst);
428   let InOperandList = (ins type0:$src1, type0:$src2);
429   let hasSideEffects = 0;
430 }
431
432 // Floating point exponentiation.
433 def G_FPOW : GenericInstruction {
434   let OutOperandList = (outs type0:$dst);
435   let InOperandList = (ins type0:$src1, type0:$src2);
436   let hasSideEffects = 0;
437 }
438
439 // Floating point base-e exponential of a value.
440 def G_FEXP : GenericInstruction {
441   let OutOperandList = (outs type0:$dst);
442   let InOperandList = (ins type0:$src1);
443   let hasSideEffects = 0;
444 }
445
446 // Floating point base-2 exponential of a value.
447 def G_FEXP2 : GenericInstruction {
448   let OutOperandList = (outs type0:$dst);
449   let InOperandList = (ins type0:$src1);
450   let hasSideEffects = 0;
451 }
452
453 // Floating point base-2 logarithm of a value.
454 def G_FLOG : GenericInstruction {
455   let OutOperandList = (outs type0:$dst);
456   let InOperandList = (ins type0:$src1);
457   let hasSideEffects = 0;
458 }
459
460 // Floating point base-2 logarithm of a value.
461 def G_FLOG2 : GenericInstruction {
462   let OutOperandList = (outs type0:$dst);
463   let InOperandList = (ins type0:$src1);
464   let hasSideEffects = 0;
465 }
466
467 //------------------------------------------------------------------------------
468 // Memory ops
469 //------------------------------------------------------------------------------
470
471 // Generic load. Expects a MachineMemOperand in addition to explicit operands.
472 def G_LOAD : GenericInstruction {
473   let OutOperandList = (outs type0:$dst);
474   let InOperandList = (ins ptype1:$addr);
475   let hasSideEffects = 0;
476   let mayLoad = 1;
477 }
478
479 // Generic store. Expects a MachineMemOperand in addition to explicit operands.
480 def G_STORE : GenericInstruction {
481   let OutOperandList = (outs);
482   let InOperandList = (ins type0:$src, ptype1:$addr);
483   let hasSideEffects = 0;
484   let mayStore = 1;
485 }
486
487 // Generic atomic cmpxchg with internal success check. Expects a
488 // MachineMemOperand in addition to explicit operands.
489 def G_ATOMIC_CMPXCHG_WITH_SUCCESS : GenericInstruction {
490   let OutOperandList = (outs type0:$oldval, type1:$success);
491   let InOperandList = (ins type2:$addr, type0:$cmpval, type0:$newval);
492   let hasSideEffects = 0;
493   let mayLoad = 1;
494   let mayStore = 1;
495 }
496
497 // Generic atomic cmpxchg. Expects a MachineMemOperand in addition to explicit
498 // operands.
499 def G_ATOMIC_CMPXCHG : GenericInstruction {
500   let OutOperandList = (outs type0:$oldval);
501   let InOperandList = (ins ptype1:$addr, type0:$cmpval, type0:$newval);
502   let hasSideEffects = 0;
503   let mayLoad = 1;
504   let mayStore = 1;
505 }
506
507 // Generic atomicrmw. Expects a MachineMemOperand in addition to explicit
508 // operands.
509 class G_ATOMICRMW_OP : GenericInstruction {
510   let OutOperandList = (outs type0:$oldval);
511   let InOperandList = (ins ptype1:$addr, type0:$val);
512   let hasSideEffects = 0;
513   let mayLoad = 1;
514   let mayStore = 1;
515 }
516
517 def G_ATOMICRMW_XCHG : G_ATOMICRMW_OP;
518 def G_ATOMICRMW_ADD : G_ATOMICRMW_OP;
519 def G_ATOMICRMW_SUB : G_ATOMICRMW_OP;
520 def G_ATOMICRMW_AND : G_ATOMICRMW_OP;
521 def G_ATOMICRMW_NAND : G_ATOMICRMW_OP;
522 def G_ATOMICRMW_OR : G_ATOMICRMW_OP;
523 def G_ATOMICRMW_XOR : G_ATOMICRMW_OP;
524 def G_ATOMICRMW_MAX : G_ATOMICRMW_OP;
525 def G_ATOMICRMW_MIN : G_ATOMICRMW_OP;
526 def G_ATOMICRMW_UMAX : G_ATOMICRMW_OP;
527 def G_ATOMICRMW_UMIN : G_ATOMICRMW_OP;
528
529 //------------------------------------------------------------------------------
530 // Variadic ops
531 //------------------------------------------------------------------------------
532
533 // Extract a register of the specified size, starting from the block given by
534 // index. This will almost certainly be mapped to sub-register COPYs after
535 // register banks have been selected.
536 def G_EXTRACT : GenericInstruction {
537   let OutOperandList = (outs type0:$res);
538   let InOperandList = (ins type1:$src, unknown:$offset);
539   let hasSideEffects = 0;
540 }
541
542 // Extract multiple registers specified size, starting from blocks given by
543 // indexes. This will almost certainly be mapped to sub-register COPYs after
544 // register banks have been selected.
545 def G_UNMERGE_VALUES : GenericInstruction {
546   let OutOperandList = (outs type0:$dst0, variable_ops);
547   let InOperandList = (ins type1:$src);
548   let hasSideEffects = 0;
549 }
550
551 // Insert a smaller register into a larger one at the specified bit-index.
552 def G_INSERT : GenericInstruction {
553   let OutOperandList = (outs type0:$dst);
554   let InOperandList = (ins type0:$src, type1:$op, unknown:$offset);
555   let hasSideEffects = 0;
556 }
557
558 /// Concatenate multiple registers of the same size into a wider register.
559 def G_MERGE_VALUES : GenericInstruction {
560   let OutOperandList = (outs type0:$dst);
561   let InOperandList = (ins type1:$src0, variable_ops);
562   let hasSideEffects = 0;
563 }
564
565 // Intrinsic without side effects.
566 def G_INTRINSIC : GenericInstruction {
567   let OutOperandList = (outs);
568   let InOperandList = (ins unknown:$intrin, variable_ops);
569   let hasSideEffects = 0;
570 }
571
572 // Intrinsic with side effects.
573 def G_INTRINSIC_W_SIDE_EFFECTS : GenericInstruction {
574   let OutOperandList = (outs);
575   let InOperandList = (ins unknown:$intrin, variable_ops);
576   let hasSideEffects = 1;
577   let mayLoad = 1;
578   let mayStore = 1;
579 }
580
581 //------------------------------------------------------------------------------
582 // Branches.
583 //------------------------------------------------------------------------------
584
585 // Generic unconditional branch.
586 def G_BR : GenericInstruction {
587   let OutOperandList = (outs);
588   let InOperandList = (ins unknown:$src1);
589   let hasSideEffects = 0;
590   let isBranch = 1;
591   let isTerminator = 1;
592   let isBarrier = 1;
593 }
594
595 // Generic conditional branch.
596 def G_BRCOND : GenericInstruction {
597   let OutOperandList = (outs);
598   let InOperandList = (ins type0:$tst, unknown:$truebb);
599   let hasSideEffects = 0;
600   let isBranch = 1;
601   let isTerminator = 1;
602 }
603
604 // Generic indirect branch.
605 def G_BRINDIRECT : GenericInstruction {
606   let OutOperandList = (outs);
607   let InOperandList = (ins type0:$src1);
608   let hasSideEffects = 0;
609   let isBranch = 1;
610   let isTerminator = 1;
611 }
612
613 //------------------------------------------------------------------------------
614 // Vector ops
615 //------------------------------------------------------------------------------
616
617 // Generic insertelement.
618 def G_INSERT_VECTOR_ELT : GenericInstruction {
619   let OutOperandList = (outs type0:$dst);
620   let InOperandList = (ins type0:$src, type1:$elt, type2:$idx);
621   let hasSideEffects = 0;
622 }
623
624 // Generic extractelement.
625 def G_EXTRACT_VECTOR_ELT : GenericInstruction {
626   let OutOperandList = (outs type0:$dst);
627   let InOperandList = (ins type1:$src, type2:$idx);
628   let hasSideEffects = 0;
629 }
630
631 // Generic shufflevector.
632 def G_SHUFFLE_VECTOR: GenericInstruction {
633   let OutOperandList = (outs type0:$dst);
634   let InOperandList = (ins type1:$v1, type1:$v2, type2:$mask);
635   let hasSideEffects = 0;
636 }
637
638 // TODO: Add the other generic opcodes.