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 //------------------------------------------------------------------------------
96 //------------------------------------------------------------------------------
99 def G_ADD : Instruction {
100 let OutOperandList = (outs type0:$dst);
101 let InOperandList = (ins type0:$src1, type0:$src2);
102 let hasSideEffects = 0;
103 let isCommutable = 1;
106 // Generic pointer offset.
107 def G_GEP : Instruction {
108 let OutOperandList = (outs type0:$dst);
109 let InOperandList = (ins type0:$src1, type1:$src2);
110 let hasSideEffects = 0;
113 // Generic subtraction.
114 def G_SUB : Instruction {
115 let OutOperandList = (outs type0:$dst);
116 let InOperandList = (ins type0:$src1, type0:$src2);
117 let hasSideEffects = 0;
118 let isCommutable = 0;
121 // Generic multiplication.
122 def G_MUL : Instruction {
123 let OutOperandList = (outs type0:$dst);
124 let InOperandList = (ins type0:$src1, type0:$src2);
125 let hasSideEffects = 0;
126 let isCommutable = 1;
129 // Generic signed division.
130 def G_SDIV : Instruction {
131 let OutOperandList = (outs type0:$dst);
132 let InOperandList = (ins type0:$src1, type0:$src2);
133 let hasSideEffects = 0;
134 let isCommutable = 0;
137 // Generic unsigned division.
138 def G_UDIV : 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 signed remainder.
146 def G_SREM : 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 unsigned remainder.
154 def G_UREM : 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 bitwise and.
162 def G_AND : Instruction {
163 let OutOperandList = (outs type0:$dst);
164 let InOperandList = (ins type0:$src1, type0:$src2);
165 let hasSideEffects = 0;
166 let isCommutable = 1;
169 // Generic bitwise or.
170 def G_OR : 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 xor.
178 def G_XOR : 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 left-shift.
186 def G_SHL : Instruction {
187 let OutOperandList = (outs type0:$dst);
188 let InOperandList = (ins type0:$src1, type0:$src2);
189 let hasSideEffects = 0;
192 // Generic logical right-shift.
193 def G_LSHR : Instruction {
194 let OutOperandList = (outs type0:$dst);
195 let InOperandList = (ins type0:$src1, type0:$src2);
196 let hasSideEffects = 0;
199 // Generic arithmetic right-shift.
200 def G_ASHR : Instruction {
201 let OutOperandList = (outs type0:$dst);
202 let InOperandList = (ins type0:$src1, type0:$src2);
203 let hasSideEffects = 0;
206 // Generic integer comparison.
207 def G_ICMP : Instruction {
208 let OutOperandList = (outs type0:$dst);
209 let InOperandList = (ins unknown:$tst, type1:$src1, type1:$src2);
210 let hasSideEffects = 0;
213 // Generic floating-point comparison.
214 def G_FCMP : Instruction {
215 let OutOperandList = (outs type0:$dst);
216 let InOperandList = (ins unknown:$tst, type1:$src1, type1:$src2);
217 let hasSideEffects = 0;
221 def G_SELECT : Instruction {
222 let OutOperandList = (outs type0:$dst);
223 let InOperandList = (ins type1:$tst, type0:$src1, type0:$src2);
224 let hasSideEffects = 0;
227 //------------------------------------------------------------------------------
229 //------------------------------------------------------------------------------
231 // Generic unsigned addition consuming and producing a carry flag.
232 def G_UADDE : Instruction {
233 let OutOperandList = (outs type0:$dst, type1:$carry_out);
234 let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
235 let hasSideEffects = 0;
238 // Generic signed addition producing a carry flag.
239 def G_SADDO : Instruction {
240 let OutOperandList = (outs type0:$dst, type1:$carry_out);
241 let InOperandList = (ins type0:$src1, type0:$src2);
242 let hasSideEffects = 0;
243 let isCommutable = 1;
246 // Generic unsigned subtraction consuming and producing a carry flag.
247 def G_USUBE : Instruction {
248 let OutOperandList = (outs type0:$dst, type1:$carry_out);
249 let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
250 let hasSideEffects = 0;
253 // Generic unsigned subtraction producing a carry flag.
254 def G_SSUBO : Instruction {
255 let OutOperandList = (outs type0:$dst, type1:$carry_out);
256 let InOperandList = (ins type0:$src1, type0:$src2);
257 let hasSideEffects = 0;
260 // Generic unsigned multiplication producing a carry flag.
261 def G_UMULO : Instruction {
262 let OutOperandList = (outs type0:$dst, type1:$carry_out);
263 let InOperandList = (ins type0:$src1, type0:$src2);
264 let hasSideEffects = 0;
265 let isCommutable = 1;
268 // Generic signed multiplication producing a carry flag.
269 def G_SMULO : Instruction {
270 let OutOperandList = (outs type0:$dst, type1:$carry_out);
271 let InOperandList = (ins type0:$src1, type0:$src2);
272 let hasSideEffects = 0;
273 let isCommutable = 1;
276 //------------------------------------------------------------------------------
277 // Floating Point Unary Ops.
278 //------------------------------------------------------------------------------
280 def G_FPEXT : Instruction {
281 let OutOperandList = (outs type0:$dst);
282 let InOperandList = (ins type1:$src);
283 let hasSideEffects = 0;
286 def G_FPTRUNC : Instruction {
287 let OutOperandList = (outs type0:$dst);
288 let InOperandList = (ins type1:$src);
289 let hasSideEffects = 0;
292 def G_FPTOSI : Instruction {
293 let OutOperandList = (outs type0:$dst);
294 let InOperandList = (ins type1:$src);
295 let hasSideEffects = 0;
298 def G_FPTOUI : Instruction {
299 let OutOperandList = (outs type0:$dst);
300 let InOperandList = (ins type1:$src);
301 let hasSideEffects = 0;
304 def G_SITOFP : Instruction {
305 let OutOperandList = (outs type0:$dst);
306 let InOperandList = (ins type1:$src);
307 let hasSideEffects = 0;
310 def G_UITOFP : Instruction {
311 let OutOperandList = (outs type0:$dst);
312 let InOperandList = (ins type1:$src);
313 let hasSideEffects = 0;
316 //------------------------------------------------------------------------------
317 // Floating Point Binary ops.
318 //------------------------------------------------------------------------------
320 // Generic FP addition.
321 def G_FADD : Instruction {
322 let OutOperandList = (outs type0:$dst);
323 let InOperandList = (ins type0:$src1, type0:$src2);
324 let hasSideEffects = 0;
325 let isCommutable = 1;
328 // Generic FP subtraction.
329 def G_FSUB : Instruction {
330 let OutOperandList = (outs type0:$dst);
331 let InOperandList = (ins type0:$src1, type0:$src2);
332 let hasSideEffects = 0;
333 let isCommutable = 0;
336 // Generic FP multiplication.
337 def G_FMUL : Instruction {
338 let OutOperandList = (outs type0:$dst);
339 let InOperandList = (ins type0:$src1, type0:$src2);
340 let hasSideEffects = 0;
341 let isCommutable = 1;
344 // Generic FP division.
345 def G_FDIV : Instruction {
346 let OutOperandList = (outs type0:$dst);
347 let InOperandList = (ins type0:$src1, type0:$src2);
348 let hasSideEffects = 0;
351 // Generic FP remainder.
352 def G_FREM : Instruction {
353 let OutOperandList = (outs type0:$dst);
354 let InOperandList = (ins type0:$src1, type0:$src2);
355 let hasSideEffects = 0;
358 //------------------------------------------------------------------------------
360 //------------------------------------------------------------------------------
362 // Generic load. Expects a MachineMemOperand in addition to explicit operands.
363 def G_LOAD : Instruction {
364 let OutOperandList = (outs type0:$dst);
365 let InOperandList = (ins type1:$addr);
366 let hasSideEffects = 0;
370 // Generic store. Expects a MachineMemOperand in addition to explicit operands.
371 def G_STORE : Instruction {
372 let OutOperandList = (outs);
373 let InOperandList = (ins type0:$src, type1:$addr);
374 let hasSideEffects = 0;
378 //------------------------------------------------------------------------------
380 //------------------------------------------------------------------------------
382 // Extract multiple registers specified size, starting from blocks given by
383 // indexes. This will almost certainly be mapped to sub-register COPYs after
384 // register banks have been selected.
385 def G_EXTRACT : Instruction {
386 let OutOperandList = (outs);
387 let InOperandList = (ins variable_ops);
388 let hasSideEffects = 0;
391 // Insert a sequence of smaller registers into a larger one at the specified
392 // indices (interleaved with the values in the operand list "op0, bit0, op1,
394 def G_INSERT : Instruction {
395 let OutOperandList = (outs type0:$dst);
396 let InOperandList = (ins type0:$src, variable_ops);
397 let hasSideEffects = 0;
400 // Combine a sequence of generic vregs into a single larger value (starting at
401 // bit 0). Essentially a G_INSERT where $src is an IMPLICIT_DEF, but it's so
402 // important to legalization it probably deserves its own instruction.
403 def G_SEQUENCE : Instruction {
404 let OutOperandList = (outs type0:$dst);
405 let InOperandList = (ins variable_ops);
406 let hasSideEffects = 0;
409 // Intrinsic without side effects.
410 def G_INTRINSIC : Instruction {
411 let OutOperandList = (outs);
412 let InOperandList = (ins unknown:$intrin, variable_ops);
413 let hasSideEffects = 0;
416 // Intrinsic with side effects.
417 def G_INTRINSIC_W_SIDE_EFFECTS : Instruction {
418 let OutOperandList = (outs);
419 let InOperandList = (ins unknown:$intrin, variable_ops);
420 let hasSideEffects = 1;
425 //------------------------------------------------------------------------------
427 //------------------------------------------------------------------------------
429 // Generic unconditional branch.
430 def G_BR : Instruction {
431 let OutOperandList = (outs);
432 let InOperandList = (ins unknown:$src1);
433 let hasSideEffects = 0;
435 let isTerminator = 1;
439 // Generic conditional branch.
440 def G_BRCOND : Instruction {
441 let OutOperandList = (outs);
442 let InOperandList = (ins type0:$tst, unknown:$truebb);
443 let hasSideEffects = 0;
445 let isTerminator = 1;
448 // TODO: Add the other generic opcodes.