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() > AMDGPUDeviceInfo::HD4XXX && "
18              "Subtarget.device()->usesHardware(AMDGPUDeviceInfo::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() == AMDGPUDeviceInfo::HD4XXX &&"
24              "Subtarget.device()->usesHardware(AMDGPUDeviceInfo::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() > AMDGPUDeviceInfo::HD5XXX">;
30
31// Predicate that is set to true if 64bit operations are supported or not
32def HasHW64Bit              : Predicate<"Subtarget.device()"
33                            "->usesHardware(AMDGPUDeviceInfo::LongOps)">;
34def HasSW64Bit              : Predicate<"Subtarget.device()"
35                            "->usesSoftware(AMDGPUDeviceInfo::LongOps)">;
36
37// Predicate that is set to true if the timer register is supported
38def HasTmrRegister          : Predicate<"Subtarget.device()"
39                            "->isSupported(AMDGPUDeviceInfo::TmrReg)">;
40// Predicate that is true if we are at least evergreen series
41def HasDeviceIDInst         : Predicate<"Subtarget.device()"
42                            "->getGeneration() >= AMDGPUDeviceInfo::HD5XXX">;
43
44// Predicate that is true if we have region address space.
45def hasRegionAS             : Predicate<"Subtarget.device()"
46                            "->usesHardware(AMDGPUDeviceInfo::RegionMem)">;
47
48// Predicate that is false if we don't have region address space.
49def noRegionAS             : Predicate<"!Subtarget.device()"
50                            "->isSupported(AMDGPUDeviceInfo::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                                          "AMDGPUDeviceInfo::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(AMDGPUDeviceInfo::HW64BitDivMod)">;
64def HasSW64DivMod           : Predicate<"Subtarget.device()"
65                            "->usesSoftware(AMDGPUDeviceInfo::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
100//===--------------------------------------------------------------------===//
101// Custom Selection DAG Nodes
102//===--------------------------------------------------------------------===//
103//===----------------------------------------------------------------------===//
104// Flow Control DAG Nodes
105//===----------------------------------------------------------------------===//
106def IL_brcond      : SDNode<"AMDGPUISD::BRANCH_COND", SDTIL_BRCond, [SDNPHasChain]>;
107
108//===----------------------------------------------------------------------===//
109// Call/Return DAG Nodes
110//===----------------------------------------------------------------------===//
111def IL_retflag       : SDNode<"AMDGPUISD::RET_FLAG", SDTNone,
112    [SDNPHasChain, SDNPOptInGlue]>;
113
114//===--------------------------------------------------------------------===//
115// Instructions
116//===--------------------------------------------------------------------===//
117// Floating point math functions
118def IL_div_inf      : SDNode<"AMDGPUISD::DIV_INF", SDTIL_GenBinaryOp>;
119def IL_mad          : SDNode<"AMDGPUISD::MAD", SDTIL_GenTernaryOp>;
120
121//===----------------------------------------------------------------------===//
122// Integer functions
123//===----------------------------------------------------------------------===//
124def IL_umul        : SDNode<"AMDGPUISD::UMUL"    , SDTIntBinOp,
125    [SDNPCommutative, SDNPAssociative]>;
126
127//===----------------------------------------------------------------------===//
128// Vector functions
129//===----------------------------------------------------------------------===//
130def IL_vbuild     : SDNode<"AMDGPUISD::VBUILD", SDTIL_GenVecBuild,
131    []>;
132
133//===--------------------------------------------------------------------===//
134// Custom Pattern DAG Nodes
135//===--------------------------------------------------------------------===//
136def global_store : PatFrag<(ops node:$val, node:$ptr),
137    (store node:$val, node:$ptr), [{
138        return isGlobalStore(dyn_cast<StoreSDNode>(N));
139}]>;
140
141//===----------------------------------------------------------------------===//
142// Load pattern fragments
143//===----------------------------------------------------------------------===//
144// Global address space loads
145def global_load : PatFrag<(ops node:$ptr), (load node:$ptr), [{
146    return isGlobalLoad(dyn_cast<LoadSDNode>(N));
147}]>;
148// Constant address space loads
149def constant_load : PatFrag<(ops node:$ptr), (load node:$ptr), [{
150    return isConstantLoad(dyn_cast<LoadSDNode>(N), -1);
151}]>;
152
153//===----------------------------------------------------------------------===//
154// Complex addressing mode patterns
155//===----------------------------------------------------------------------===//
156def ADDR : ComplexPattern<i32, 2, "SelectADDR", [], []>;
157def ADDRF : ComplexPattern<i32, 2, "SelectADDR", [frameindex], []>;
158def ADDR64 : ComplexPattern<i64, 2, "SelectADDR64", [], []>;
159def ADDR64F : ComplexPattern<i64, 2, "SelectADDR64", [frameindex], []>;
160
161//===----------------------------------------------------------------------===//
162// Instruction format classes
163//===----------------------------------------------------------------------===//
164class ILFormat<dag outs, dag ins, string asmstr, list<dag> pattern>
165: Instruction {
166
167     let Namespace = "AMDGPU";
168     dag OutOperandList = outs;
169     dag InOperandList = ins;
170     let Pattern = pattern;
171     let AsmString = !strconcat(asmstr, "\n");
172     let isPseudo = 1;
173     let Itinerary = NullALU;
174     bit hasIEEEFlag = 0;
175     bit hasZeroOpFlag = 0;
176}
177
178//===--------------------------------------------------------------------===//
179// Multiclass Instruction formats
180//===--------------------------------------------------------------------===//
181// Multiclass that handles branch instructions
182multiclass BranchConditional<SDNode Op> {
183    def _i32 : ILFormat<(outs),
184  (ins brtarget:$target, GPRI32:$src0),
185        "; i32 Pseudo branch instruction",
186  [(Op bb:$target, GPRI32:$src0)]>;
187    def _f32 : ILFormat<(outs),
188  (ins brtarget:$target, GPRF32:$src0),
189        "; f32 Pseudo branch instruction",
190  [(Op bb:$target, GPRF32:$src0)]>;
191}
192
193// Only scalar types should generate flow control
194multiclass BranchInstr<string name> {
195  def _i32 : ILFormat<(outs), (ins GPRI32:$src),
196      !strconcat(name, " $src"), []>;
197  def _f32 : ILFormat<(outs), (ins GPRF32:$src),
198      !strconcat(name, " $src"), []>;
199}
200// Only scalar types should generate flow control
201multiclass BranchInstr2<string name> {
202  def _i32 : ILFormat<(outs), (ins GPRI32:$src0, GPRI32:$src1),
203      !strconcat(name, " $src0, $src1"), []>;
204  def _f32 : ILFormat<(outs), (ins GPRF32:$src0, GPRF32:$src1),
205      !strconcat(name, " $src0, $src1"), []>;
206}
207
208//===--------------------------------------------------------------------===//
209// Intrinsics support
210//===--------------------------------------------------------------------===//
211include "AMDILIntrinsics.td"
212
213//===--------------------------------------------------------------------===//
214// Instructions support
215//===--------------------------------------------------------------------===//
216//===---------------------------------------------------------------------===//
217// Custom Inserter for Branches and returns, this eventually will be a
218// seperate pass
219//===---------------------------------------------------------------------===//
220let isTerminator = 1, usesCustomInserter = 1 in {
221  def BRANCH : ILFormat<(outs), (ins brtarget:$target),
222      "; Pseudo unconditional branch instruction",
223      [(br bb:$target)]>;
224  defm BRANCH_COND : BranchConditional<IL_brcond>;
225}
226
227//===---------------------------------------------------------------------===//
228// Flow and Program control Instructions
229//===---------------------------------------------------------------------===//
230let isTerminator=1 in {
231  def SWITCH      : ILFormat< (outs), (ins GPRI32:$src),
232  !strconcat("SWITCH", " $src"), []>;
233  def CASE        : ILFormat< (outs), (ins GPRI32:$src),
234      !strconcat("CASE", " $src"), []>;
235  def BREAK       : ILFormat< (outs), (ins),
236      "BREAK", []>;
237  def CONTINUE    : ILFormat< (outs), (ins),
238      "CONTINUE", []>;
239  def DEFAULT     : ILFormat< (outs), (ins),
240      "DEFAULT", []>;
241  def ELSE        : ILFormat< (outs), (ins),
242      "ELSE", []>;
243  def ENDSWITCH   : ILFormat< (outs), (ins),
244      "ENDSWITCH", []>;
245  def ENDMAIN     : ILFormat< (outs), (ins),
246      "ENDMAIN", []>;
247  def END         : ILFormat< (outs), (ins),
248      "END", []>;
249  def ENDFUNC     : ILFormat< (outs), (ins),
250      "ENDFUNC", []>;
251  def ENDIF       : ILFormat< (outs), (ins),
252      "ENDIF", []>;
253  def WHILELOOP   : ILFormat< (outs), (ins),
254      "WHILE", []>;
255  def ENDLOOP     : ILFormat< (outs), (ins),
256      "ENDLOOP", []>;
257  def FUNC        : ILFormat< (outs), (ins),
258      "FUNC", []>;
259  def RETDYN      : ILFormat< (outs), (ins),
260      "RET_DYN", []>;
261  // This opcode has custom swizzle pattern encoded in Swizzle Encoder
262  defm IF_LOGICALNZ  : BranchInstr<"IF_LOGICALNZ">;
263  // This opcode has custom swizzle pattern encoded in Swizzle Encoder
264  defm IF_LOGICALZ   : BranchInstr<"IF_LOGICALZ">;
265  // This opcode has custom swizzle pattern encoded in Swizzle Encoder
266  defm BREAK_LOGICALNZ : BranchInstr<"BREAK_LOGICALNZ">;
267  // This opcode has custom swizzle pattern encoded in Swizzle Encoder
268  defm BREAK_LOGICALZ : BranchInstr<"BREAK_LOGICALZ">;
269  // This opcode has custom swizzle pattern encoded in Swizzle Encoder
270  defm CONTINUE_LOGICALNZ : BranchInstr<"CONTINUE_LOGICALNZ">;
271  // This opcode has custom swizzle pattern encoded in Swizzle Encoder
272  defm CONTINUE_LOGICALZ : BranchInstr<"CONTINUE_LOGICALZ">;
273  defm IFC         : BranchInstr2<"IFC">;
274  defm BREAKC      : BranchInstr2<"BREAKC">;
275  defm CONTINUEC   : BranchInstr2<"CONTINUEC">;
276}
277