AMDILInstrInfo.td revision aece7970eb171ec6c28c412d22f42362b4f52bac
1//===------------ AMDILInstrInfo.td - AMDIL Target ------*-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 describes the AMDIL instructions in TableGen format.
11//
12//===----------------------------------------------------------------------===//
13// AMDIL Instruction Predicate Definitions
14// Predicate that is set to true if the hardware supports double precision
15// divide
16def HasHWDDiv                 : Predicate<"Subtarget.device()"
17                           "->getGeneration() > AMDILDeviceInfo::HD4XXX && "
18              "Subtarget.device()->usesHardware(AMDILDeviceInfo::DoubleOps)">;
19
20// Predicate that is set to true if the hardware supports double, but not double
21// precision divide in hardware
22def HasSWDDiv             : Predicate<"Subtarget.device()"
23                           "->getGeneration() == AMDILDeviceInfo::HD4XXX &&"
24              "Subtarget.device()->usesHardware(AMDILDeviceInfo::DoubleOps)">;
25
26// Predicate that is set to true if the hardware support 24bit signed
27// math ops. Otherwise a software expansion to 32bit math ops is used instead.
28def HasHWSign24Bit          : Predicate<"Subtarget.device()"
29                            "->getGeneration() > AMDILDeviceInfo::HD5XXX">;
30
31// Predicate that is set to true if 64bit operations are supported or not
32def HasHW64Bit              : Predicate<"Subtarget.device()"
33                            "->usesHardware(AMDILDeviceInfo::LongOps)">;
34def HasSW64Bit              : Predicate<"Subtarget.device()"
35                            "->usesSoftware(AMDILDeviceInfo::LongOps)">;
36
37// Predicate that is set to true if the timer register is supported
38def HasTmrRegister          : Predicate<"Subtarget.device()"
39                            "->isSupported(AMDILDeviceInfo::TmrReg)">;
40// Predicate that is true if we are at least evergreen series
41def HasDeviceIDInst         : Predicate<"Subtarget.device()"
42                            "->getGeneration() >= AMDILDeviceInfo::HD5XXX">;
43
44// Predicate that is true if we have region address space.
45def hasRegionAS             : Predicate<"Subtarget.device()"
46                            "->usesHardware(AMDILDeviceInfo::RegionMem)">;
47
48// Predicate that is false if we don't have region address space.
49def noRegionAS             : Predicate<"!Subtarget.device()"
50                            "->isSupported(AMDILDeviceInfo::RegionMem)">;
51
52
53// Predicate that is set to true if 64bit Mul is supported in the IL or not
54def HasHW64Mul              : Predicate<"Subtarget.calVersion()" 
55                                          ">= CAL_VERSION_SC_139"
56                                          "&& Subtarget.device()"
57                                          "->getGeneration() >="
58                                          "AMDILDeviceInfo::HD5XXX">;
59def HasSW64Mul              : Predicate<"Subtarget.calVersion()" 
60                                          "< CAL_VERSION_SC_139">;
61// Predicate that is set to true if 64bit Div/Mod is supported in the IL or not
62def HasHW64DivMod           : Predicate<"Subtarget.device()"
63                            "->usesHardware(AMDILDeviceInfo::HW64BitDivMod)">;
64def HasSW64DivMod           : Predicate<"Subtarget.device()"
65                            "->usesSoftware(AMDILDeviceInfo::HW64BitDivMod)">;
66
67// Predicate that is set to true if 64bit pointer are used.
68def Has64BitPtr             : Predicate<"Subtarget.is64bit()">;
69def Has32BitPtr             : Predicate<"!Subtarget.is64bit()">;
70//===--------------------------------------------------------------------===//
71// Custom Operands
72//===--------------------------------------------------------------------===//
73def brtarget   : Operand<OtherVT>;
74
75//===--------------------------------------------------------------------===//
76// Custom Selection DAG Type Profiles
77//===--------------------------------------------------------------------===//
78//===----------------------------------------------------------------------===//
79// Generic Profile Types
80//===----------------------------------------------------------------------===//
81
82def SDTIL_GenBinaryOp : SDTypeProfile<1, 2, [
83    SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>
84    ]>;
85def SDTIL_GenTernaryOp : SDTypeProfile<1, 3, [
86    SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, SDTCisSameAs<2, 3>
87    ]>;
88def SDTIL_GenVecBuild : SDTypeProfile<1, 1, [
89    SDTCisEltOfVec<1, 0>
90    ]>;
91
92//===----------------------------------------------------------------------===//
93// Flow Control Profile Types
94//===----------------------------------------------------------------------===//
95// Branch instruction where second and third are basic blocks
96def SDTIL_BRCond : SDTypeProfile<0, 2, [
97    SDTCisVT<0, OtherVT>
98    ]>;
99// Comparison instruction
100def SDTIL_Cmp  : SDTypeProfile<1, 3, [
101    SDTCisSameAs<0, 2>, SDTCisSameAs<2,3>, SDTCisVT<1, i32>
102    ]>;
103
104//===--------------------------------------------------------------------===//
105// Custom Selection DAG Nodes
106//===--------------------------------------------------------------------===//
107//===----------------------------------------------------------------------===//
108// Flow Control DAG Nodes
109//===----------------------------------------------------------------------===//
110def IL_brcond      : SDNode<"AMDILISD::BRANCH_COND", SDTIL_BRCond, [SDNPHasChain]>;
111
112//===----------------------------------------------------------------------===//
113// Comparison DAG Nodes
114//===----------------------------------------------------------------------===//
115def IL_cmp       : SDNode<"AMDILISD::CMP", SDTIL_Cmp>;
116
117//===----------------------------------------------------------------------===//
118// Call/Return DAG Nodes
119//===----------------------------------------------------------------------===//
120def IL_retflag       : SDNode<"AMDILISD::RET_FLAG", SDTNone,
121    [SDNPHasChain, SDNPOptInGlue]>;
122
123//===--------------------------------------------------------------------===//
124// Instructions
125//===--------------------------------------------------------------------===//
126// Floating point math functions
127def IL_cmov_logical : SDNode<"AMDILISD::CMOVLOG", SDTIL_GenTernaryOp>;
128def IL_div_inf      : SDNode<"AMDILISD::DIV_INF", SDTIL_GenBinaryOp>;
129def IL_mad          : SDNode<"AMDILISD::MAD", SDTIL_GenTernaryOp>;
130
131//===----------------------------------------------------------------------===//
132// Integer functions
133//===----------------------------------------------------------------------===//
134def IL_umul        : SDNode<"AMDILISD::UMUL"    , SDTIntBinOp,
135    [SDNPCommutative, SDNPAssociative]>;
136
137//===----------------------------------------------------------------------===//
138// Vector functions
139//===----------------------------------------------------------------------===//
140def IL_vbuild     : SDNode<"AMDILISD::VBUILD", SDTIL_GenVecBuild,
141    []>;
142
143//===--------------------------------------------------------------------===//
144// Custom Pattern DAG Nodes
145//===--------------------------------------------------------------------===//
146def global_store : PatFrag<(ops node:$val, node:$ptr),
147    (store node:$val, node:$ptr), [{
148        return isGlobalStore(dyn_cast<StoreSDNode>(N));
149}]>;
150
151//===----------------------------------------------------------------------===//
152// Load pattern fragments
153//===----------------------------------------------------------------------===//
154// Global address space loads
155def global_load : PatFrag<(ops node:$ptr), (load node:$ptr), [{
156    return isGlobalLoad(dyn_cast<LoadSDNode>(N));
157}]>;
158// Constant address space loads
159def constant_load : PatFrag<(ops node:$ptr), (load node:$ptr), [{
160    return isConstantLoad(dyn_cast<LoadSDNode>(N), -1);
161}]>;
162
163//===----------------------------------------------------------------------===//
164// Complex addressing mode patterns
165//===----------------------------------------------------------------------===//
166def ADDR : ComplexPattern<i32, 2, "SelectADDR", [], []>;
167def ADDRF : ComplexPattern<i32, 2, "SelectADDR", [frameindex], []>;
168def ADDR64 : ComplexPattern<i64, 2, "SelectADDR64", [], []>;
169def ADDR64F : ComplexPattern<i64, 2, "SelectADDR64", [frameindex], []>;
170
171
172//===----------------------------------------------------------------------===//
173// Conditional Instruction Pattern Leafs
174//===----------------------------------------------------------------------===//
175class IL_CC_Op<int N> : PatLeaf<(i32 N)>;
176def IL_CC_D_EQ  : IL_CC_Op<0>;
177def IL_CC_D_GE  : IL_CC_Op<1>;
178def IL_CC_D_LT  : IL_CC_Op<2>;
179def IL_CC_D_NE  : IL_CC_Op<3>;
180def IL_CC_F_EQ  : IL_CC_Op<4>;
181def IL_CC_F_GE  : IL_CC_Op<5>;
182def IL_CC_F_LT  : IL_CC_Op<6>;
183def IL_CC_F_NE  : IL_CC_Op<7>;
184def IL_CC_I_EQ  : IL_CC_Op<8>;
185def IL_CC_I_GE  : IL_CC_Op<9>;
186def IL_CC_I_LT  : IL_CC_Op<10>;
187def IL_CC_I_NE  : IL_CC_Op<11>;
188def IL_CC_U_GE  : IL_CC_Op<12>;
189def IL_CC_U_LT  : IL_CC_Op<13>;
190// Pseudo IL comparison instructions that aren't natively supported
191def IL_CC_F_GT  : IL_CC_Op<14>;
192def IL_CC_U_GT  : IL_CC_Op<15>;
193def IL_CC_I_GT  : IL_CC_Op<16>;
194def IL_CC_D_GT  : IL_CC_Op<17>;
195def IL_CC_F_LE  : IL_CC_Op<18>;
196def IL_CC_U_LE  : IL_CC_Op<19>;
197def IL_CC_I_LE  : IL_CC_Op<20>;
198def IL_CC_D_LE  : IL_CC_Op<21>;
199def IL_CC_F_UNE : IL_CC_Op<22>;
200def IL_CC_F_UEQ : IL_CC_Op<23>;
201def IL_CC_F_ULT : IL_CC_Op<24>;
202def IL_CC_F_UGT : IL_CC_Op<25>;
203def IL_CC_F_ULE : IL_CC_Op<26>;
204def IL_CC_F_UGE : IL_CC_Op<27>;
205def IL_CC_F_ONE : IL_CC_Op<28>;
206def IL_CC_F_OEQ : IL_CC_Op<29>;
207def IL_CC_F_OLT : IL_CC_Op<30>;
208def IL_CC_F_OGT : IL_CC_Op<31>;
209def IL_CC_F_OLE : IL_CC_Op<32>;
210def IL_CC_F_OGE : IL_CC_Op<33>;
211def IL_CC_D_UNE : IL_CC_Op<34>;
212def IL_CC_D_UEQ : IL_CC_Op<35>;
213def IL_CC_D_ULT : IL_CC_Op<36>;
214def IL_CC_D_UGT : IL_CC_Op<37>;
215def IL_CC_D_ULE : IL_CC_Op<38>;
216def IL_CC_D_UGE : IL_CC_Op<39>;
217def IL_CC_D_ONE : IL_CC_Op<30>;
218def IL_CC_D_OEQ : IL_CC_Op<41>;
219def IL_CC_D_OLT : IL_CC_Op<42>;
220def IL_CC_D_OGT : IL_CC_Op<43>;
221def IL_CC_D_OLE : IL_CC_Op<44>;
222def IL_CC_D_OGE : IL_CC_Op<45>;
223def IL_CC_U_EQ  : IL_CC_Op<46>;
224def IL_CC_U_NE  : IL_CC_Op<47>;
225def IL_CC_F_O   : IL_CC_Op<48>;
226def IL_CC_D_O   : IL_CC_Op<49>;
227def IL_CC_F_UO  : IL_CC_Op<50>;
228def IL_CC_D_UO  : IL_CC_Op<51>;
229def IL_CC_L_LE  : IL_CC_Op<52>;
230def IL_CC_L_GE  : IL_CC_Op<53>;
231def IL_CC_L_EQ  : IL_CC_Op<54>;
232def IL_CC_L_NE  : IL_CC_Op<55>;
233def IL_CC_L_LT  : IL_CC_Op<56>;
234def IL_CC_L_GT  : IL_CC_Op<57>;
235def IL_CC_UL_LE  : IL_CC_Op<58>;
236def IL_CC_UL_GE  : IL_CC_Op<59>;
237def IL_CC_UL_EQ  : IL_CC_Op<60>;
238def IL_CC_UL_NE  : IL_CC_Op<61>;
239def IL_CC_UL_LT  : IL_CC_Op<62>;
240def IL_CC_UL_GT  : IL_CC_Op<63>;
241
242//===----------------------------------------------------------------------===//
243// Instruction format classes
244//===----------------------------------------------------------------------===//
245class ILFormat<dag outs, dag ins, string asmstr, list<dag> pattern>
246: Instruction {
247
248     let Namespace = "AMDGPU";
249     dag OutOperandList = outs;
250     dag InOperandList = ins;
251     let Pattern = pattern;
252     let AsmString = !strconcat(asmstr, "\n");
253     let isPseudo = 1;
254     let Itinerary = NullALU;
255     bit hasIEEEFlag = 0;
256     bit hasZeroOpFlag = 0;
257}
258
259//===--------------------------------------------------------------------===//
260// Multiclass Instruction formats
261//===--------------------------------------------------------------------===//
262// Multiclass that handles branch instructions
263multiclass BranchConditional<SDNode Op> {
264    def _i32 : ILFormat<(outs),
265  (ins brtarget:$target, GPRI32:$src0),
266        "; i32 Pseudo branch instruction",
267  [(Op bb:$target, GPRI32:$src0)]>;
268    def _f32 : ILFormat<(outs),
269  (ins brtarget:$target, GPRF32:$src0),
270        "; f32 Pseudo branch instruction",
271  [(Op bb:$target, GPRF32:$src0)]>;
272}
273
274// Only scalar types should generate flow control
275multiclass BranchInstr<string name> {
276  def _i32 : ILFormat<(outs), (ins GPRI32:$src),
277      !strconcat(name, " $src"), []>;
278  def _f32 : ILFormat<(outs), (ins GPRF32:$src),
279      !strconcat(name, " $src"), []>;
280}
281// Only scalar types should generate flow control
282multiclass BranchInstr2<string name> {
283  def _i32 : ILFormat<(outs), (ins GPRI32:$src0, GPRI32:$src1),
284      !strconcat(name, " $src0, $src1"), []>;
285  def _f32 : ILFormat<(outs), (ins GPRF32:$src0, GPRF32:$src1),
286      !strconcat(name, " $src0, $src1"), []>;
287}
288
289//===--------------------------------------------------------------------===//
290// Intrinsics support
291//===--------------------------------------------------------------------===//
292include "AMDILIntrinsics.td"
293
294//===--------------------------------------------------------------------===//
295// Instructions support
296//===--------------------------------------------------------------------===//
297//===---------------------------------------------------------------------===//
298// Custom Inserter for Branches and returns, this eventually will be a
299// seperate pass
300//===---------------------------------------------------------------------===//
301let isTerminator = 1 in {
302  def BRANCH : ILFormat<(outs), (ins brtarget:$target),
303      "; Pseudo unconditional branch instruction",
304      [(br bb:$target)]>;
305  defm BRANCH_COND : BranchConditional<IL_brcond>;
306}
307//===---------------------------------------------------------------------===//
308// return instructions
309//===---------------------------------------------------------------------===//
310let isTerminator = 1, isReturn = 1, isBarrier = 1, hasCtrlDep = 1 in {
311  def RETURN          : ILFormat<(outs), (ins variable_ops),
312      "RETURN", [(IL_retflag)]>;
313}
314
315//===---------------------------------------------------------------------===//
316// Flow and Program control Instructions
317//===---------------------------------------------------------------------===//
318let isTerminator=1 in {
319  def SWITCH      : ILFormat< (outs), (ins GPRI32:$src),
320  !strconcat("SWITCH", " $src"), []>;
321  def CASE        : ILFormat< (outs), (ins GPRI32:$src),
322      !strconcat("CASE", " $src"), []>;
323  def BREAK       : ILFormat< (outs), (ins),
324      "BREAK", []>;
325  def CONTINUE    : ILFormat< (outs), (ins),
326      "CONTINUE", []>;
327  def DEFAULT     : ILFormat< (outs), (ins),
328      "DEFAULT", []>;
329  def ELSE        : ILFormat< (outs), (ins),
330      "ELSE", []>;
331  def ENDSWITCH   : ILFormat< (outs), (ins),
332      "ENDSWITCH", []>;
333  def ENDMAIN     : ILFormat< (outs), (ins),
334      "ENDMAIN", []>;
335  def END         : ILFormat< (outs), (ins),
336      "END", []>;
337  def ENDFUNC     : ILFormat< (outs), (ins),
338      "ENDFUNC", []>;
339  def ENDIF       : ILFormat< (outs), (ins),
340      "ENDIF", []>;
341  def WHILELOOP   : ILFormat< (outs), (ins),
342      "WHILE", []>;
343  def ENDLOOP     : ILFormat< (outs), (ins),
344      "ENDLOOP", []>;
345  def FUNC        : ILFormat< (outs), (ins),
346      "FUNC", []>;
347  def RETDYN      : ILFormat< (outs), (ins),
348      "RET_DYN", []>;
349  // This opcode has custom swizzle pattern encoded in Swizzle Encoder
350  defm IF_LOGICALNZ  : BranchInstr<"IF_LOGICALNZ">;
351  // This opcode has custom swizzle pattern encoded in Swizzle Encoder
352  defm IF_LOGICALZ   : BranchInstr<"IF_LOGICALZ">;
353  // This opcode has custom swizzle pattern encoded in Swizzle Encoder
354  defm BREAK_LOGICALNZ : BranchInstr<"BREAK_LOGICALNZ">;
355  // This opcode has custom swizzle pattern encoded in Swizzle Encoder
356  defm BREAK_LOGICALZ : BranchInstr<"BREAK_LOGICALZ">;
357  // This opcode has custom swizzle pattern encoded in Swizzle Encoder
358  defm CONTINUE_LOGICALNZ : BranchInstr<"CONTINUE_LOGICALNZ">;
359  // This opcode has custom swizzle pattern encoded in Swizzle Encoder
360  defm CONTINUE_LOGICALZ : BranchInstr<"CONTINUE_LOGICALZ">;
361  defm IFC         : BranchInstr2<"IFC">;
362  defm BREAKC      : BranchInstr2<"BREAKC">;
363  defm CONTINUEC   : BranchInstr2<"CONTINUEC">;
364}
365