1 //==- AMDILFormats.td - AMDIL Instruction Formats ----*- 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 //===--------------------------------------------------------------------===//
11 include "AMDILTokenDesc.td"
13 //===--------------------------------------------------------------------===//
14 // The parent IL instruction class that inherits the Instruction class. This
15 // class sets the corresponding namespace, the out and input dag lists the
16 // pattern to match to and the string to print out for the assembly printer.
17 //===--------------------------------------------------------------------===//
18 class ILFormat<ILOpCode op, dag outs, dag ins, string asmstr, list<dag> pattern>
21 let Namespace = "AMDIL";
22 dag OutOperandList = outs;
23 dag InOperandList = ins;
24 ILOpCode operation = op;
25 let Pattern = pattern;
26 let AsmString = !strconcat(asmstr, "\n");
29 bit hasZeroOpFlag = 0;
32 //===--------------------------------------------------------------------===//
33 // The base class for vector insert instructions. It is a single dest, quad
34 // source instruction where the last two source operands must be 32bit
35 // immediate values that are encoding the swizzle of the source register
36 // The src2 and src3 instructions must also be inversion of each other such
37 // that if src2 is 0x1000300(x0z0), src3 must be 0x20004(0y0w). The values
38 // are encoded as 32bit integer with each 8 char representing a swizzle value.
39 // The encoding is as follows for 32bit register types:
50 // The encoding is as follows for 64bit register types:
57 //===--------------------------------------------------------------------===//
58 class InsertVectorClass<ILOpCode op, RegisterClass DReg, RegisterClass SReg,
59 SDNode OpNode, string asmstr> :
60 ILFormat<op, (outs DReg:$dst),
61 (ins DReg:$src0, SReg:$src1, i32imm:$src2, i32imm:$src3),
62 !strconcat(asmstr, " $dst, $src0, $src1"),
63 [(set DReg:$dst, (OpNode DReg:$src0, SReg:$src1,
64 timm:$src2, timm:$src3))]>;
66 //===--------------------------------------------------------------------===//
67 // Class that has one input parameters and one output parameter.
68 // The basic pattern for this class is "Opcode Dst, Src0" and
69 // handles the unary math operators.
70 // It sets the binary token ILSrc, ILSrcMod, ILRelAddr and ILSrc and ILSrcMod
71 // if the addressing is register relative for input and output register 0.
72 //===--------------------------------------------------------------------===//
73 class OneInOneOut<ILOpCode op, dag outs, dag ins,
74 string asmstr, list<dag> pattern>
75 : ILFormat<op, outs, ins, asmstr, pattern>
81 ILSrcMod dst_reg_rel_mod;
86 ILSrcMod src0_reg_rel_mod;
89 //===--------------------------------------------------------------------===//
90 // A simplified version of OneInOneOut class where the pattern is standard
91 // and does not need special cases. This requires that the pattern has
92 // a SDNode and takes a source and destination register that is of type
93 // RegisterClass. This is the standard unary op class.
94 //===--------------------------------------------------------------------===//
95 class UnaryOp<ILOpCode op, SDNode OpNode,
96 RegisterClass dRegs, RegisterClass sRegs>
97 : OneInOneOut<op, (outs dRegs:$dst), (ins sRegs:$src),
98 !strconcat(op.Text, " $dst, $src"),
99 [(set dRegs:$dst, (OpNode sRegs:$src))]>;
101 //===--------------------------------------------------------------------===//
102 // This class is similiar to the UnaryOp class, however, there is no
103 // result value to assign.
104 //===--------------------------------------------------------------------===//
105 class UnaryOpNoRet<ILOpCode op, dag outs, dag ins,
106 string asmstr, list<dag> pattern>
107 : ILFormat<op, outs, ins, asmstr, pattern>
113 ILSrcMod src0_reg_rel_mod;
116 //===--------------------------------------------------------------------===//
117 // Set of classes that have two input parameters and one output parameter.
118 // The basic pattern for this class is "Opcode Dst, Src0, Src1" and
119 // handles the binary math operators and comparison operations.
120 // It sets the binary token ILSrc, ILSrcMod, ILRelAddr and ILSrc and ILSrcMod
121 // if the addressing is register relative for input register 1.
122 //===--------------------------------------------------------------------===//
123 class TwoInOneOut<ILOpCode op, dag outs, dag ins,
124 string asmstr, list<dag> pattern>
125 : OneInOneOut<op, outs, ins, asmstr, pattern>
131 ILSrcMod src1_reg_rel_mod;
133 //===--------------------------------------------------------------------===//
134 // A simplification of the TwoInOneOut pattern for Binary Operations.
135 // This class is a helper class that assumes the simple pattern of
136 // $dst = op $src0 $src1.
137 // Other type of matching patterns need to use the TwoInOneOut class.
138 //===--------------------------------------------------------------------===//
139 class BinaryOp<ILOpCode op, SDNode OpNode, RegisterClass dReg,
140 RegisterClass sReg0, RegisterClass sReg1>
141 : TwoInOneOut<op, (outs dReg:$dst), (ins sReg0:$src0, sReg1:$src1),
142 !strconcat(op.Text, " $dst, $src0, $src1"),
143 [(set dReg:$dst, (OpNode sReg0:$src0, sReg1:$src1))]>;
145 //===--------------------------------------------------------------------===//
146 // The base class for vector extract instructions. The vector extract
147 // instructions take as an input value a source register and a 32bit integer
148 // with the same encoding as specified in InsertVectorClass and produces
149 // a result with only the swizzled component in the destination register.
150 //===--------------------------------------------------------------------===//
151 class ExtractVectorClass<RegisterClass DReg, RegisterClass SReg, SDNode OpNode>
152 : TwoInOneOut<IL_OP_MOV, (outs DReg:$dst), (ins SReg:$src0, i32imm:$src1),
154 [(set DReg:$dst, (OpNode SReg:$src0, timm:$src1))]>;
156 //===--------------------------------------------------------------------===//
157 // The base class for vector concatenation. This class creates either a vec2
158 // or a vec4 of 32bit data types or a vec2 of 64bit data types. This is done
159 // by swizzling either the 'x' or 'xy' components of the source operands
160 // into the destination register.
161 //===--------------------------------------------------------------------===//
162 class VectorConcatClass<RegisterClass Dst, RegisterClass Src, SDNode OpNode>
163 : TwoInOneOut<IL_OP_I_ADD, (outs Dst:$dst), (ins Src:$src0, Src:$src1),
164 "iadd $dst, $src0, $src1",
165 [(set Dst:$dst, (OpNode Src:$src0, Src:$src1))]>;
167 //===--------------------------------------------------------------------===//
168 // Similiar to the UnaryOpNoRet class, but takes as arguments two input
169 // operands. Used mainly for barrier instructions on PC platform.
170 //===--------------------------------------------------------------------===//
171 class BinaryOpNoRet<ILOpCode op, dag outs, dag ins,
172 string asmstr, list<dag> pattern>
173 : UnaryOpNoRet<op, outs, ins, asmstr, pattern>
179 ILSrcMod src1_reg_rel_mod;
182 //===--------------------------------------------------------------------===//
183 // Set of classes that have three input parameters and one output parameter.
184 // The basic pattern for this class is "Opcode Dst, Src0, Src1, Src2" and
185 // handles the mad and conditional mov instruction.
186 // It sets the binary token ILSrc, ILSrcMod, ILRelAddr and ILSrc and ILSrcMod
187 // if the addressing is register relative.
188 // This class is the parent class of TernaryOp
189 //===--------------------------------------------------------------------===//
190 class ThreeInOneOut<ILOpCode op, dag outs, dag ins,
191 string asmstr, list<dag> pattern>
192 : TwoInOneOut<op, outs, ins, asmstr, pattern> {
197 ILSrcMod src2_reg_rel_mod;
200 //===--------------------------------------------------------------------===//
201 // The g version of the Three Input pattern uses a standard pattern but
202 // but allows specification of the register to further generalize the class
203 // This class is mainly used in the generic multiclasses in AMDILMultiClass.td
204 //===--------------------------------------------------------------------===//
205 class TernaryOp<ILOpCode op, SDNode OpNode,
210 : ThreeInOneOut<op, (outs dReg:$dst),
211 (ins sReg0:$src0, sReg1:$src1, sReg2:$src2),
212 !strconcat(op.Text, " $dst, $src0, $src1, $src2"),
214 (OpNode sReg0:$src0, sReg1:$src1, sReg2:$src2))]>;
216 //===--------------------------------------------------------------------===//
217 // Set of classes that have three input parameters and one output parameter.
218 // The basic pattern for this class is "Opcode Dst, Src0, Src1, Src2" and
219 // handles the mad and conditional mov instruction.
220 // It sets the binary token ILSrc, ILSrcMod, ILRelAddr and ILSrc and ILSrcMod
221 // if the addressing is register relative.
222 // This class is the parent class of TernaryOp
223 //===--------------------------------------------------------------------===//
224 class FourInOneOut<ILOpCode op, dag outs, dag ins,
225 string asmstr, list<dag> pattern>
226 : ThreeInOneOut<op, outs, ins, asmstr, pattern> {
231 ILSrcMod src3_reg_rel_mod;
235 //===--------------------------------------------------------------------===//
236 // The macro class that is an extension of OneInOneOut but is tailored for
237 // macros only where all the register types are the same
238 //===--------------------------------------------------------------------===//
239 class UnaryMacro<RegisterClass Dst, RegisterClass Src0, SDNode OpNode>
240 : OneInOneOut<IL_OP_MACRO, (outs Dst:$dst),
243 [(set Dst:$dst, (OpNode Src0:$src0))]>;
245 //===--------------------------------------------------------------------===//
246 // The macro class is an extension of TwoInOneOut but is tailored for
247 // macros only where all the register types are the same
248 //===--------------------------------------------------------------------===//
249 class BinaryMacro<RegisterClass Dst,
253 : TwoInOneOut<IL_OP_MACRO, (outs Dst:$dst),
254 (ins Src0: $src0, Src1:$src1),
255 "($dst),($src0, $src1)",
256 [(set Dst:$dst, (OpNode Src0:$src0, Src1:$src1))]>;
258 //===--------------------------------------------------------------------===//
259 // Classes for dealing with atomic instructions w/ 32bit pointers
260 //===--------------------------------------------------------------------===//
261 class Append<ILOpCode op, string idType, SDNode intr>
262 : ILFormat<op, (outs GPRI32:$dst),
264 !strconcat(op.Text, !strconcat(idType," $dst")),
265 [(set GPRI32:$dst, (intr ADDR:$id))]>;
268 // TODO: Need to get this working without dst...
269 class AppendNoRet<ILOpCode op, string idType, SDNode intr>
270 : ILFormat<op, (outs GPRI32:$dst),
272 !strconcat(op.Text, !strconcat(idType," $dst")),
273 [(set GPRI32:$dst, (intr ADDR:$id))]>;
275 class UniAtom<ILOpCode op, string idType, SDNode intr>
276 : ILFormat<op, (outs GPRI32:$dst),
277 (ins MEMI32:$ptr, i32imm:$id),
278 !strconcat(op.Text, !strconcat(idType," $dst, $ptr")),
279 [(set GPRI32:$dst, (intr ADDR:$ptr, timm:$id))]>;
282 // TODO: Need to get this working without dst...
283 class UniAtomNoRet<ILOpCode op, string idType, SDNode intr>
284 : ILFormat<op, (outs GPRI32:$dst), (ins MEMI32:$ptr, i32imm:$id),
285 !strconcat(op.Text, !strconcat(idType," $ptr")),
286 [(set GPRI32:$dst, (intr ADDR:$ptr, timm:$id))]>;
288 class BinAtom<ILOpCode op, string idType, SDNode intr>
289 : ILFormat<op, (outs GPRI32:$dst),
290 (ins MEMI32:$ptr, GPRI32:$src, i32imm:$id),
291 !strconcat(op.Text, !strconcat(idType," $dst, $ptr, $src")),
292 [(set GPRI32:$dst, (intr ADDR:$ptr, GPRI32:$src, timm:$id))]>;
295 // TODO: Need to get this working without dst...
296 class BinAtomNoRet<ILOpCode op, string idType, SDNode intr>
297 : ILFormat<op, (outs GPRI32:$dst), (ins MEMI32:$ptr, GPRI32:$src, i32imm:$id),
298 !strconcat(op.Text, !strconcat(idType," $ptr, $src")),
299 [(set GPRI32:$dst, (intr ADDR:$ptr, GPRI32:$src, timm:$id))]>;
301 class TriAtom<ILOpCode op, string idType, SDNode intr>
302 : ILFormat<op, (outs GPRI32:$dst),
303 (ins MEMI32:$ptr, GPRI32:$src, GPRI32:$src1, i32imm:$id),
304 !strconcat(op.Text, !strconcat(idType," $dst, $ptr, $src, $src1")),
305 [(set GPRI32:$dst, (intr ADDR:$ptr, GPRI32:$src, GPRI32:$src1, timm:$id))]>;
307 class CmpXChg<ILOpCode op, string idType, SDNode intr>
308 : ILFormat<op, (outs GPRI32:$dst),
309 (ins MEMI32:$ptr, GPRI32:$src, GPRI32:$src1, i32imm:$id),
310 !strconcat(op.Text, !strconcat(idType," $dst, $ptr, $src1, $src")),
311 [(set GPRI32:$dst, (intr ADDR:$ptr, GPRI32:$src, GPRI32:$src1, timm:$id))]>;
313 // TODO: Need to get this working without dst...
314 class TriAtomNoRet<ILOpCode op, string idType, SDNode intr>
315 : ILFormat<op, (outs GPRI32:$dst),
316 (ins MEMI32:$ptr, GPRI32:$src, GPRI32:$src1, i32imm:$id),
317 !strconcat(op.Text, !strconcat(idType," $ptr, $src, $src1")),
318 [(set GPRI32:$dst, (intr ADDR:$ptr, GPRI32:$src, GPRI32:$src1, timm:$id))]>;
320 // TODO: Need to get this working without dst...
321 class CmpXChgNoRet<ILOpCode op, string idType, SDNode intr>
322 : ILFormat<op, (outs GPRI32:$dst),
323 (ins MEMI32:$ptr, GPRI32:$src, GPRI32:$src1, i32imm:$id),
324 !strconcat(op.Text, !strconcat(idType," $ptr, $src1, $src")),
325 [(set GPRI32:$dst, (intr ADDR:$ptr, GPRI32:$src, GPRI32:$src1, timm:$id))]>;
328 //===--------------------------------------------------------------------===//
329 // Classes for dealing with atomic instructions w/ 64bit pointers
330 //===--------------------------------------------------------------------===//
331 class Append64<ILOpCode op, string idType, SDNode intr>
332 : ILFormat<op, (outs GPRI32:$dst),
334 !strconcat(op.Text, !strconcat(idType," $dst")),
335 [(set GPRI32:$dst, (intr ADDR64:$id))]>;
338 // TODO: Need to get this working without dst...
339 class AppendNoRet64<ILOpCode op, string idType, SDNode intr>
340 : ILFormat<op, (outs GPRI32:$dst),
342 !strconcat(op.Text, !strconcat(idType," $dst")),
343 [(set GPRI32:$dst, (intr ADDR64:$id))]>;
345 class UniAtom64<ILOpCode op, string idType, SDNode intr>
346 : ILFormat<op, (outs GPRI32:$dst),
347 (ins MEMI64:$ptr, i32imm:$id),
348 !strconcat(op.Text, !strconcat(idType," $dst, $ptr")),
349 [(set GPRI32:$dst, (intr ADDR64:$ptr, timm:$id))]>;
352 // TODO: Need to get this working without dst...
353 class UniAtomNoRet64<ILOpCode op, string idType, SDNode intr>
354 : ILFormat<op, (outs GPRI32:$dst), (ins MEMI64:$ptr, i32imm:$id),
355 !strconcat(op.Text, !strconcat(idType," $ptr")),
356 [(set GPRI32:$dst, (intr ADDR64:$ptr, timm:$id))]>;
358 class BinAtom64<ILOpCode op, string idType, SDNode intr>
359 : ILFormat<op, (outs GPRI32:$dst),
360 (ins MEMI64:$ptr, GPRI32:$src, i32imm:$id),
361 !strconcat(op.Text, !strconcat(idType," $dst, $ptr, $src")),
362 [(set GPRI32:$dst, (intr ADDR64:$ptr, GPRI32:$src, timm:$id))]>;
365 // TODO: Need to get this working without dst...
366 class BinAtomNoRet64<ILOpCode op, string idType, SDNode intr>
367 : ILFormat<op, (outs GPRI32:$dst), (ins MEMI64:$ptr, GPRI32:$src, i32imm:$id),
368 !strconcat(op.Text, !strconcat(idType," $ptr, $src")),
369 [(set GPRI32:$dst, (intr ADDR64:$ptr, GPRI32:$src, timm:$id))]>;
371 class TriAtom64<ILOpCode op, string idType, SDNode intr>
372 : ILFormat<op, (outs GPRI32:$dst),
373 (ins MEMI64:$ptr, GPRI32:$src, GPRI32:$src1, i32imm:$id),
374 !strconcat(op.Text, !strconcat(idType," $dst, $ptr, $src, $src1")),
375 [(set GPRI32:$dst, (intr ADDR64:$ptr, GPRI32:$src, GPRI32:$src1, timm:$id))]>;
377 class CmpXChg64<ILOpCode op, string idType, SDNode intr>
378 : ILFormat<op, (outs GPRI32:$dst),
379 (ins MEMI64:$ptr, GPRI32:$src, GPRI32:$src1, i32imm:$id),
380 !strconcat(op.Text, !strconcat(idType," $dst, $ptr, $src1, $src")),
381 [(set GPRI32:$dst, (intr ADDR64:$ptr, GPRI32:$src, GPRI32:$src1, timm:$id))]>;
383 // TODO: Need to get this working without dst...
384 class TriAtomNoRet64<ILOpCode op, string idType, SDNode intr>
385 : ILFormat<op, (outs GPRI32:$dst),
386 (ins MEMI64:$ptr, GPRI32:$src, GPRI32:$src1, i32imm:$id),
387 !strconcat(op.Text, !strconcat(idType," $ptr, $src, $src1")),
388 [(set GPRI32:$dst, (intr ADDR64:$ptr, GPRI32:$src, GPRI32:$src1, timm:$id))]>;
390 // TODO: Need to get this working without dst...
391 class CmpXChgNoRet64<ILOpCode op, string idType, SDNode intr>
392 : ILFormat<op, (outs GPRI32:$dst),
393 (ins MEMI64:$ptr, GPRI32:$src, GPRI32:$src1, i32imm:$id),
394 !strconcat(op.Text, !strconcat(idType," $ptr, $src1, $src")),
395 [(set GPRI32:$dst, (intr ADDR64:$ptr, GPRI32:$src, GPRI32:$src1, timm:$id))]>;
397 //===--------------------------------------------------------------------===//
399 // Generic versions of the above classes but for Target specific intrinsics
400 // instead of SDNode patterns.
401 //===--------------------------------------------------------------------===//
402 let TargetPrefix = "AMDIL", isTarget = 1 in {
404 Intrinsic<[llvm_i64_ty], [], []>;
406 Intrinsic<[llvm_i32_ty], [], []>;
408 Intrinsic<[llvm_i32_ty], [], []>;
410 Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>], []>;
411 class UnaryIntFloat :
412 Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], []>;
413 class ConvertIntFTOI :
414 Intrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty], []>;
415 class ConvertIntITOF :
416 Intrinsic<[llvm_anyfloat_ty], [llvm_anyint_ty], []>;
417 class UnaryIntNoRetInt :
418 Intrinsic<[], [llvm_anyint_ty], []>;
419 class UnaryIntNoRetFloat :
420 Intrinsic<[], [llvm_anyfloat_ty], []>;
422 Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>], []>;
423 class BinaryIntFloat :
424 Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, LLVMMatchType<0>], []>;
425 class BinaryIntNoRetInt :
426 Intrinsic<[], [llvm_anyint_ty, LLVMMatchType<0>], []>;
427 class BinaryIntNoRetFloat :
428 Intrinsic<[], [llvm_anyfloat_ty, LLVMMatchType<0>], []>;
429 class TernaryIntInt :
430 Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>,
431 LLVMMatchType<0>, LLVMMatchType<0>], []>;
432 class TernaryIntFloat :
433 Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>,
434 LLVMMatchType<0>, LLVMMatchType<0>], []>;
435 class QuaternaryIntInt :
436 Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>,
437 LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], []>;
438 class UnaryAtomicInt :
439 Intrinsic<[llvm_i32_ty], [llvm_ptr_ty, llvm_i32_ty], [IntrReadWriteArgMem]>;
440 class BinaryAtomicInt :
441 Intrinsic<[llvm_i32_ty], [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], [IntrReadWriteArgMem]>;
442 class TernaryAtomicInt :
443 Intrinsic<[llvm_i32_ty], [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty]>;
444 class UnaryAtomicIntNoRet :
445 Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty], [IntrReadWriteArgMem]>;
446 class BinaryAtomicIntNoRet :
447 Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], [IntrReadWriteArgMem]>;
448 class TernaryAtomicIntNoRet :
449 Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrReadWriteArgMem]>;