1//===- NVPTXInstrInfo.td - NVPTX Instruction defs -------------*- tblgen-*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file describes the PTX instructions in TableGen format.
10//
11//===----------------------------------------------------------------------===//
12
13include "NVPTXInstrFormats.td"
14
15// A NOP instruction
16let hasSideEffects = false in {
17  def NOP : NVPTXInst<(outs), (ins), "", []>;
18}
19
20let OperandType = "OPERAND_IMMEDIATE" in {
21  def f16imm : Operand<f16>;
22}
23
24// List of vector specific properties
25def isVecLD      : VecInstTypeEnum<1>;
26def isVecST      : VecInstTypeEnum<2>;
27def isVecBuild   : VecInstTypeEnum<3>;
28def isVecShuffle : VecInstTypeEnum<4>;
29def isVecExtract : VecInstTypeEnum<5>;
30def isVecInsert  : VecInstTypeEnum<6>;
31def isVecDest    : VecInstTypeEnum<7>;
32def isVecOther   : VecInstTypeEnum<15>;
33
34//===----------------------------------------------------------------------===//
35// NVPTX Operand Definitions.
36//===----------------------------------------------------------------------===//
37
38def brtarget    : Operand<OtherVT>;
39
40// CVT conversion modes
41// These must match the enum in NVPTX.h
42def CvtNONE : PatLeaf<(i32 0x0)>;
43def CvtRNI  : PatLeaf<(i32 0x1)>;
44def CvtRZI  : PatLeaf<(i32 0x2)>;
45def CvtRMI  : PatLeaf<(i32 0x3)>;
46def CvtRPI  : PatLeaf<(i32 0x4)>;
47def CvtRN   : PatLeaf<(i32 0x5)>;
48def CvtRZ   : PatLeaf<(i32 0x6)>;
49def CvtRM   : PatLeaf<(i32 0x7)>;
50def CvtRP   : PatLeaf<(i32 0x8)>;
51
52def CvtNONE_FTZ : PatLeaf<(i32 0x10)>;
53def CvtRNI_FTZ  : PatLeaf<(i32 0x11)>;
54def CvtRZI_FTZ  : PatLeaf<(i32 0x12)>;
55def CvtRMI_FTZ  : PatLeaf<(i32 0x13)>;
56def CvtRPI_FTZ  : PatLeaf<(i32 0x14)>;
57def CvtRN_FTZ   : PatLeaf<(i32 0x15)>;
58def CvtRZ_FTZ   : PatLeaf<(i32 0x16)>;
59def CvtRM_FTZ   : PatLeaf<(i32 0x17)>;
60def CvtRP_FTZ   : PatLeaf<(i32 0x18)>;
61
62def CvtSAT      : PatLeaf<(i32 0x20)>;
63def CvtSAT_FTZ  : PatLeaf<(i32 0x30)>;
64
65def CvtMode : Operand<i32> {
66  let PrintMethod = "printCvtMode";
67}
68
69// Compare modes
70// These must match the enum in NVPTX.h
71def CmpEQ   : PatLeaf<(i32 0)>;
72def CmpNE   : PatLeaf<(i32 1)>;
73def CmpLT   : PatLeaf<(i32 2)>;
74def CmpLE   : PatLeaf<(i32 3)>;
75def CmpGT   : PatLeaf<(i32 4)>;
76def CmpGE   : PatLeaf<(i32 5)>;
77def CmpEQU  : PatLeaf<(i32 10)>;
78def CmpNEU  : PatLeaf<(i32 11)>;
79def CmpLTU  : PatLeaf<(i32 12)>;
80def CmpLEU  : PatLeaf<(i32 13)>;
81def CmpGTU  : PatLeaf<(i32 14)>;
82def CmpGEU  : PatLeaf<(i32 15)>;
83def CmpNUM  : PatLeaf<(i32 16)>;
84def CmpNAN  : PatLeaf<(i32 17)>;
85
86def CmpEQ_FTZ   : PatLeaf<(i32 0x100)>;
87def CmpNE_FTZ   : PatLeaf<(i32 0x101)>;
88def CmpLT_FTZ   : PatLeaf<(i32 0x102)>;
89def CmpLE_FTZ   : PatLeaf<(i32 0x103)>;
90def CmpGT_FTZ   : PatLeaf<(i32 0x104)>;
91def CmpGE_FTZ   : PatLeaf<(i32 0x105)>;
92def CmpEQU_FTZ  : PatLeaf<(i32 0x10A)>;
93def CmpNEU_FTZ  : PatLeaf<(i32 0x10B)>;
94def CmpLTU_FTZ  : PatLeaf<(i32 0x10C)>;
95def CmpLEU_FTZ  : PatLeaf<(i32 0x10D)>;
96def CmpGTU_FTZ  : PatLeaf<(i32 0x10E)>;
97def CmpGEU_FTZ  : PatLeaf<(i32 0x10F)>;
98def CmpNUM_FTZ  : PatLeaf<(i32 0x110)>;
99def CmpNAN_FTZ  : PatLeaf<(i32 0x111)>;
100
101def CmpMode : Operand<i32> {
102  let PrintMethod = "printCmpMode";
103}
104def VecElement : Operand<i32> {
105  let PrintMethod = "printVecElement";
106}
107
108//===----------------------------------------------------------------------===//
109// NVPTX Instruction Predicate Definitions
110//===----------------------------------------------------------------------===//
111
112
113def hasAtomAddF64 : Predicate<"Subtarget->hasAtomAddF64()">;
114def hasAtomScope : Predicate<"Subtarget->hasAtomScope()">;
115def hasAtomBitwise64 : Predicate<"Subtarget->hasAtomBitwise64()">;
116def hasAtomMinMax64 : Predicate<"Subtarget->hasAtomMinMax64()">;
117def hasVote : Predicate<"Subtarget->hasVote()">;
118def hasDouble : Predicate<"Subtarget->hasDouble()">;
119def hasLDG : Predicate<"Subtarget->hasLDG()">;
120def hasLDU : Predicate<"Subtarget->hasLDU()">;
121
122def doF32FTZ : Predicate<"useF32FTZ()">;
123def doNoF32FTZ : Predicate<"!useF32FTZ()">;
124
125def doMulWide      : Predicate<"doMulWide">;
126
127def allowFMA : Predicate<"allowFMA()">;
128def noFMA : Predicate<"!allowFMA()">;
129def allowUnsafeFPMath : Predicate<"allowUnsafeFPMath()">;
130
131def do_DIVF32_APPROX : Predicate<"getDivF32Level()==0">;
132def do_DIVF32_FULL : Predicate<"getDivF32Level()==1">;
133
134def do_SQRTF32_APPROX : Predicate<"!usePrecSqrtF32()">;
135def do_SQRTF32_RN : Predicate<"usePrecSqrtF32()">;
136
137def hasHWROT32 : Predicate<"Subtarget->hasHWROT32()">;
138def noHWROT32 : Predicate<"!Subtarget->hasHWROT32()">;
139
140def True : Predicate<"true">;
141
142def hasPTX31 : Predicate<"Subtarget->getPTXVersion() >= 31">;
143def hasPTX60 : Predicate<"Subtarget->getPTXVersion() >= 60">;
144def hasPTX61 : Predicate<"Subtarget->getPTXVersion() >= 61">;
145def hasPTX63 : Predicate<"Subtarget->getPTXVersion() >= 63">;
146def hasPTX64 : Predicate<"Subtarget->getPTXVersion() >= 64">;
147def hasPTX65 : Predicate<"Subtarget->getPTXVersion() >= 65">;
148def hasPTX70 : Predicate<"Subtarget->getPTXVersion() >= 70">;
149def hasPTX71 : Predicate<"Subtarget->getPTXVersion() >= 71">;
150
151def hasSM30 : Predicate<"Subtarget->getSmVersion() >= 30">;
152def hasSM70 : Predicate<"Subtarget->getSmVersion() >= 70">;
153def hasSM72 : Predicate<"Subtarget->getSmVersion() >= 72">;
154def hasSM75 : Predicate<"Subtarget->getSmVersion() >= 75">;
155def hasSM80 : Predicate<"Subtarget->getSmVersion() >= 80">;
156
157// non-sync shfl instructions are not available on sm_70+ in PTX6.4+
158def hasSHFL : Predicate<"!(Subtarget->getSmVersion() >= 70"
159                          "&& Subtarget->getPTXVersion() >= 64)">;
160
161def useShortPtr : Predicate<"useShortPointers()">;
162def useFP16Math: Predicate<"Subtarget->allowFP16Math()">;
163
164//===----------------------------------------------------------------------===//
165// Some Common Instruction Class Templates
166//===----------------------------------------------------------------------===//
167
168// Template for instructions which take three int64, int32, or int16 args.
169// The instructions are named "<OpcStr><Width>" (e.g. "add.s64").
170multiclass I3<string OpcStr, SDNode OpNode> {
171  def i64rr :
172    NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$a, Int64Regs:$b),
173              !strconcat(OpcStr, "64 \t$dst, $a, $b;"),
174              [(set Int64Regs:$dst, (OpNode Int64Regs:$a, Int64Regs:$b))]>;
175  def i64ri :
176    NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$a, i64imm:$b),
177              !strconcat(OpcStr, "64 \t$dst, $a, $b;"),
178              [(set Int64Regs:$dst, (OpNode Int64Regs:$a, imm:$b))]>;
179  def i32rr :
180    NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$a, Int32Regs:$b),
181              !strconcat(OpcStr, "32 \t$dst, $a, $b;"),
182              [(set Int32Regs:$dst, (OpNode Int32Regs:$a, Int32Regs:$b))]>;
183  def i32ri :
184    NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$a, i32imm:$b),
185              !strconcat(OpcStr, "32 \t$dst, $a, $b;"),
186              [(set Int32Regs:$dst, (OpNode Int32Regs:$a, imm:$b))]>;
187  def i16rr :
188    NVPTXInst<(outs Int16Regs:$dst), (ins Int16Regs:$a, Int16Regs:$b),
189              !strconcat(OpcStr, "16 \t$dst, $a, $b;"),
190              [(set Int16Regs:$dst, (OpNode Int16Regs:$a, Int16Regs:$b))]>;
191  def i16ri :
192    NVPTXInst<(outs Int16Regs:$dst), (ins Int16Regs:$a, i16imm:$b),
193              !strconcat(OpcStr, "16 \t$dst, $a, $b;"),
194              [(set Int16Regs:$dst, (OpNode Int16Regs:$a, (imm):$b))]>;
195}
196
197// Template for instructions which take 3 int32 args.  The instructions are
198// named "<OpcStr>.s32" (e.g. "addc.cc.s32").
199multiclass ADD_SUB_INT_32<string OpcStr, SDNode OpNode> {
200   def i32rr :
201     NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$a, Int32Regs:$b),
202               !strconcat(OpcStr, ".s32 \t$dst, $a, $b;"),
203               [(set Int32Regs:$dst, (OpNode Int32Regs:$a, Int32Regs:$b))]>;
204   def i32ri :
205     NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$a, i32imm:$b),
206               !strconcat(OpcStr, ".s32 \t$dst, $a, $b;"),
207               [(set Int32Regs:$dst, (OpNode Int32Regs:$a, imm:$b))]>;
208}
209
210// Template for instructions which take three fp64 or fp32 args.  The
211// instructions are named "<OpcStr>.f<Width>" (e.g. "min.f64").
212//
213// Also defines ftz (flush subnormal inputs and results to sign-preserving
214// zero) variants for fp32 functions.
215//
216// This multiclass should be used for nodes that cannot be folded into FMAs.
217// For nodes that can be folded into FMAs (i.e. adds and muls), use
218// F3_fma_component.
219multiclass F3<string OpcStr, SDNode OpNode> {
220   def f64rr :
221     NVPTXInst<(outs Float64Regs:$dst),
222               (ins Float64Regs:$a, Float64Regs:$b),
223               !strconcat(OpcStr, ".f64 \t$dst, $a, $b;"),
224               [(set Float64Regs:$dst, (OpNode Float64Regs:$a, Float64Regs:$b))]>;
225   def f64ri :
226     NVPTXInst<(outs Float64Regs:$dst),
227               (ins Float64Regs:$a, f64imm:$b),
228               !strconcat(OpcStr, ".f64 \t$dst, $a, $b;"),
229               [(set Float64Regs:$dst, (OpNode Float64Regs:$a, fpimm:$b))]>;
230   def f32rr_ftz :
231     NVPTXInst<(outs Float32Regs:$dst),
232               (ins Float32Regs:$a, Float32Regs:$b),
233               !strconcat(OpcStr, ".ftz.f32 \t$dst, $a, $b;"),
234               [(set Float32Regs:$dst, (OpNode Float32Regs:$a, Float32Regs:$b))]>,
235               Requires<[doF32FTZ]>;
236   def f32ri_ftz :
237     NVPTXInst<(outs Float32Regs:$dst),
238               (ins Float32Regs:$a, f32imm:$b),
239               !strconcat(OpcStr, ".ftz.f32 \t$dst, $a, $b;"),
240               [(set Float32Regs:$dst, (OpNode Float32Regs:$a, fpimm:$b))]>,
241               Requires<[doF32FTZ]>;
242   def f32rr :
243     NVPTXInst<(outs Float32Regs:$dst),
244               (ins Float32Regs:$a, Float32Regs:$b),
245               !strconcat(OpcStr, ".f32 \t$dst, $a, $b;"),
246               [(set Float32Regs:$dst, (OpNode Float32Regs:$a, Float32Regs:$b))]>;
247   def f32ri :
248     NVPTXInst<(outs Float32Regs:$dst),
249               (ins Float32Regs:$a, f32imm:$b),
250               !strconcat(OpcStr, ".f32 \t$dst, $a, $b;"),
251               [(set Float32Regs:$dst, (OpNode Float32Regs:$a, fpimm:$b))]>;
252}
253
254// Template for instructions which take three FP args.  The
255// instructions are named "<OpcStr>.f<Width>" (e.g. "add.f64").
256//
257// Also defines ftz (flush subnormal inputs and results to sign-preserving
258// zero) variants for fp32/fp16 functions.
259//
260// This multiclass should be used for nodes that can be folded to make fma ops.
261// In this case, we use the ".rn" variant when FMA is disabled, as this behaves
262// just like the non ".rn" op, but prevents ptxas from creating FMAs.
263multiclass F3_fma_component<string OpcStr, SDNode OpNode> {
264   def f64rr :
265     NVPTXInst<(outs Float64Regs:$dst),
266               (ins Float64Regs:$a, Float64Regs:$b),
267               !strconcat(OpcStr, ".f64 \t$dst, $a, $b;"),
268               [(set Float64Regs:$dst, (OpNode Float64Regs:$a, Float64Regs:$b))]>,
269               Requires<[allowFMA]>;
270   def f64ri :
271     NVPTXInst<(outs Float64Regs:$dst),
272               (ins Float64Regs:$a, f64imm:$b),
273               !strconcat(OpcStr, ".f64 \t$dst, $a, $b;"),
274               [(set Float64Regs:$dst, (OpNode Float64Regs:$a, fpimm:$b))]>,
275               Requires<[allowFMA]>;
276   def f32rr_ftz :
277     NVPTXInst<(outs Float32Regs:$dst),
278               (ins Float32Regs:$a, Float32Regs:$b),
279               !strconcat(OpcStr, ".ftz.f32 \t$dst, $a, $b;"),
280               [(set Float32Regs:$dst, (OpNode Float32Regs:$a, Float32Regs:$b))]>,
281               Requires<[allowFMA, doF32FTZ]>;
282   def f32ri_ftz :
283     NVPTXInst<(outs Float32Regs:$dst),
284               (ins Float32Regs:$a, f32imm:$b),
285               !strconcat(OpcStr, ".ftz.f32 \t$dst, $a, $b;"),
286               [(set Float32Regs:$dst, (OpNode Float32Regs:$a, fpimm:$b))]>,
287               Requires<[allowFMA, doF32FTZ]>;
288   def f32rr :
289     NVPTXInst<(outs Float32Regs:$dst),
290               (ins Float32Regs:$a, Float32Regs:$b),
291               !strconcat(OpcStr, ".f32 \t$dst, $a, $b;"),
292               [(set Float32Regs:$dst, (OpNode Float32Regs:$a, Float32Regs:$b))]>,
293               Requires<[allowFMA]>;
294   def f32ri :
295     NVPTXInst<(outs Float32Regs:$dst),
296               (ins Float32Regs:$a, f32imm:$b),
297               !strconcat(OpcStr, ".f32 \t$dst, $a, $b;"),
298               [(set Float32Regs:$dst, (OpNode Float32Regs:$a, fpimm:$b))]>,
299               Requires<[allowFMA]>;
300
301   def f16rr_ftz :
302     NVPTXInst<(outs Float16Regs:$dst),
303               (ins Float16Regs:$a, Float16Regs:$b),
304               !strconcat(OpcStr, ".ftz.f16 \t$dst, $a, $b;"),
305               [(set Float16Regs:$dst, (OpNode Float16Regs:$a, Float16Regs:$b))]>,
306               Requires<[useFP16Math, allowFMA, doF32FTZ]>;
307   def f16rr :
308     NVPTXInst<(outs Float16Regs:$dst),
309               (ins Float16Regs:$a, Float16Regs:$b),
310               !strconcat(OpcStr, ".f16 \t$dst, $a, $b;"),
311               [(set Float16Regs:$dst, (OpNode Float16Regs:$a, Float16Regs:$b))]>,
312               Requires<[useFP16Math, allowFMA]>;
313
314   def f16x2rr_ftz :
315     NVPTXInst<(outs Float16x2Regs:$dst),
316               (ins Float16x2Regs:$a, Float16x2Regs:$b),
317               !strconcat(OpcStr, ".ftz.f16x2 \t$dst, $a, $b;"),
318               [(set Float16x2Regs:$dst, (OpNode Float16x2Regs:$a, Float16x2Regs:$b))]>,
319               Requires<[useFP16Math, allowFMA, doF32FTZ]>;
320   def f16x2rr :
321     NVPTXInst<(outs Float16x2Regs:$dst),
322               (ins Float16x2Regs:$a, Float16x2Regs:$b),
323               !strconcat(OpcStr, ".f16x2 \t$dst, $a, $b;"),
324               [(set Float16x2Regs:$dst, (OpNode Float16x2Regs:$a, Float16x2Regs:$b))]>,
325               Requires<[useFP16Math, allowFMA]>;
326
327   // These have strange names so we don't perturb existing mir tests.
328   def _rnf64rr :
329     NVPTXInst<(outs Float64Regs:$dst),
330               (ins Float64Regs:$a, Float64Regs:$b),
331               !strconcat(OpcStr, ".rn.f64 \t$dst, $a, $b;"),
332               [(set Float64Regs:$dst, (OpNode Float64Regs:$a, Float64Regs:$b))]>,
333               Requires<[noFMA]>;
334   def _rnf64ri :
335     NVPTXInst<(outs Float64Regs:$dst),
336               (ins Float64Regs:$a, f64imm:$b),
337               !strconcat(OpcStr, ".rn.f64 \t$dst, $a, $b;"),
338               [(set Float64Regs:$dst, (OpNode Float64Regs:$a, fpimm:$b))]>,
339               Requires<[noFMA]>;
340   def _rnf32rr_ftz :
341     NVPTXInst<(outs Float32Regs:$dst),
342               (ins Float32Regs:$a, Float32Regs:$b),
343               !strconcat(OpcStr, ".rn.ftz.f32 \t$dst, $a, $b;"),
344               [(set Float32Regs:$dst, (OpNode Float32Regs:$a, Float32Regs:$b))]>,
345               Requires<[noFMA, doF32FTZ]>;
346   def _rnf32ri_ftz :
347     NVPTXInst<(outs Float32Regs:$dst),
348               (ins Float32Regs:$a, f32imm:$b),
349               !strconcat(OpcStr, ".rn.ftz.f32 \t$dst, $a, $b;"),
350               [(set Float32Regs:$dst, (OpNode Float32Regs:$a, fpimm:$b))]>,
351               Requires<[noFMA, doF32FTZ]>;
352   def _rnf32rr :
353     NVPTXInst<(outs Float32Regs:$dst),
354               (ins Float32Regs:$a, Float32Regs:$b),
355               !strconcat(OpcStr, ".rn.f32 \t$dst, $a, $b;"),
356               [(set Float32Regs:$dst, (OpNode Float32Regs:$a, Float32Regs:$b))]>,
357               Requires<[noFMA]>;
358   def _rnf32ri :
359     NVPTXInst<(outs Float32Regs:$dst),
360               (ins Float32Regs:$a, f32imm:$b),
361               !strconcat(OpcStr, ".rn.f32 \t$dst, $a, $b;"),
362               [(set Float32Regs:$dst, (OpNode Float32Regs:$a, fpimm:$b))]>,
363               Requires<[noFMA]>;
364   def _rnf16rr_ftz :
365     NVPTXInst<(outs Float16Regs:$dst),
366               (ins Float16Regs:$a, Float16Regs:$b),
367               !strconcat(OpcStr, ".rn.ftz.f16 \t$dst, $a, $b;"),
368               [(set Float16Regs:$dst, (OpNode Float16Regs:$a, Float16Regs:$b))]>,
369               Requires<[useFP16Math, noFMA, doF32FTZ]>;
370   def _rnf16rr :
371     NVPTXInst<(outs Float16Regs:$dst),
372               (ins Float16Regs:$a, Float16Regs:$b),
373               !strconcat(OpcStr, ".rn.f16 \t$dst, $a, $b;"),
374               [(set Float16Regs:$dst, (OpNode Float16Regs:$a, Float16Regs:$b))]>,
375               Requires<[useFP16Math, noFMA]>;
376   def _rnf16x2rr_ftz :
377     NVPTXInst<(outs Float16x2Regs:$dst),
378               (ins Float16x2Regs:$a, Float16x2Regs:$b),
379               !strconcat(OpcStr, ".rn.ftz.f16x2 \t$dst, $a, $b;"),
380               [(set Float16x2Regs:$dst, (OpNode Float16x2Regs:$a, Float16x2Regs:$b))]>,
381               Requires<[useFP16Math, noFMA, doF32FTZ]>;
382   def _rnf16x2rr :
383     NVPTXInst<(outs Float16x2Regs:$dst),
384               (ins Float16x2Regs:$a, Float16x2Regs:$b),
385               !strconcat(OpcStr, ".rn.f16x2 \t$dst, $a, $b;"),
386               [(set Float16x2Regs:$dst, (OpNode Float16x2Regs:$a, Float16x2Regs:$b))]>,
387               Requires<[useFP16Math, noFMA]>;
388}
389
390// Template for operations which take two f32 or f64 operands.  Provides three
391// instructions: <OpcStr>.f64, <OpcStr>.f32, and <OpcStr>.ftz.f32 (flush
392// subnormal inputs and results to zero).
393multiclass F2<string OpcStr, SDNode OpNode> {
394   def f64 :     NVPTXInst<(outs Float64Regs:$dst), (ins Float64Regs:$a),
395                           !strconcat(OpcStr, ".f64 \t$dst, $a;"),
396                           [(set Float64Regs:$dst, (OpNode Float64Regs:$a))]>;
397   def f32_ftz : NVPTXInst<(outs Float32Regs:$dst), (ins Float32Regs:$a),
398                           !strconcat(OpcStr, ".ftz.f32 \t$dst, $a;"),
399                           [(set Float32Regs:$dst, (OpNode Float32Regs:$a))]>,
400                           Requires<[doF32FTZ]>;
401   def f32 :     NVPTXInst<(outs Float32Regs:$dst), (ins Float32Regs:$a),
402                           !strconcat(OpcStr, ".f32 \t$dst, $a;"),
403                           [(set Float32Regs:$dst, (OpNode Float32Regs:$a))]>;
404}
405
406//===----------------------------------------------------------------------===//
407// NVPTX Instructions.
408//===----------------------------------------------------------------------===//
409
410//-----------------------------------
411// Type Conversion
412//-----------------------------------
413
414let hasSideEffects = false in {
415  // Generate a cvt to the given type from all possible types.  Each instance
416  // takes a CvtMode immediate that defines the conversion mode to use.  It can
417  // be CvtNONE to omit a conversion mode.
418  multiclass CVT_FROM_ALL<string FromName, RegisterClass RC> {
419    def _s8 :
420      NVPTXInst<(outs RC:$dst),
421                (ins Int16Regs:$src, CvtMode:$mode),
422                !strconcat("cvt${mode:base}${mode:ftz}${mode:sat}.",
423                FromName, ".s8 \t$dst, $src;"), []>;
424    def _u8 :
425      NVPTXInst<(outs RC:$dst),
426                (ins Int16Regs:$src, CvtMode:$mode),
427                !strconcat("cvt${mode:base}${mode:ftz}${mode:sat}.",
428                FromName, ".u8 \t$dst, $src;"), []>;
429    def _s16 :
430      NVPTXInst<(outs RC:$dst),
431                (ins Int16Regs:$src, CvtMode:$mode),
432                !strconcat("cvt${mode:base}${mode:ftz}${mode:sat}.",
433                FromName, ".s16 \t$dst, $src;"), []>;
434    def _u16 :
435      NVPTXInst<(outs RC:$dst),
436                (ins Int16Regs:$src, CvtMode:$mode),
437                !strconcat("cvt${mode:base}${mode:ftz}${mode:sat}.",
438                FromName, ".u16 \t$dst, $src;"), []>;
439    def _s32 :
440      NVPTXInst<(outs RC:$dst),
441                (ins Int32Regs:$src, CvtMode:$mode),
442                !strconcat("cvt${mode:base}${mode:ftz}${mode:sat}.",
443                FromName, ".s32 \t$dst, $src;"), []>;
444    def _u32 :
445      NVPTXInst<(outs RC:$dst),
446                (ins Int32Regs:$src, CvtMode:$mode),
447                !strconcat("cvt${mode:base}${mode:ftz}${mode:sat}.",
448                FromName, ".u32 \t$dst, $src;"), []>;
449    def _s64 :
450      NVPTXInst<(outs RC:$dst),
451                (ins Int64Regs:$src, CvtMode:$mode),
452                !strconcat("cvt${mode:base}${mode:ftz}${mode:sat}.",
453                FromName, ".s64 \t$dst, $src;"), []>;
454    def _u64 :
455      NVPTXInst<(outs RC:$dst),
456                (ins Int64Regs:$src, CvtMode:$mode),
457                !strconcat("cvt${mode:base}${mode:ftz}${mode:sat}.",
458                FromName, ".u64 \t$dst, $src;"), []>;
459    def _f16 :
460      NVPTXInst<(outs RC:$dst),
461                (ins Float16Regs:$src, CvtMode:$mode),
462                !strconcat("cvt${mode:base}${mode:ftz}${mode:sat}.",
463                FromName, ".f16 \t$dst, $src;"), []>;
464    def _f32 :
465      NVPTXInst<(outs RC:$dst),
466                (ins Float32Regs:$src, CvtMode:$mode),
467                !strconcat("cvt${mode:base}${mode:ftz}${mode:sat}.",
468                FromName, ".f32 \t$dst, $src;"), []>;
469    def _f64 :
470      NVPTXInst<(outs RC:$dst),
471                (ins Float64Regs:$src, CvtMode:$mode),
472                !strconcat("cvt${mode:base}${mode:ftz}${mode:sat}.",
473                FromName, ".f64 \t$dst, $src;"), []>;
474  }
475
476  // Generate cvts from all types to all types.
477  defm CVT_s8  : CVT_FROM_ALL<"s8",  Int16Regs>;
478  defm CVT_u8  : CVT_FROM_ALL<"u8",  Int16Regs>;
479  defm CVT_s16 : CVT_FROM_ALL<"s16", Int16Regs>;
480  defm CVT_u16 : CVT_FROM_ALL<"u16", Int16Regs>;
481  defm CVT_s32 : CVT_FROM_ALL<"s32", Int32Regs>;
482  defm CVT_u32 : CVT_FROM_ALL<"u32", Int32Regs>;
483  defm CVT_s64 : CVT_FROM_ALL<"s64", Int64Regs>;
484  defm CVT_u64 : CVT_FROM_ALL<"u64", Int64Regs>;
485  defm CVT_f16 : CVT_FROM_ALL<"f16", Float16Regs>;
486  defm CVT_f32 : CVT_FROM_ALL<"f32", Float32Regs>;
487  defm CVT_f64 : CVT_FROM_ALL<"f64", Float64Regs>;
488
489  // These cvts are different from those above: The source and dest registers
490  // are of the same type.
491  def CVT_INREG_s16_s8 :  NVPTXInst<(outs Int16Regs:$dst), (ins Int16Regs:$src),
492                                    "cvt.s16.s8 \t$dst, $src;", []>;
493  def CVT_INREG_s32_s8 :  NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$src),
494                                    "cvt.s32.s8 \t$dst, $src;", []>;
495  def CVT_INREG_s32_s16 : NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$src),
496                                    "cvt.s32.s16 \t$dst, $src;", []>;
497  def CVT_INREG_s64_s8 :  NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$src),
498                                    "cvt.s64.s8 \t$dst, $src;", []>;
499  def CVT_INREG_s64_s16 : NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$src),
500                                    "cvt.s64.s16 \t$dst, $src;", []>;
501  def CVT_INREG_s64_s32 : NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$src),
502                                    "cvt.s64.s32 \t$dst, $src;", []>;
503}
504
505//-----------------------------------
506// Integer Arithmetic
507//-----------------------------------
508
509// Template for xor masquerading as int1 arithmetic.
510multiclass ADD_SUB_i1<SDNode OpNode> {
511   def _rr: NVPTXInst<(outs Int1Regs:$dst), (ins Int1Regs:$a, Int1Regs:$b),
512                      "xor.pred \t$dst, $a, $b;",
513                      [(set Int1Regs:$dst, (OpNode Int1Regs:$a, Int1Regs:$b))]>;
514   def _ri: NVPTXInst<(outs Int1Regs:$dst), (ins Int1Regs:$a, i1imm:$b),
515                      "xor.pred \t$dst, $a, $b;",
516                      [(set Int1Regs:$dst, (OpNode Int1Regs:$a, (imm):$b))]>;
517}
518
519// int1 addition and subtraction are both just xor.
520defm ADD_i1 : ADD_SUB_i1<add>;
521defm SUB_i1 : ADD_SUB_i1<sub>;
522
523// int16, int32, and int64 signed addition.  Since nvptx is 2's complement, we
524// also use these for unsigned arithmetic.
525defm ADD : I3<"add.s", add>;
526defm SUB : I3<"sub.s", sub>;
527
528// int32 addition and subtraction with carry-out.
529// FIXME: PTX 4.3 adds a 64-bit add.cc (and maybe also 64-bit addc.cc?).
530defm ADDCC : ADD_SUB_INT_32<"add.cc", addc>;
531defm SUBCC : ADD_SUB_INT_32<"sub.cc", subc>;
532
533// int32 addition and subtraction with carry-in and carry-out.
534defm ADDCCC : ADD_SUB_INT_32<"addc.cc", adde>;
535defm SUBCCC : ADD_SUB_INT_32<"subc.cc", sube>;
536
537defm MULT : I3<"mul.lo.s", mul>;
538
539defm MULTHS : I3<"mul.hi.s", mulhs>;
540defm MULTHU : I3<"mul.hi.u", mulhu>;
541
542defm SDIV : I3<"div.s", sdiv>;
543defm UDIV : I3<"div.u", udiv>;
544
545// The ri versions of rem.s and rem.u won't be selected; DAGCombiner::visitSREM
546// will lower it.
547defm SREM : I3<"rem.s", srem>;
548defm UREM : I3<"rem.u", urem>;
549
550// Integer absolute value.  NumBits should be one minus the bit width of RC.
551// This idiom implements the algorithm at
552// http://graphics.stanford.edu/~seander/bithacks.html#IntegerAbs.
553multiclass ABS<RegisterClass RC, string SizeName> {
554  def : NVPTXInst<(outs RC:$dst), (ins RC:$a),
555                  !strconcat("abs", SizeName, " \t$dst, $a;"),
556                  [(set RC:$dst, (abs RC:$a))]>;
557}
558defm ABS_16 : ABS<Int16Regs, ".s16">;
559defm ABS_32 : ABS<Int32Regs, ".s32">;
560defm ABS_64 : ABS<Int64Regs, ".s64">;
561
562// Integer min/max.
563defm SMAX : I3<"max.s", smax>;
564defm UMAX : I3<"max.u", umax>;
565defm SMIN : I3<"min.s", smin>;
566defm UMIN : I3<"min.u", umin>;
567
568//
569// Wide multiplication
570//
571def MULWIDES64 :
572  NVPTXInst<(outs Int64Regs:$dst), (ins Int32Regs:$a, Int32Regs:$b),
573            "mul.wide.s32 \t$dst, $a, $b;", []>;
574def MULWIDES64Imm :
575  NVPTXInst<(outs Int64Regs:$dst), (ins Int32Regs:$a, i32imm:$b),
576            "mul.wide.s32 \t$dst, $a, $b;", []>;
577def MULWIDES64Imm64 :
578  NVPTXInst<(outs Int64Regs:$dst), (ins Int32Regs:$a, i64imm:$b),
579            "mul.wide.s32 \t$dst, $a, $b;", []>;
580
581def MULWIDEU64 :
582  NVPTXInst<(outs Int64Regs:$dst), (ins Int32Regs:$a, Int32Regs:$b),
583            "mul.wide.u32 \t$dst, $a, $b;", []>;
584def MULWIDEU64Imm :
585  NVPTXInst<(outs Int64Regs:$dst), (ins Int32Regs:$a, i32imm:$b),
586            "mul.wide.u32 \t$dst, $a, $b;", []>;
587def MULWIDEU64Imm64 :
588  NVPTXInst<(outs Int64Regs:$dst), (ins Int32Regs:$a, i64imm:$b),
589            "mul.wide.u32 \t$dst, $a, $b;", []>;
590
591def MULWIDES32 :
592  NVPTXInst<(outs Int32Regs:$dst), (ins Int16Regs:$a, Int16Regs:$b),
593            "mul.wide.s16 \t$dst, $a, $b;", []>;
594def MULWIDES32Imm :
595  NVPTXInst<(outs Int32Regs:$dst), (ins Int16Regs:$a, i16imm:$b),
596            "mul.wide.s16 \t$dst, $a, $b;", []>;
597def MULWIDES32Imm32 :
598  NVPTXInst<(outs Int32Regs:$dst), (ins Int16Regs:$a, i32imm:$b),
599            "mul.wide.s16 \t$dst, $a, $b;", []>;
600
601def MULWIDEU32 :
602  NVPTXInst<(outs Int32Regs:$dst), (ins Int16Regs:$a, Int16Regs:$b),
603            "mul.wide.u16 \t$dst, $a, $b;", []>;
604def MULWIDEU32Imm :
605  NVPTXInst<(outs Int32Regs:$dst), (ins Int16Regs:$a, i16imm:$b),
606            "mul.wide.u16 \t$dst, $a, $b;", []>;
607def MULWIDEU32Imm32 :
608  NVPTXInst<(outs Int32Regs:$dst), (ins Int16Regs:$a, i32imm:$b),
609            "mul.wide.u16 \t$dst, $a, $b;", []>;
610
611def SDTMulWide : SDTypeProfile<1, 2, [SDTCisSameAs<1, 2>]>;
612def mul_wide_signed : SDNode<"NVPTXISD::MUL_WIDE_SIGNED", SDTMulWide>;
613def mul_wide_unsigned : SDNode<"NVPTXISD::MUL_WIDE_UNSIGNED", SDTMulWide>;
614
615// Matchers for signed, unsigned mul.wide ISD nodes.
616def : Pat<(i32 (mul_wide_signed Int16Regs:$a, Int16Regs:$b)),
617          (MULWIDES32 Int16Regs:$a, Int16Regs:$b)>,
618      Requires<[doMulWide]>;
619def : Pat<(i32 (mul_wide_signed Int16Regs:$a, imm:$b)),
620          (MULWIDES32Imm Int16Regs:$a, imm:$b)>,
621      Requires<[doMulWide]>;
622def : Pat<(i32 (mul_wide_unsigned Int16Regs:$a, Int16Regs:$b)),
623          (MULWIDEU32 Int16Regs:$a, Int16Regs:$b)>,
624      Requires<[doMulWide]>;
625def : Pat<(i32 (mul_wide_unsigned Int16Regs:$a, imm:$b)),
626          (MULWIDEU32Imm Int16Regs:$a, imm:$b)>,
627      Requires<[doMulWide]>;
628
629def : Pat<(i64 (mul_wide_signed Int32Regs:$a, Int32Regs:$b)),
630          (MULWIDES64 Int32Regs:$a, Int32Regs:$b)>,
631      Requires<[doMulWide]>;
632def : Pat<(i64 (mul_wide_signed Int32Regs:$a, imm:$b)),
633          (MULWIDES64Imm Int32Regs:$a, imm:$b)>,
634      Requires<[doMulWide]>;
635def : Pat<(i64 (mul_wide_unsigned Int32Regs:$a, Int32Regs:$b)),
636          (MULWIDEU64 Int32Regs:$a, Int32Regs:$b)>,
637      Requires<[doMulWide]>;
638def : Pat<(i64 (mul_wide_unsigned Int32Regs:$a, imm:$b)),
639          (MULWIDEU64Imm Int32Regs:$a, imm:$b)>,
640      Requires<[doMulWide]>;
641
642// Predicates used for converting some patterns to mul.wide.
643def SInt32Const : PatLeaf<(imm), [{
644  const APInt &v = N->getAPIntValue();
645  return v.isSignedIntN(32);
646}]>;
647
648def UInt32Const : PatLeaf<(imm), [{
649  const APInt &v = N->getAPIntValue();
650  return v.isIntN(32);
651}]>;
652
653def SInt16Const : PatLeaf<(imm), [{
654  const APInt &v = N->getAPIntValue();
655  return v.isSignedIntN(16);
656}]>;
657
658def UInt16Const : PatLeaf<(imm), [{
659  const APInt &v = N->getAPIntValue();
660  return v.isIntN(16);
661}]>;
662
663def Int5Const : PatLeaf<(imm), [{
664  // Check if 0 <= v < 32; only then will the result of (x << v) be an int32.
665  const APInt &v = N->getAPIntValue();
666  return v.sge(0) && v.slt(32);
667}]>;
668
669def Int4Const : PatLeaf<(imm), [{
670  // Check if 0 <= v < 16; only then will the result of (x << v) be an int16.
671  const APInt &v = N->getAPIntValue();
672  return v.sge(0) && v.slt(16);
673}]>;
674
675def SHL2MUL32 : SDNodeXForm<imm, [{
676  const APInt &v = N->getAPIntValue();
677  APInt temp(32, 1);
678  return CurDAG->getTargetConstant(temp.shl(v), SDLoc(N), MVT::i32);
679}]>;
680
681def SHL2MUL16 : SDNodeXForm<imm, [{
682  const APInt &v = N->getAPIntValue();
683  APInt temp(16, 1);
684  return CurDAG->getTargetConstant(temp.shl(v), SDLoc(N), MVT::i16);
685}]>;
686
687// Convert "sign/zero-extend, then shift left by an immediate" to mul.wide.
688def : Pat<(shl (sext Int32Regs:$a), (i32 Int5Const:$b)),
689          (MULWIDES64Imm Int32Regs:$a, (SHL2MUL32 node:$b))>,
690      Requires<[doMulWide]>;
691def : Pat<(shl (zext Int32Regs:$a), (i32 Int5Const:$b)),
692          (MULWIDEU64Imm Int32Regs:$a, (SHL2MUL32 node:$b))>,
693      Requires<[doMulWide]>;
694
695def : Pat<(shl (sext Int16Regs:$a), (i16 Int4Const:$b)),
696          (MULWIDES32Imm Int16Regs:$a, (SHL2MUL16 node:$b))>,
697      Requires<[doMulWide]>;
698def : Pat<(shl (zext Int16Regs:$a), (i16 Int4Const:$b)),
699          (MULWIDEU32Imm Int16Regs:$a, (SHL2MUL16 node:$b))>,
700      Requires<[doMulWide]>;
701
702// Convert "sign/zero-extend then multiply" to mul.wide.
703def : Pat<(mul (sext Int32Regs:$a), (sext Int32Regs:$b)),
704          (MULWIDES64 Int32Regs:$a, Int32Regs:$b)>,
705      Requires<[doMulWide]>;
706def : Pat<(mul (sext Int32Regs:$a), (i64 SInt32Const:$b)),
707          (MULWIDES64Imm64 Int32Regs:$a, (i64 SInt32Const:$b))>,
708      Requires<[doMulWide]>;
709
710def : Pat<(mul (zext Int32Regs:$a), (zext Int32Regs:$b)),
711          (MULWIDEU64 Int32Regs:$a, Int32Regs:$b)>,
712      Requires<[doMulWide]>;
713def : Pat<(mul (zext Int32Regs:$a), (i64 UInt32Const:$b)),
714          (MULWIDEU64Imm64 Int32Regs:$a, (i64 UInt32Const:$b))>,
715      Requires<[doMulWide]>;
716
717def : Pat<(mul (sext Int16Regs:$a), (sext Int16Regs:$b)),
718          (MULWIDES32 Int16Regs:$a, Int16Regs:$b)>,
719      Requires<[doMulWide]>;
720def : Pat<(mul (sext Int16Regs:$a), (i32 SInt16Const:$b)),
721          (MULWIDES32Imm32 Int16Regs:$a, (i32 SInt16Const:$b))>,
722      Requires<[doMulWide]>;
723
724def : Pat<(mul (zext Int16Regs:$a), (zext Int16Regs:$b)),
725          (MULWIDEU32 Int16Regs:$a, Int16Regs:$b)>,
726      Requires<[doMulWide]>;
727def : Pat<(mul (zext Int16Regs:$a), (i32 UInt16Const:$b)),
728          (MULWIDEU32Imm32 Int16Regs:$a, (i32 UInt16Const:$b))>,
729      Requires<[doMulWide]>;
730
731//
732// Integer multiply-add
733//
734def SDTIMAD :
735  SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisInt<2>,
736                       SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>]>;
737def imad : SDNode<"NVPTXISD::IMAD", SDTIMAD>;
738
739def MAD16rrr :
740  NVPTXInst<(outs Int16Regs:$dst),
741            (ins Int16Regs:$a, Int16Regs:$b, Int16Regs:$c),
742            "mad.lo.s16 \t$dst, $a, $b, $c;",
743            [(set Int16Regs:$dst, (imad Int16Regs:$a, Int16Regs:$b, Int16Regs:$c))]>;
744def MAD16rri :
745  NVPTXInst<(outs Int16Regs:$dst),
746            (ins Int16Regs:$a, Int16Regs:$b, i16imm:$c),
747            "mad.lo.s16 \t$dst, $a, $b, $c;",
748            [(set Int16Regs:$dst, (imad Int16Regs:$a, Int16Regs:$b, imm:$c))]>;
749def MAD16rir :
750  NVPTXInst<(outs Int16Regs:$dst),
751            (ins Int16Regs:$a, i16imm:$b, Int16Regs:$c),
752            "mad.lo.s16 \t$dst, $a, $b, $c;",
753            [(set Int16Regs:$dst, (imad Int16Regs:$a, imm:$b, Int16Regs:$c))]>;
754def MAD16rii :
755  NVPTXInst<(outs Int16Regs:$dst),
756            (ins Int16Regs:$a, i16imm:$b, i16imm:$c),
757            "mad.lo.s16 \t$dst, $a, $b, $c;",
758            [(set Int16Regs:$dst, (imad Int16Regs:$a, imm:$b, imm:$c))]>;
759
760def MAD32rrr :
761  NVPTXInst<(outs Int32Regs:$dst),
762            (ins Int32Regs:$a, Int32Regs:$b, Int32Regs:$c),
763            "mad.lo.s32 \t$dst, $a, $b, $c;",
764            [(set Int32Regs:$dst, (imad Int32Regs:$a, Int32Regs:$b, Int32Regs:$c))]>;
765def MAD32rri :
766  NVPTXInst<(outs Int32Regs:$dst),
767            (ins Int32Regs:$a, Int32Regs:$b, i32imm:$c),
768            "mad.lo.s32 \t$dst, $a, $b, $c;",
769            [(set Int32Regs:$dst, (imad Int32Regs:$a, Int32Regs:$b, imm:$c))]>;
770def MAD32rir :
771  NVPTXInst<(outs Int32Regs:$dst),
772            (ins Int32Regs:$a, i32imm:$b, Int32Regs:$c),
773            "mad.lo.s32 \t$dst, $a, $b, $c;",
774            [(set Int32Regs:$dst, (imad Int32Regs:$a, imm:$b, Int32Regs:$c))]>;
775def MAD32rii :
776  NVPTXInst<(outs Int32Regs:$dst),
777            (ins Int32Regs:$a, i32imm:$b, i32imm:$c),
778            "mad.lo.s32 \t$dst, $a, $b, $c;",
779            [(set Int32Regs:$dst, (imad Int32Regs:$a, imm:$b, imm:$c))]>;
780
781def MAD64rrr :
782  NVPTXInst<(outs Int64Regs:$dst),
783            (ins Int64Regs:$a, Int64Regs:$b, Int64Regs:$c),
784            "mad.lo.s64 \t$dst, $a, $b, $c;",
785            [(set Int64Regs:$dst, (imad Int64Regs:$a, Int64Regs:$b, Int64Regs:$c))]>;
786def MAD64rri :
787  NVPTXInst<(outs Int64Regs:$dst),
788            (ins Int64Regs:$a, Int64Regs:$b, i64imm:$c),
789            "mad.lo.s64 \t$dst, $a, $b, $c;",
790            [(set Int64Regs:$dst, (imad Int64Regs:$a, Int64Regs:$b, imm:$c))]>;
791def MAD64rir :
792  NVPTXInst<(outs Int64Regs:$dst),
793            (ins Int64Regs:$a, i64imm:$b, Int64Regs:$c),
794            "mad.lo.s64 \t$dst, $a, $b, $c;",
795            [(set Int64Regs:$dst, (imad Int64Regs:$a, imm:$b, Int64Regs:$c))]>;
796def MAD64rii :
797  NVPTXInst<(outs Int64Regs:$dst),
798            (ins Int64Regs:$a, i64imm:$b, i64imm:$c),
799            "mad.lo.s64 \t$dst, $a, $b, $c;",
800            [(set Int64Regs:$dst, (imad Int64Regs:$a, imm:$b, imm:$c))]>;
801
802def INEG16 :
803  NVPTXInst<(outs Int16Regs:$dst), (ins Int16Regs:$src),
804            "neg.s16 \t$dst, $src;",
805            [(set Int16Regs:$dst, (ineg Int16Regs:$src))]>;
806def INEG32 :
807  NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$src),
808            "neg.s32 \t$dst, $src;",
809            [(set Int32Regs:$dst, (ineg Int32Regs:$src))]>;
810def INEG64 :
811  NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$src),
812            "neg.s64 \t$dst, $src;",
813            [(set Int64Regs:$dst, (ineg Int64Regs:$src))]>;
814
815//-----------------------------------
816// Floating Point Arithmetic
817//-----------------------------------
818
819// Constant 1.0f
820def FloatConst1 : PatLeaf<(fpimm), [{
821  return &N->getValueAPF().getSemantics() == &llvm::APFloat::IEEEsingle() &&
822         N->getValueAPF().convertToFloat() == 1.0f;
823}]>;
824// Constant 1.0 (double)
825def DoubleConst1 : PatLeaf<(fpimm), [{
826  return &N->getValueAPF().getSemantics() == &llvm::APFloat::IEEEdouble() &&
827         N->getValueAPF().convertToDouble() == 1.0;
828}]>;
829
830// Loads FP16 constant into a register.
831//
832// ptxas does not have hex representation for fp16, so we can't use
833// fp16 immediate values in .f16 instructions. Instead we have to load
834// the constant into a register using mov.b16.
835def LOAD_CONST_F16 :
836  NVPTXInst<(outs Float16Regs:$dst), (ins f16imm:$a),
837            "mov.b16 \t$dst, $a;", []>;
838
839defm FADD : F3_fma_component<"add", fadd>;
840defm FSUB : F3_fma_component<"sub", fsub>;
841defm FMUL : F3_fma_component<"mul", fmul>;
842
843defm FMIN : F3<"min", fminnum>;
844defm FMAX : F3<"max", fmaxnum>;
845
846defm FABS  : F2<"abs", fabs>;
847defm FNEG  : F2<"neg", fneg>;
848defm FSQRT : F2<"sqrt.rn", fsqrt>;
849
850//
851// F64 division
852//
853def FDIV641r :
854  NVPTXInst<(outs Float64Regs:$dst),
855            (ins f64imm:$a, Float64Regs:$b),
856            "rcp.rn.f64 \t$dst, $b;",
857            [(set Float64Regs:$dst, (fdiv DoubleConst1:$a, Float64Regs:$b))]>;
858def FDIV64rr :
859  NVPTXInst<(outs Float64Regs:$dst),
860            (ins Float64Regs:$a, Float64Regs:$b),
861            "div.rn.f64 \t$dst, $a, $b;",
862            [(set Float64Regs:$dst, (fdiv Float64Regs:$a, Float64Regs:$b))]>;
863def FDIV64ri :
864  NVPTXInst<(outs Float64Regs:$dst),
865            (ins Float64Regs:$a, f64imm:$b),
866            "div.rn.f64 \t$dst, $a, $b;",
867            [(set Float64Regs:$dst, (fdiv Float64Regs:$a, fpimm:$b))]>;
868
869//
870// F32 Approximate reciprocal
871//
872def FDIV321r_ftz :
873  NVPTXInst<(outs Float32Regs:$dst),
874            (ins f32imm:$a, Float32Regs:$b),
875            "rcp.approx.ftz.f32 \t$dst, $b;",
876            [(set Float32Regs:$dst, (fdiv FloatConst1:$a, Float32Regs:$b))]>,
877            Requires<[do_DIVF32_APPROX, doF32FTZ]>;
878def FDIV321r :
879  NVPTXInst<(outs Float32Regs:$dst),
880            (ins f32imm:$a, Float32Regs:$b),
881            "rcp.approx.f32 \t$dst, $b;",
882            [(set Float32Regs:$dst, (fdiv FloatConst1:$a, Float32Regs:$b))]>,
883            Requires<[do_DIVF32_APPROX]>;
884//
885// F32 Approximate division
886//
887def FDIV32approxrr_ftz :
888  NVPTXInst<(outs Float32Regs:$dst),
889            (ins Float32Regs:$a, Float32Regs:$b),
890            "div.approx.ftz.f32 \t$dst, $a, $b;",
891            [(set Float32Regs:$dst, (fdiv Float32Regs:$a, Float32Regs:$b))]>,
892            Requires<[do_DIVF32_APPROX, doF32FTZ]>;
893def FDIV32approxri_ftz :
894  NVPTXInst<(outs Float32Regs:$dst),
895            (ins Float32Regs:$a, f32imm:$b),
896            "div.approx.ftz.f32 \t$dst, $a, $b;",
897            [(set Float32Regs:$dst, (fdiv Float32Regs:$a, fpimm:$b))]>,
898            Requires<[do_DIVF32_APPROX, doF32FTZ]>;
899def FDIV32approxrr :
900  NVPTXInst<(outs Float32Regs:$dst),
901            (ins Float32Regs:$a, Float32Regs:$b),
902            "div.approx.f32 \t$dst, $a, $b;",
903            [(set Float32Regs:$dst, (fdiv Float32Regs:$a, Float32Regs:$b))]>,
904            Requires<[do_DIVF32_APPROX]>;
905def FDIV32approxri :
906  NVPTXInst<(outs Float32Regs:$dst),
907            (ins Float32Regs:$a, f32imm:$b),
908            "div.approx.f32 \t$dst, $a, $b;",
909            [(set Float32Regs:$dst, (fdiv Float32Regs:$a, fpimm:$b))]>,
910            Requires<[do_DIVF32_APPROX]>;
911//
912// F32 Semi-accurate reciprocal
913//
914// rcp.approx gives the same result as div.full(1.0f, a) and is faster.
915//
916def FDIV321r_approx_ftz :
917  NVPTXInst<(outs Float32Regs:$dst),
918            (ins f32imm:$a, Float32Regs:$b),
919            "rcp.approx.ftz.f32 \t$dst, $b;",
920            [(set Float32Regs:$dst, (fdiv FloatConst1:$a, Float32Regs:$b))]>,
921            Requires<[do_DIVF32_FULL, doF32FTZ]>;
922def FDIV321r_approx :
923  NVPTXInst<(outs Float32Regs:$dst),
924            (ins f32imm:$a, Float32Regs:$b),
925            "rcp.approx.f32 \t$dst, $b;",
926            [(set Float32Regs:$dst, (fdiv FloatConst1:$a, Float32Regs:$b))]>,
927            Requires<[do_DIVF32_FULL]>;
928//
929// F32 Semi-accurate division
930//
931def FDIV32rr_ftz :
932  NVPTXInst<(outs Float32Regs:$dst),
933            (ins Float32Regs:$a, Float32Regs:$b),
934            "div.full.ftz.f32 \t$dst, $a, $b;",
935            [(set Float32Regs:$dst, (fdiv Float32Regs:$a, Float32Regs:$b))]>,
936            Requires<[do_DIVF32_FULL, doF32FTZ]>;
937def FDIV32ri_ftz :
938  NVPTXInst<(outs Float32Regs:$dst),
939            (ins Float32Regs:$a, f32imm:$b),
940            "div.full.ftz.f32 \t$dst, $a, $b;",
941            [(set Float32Regs:$dst, (fdiv Float32Regs:$a, fpimm:$b))]>,
942            Requires<[do_DIVF32_FULL, doF32FTZ]>;
943def FDIV32rr :
944  NVPTXInst<(outs Float32Regs:$dst),
945            (ins Float32Regs:$a, Float32Regs:$b),
946            "div.full.f32 \t$dst, $a, $b;",
947            [(set Float32Regs:$dst, (fdiv Float32Regs:$a, Float32Regs:$b))]>,
948            Requires<[do_DIVF32_FULL]>;
949def FDIV32ri :
950  NVPTXInst<(outs Float32Regs:$dst),
951            (ins Float32Regs:$a, f32imm:$b),
952            "div.full.f32 \t$dst, $a, $b;",
953            [(set Float32Regs:$dst, (fdiv Float32Regs:$a, fpimm:$b))]>,
954            Requires<[do_DIVF32_FULL]>;
955//
956// F32 Accurate reciprocal
957//
958def FDIV321r_prec_ftz :
959  NVPTXInst<(outs Float32Regs:$dst),
960            (ins f32imm:$a, Float32Regs:$b),
961            "rcp.rn.ftz.f32 \t$dst, $b;",
962            [(set Float32Regs:$dst, (fdiv FloatConst1:$a, Float32Regs:$b))]>,
963            Requires<[doF32FTZ]>;
964def FDIV321r_prec :
965  NVPTXInst<(outs Float32Regs:$dst),
966            (ins f32imm:$a, Float32Regs:$b),
967            "rcp.rn.f32 \t$dst, $b;",
968            [(set Float32Regs:$dst, (fdiv FloatConst1:$a, Float32Regs:$b))]>;
969//
970// F32 Accurate division
971//
972def FDIV32rr_prec_ftz :
973  NVPTXInst<(outs Float32Regs:$dst),
974            (ins Float32Regs:$a, Float32Regs:$b),
975            "div.rn.ftz.f32 \t$dst, $a, $b;",
976            [(set Float32Regs:$dst, (fdiv Float32Regs:$a, Float32Regs:$b))]>,
977            Requires<[doF32FTZ]>;
978def FDIV32ri_prec_ftz :
979  NVPTXInst<(outs Float32Regs:$dst),
980            (ins Float32Regs:$a, f32imm:$b),
981            "div.rn.ftz.f32 \t$dst, $a, $b;",
982            [(set Float32Regs:$dst, (fdiv Float32Regs:$a, fpimm:$b))]>,
983            Requires<[doF32FTZ]>;
984def FDIV32rr_prec :
985  NVPTXInst<(outs Float32Regs:$dst),
986            (ins Float32Regs:$a, Float32Regs:$b),
987            "div.rn.f32 \t$dst, $a, $b;",
988            [(set Float32Regs:$dst, (fdiv Float32Regs:$a, Float32Regs:$b))]>;
989def FDIV32ri_prec :
990  NVPTXInst<(outs Float32Regs:$dst),
991            (ins Float32Regs:$a, f32imm:$b),
992            "div.rn.f32 \t$dst, $a, $b;",
993            [(set Float32Regs:$dst, (fdiv Float32Regs:$a, fpimm:$b))]>;
994
995//
996// FMA
997//
998
999multiclass FMA<string OpcStr, RegisterClass RC, Operand ImmCls, Predicate Pred> {
1000   def rrr : NVPTXInst<(outs RC:$dst), (ins RC:$a, RC:$b, RC:$c),
1001                       !strconcat(OpcStr, " \t$dst, $a, $b, $c;"),
1002                       [(set RC:$dst, (fma RC:$a, RC:$b, RC:$c))]>,
1003                       Requires<[Pred]>;
1004   def rri : NVPTXInst<(outs RC:$dst),
1005                       (ins RC:$a, RC:$b, ImmCls:$c),
1006                       !strconcat(OpcStr, " \t$dst, $a, $b, $c;"),
1007                       [(set RC:$dst, (fma RC:$a, RC:$b, fpimm:$c))]>,
1008                       Requires<[Pred]>;
1009   def rir : NVPTXInst<(outs RC:$dst),
1010                       (ins RC:$a, ImmCls:$b, RC:$c),
1011                       !strconcat(OpcStr, " \t$dst, $a, $b, $c;"),
1012                       [(set RC:$dst, (fma RC:$a, fpimm:$b, RC:$c))]>,
1013                       Requires<[Pred]>;
1014   def rii : NVPTXInst<(outs RC:$dst),
1015                       (ins RC:$a, ImmCls:$b, ImmCls:$c),
1016                       !strconcat(OpcStr, " \t$dst, $a, $b, $c;"),
1017                       [(set RC:$dst, (fma RC:$a, fpimm:$b, fpimm:$c))]>,
1018                       Requires<[Pred]>;
1019}
1020
1021multiclass FMA_F16<string OpcStr, RegisterClass RC, Predicate Pred> {
1022   def rrr : NVPTXInst<(outs RC:$dst), (ins RC:$a, RC:$b, RC:$c),
1023                       !strconcat(OpcStr, " \t$dst, $a, $b, $c;"),
1024                       [(set RC:$dst, (fma RC:$a, RC:$b, RC:$c))]>,
1025                       Requires<[useFP16Math, Pred]>;
1026}
1027
1028defm FMA16_ftz : FMA_F16<"fma.rn.ftz.f16", Float16Regs, doF32FTZ>;
1029defm FMA16     : FMA_F16<"fma.rn.f16", Float16Regs, True>;
1030defm FMA16x2_ftz : FMA_F16<"fma.rn.ftz.f16x2", Float16x2Regs, doF32FTZ>;
1031defm FMA16x2     : FMA_F16<"fma.rn.f16x2", Float16x2Regs, True>;
1032defm FMA32_ftz : FMA<"fma.rn.ftz.f32", Float32Regs, f32imm, doF32FTZ>;
1033defm FMA32     : FMA<"fma.rn.f32", Float32Regs, f32imm, True>;
1034defm FMA64     : FMA<"fma.rn.f64", Float64Regs, f64imm, True>;
1035
1036// sin/cos
1037def SINF:  NVPTXInst<(outs Float32Regs:$dst), (ins Float32Regs:$src),
1038                      "sin.approx.f32 \t$dst, $src;",
1039                      [(set Float32Regs:$dst, (fsin Float32Regs:$src))]>,
1040                      Requires<[allowUnsafeFPMath]>;
1041def COSF:  NVPTXInst<(outs Float32Regs:$dst), (ins Float32Regs:$src),
1042                      "cos.approx.f32 \t$dst, $src;",
1043                      [(set Float32Regs:$dst, (fcos Float32Regs:$src))]>,
1044                      Requires<[allowUnsafeFPMath]>;
1045
1046// Lower (frem x, y) into (sub x, (mul (ftrunc (div x, y)) y)),
1047// i.e. "poor man's fmod()"
1048
1049// frem - f32 FTZ
1050def : Pat<(frem Float32Regs:$x, Float32Regs:$y),
1051          (FSUBf32rr_ftz Float32Regs:$x, (FMULf32rr_ftz (CVT_f32_f32
1052            (FDIV32rr_prec_ftz Float32Regs:$x, Float32Regs:$y), CvtRZI_FTZ),
1053             Float32Regs:$y))>,
1054          Requires<[doF32FTZ]>;
1055def : Pat<(frem Float32Regs:$x, fpimm:$y),
1056          (FSUBf32rr_ftz Float32Regs:$x, (FMULf32ri_ftz (CVT_f32_f32
1057            (FDIV32ri_prec_ftz Float32Regs:$x, fpimm:$y), CvtRZI_FTZ),
1058             fpimm:$y))>,
1059          Requires<[doF32FTZ]>;
1060
1061// frem - f32
1062def : Pat<(frem Float32Regs:$x, Float32Regs:$y),
1063          (FSUBf32rr Float32Regs:$x, (FMULf32rr (CVT_f32_f32
1064            (FDIV32rr_prec Float32Regs:$x, Float32Regs:$y), CvtRZI),
1065             Float32Regs:$y))>;
1066def : Pat<(frem Float32Regs:$x, fpimm:$y),
1067          (FSUBf32rr Float32Regs:$x, (FMULf32ri (CVT_f32_f32
1068            (FDIV32ri_prec Float32Regs:$x, fpimm:$y), CvtRZI),
1069             fpimm:$y))>;
1070
1071// frem - f64
1072def : Pat<(frem Float64Regs:$x, Float64Regs:$y),
1073          (FSUBf64rr Float64Regs:$x, (FMULf64rr (CVT_f64_f64
1074            (FDIV64rr Float64Regs:$x, Float64Regs:$y), CvtRZI),
1075             Float64Regs:$y))>;
1076def : Pat<(frem Float64Regs:$x, fpimm:$y),
1077          (FSUBf64rr Float64Regs:$x, (FMULf64ri (CVT_f64_f64
1078            (FDIV64ri Float64Regs:$x, fpimm:$y), CvtRZI),
1079             fpimm:$y))>;
1080
1081//-----------------------------------
1082// Bitwise operations
1083//-----------------------------------
1084
1085// Template for three-arg bitwise operations.  Takes three args, Creates .b16,
1086// .b32, .b64, and .pred (predicate registers -- i.e., i1) versions of OpcStr.
1087multiclass BITWISE<string OpcStr, SDNode OpNode> {
1088  def b1rr :
1089    NVPTXInst<(outs Int1Regs:$dst), (ins Int1Regs:$a, Int1Regs:$b),
1090              !strconcat(OpcStr, ".pred  \t$dst, $a, $b;"),
1091              [(set Int1Regs:$dst, (OpNode Int1Regs:$a, Int1Regs:$b))]>;
1092  def b1ri :
1093    NVPTXInst<(outs Int1Regs:$dst), (ins Int1Regs:$a, i1imm:$b),
1094              !strconcat(OpcStr, ".pred  \t$dst, $a, $b;"),
1095              [(set Int1Regs:$dst, (OpNode Int1Regs:$a, imm:$b))]>;
1096  def b16rr :
1097    NVPTXInst<(outs Int16Regs:$dst), (ins Int16Regs:$a, Int16Regs:$b),
1098              !strconcat(OpcStr, ".b16  \t$dst, $a, $b;"),
1099              [(set Int16Regs:$dst, (OpNode Int16Regs:$a, Int16Regs:$b))]>;
1100  def b16ri :
1101    NVPTXInst<(outs Int16Regs:$dst), (ins Int16Regs:$a, i16imm:$b),
1102              !strconcat(OpcStr, ".b16  \t$dst, $a, $b;"),
1103              [(set Int16Regs:$dst, (OpNode Int16Regs:$a, imm:$b))]>;
1104  def b32rr :
1105    NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$a, Int32Regs:$b),
1106              !strconcat(OpcStr, ".b32  \t$dst, $a, $b;"),
1107              [(set Int32Regs:$dst, (OpNode Int32Regs:$a, Int32Regs:$b))]>;
1108  def b32ri :
1109    NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$a, i32imm:$b),
1110              !strconcat(OpcStr, ".b32  \t$dst, $a, $b;"),
1111              [(set Int32Regs:$dst, (OpNode Int32Regs:$a, imm:$b))]>;
1112  def b64rr :
1113    NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$a, Int64Regs:$b),
1114              !strconcat(OpcStr, ".b64  \t$dst, $a, $b;"),
1115              [(set Int64Regs:$dst, (OpNode Int64Regs:$a, Int64Regs:$b))]>;
1116  def b64ri :
1117    NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$a, i64imm:$b),
1118              !strconcat(OpcStr, ".b64  \t$dst, $a, $b;"),
1119              [(set Int64Regs:$dst, (OpNode Int64Regs:$a, imm:$b))]>;
1120}
1121
1122defm OR  : BITWISE<"or", or>;
1123defm AND : BITWISE<"and", and>;
1124defm XOR : BITWISE<"xor", xor>;
1125
1126def NOT1  : NVPTXInst<(outs Int1Regs:$dst), (ins Int1Regs:$src),
1127                      "not.pred \t$dst, $src;",
1128                      [(set Int1Regs:$dst, (not Int1Regs:$src))]>;
1129def NOT16 : NVPTXInst<(outs Int16Regs:$dst), (ins Int16Regs:$src),
1130                      "not.b16 \t$dst, $src;",
1131                      [(set Int16Regs:$dst, (not Int16Regs:$src))]>;
1132def NOT32 : NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$src),
1133                      "not.b32 \t$dst, $src;",
1134                      [(set Int32Regs:$dst, (not Int32Regs:$src))]>;
1135def NOT64 : NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$src),
1136                       "not.b64 \t$dst, $src;",
1137                       [(set Int64Regs:$dst, (not Int64Regs:$src))]>;
1138
1139// Template for left/right shifts.  Takes three operands,
1140//   [dest (reg), src (reg), shift (reg or imm)].
1141// dest and src may be int64, int32, or int16, but shift is always int32.
1142//
1143// This template also defines a 32-bit shift (imm, imm) instruction.
1144multiclass SHIFT<string OpcStr, SDNode OpNode> {
1145   def i64rr :
1146     NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$a, Int32Regs:$b),
1147               !strconcat(OpcStr, "64 \t$dst, $a, $b;"),
1148               [(set Int64Regs:$dst, (OpNode Int64Regs:$a, Int32Regs:$b))]>;
1149   def i64ri :
1150     NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$a, i32imm:$b),
1151               !strconcat(OpcStr, "64 \t$dst, $a, $b;"),
1152               [(set Int64Regs:$dst, (OpNode Int64Regs:$a, (i32 imm:$b)))]>;
1153   def i32rr :
1154     NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$a, Int32Regs:$b),
1155               !strconcat(OpcStr, "32 \t$dst, $a, $b;"),
1156               [(set Int32Regs:$dst, (OpNode Int32Regs:$a, Int32Regs:$b))]>;
1157   def i32ri :
1158     NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$a, i32imm:$b),
1159               !strconcat(OpcStr, "32 \t$dst, $a, $b;"),
1160               [(set Int32Regs:$dst, (OpNode Int32Regs:$a, (i32 imm:$b)))]>;
1161   def i32ii :
1162     NVPTXInst<(outs Int32Regs:$dst), (ins i32imm:$a, i32imm:$b),
1163               !strconcat(OpcStr, "32 \t$dst, $a, $b;"),
1164               [(set Int32Regs:$dst, (OpNode (i32 imm:$a), (i32 imm:$b)))]>;
1165   def i16rr :
1166     NVPTXInst<(outs Int16Regs:$dst), (ins Int16Regs:$a, Int32Regs:$b),
1167               !strconcat(OpcStr, "16 \t$dst, $a, $b;"),
1168               [(set Int16Regs:$dst, (OpNode Int16Regs:$a, Int32Regs:$b))]>;
1169   def i16ri :
1170     NVPTXInst<(outs Int16Regs:$dst), (ins Int16Regs:$a, i32imm:$b),
1171               !strconcat(OpcStr, "16 \t$dst, $a, $b;"),
1172               [(set Int16Regs:$dst, (OpNode Int16Regs:$a, (i32 imm:$b)))]>;
1173}
1174
1175defm SHL : SHIFT<"shl.b", shl>;
1176defm SRA : SHIFT<"shr.s", sra>;
1177defm SRL : SHIFT<"shr.u", srl>;
1178
1179// Bit-reverse
1180def BREV32 :
1181  NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$a),
1182             "brev.b32 \t$dst, $a;",
1183             [(set Int32Regs:$dst, (bitreverse Int32Regs:$a))]>;
1184def BREV64 :
1185  NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$a),
1186             "brev.b64 \t$dst, $a;",
1187             [(set Int64Regs:$dst, (bitreverse Int64Regs:$a))]>;
1188
1189//
1190// Rotate: Use ptx shf instruction if available.
1191//
1192
1193// 32 bit r2 = rotl r1, n
1194//    =>
1195//        r2 = shf.l r1, r1, n
1196def ROTL32imm_hw :
1197  NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$src, i32imm:$amt),
1198            "shf.l.wrap.b32 \t$dst, $src, $src, $amt;",
1199            [(set Int32Regs:$dst, (rotl Int32Regs:$src, (i32 imm:$amt)))]>,
1200           Requires<[hasHWROT32]>;
1201
1202def ROTL32reg_hw :
1203  NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$src, Int32Regs:$amt),
1204            "shf.l.wrap.b32 \t$dst, $src, $src, $amt;",
1205            [(set Int32Regs:$dst, (rotl Int32Regs:$src, Int32Regs:$amt))]>,
1206           Requires<[hasHWROT32]>;
1207
1208// 32 bit r2 = rotr r1, n
1209//    =>
1210//        r2 = shf.r r1, r1, n
1211def ROTR32imm_hw :
1212  NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$src, i32imm:$amt),
1213            "shf.r.wrap.b32 \t$dst, $src, $src, $amt;",
1214            [(set Int32Regs:$dst, (rotr Int32Regs:$src, (i32 imm:$amt)))]>,
1215           Requires<[hasHWROT32]>;
1216
1217def ROTR32reg_hw :
1218  NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$src, Int32Regs:$amt),
1219            "shf.r.wrap.b32 \t$dst, $src, $src, $amt;",
1220            [(set Int32Regs:$dst, (rotr Int32Regs:$src, Int32Regs:$amt))]>,
1221           Requires<[hasHWROT32]>;
1222
1223// 32-bit software rotate by immediate.  $amt2 should equal 32 - $amt1.
1224def ROT32imm_sw :
1225  NVPTXInst<(outs Int32Regs:$dst),
1226            (ins Int32Regs:$src, i32imm:$amt1, i32imm:$amt2),
1227            "{{\n\t"
1228            ".reg .b32 %lhs;\n\t"
1229            ".reg .b32 %rhs;\n\t"
1230            "shl.b32 \t%lhs, $src, $amt1;\n\t"
1231            "shr.b32 \t%rhs, $src, $amt2;\n\t"
1232            "add.u32 \t$dst, %lhs, %rhs;\n\t"
1233            "}}",
1234            []>;
1235
1236def SUB_FRM_32 : SDNodeXForm<imm, [{
1237  return CurDAG->getTargetConstant(32 - N->getZExtValue(), SDLoc(N), MVT::i32);
1238}]>;
1239
1240def : Pat<(rotl Int32Regs:$src, (i32 imm:$amt)),
1241          (ROT32imm_sw Int32Regs:$src, imm:$amt, (SUB_FRM_32 node:$amt))>,
1242      Requires<[noHWROT32]>;
1243def : Pat<(rotr Int32Regs:$src, (i32 imm:$amt)),
1244          (ROT32imm_sw Int32Regs:$src, (SUB_FRM_32 node:$amt), imm:$amt)>,
1245      Requires<[noHWROT32]>;
1246
1247// 32-bit software rotate left by register.
1248def ROTL32reg_sw :
1249  NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$src, Int32Regs:$amt),
1250            "{{\n\t"
1251            ".reg .b32 %lhs;\n\t"
1252            ".reg .b32 %rhs;\n\t"
1253            ".reg .b32 %amt2;\n\t"
1254            "shl.b32 \t%lhs, $src, $amt;\n\t"
1255            "sub.s32 \t%amt2, 32, $amt;\n\t"
1256            "shr.b32 \t%rhs, $src, %amt2;\n\t"
1257            "add.u32 \t$dst, %lhs, %rhs;\n\t"
1258            "}}",
1259            [(set Int32Regs:$dst, (rotl Int32Regs:$src, Int32Regs:$amt))]>,
1260           Requires<[noHWROT32]>;
1261
1262// 32-bit software rotate right by register.
1263def ROTR32reg_sw :
1264  NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$src, Int32Regs:$amt),
1265            "{{\n\t"
1266            ".reg .b32 %lhs;\n\t"
1267            ".reg .b32 %rhs;\n\t"
1268            ".reg .b32 %amt2;\n\t"
1269            "shr.b32 \t%lhs, $src, $amt;\n\t"
1270            "sub.s32 \t%amt2, 32, $amt;\n\t"
1271            "shl.b32 \t%rhs, $src, %amt2;\n\t"
1272            "add.u32 \t$dst, %lhs, %rhs;\n\t"
1273            "}}",
1274            [(set Int32Regs:$dst, (rotr Int32Regs:$src, Int32Regs:$amt))]>,
1275           Requires<[noHWROT32]>;
1276
1277// 64-bit software rotate by immediate.  $amt2 should equal 64 - $amt1.
1278def ROT64imm_sw :
1279  NVPTXInst<(outs Int64Regs:$dst),
1280            (ins Int64Regs:$src, i32imm:$amt1, i32imm:$amt2),
1281            "{{\n\t"
1282            ".reg .b64 %lhs;\n\t"
1283            ".reg .b64 %rhs;\n\t"
1284            "shl.b64 \t%lhs, $src, $amt1;\n\t"
1285            "shr.b64 \t%rhs, $src, $amt2;\n\t"
1286            "add.u64 \t$dst, %lhs, %rhs;\n\t"
1287            "}}",
1288            []>;
1289
1290def SUB_FRM_64 : SDNodeXForm<imm, [{
1291    return CurDAG->getTargetConstant(64-N->getZExtValue(), SDLoc(N), MVT::i32);
1292}]>;
1293
1294def : Pat<(rotl Int64Regs:$src, (i32 imm:$amt)),
1295          (ROT64imm_sw Int64Regs:$src, imm:$amt, (SUB_FRM_64 node:$amt))>;
1296def : Pat<(rotr Int64Regs:$src, (i32 imm:$amt)),
1297          (ROT64imm_sw Int64Regs:$src, (SUB_FRM_64 node:$amt), imm:$amt)>;
1298
1299// 64-bit software rotate left by register.
1300def ROTL64reg_sw :
1301  NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$src, Int32Regs:$amt),
1302            "{{\n\t"
1303            ".reg .b64 %lhs;\n\t"
1304            ".reg .b64 %rhs;\n\t"
1305            ".reg .u32 %amt2;\n\t"
1306            "shl.b64 \t%lhs, $src, $amt;\n\t"
1307            "sub.u32 \t%amt2, 64, $amt;\n\t"
1308            "shr.b64 \t%rhs, $src, %amt2;\n\t"
1309            "add.u64 \t$dst, %lhs, %rhs;\n\t"
1310            "}}",
1311            [(set Int64Regs:$dst, (rotl Int64Regs:$src, Int32Regs:$amt))]>;
1312
1313def ROTR64reg_sw :
1314  NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$src, Int32Regs:$amt),
1315            "{{\n\t"
1316            ".reg .b64 %lhs;\n\t"
1317            ".reg .b64 %rhs;\n\t"
1318            ".reg .u32 %amt2;\n\t"
1319            "shr.b64 \t%lhs, $src, $amt;\n\t"
1320            "sub.u32 \t%amt2, 64, $amt;\n\t"
1321            "shl.b64 \t%rhs, $src, %amt2;\n\t"
1322            "add.u64 \t$dst, %lhs, %rhs;\n\t"
1323            "}}",
1324            [(set Int64Regs:$dst, (rotr Int64Regs:$src, Int32Regs:$amt))]>;
1325
1326//
1327// Funnnel shift in clamp mode
1328//
1329
1330// Create SDNodes so they can be used in the DAG code, e.g.
1331// NVPTXISelLowering (LowerShiftLeftParts and LowerShiftRightParts)
1332def FUN_SHFL_CLAMP : SDNode<"NVPTXISD::FUN_SHFL_CLAMP", SDTIntShiftDOp, []>;
1333def FUN_SHFR_CLAMP : SDNode<"NVPTXISD::FUN_SHFR_CLAMP", SDTIntShiftDOp, []>;
1334
1335def FUNSHFLCLAMP :
1336  NVPTXInst<(outs Int32Regs:$dst),
1337            (ins Int32Regs:$lo, Int32Regs:$hi, Int32Regs:$amt),
1338            "shf.l.clamp.b32 \t$dst, $lo, $hi, $amt;",
1339            [(set Int32Regs:$dst,
1340              (FUN_SHFL_CLAMP Int32Regs:$lo, Int32Regs:$hi, Int32Regs:$amt))]>;
1341
1342def FUNSHFRCLAMP :
1343  NVPTXInst<(outs Int32Regs:$dst),
1344            (ins Int32Regs:$lo, Int32Regs:$hi, Int32Regs:$amt),
1345            "shf.r.clamp.b32 \t$dst, $lo, $hi, $amt;",
1346            [(set Int32Regs:$dst,
1347             (FUN_SHFR_CLAMP Int32Regs:$lo, Int32Regs:$hi, Int32Regs:$amt))]>;
1348
1349//
1350// BFE - bit-field extract
1351//
1352
1353// Template for BFE instructions.  Takes four args,
1354//   [dest (reg), src (reg), start (reg or imm), end (reg or imm)].
1355// Start may be an imm only if end is also an imm.  FIXME: Is this a
1356// restriction in PTX?
1357//
1358// dest and src may be int32 or int64, but start and end are always int32.
1359multiclass BFE<string TyStr, RegisterClass RC> {
1360  def rrr
1361    : NVPTXInst<(outs RC:$d),
1362                (ins RC:$a, Int32Regs:$b, Int32Regs:$c),
1363                !strconcat("bfe.", TyStr, " \t$d, $a, $b, $c;"), []>;
1364  def rri
1365    : NVPTXInst<(outs RC:$d),
1366                (ins RC:$a, Int32Regs:$b, i32imm:$c),
1367                !strconcat("bfe.", TyStr, " \t$d, $a, $b, $c;"), []>;
1368  def rii
1369    : NVPTXInst<(outs RC:$d),
1370                (ins RC:$a, i32imm:$b, i32imm:$c),
1371                !strconcat("bfe.", TyStr, " \t$d, $a, $b, $c;"), []>;
1372}
1373
1374let hasSideEffects = false in {
1375  defm BFE_S32 : BFE<"s32", Int32Regs>;
1376  defm BFE_U32 : BFE<"u32", Int32Regs>;
1377  defm BFE_S64 : BFE<"s64", Int64Regs>;
1378  defm BFE_U64 : BFE<"u64", Int64Regs>;
1379}
1380
1381//-----------------------------------
1382// Comparison instructions (setp, set)
1383//-----------------------------------
1384
1385// FIXME: This doesn't cover versions of set and setp that combine with a
1386// boolean predicate, e.g. setp.eq.and.b16.
1387
1388let hasSideEffects = false in {
1389  multiclass SETP<string TypeStr, RegisterClass RC, Operand ImmCls> {
1390    def rr :
1391      NVPTXInst<(outs Int1Regs:$dst), (ins RC:$a, RC:$b, CmpMode:$cmp),
1392                !strconcat("setp${cmp:base}${cmp:ftz}.", TypeStr,
1393                           " \t$dst, $a, $b;"), []>;
1394    def ri :
1395      NVPTXInst<(outs Int1Regs:$dst), (ins RC:$a, ImmCls:$b, CmpMode:$cmp),
1396                !strconcat("setp${cmp:base}${cmp:ftz}.", TypeStr,
1397                           " \t$dst, $a, $b;"), []>;
1398    def ir :
1399      NVPTXInst<(outs Int1Regs:$dst), (ins ImmCls:$a, RC:$b, CmpMode:$cmp),
1400                !strconcat("setp${cmp:base}${cmp:ftz}.", TypeStr,
1401                           " \t$dst, $a, $b;"), []>;
1402  }
1403}
1404
1405defm SETP_b16 : SETP<"b16", Int16Regs, i16imm>;
1406defm SETP_s16 : SETP<"s16", Int16Regs, i16imm>;
1407defm SETP_u16 : SETP<"u16", Int16Regs, i16imm>;
1408defm SETP_b32 : SETP<"b32", Int32Regs, i32imm>;
1409defm SETP_s32 : SETP<"s32", Int32Regs, i32imm>;
1410defm SETP_u32 : SETP<"u32", Int32Regs, i32imm>;
1411defm SETP_b64 : SETP<"b64", Int64Regs, i64imm>;
1412defm SETP_s64 : SETP<"s64", Int64Regs, i64imm>;
1413defm SETP_u64 : SETP<"u64", Int64Regs, i64imm>;
1414defm SETP_f32 : SETP<"f32", Float32Regs, f32imm>;
1415defm SETP_f64 : SETP<"f64", Float64Regs, f64imm>;
1416def SETP_f16rr :
1417      NVPTXInst<(outs Int1Regs:$dst),
1418                (ins Float16Regs:$a, Float16Regs:$b, CmpMode:$cmp),
1419                "setp${cmp:base}${cmp:ftz}.f16 \t$dst, $a, $b;",
1420                []>, Requires<[useFP16Math]>;
1421
1422def SETP_f16x2rr :
1423      NVPTXInst<(outs Int1Regs:$p, Int1Regs:$q),
1424                (ins Float16x2Regs:$a, Float16x2Regs:$b, CmpMode:$cmp),
1425                "setp${cmp:base}${cmp:ftz}.f16x2 \t$p|$q, $a, $b;",
1426                []>,
1427                Requires<[useFP16Math]>;
1428
1429
1430// FIXME: This doesn't appear to be correct.  The "set" mnemonic has the form
1431// "set.CmpOp{.ftz}.dtype.stype", where dtype is the type of the destination
1432// reg, either u32, s32, or f32.  Anyway these aren't used at the moment.
1433
1434let hasSideEffects = false in {
1435  multiclass SET<string TypeStr, RegisterClass RC, Operand ImmCls> {
1436    def rr : NVPTXInst<(outs Int32Regs:$dst),
1437                       (ins RC:$a, RC:$b, CmpMode:$cmp),
1438                       !strconcat("set$cmp.", TypeStr, " \t$dst, $a, $b;"), []>;
1439    def ri : NVPTXInst<(outs Int32Regs:$dst),
1440                       (ins RC:$a, ImmCls:$b, CmpMode:$cmp),
1441                       !strconcat("set$cmp.", TypeStr, " \t$dst, $a, $b;"), []>;
1442    def ir : NVPTXInst<(outs Int32Regs:$dst),
1443                       (ins ImmCls:$a, RC:$b, CmpMode:$cmp),
1444                       !strconcat("set$cmp.", TypeStr, " \t$dst, $a, $b;"), []>;
1445  }
1446}
1447
1448defm SET_b16 : SET<"b16", Int16Regs, i16imm>;
1449defm SET_s16 : SET<"s16", Int16Regs, i16imm>;
1450defm SET_u16 : SET<"u16", Int16Regs, i16imm>;
1451defm SET_b32 : SET<"b32", Int32Regs, i32imm>;
1452defm SET_s32 : SET<"s32", Int32Regs, i32imm>;
1453defm SET_u32 : SET<"u32", Int32Regs, i32imm>;
1454defm SET_b64 : SET<"b64", Int64Regs, i64imm>;
1455defm SET_s64 : SET<"s64", Int64Regs, i64imm>;
1456defm SET_u64 : SET<"u64", Int64Regs, i64imm>;
1457defm SET_f16 : SET<"f16", Float16Regs, f16imm>;
1458defm SET_f32 : SET<"f32", Float32Regs, f32imm>;
1459defm SET_f64 : SET<"f64", Float64Regs, f64imm>;
1460
1461//-----------------------------------
1462// Selection instructions (selp)
1463//-----------------------------------
1464
1465// FIXME: Missing slct
1466
1467// selp instructions that don't have any pattern matches; we explicitly use
1468// them within this file.
1469let hasSideEffects = false in {
1470  multiclass SELP<string TypeStr, RegisterClass RC, Operand ImmCls> {
1471    def rr : NVPTXInst<(outs RC:$dst),
1472                       (ins RC:$a, RC:$b, Int1Regs:$p),
1473                       !strconcat("selp.", TypeStr, " \t$dst, $a, $b, $p;"), []>;
1474    def ri : NVPTXInst<(outs RC:$dst),
1475                       (ins RC:$a, ImmCls:$b, Int1Regs:$p),
1476                       !strconcat("selp.", TypeStr, " \t$dst, $a, $b, $p;"), []>;
1477    def ir : NVPTXInst<(outs RC:$dst),
1478                       (ins ImmCls:$a, RC:$b, Int1Regs:$p),
1479                       !strconcat("selp.", TypeStr, " \t$dst, $a, $b, $p;"), []>;
1480    def ii : NVPTXInst<(outs RC:$dst),
1481                       (ins ImmCls:$a, ImmCls:$b, Int1Regs:$p),
1482                       !strconcat("selp.", TypeStr, " \t$dst, $a, $b, $p;"), []>;
1483  }
1484
1485  multiclass SELP_PATTERN<string TypeStr, RegisterClass RC, Operand ImmCls,
1486                          SDNode ImmNode> {
1487    def rr :
1488      NVPTXInst<(outs RC:$dst),
1489                (ins RC:$a, RC:$b, Int1Regs:$p),
1490                !strconcat("selp.", TypeStr, " \t$dst, $a, $b, $p;"),
1491                [(set RC:$dst, (select Int1Regs:$p, RC:$a, RC:$b))]>;
1492    def ri :
1493      NVPTXInst<(outs RC:$dst),
1494                (ins RC:$a, ImmCls:$b, Int1Regs:$p),
1495                !strconcat("selp.", TypeStr, " \t$dst, $a, $b, $p;"),
1496                [(set RC:$dst, (select Int1Regs:$p, RC:$a, ImmNode:$b))]>;
1497    def ir :
1498      NVPTXInst<(outs RC:$dst),
1499                (ins ImmCls:$a, RC:$b, Int1Regs:$p),
1500                !strconcat("selp.", TypeStr, " \t$dst, $a, $b, $p;"),
1501                [(set RC:$dst, (select Int1Regs:$p, ImmNode:$a, RC:$b))]>;
1502    def ii :
1503      NVPTXInst<(outs RC:$dst),
1504                (ins ImmCls:$a, ImmCls:$b, Int1Regs:$p),
1505                !strconcat("selp.", TypeStr, " \t$dst, $a, $b, $p;"),
1506                [(set RC:$dst, (select Int1Regs:$p, ImmNode:$a, ImmNode:$b))]>;
1507  }
1508}
1509
1510// Don't pattern match on selp.{s,u}{16,32,64} -- selp.b{16,32,64} is just as
1511// good.
1512defm SELP_b16 : SELP_PATTERN<"b16", Int16Regs, i16imm, imm>;
1513defm SELP_s16 : SELP<"s16", Int16Regs, i16imm>;
1514defm SELP_u16 : SELP<"u16", Int16Regs, i16imm>;
1515defm SELP_b32 : SELP_PATTERN<"b32", Int32Regs, i32imm, imm>;
1516defm SELP_s32 : SELP<"s32", Int32Regs, i32imm>;
1517defm SELP_u32 : SELP<"u32", Int32Regs, i32imm>;
1518defm SELP_b64 : SELP_PATTERN<"b64", Int64Regs, i64imm, imm>;
1519defm SELP_s64 : SELP<"s64", Int64Regs, i64imm>;
1520defm SELP_u64 : SELP<"u64", Int64Regs, i64imm>;
1521defm SELP_f16 : SELP_PATTERN<"b16", Float16Regs, f16imm, fpimm>;
1522defm SELP_f32 : SELP_PATTERN<"f32", Float32Regs, f32imm, fpimm>;
1523defm SELP_f64 : SELP_PATTERN<"f64", Float64Regs, f64imm, fpimm>;
1524
1525def SELP_f16x2rr :
1526    NVPTXInst<(outs Float16x2Regs:$dst),
1527              (ins Float16x2Regs:$a, Float16x2Regs:$b, Int1Regs:$p),
1528              "selp.b32 \t$dst, $a, $b, $p;",
1529              [(set Float16x2Regs:$dst,
1530                    (select Int1Regs:$p, Float16x2Regs:$a, Float16x2Regs:$b))]>;
1531
1532//-----------------------------------
1533// Data Movement (Load / Store, Move)
1534//-----------------------------------
1535
1536def ADDRri : ComplexPattern<i32, 2, "SelectADDRri", [frameindex],
1537                            [SDNPWantRoot]>;
1538def ADDRri64 : ComplexPattern<i64, 2, "SelectADDRri64", [frameindex],
1539                              [SDNPWantRoot]>;
1540def ADDRvar : ComplexPattern<iPTR, 1, "SelectDirectAddr", [], []>;
1541
1542def MEMri : Operand<i32> {
1543  let PrintMethod = "printMemOperand";
1544  let MIOperandInfo = (ops Int32Regs, i32imm);
1545}
1546def MEMri64 : Operand<i64> {
1547  let PrintMethod = "printMemOperand";
1548  let MIOperandInfo = (ops Int64Regs, i64imm);
1549}
1550
1551def imem : Operand<iPTR> {
1552  let PrintMethod = "printOperand";
1553}
1554
1555def imemAny : Operand<iPTRAny> {
1556  let PrintMethod = "printOperand";
1557}
1558
1559def LdStCode : Operand<i32> {
1560  let PrintMethod = "printLdStCode";
1561}
1562
1563def MmaCode : Operand<i32> {
1564  let PrintMethod = "printMmaCode";
1565}
1566
1567def SDTWrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>;
1568def Wrapper    : SDNode<"NVPTXISD::Wrapper", SDTWrapper>;
1569
1570// Load a memory address into a u32 or u64 register.
1571def MOV_ADDR : NVPTXInst<(outs Int32Regs:$dst), (ins imem:$a),
1572                         "mov.u32 \t$dst, $a;",
1573                         [(set Int32Regs:$dst, (Wrapper tglobaladdr:$a))]>;
1574def MOV_ADDR64 : NVPTXInst<(outs Int64Regs:$dst), (ins imem:$a),
1575                           "mov.u64 \t$dst, $a;",
1576                           [(set Int64Regs:$dst, (Wrapper tglobaladdr:$a))]>;
1577
1578// Get pointer to local stack.
1579let hasSideEffects = false in {
1580  def MOV_DEPOT_ADDR :    NVPTXInst<(outs Int32Regs:$d), (ins i32imm:$num),
1581                                     "mov.u32 \t$d, __local_depot$num;", []>;
1582  def MOV_DEPOT_ADDR_64 : NVPTXInst<(outs Int64Regs:$d), (ins i32imm:$num),
1583                                    "mov.u64 \t$d, __local_depot$num;", []>;
1584}
1585
1586
1587// copyPhysreg is hard-coded in NVPTXInstrInfo.cpp
1588let IsSimpleMove=1, hasSideEffects=0 in {
1589  def IMOV1rr :  NVPTXInst<(outs Int1Regs:$dst), (ins Int1Regs:$sss),
1590                           "mov.pred \t$dst, $sss;", []>;
1591  def IMOV16rr : NVPTXInst<(outs Int16Regs:$dst), (ins Int16Regs:$sss),
1592                           "mov.u16 \t$dst, $sss;", []>;
1593  def IMOV32rr : NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$sss),
1594                           "mov.u32 \t$dst, $sss;", []>;
1595  def IMOV64rr : NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$sss),
1596                           "mov.u64 \t$dst, $sss;", []>;
1597
1598  def FMOV16rr : NVPTXInst<(outs Float16Regs:$dst), (ins Float16Regs:$src),
1599                           // We have to use .b16 here as there's no mov.f16.
1600                           "mov.b16 \t$dst, $src;", []>;
1601  def FMOV32rr : NVPTXInst<(outs Float32Regs:$dst), (ins Float32Regs:$src),
1602                           "mov.f32 \t$dst, $src;", []>;
1603  def FMOV64rr : NVPTXInst<(outs Float64Regs:$dst), (ins Float64Regs:$src),
1604                           "mov.f64 \t$dst, $src;", []>;
1605}
1606
1607def IMOV1ri : NVPTXInst<(outs Int1Regs:$dst), (ins i1imm:$src),
1608                        "mov.pred \t$dst, $src;",
1609                        [(set Int1Regs:$dst, imm:$src)]>;
1610def IMOV16ri : NVPTXInst<(outs Int16Regs:$dst), (ins i16imm:$src),
1611                         "mov.u16 \t$dst, $src;",
1612                         [(set Int16Regs:$dst, imm:$src)]>;
1613def IMOV32ri : NVPTXInst<(outs Int32Regs:$dst), (ins i32imm:$src),
1614                         "mov.u32 \t$dst, $src;",
1615                         [(set Int32Regs:$dst, imm:$src)]>;
1616def IMOV64i : NVPTXInst<(outs Int64Regs:$dst), (ins i64imm:$src),
1617                        "mov.u64 \t$dst, $src;",
1618                        [(set Int64Regs:$dst, imm:$src)]>;
1619
1620def FMOV32ri : NVPTXInst<(outs Float32Regs:$dst), (ins f32imm:$src),
1621                         "mov.f32 \t$dst, $src;",
1622                         [(set Float32Regs:$dst, fpimm:$src)]>;
1623def FMOV64ri : NVPTXInst<(outs Float64Regs:$dst), (ins f64imm:$src),
1624                         "mov.f64 \t$dst, $src;",
1625                         [(set Float64Regs:$dst, fpimm:$src)]>;
1626
1627def : Pat<(i32 (Wrapper texternalsym:$dst)), (IMOV32ri texternalsym:$dst)>;
1628
1629//---- Copy Frame Index ----
1630def LEA_ADDRi :   NVPTXInst<(outs Int32Regs:$dst), (ins MEMri:$addr),
1631                            "add.u32 \t$dst, ${addr:add};",
1632                            [(set Int32Regs:$dst, ADDRri:$addr)]>;
1633def LEA_ADDRi64 : NVPTXInst<(outs Int64Regs:$dst), (ins MEMri64:$addr),
1634                            "add.u64 \t$dst, ${addr:add};",
1635                            [(set Int64Regs:$dst, ADDRri64:$addr)]>;
1636
1637//-----------------------------------
1638// Comparison and Selection
1639//-----------------------------------
1640
1641multiclass ISET_FORMAT<PatFrag OpNode, PatLeaf Mode,
1642                       Instruction setp_16rr,
1643                       Instruction setp_16ri,
1644                       Instruction setp_16ir,
1645                       Instruction setp_32rr,
1646                       Instruction setp_32ri,
1647                       Instruction setp_32ir,
1648                       Instruction setp_64rr,
1649                       Instruction setp_64ri,
1650                       Instruction setp_64ir,
1651                       Instruction set_16rr,
1652                       Instruction set_16ri,
1653                       Instruction set_16ir,
1654                       Instruction set_32rr,
1655                       Instruction set_32ri,
1656                       Instruction set_32ir,
1657                       Instruction set_64rr,
1658                       Instruction set_64ri,
1659                       Instruction set_64ir> {
1660  // i16 -> pred
1661  def : Pat<(i1 (OpNode Int16Regs:$a, Int16Regs:$b)),
1662            (setp_16rr Int16Regs:$a, Int16Regs:$b, Mode)>;
1663  def : Pat<(i1 (OpNode Int16Regs:$a, imm:$b)),
1664            (setp_16ri Int16Regs:$a, imm:$b, Mode)>;
1665  def : Pat<(i1 (OpNode imm:$a, Int16Regs:$b)),
1666            (setp_16ir imm:$a, Int16Regs:$b, Mode)>;
1667  // i32 -> pred
1668  def : Pat<(i1 (OpNode Int32Regs:$a, Int32Regs:$b)),
1669            (setp_32rr Int32Regs:$a, Int32Regs:$b, Mode)>;
1670  def : Pat<(i1 (OpNode Int32Regs:$a, imm:$b)),
1671            (setp_32ri Int32Regs:$a, imm:$b, Mode)>;
1672  def : Pat<(i1 (OpNode imm:$a, Int32Regs:$b)),
1673            (setp_32ir imm:$a, Int32Regs:$b, Mode)>;
1674  // i64 -> pred
1675  def : Pat<(i1 (OpNode Int64Regs:$a, Int64Regs:$b)),
1676            (setp_64rr Int64Regs:$a, Int64Regs:$b, Mode)>;
1677  def : Pat<(i1 (OpNode Int64Regs:$a, imm:$b)),
1678            (setp_64ri Int64Regs:$a, imm:$b, Mode)>;
1679  def : Pat<(i1 (OpNode imm:$a, Int64Regs:$b)),
1680            (setp_64ir imm:$a, Int64Regs:$b, Mode)>;
1681
1682  // i16 -> i32
1683  def : Pat<(i32 (OpNode Int16Regs:$a, Int16Regs:$b)),
1684            (set_16rr Int16Regs:$a, Int16Regs:$b, Mode)>;
1685  def : Pat<(i32 (OpNode Int16Regs:$a, imm:$b)),
1686            (set_16ri Int16Regs:$a, imm:$b, Mode)>;
1687  def : Pat<(i32 (OpNode imm:$a, Int16Regs:$b)),
1688            (set_16ir imm:$a, Int16Regs:$b, Mode)>;
1689  // i32 -> i32
1690  def : Pat<(i32 (OpNode Int32Regs:$a, Int32Regs:$b)),
1691            (set_32rr Int32Regs:$a, Int32Regs:$b, Mode)>;
1692  def : Pat<(i32 (OpNode Int32Regs:$a, imm:$b)),
1693            (set_32ri Int32Regs:$a, imm:$b, Mode)>;
1694  def : Pat<(i32 (OpNode imm:$a, Int32Regs:$b)),
1695            (set_32ir imm:$a, Int32Regs:$b, Mode)>;
1696  // i64 -> i32
1697  def : Pat<(i32 (OpNode Int64Regs:$a, Int64Regs:$b)),
1698            (set_64rr Int64Regs:$a, Int64Regs:$b, Mode)>;
1699  def : Pat<(i32 (OpNode Int64Regs:$a, imm:$b)),
1700            (set_64ri Int64Regs:$a, imm:$b, Mode)>;
1701  def : Pat<(i32 (OpNode imm:$a, Int64Regs:$b)),
1702            (set_64ir imm:$a, Int64Regs:$b, Mode)>;
1703}
1704
1705multiclass ISET_FORMAT_SIGNED<PatFrag OpNode, PatLeaf Mode>
1706  : ISET_FORMAT<OpNode, Mode,
1707                SETP_s16rr, SETP_s16ri, SETP_s16ir,
1708                SETP_s32rr, SETP_s32ri, SETP_s32ir,
1709                SETP_s64rr, SETP_s64ri, SETP_s64ir,
1710                SET_s16rr, SET_s16ri, SET_s16ir,
1711                SET_s32rr, SET_s32ri, SET_s32ir,
1712                SET_s64rr, SET_s64ri, SET_s64ir> {
1713  // TableGen doesn't like empty multiclasses.
1714  def : PatLeaf<(i32 0)>;
1715}
1716
1717multiclass ISET_FORMAT_UNSIGNED<PatFrag OpNode, PatLeaf Mode>
1718  : ISET_FORMAT<OpNode, Mode,
1719                SETP_u16rr, SETP_u16ri, SETP_u16ir,
1720                SETP_u32rr, SETP_u32ri, SETP_u32ir,
1721                SETP_u64rr, SETP_u64ri, SETP_u64ir,
1722                SET_u16rr, SET_u16ri, SET_u16ir,
1723                SET_u32rr, SET_u32ri, SET_u32ir,
1724                SET_u64rr, SET_u64ri, SET_u64ir> {
1725  // TableGen doesn't like empty multiclasses.
1726  def : PatLeaf<(i32 0)>;
1727}
1728
1729defm : ISET_FORMAT_SIGNED<setgt, CmpGT>;
1730defm : ISET_FORMAT_SIGNED<setlt, CmpLT>;
1731defm : ISET_FORMAT_SIGNED<setge, CmpGE>;
1732defm : ISET_FORMAT_SIGNED<setle, CmpLE>;
1733defm : ISET_FORMAT_SIGNED<seteq, CmpEQ>;
1734defm : ISET_FORMAT_SIGNED<setne, CmpNE>;
1735defm : ISET_FORMAT_UNSIGNED<setugt, CmpGT>;
1736defm : ISET_FORMAT_UNSIGNED<setult, CmpLT>;
1737defm : ISET_FORMAT_UNSIGNED<setuge, CmpGE>;
1738defm : ISET_FORMAT_UNSIGNED<setule, CmpLE>;
1739defm : ISET_FORMAT_UNSIGNED<setueq, CmpEQ>;
1740defm : ISET_FORMAT_UNSIGNED<setune, CmpNE>;
1741
1742// i1 compares
1743def : Pat<(setne Int1Regs:$a, Int1Regs:$b),
1744          (XORb1rr Int1Regs:$a, Int1Regs:$b)>;
1745def : Pat<(setune Int1Regs:$a, Int1Regs:$b),
1746          (XORb1rr Int1Regs:$a, Int1Regs:$b)>;
1747
1748def : Pat<(seteq Int1Regs:$a, Int1Regs:$b),
1749          (NOT1 (XORb1rr Int1Regs:$a, Int1Regs:$b))>;
1750def : Pat<(setueq Int1Regs:$a, Int1Regs:$b),
1751          (NOT1 (XORb1rr Int1Regs:$a, Int1Regs:$b))>;
1752
1753// i1 compare -> i32
1754def : Pat<(i32 (setne Int1Regs:$a, Int1Regs:$b)),
1755          (SELP_u32ii -1, 0, (XORb1rr Int1Regs:$a, Int1Regs:$b))>;
1756def : Pat<(i32 (setne Int1Regs:$a, Int1Regs:$b)),
1757          (SELP_u32ii 0, -1, (XORb1rr Int1Regs:$a, Int1Regs:$b))>;
1758
1759
1760
1761multiclass FSET_FORMAT<PatFrag OpNode, PatLeaf Mode, PatLeaf ModeFTZ> {
1762  // f16 -> pred
1763  def : Pat<(i1 (OpNode Float16Regs:$a, Float16Regs:$b)),
1764            (SETP_f16rr Float16Regs:$a, Float16Regs:$b, ModeFTZ)>,
1765        Requires<[useFP16Math,doF32FTZ]>;
1766  def : Pat<(i1 (OpNode Float16Regs:$a, Float16Regs:$b)),
1767            (SETP_f16rr Float16Regs:$a, Float16Regs:$b, Mode)>,
1768        Requires<[useFP16Math]>;
1769  def : Pat<(i1 (OpNode Float16Regs:$a, fpimm:$b)),
1770            (SETP_f16rr Float16Regs:$a, (LOAD_CONST_F16 fpimm:$b), ModeFTZ)>,
1771        Requires<[useFP16Math,doF32FTZ]>;
1772  def : Pat<(i1 (OpNode Float16Regs:$a, fpimm:$b)),
1773            (SETP_f16rr Float16Regs:$a, (LOAD_CONST_F16 fpimm:$b), Mode)>,
1774        Requires<[useFP16Math]>;
1775  def : Pat<(i1 (OpNode fpimm:$a, Float16Regs:$b)),
1776            (SETP_f16rr (LOAD_CONST_F16 fpimm:$a), Float16Regs:$b, ModeFTZ)>,
1777        Requires<[useFP16Math,doF32FTZ]>;
1778  def : Pat<(i1 (OpNode fpimm:$a, Float16Regs:$b)),
1779            (SETP_f16rr (LOAD_CONST_F16 fpimm:$a), Float16Regs:$b, Mode)>,
1780        Requires<[useFP16Math]>;
1781
1782  // f32 -> pred
1783  def : Pat<(i1 (OpNode Float32Regs:$a, Float32Regs:$b)),
1784            (SETP_f32rr Float32Regs:$a, Float32Regs:$b, ModeFTZ)>,
1785        Requires<[doF32FTZ]>;
1786  def : Pat<(i1 (OpNode Float32Regs:$a, Float32Regs:$b)),
1787            (SETP_f32rr Float32Regs:$a, Float32Regs:$b, Mode)>;
1788  def : Pat<(i1 (OpNode Float32Regs:$a, fpimm:$b)),
1789            (SETP_f32ri Float32Regs:$a, fpimm:$b, ModeFTZ)>,
1790        Requires<[doF32FTZ]>;
1791  def : Pat<(i1 (OpNode Float32Regs:$a, fpimm:$b)),
1792            (SETP_f32ri Float32Regs:$a, fpimm:$b, Mode)>;
1793  def : Pat<(i1 (OpNode fpimm:$a, Float32Regs:$b)),
1794            (SETP_f32ir fpimm:$a, Float32Regs:$b, ModeFTZ)>,
1795        Requires<[doF32FTZ]>;
1796  def : Pat<(i1 (OpNode fpimm:$a, Float32Regs:$b)),
1797            (SETP_f32ir fpimm:$a, Float32Regs:$b, Mode)>;
1798
1799  // f64 -> pred
1800  def : Pat<(i1 (OpNode Float64Regs:$a, Float64Regs:$b)),
1801            (SETP_f64rr Float64Regs:$a, Float64Regs:$b, Mode)>;
1802  def : Pat<(i1 (OpNode Float64Regs:$a, fpimm:$b)),
1803            (SETP_f64ri Float64Regs:$a, fpimm:$b, Mode)>;
1804  def : Pat<(i1 (OpNode fpimm:$a, Float64Regs:$b)),
1805            (SETP_f64ir fpimm:$a, Float64Regs:$b, Mode)>;
1806
1807  // f16 -> i32
1808  def : Pat<(i32 (OpNode Float16Regs:$a, Float16Regs:$b)),
1809            (SET_f16rr Float16Regs:$a, Float16Regs:$b, ModeFTZ)>,
1810        Requires<[useFP16Math, doF32FTZ]>;
1811  def : Pat<(i32 (OpNode Float16Regs:$a, Float16Regs:$b)),
1812            (SET_f16rr Float16Regs:$a, Float16Regs:$b, Mode)>,
1813        Requires<[useFP16Math]>;
1814  def : Pat<(i32 (OpNode Float16Regs:$a, fpimm:$b)),
1815            (SET_f16rr Float16Regs:$a, (LOAD_CONST_F16 fpimm:$b), ModeFTZ)>,
1816        Requires<[useFP16Math, doF32FTZ]>;
1817  def : Pat<(i32 (OpNode Float16Regs:$a, fpimm:$b)),
1818            (SET_f16rr Float16Regs:$a, (LOAD_CONST_F16 fpimm:$b), Mode)>,
1819        Requires<[useFP16Math]>;
1820  def : Pat<(i32 (OpNode fpimm:$a, Float16Regs:$b)),
1821            (SET_f16ir (LOAD_CONST_F16 fpimm:$a), Float16Regs:$b, ModeFTZ)>,
1822        Requires<[useFP16Math, doF32FTZ]>;
1823  def : Pat<(i32 (OpNode fpimm:$a, Float16Regs:$b)),
1824            (SET_f16ir (LOAD_CONST_F16 fpimm:$a), Float16Regs:$b, Mode)>,
1825        Requires<[useFP16Math]>;
1826
1827  // f32 -> i32
1828  def : Pat<(i32 (OpNode Float32Regs:$a, Float32Regs:$b)),
1829            (SET_f32rr Float32Regs:$a, Float32Regs:$b, ModeFTZ)>,
1830        Requires<[doF32FTZ]>;
1831  def : Pat<(i32 (OpNode Float32Regs:$a, Float32Regs:$b)),
1832            (SET_f32rr Float32Regs:$a, Float32Regs:$b, Mode)>;
1833  def : Pat<(i32 (OpNode Float32Regs:$a, fpimm:$b)),
1834            (SET_f32ri Float32Regs:$a, fpimm:$b, ModeFTZ)>,
1835        Requires<[doF32FTZ]>;
1836  def : Pat<(i32 (OpNode Float32Regs:$a, fpimm:$b)),
1837            (SET_f32ri Float32Regs:$a, fpimm:$b, Mode)>;
1838  def : Pat<(i32 (OpNode fpimm:$a, Float32Regs:$b)),
1839            (SET_f32ir fpimm:$a, Float32Regs:$b, ModeFTZ)>,
1840        Requires<[doF32FTZ]>;
1841  def : Pat<(i32 (OpNode fpimm:$a, Float32Regs:$b)),
1842            (SET_f32ir fpimm:$a, Float32Regs:$b, Mode)>;
1843
1844  // f64 -> i32
1845  def : Pat<(i32 (OpNode Float64Regs:$a, Float64Regs:$b)),
1846            (SET_f64rr Float64Regs:$a, Float64Regs:$b, Mode)>;
1847  def : Pat<(i32 (OpNode Float64Regs:$a, fpimm:$b)),
1848            (SET_f64ri Float64Regs:$a, fpimm:$b, Mode)>;
1849  def : Pat<(i32 (OpNode fpimm:$a, Float64Regs:$b)),
1850            (SET_f64ir fpimm:$a, Float64Regs:$b, Mode)>;
1851}
1852
1853defm FSetOGT : FSET_FORMAT<setogt, CmpGT, CmpGT_FTZ>;
1854defm FSetOLT : FSET_FORMAT<setolt, CmpLT, CmpLT_FTZ>;
1855defm FSetOGE : FSET_FORMAT<setoge, CmpGE, CmpGE_FTZ>;
1856defm FSetOLE : FSET_FORMAT<setole, CmpLE, CmpLE_FTZ>;
1857defm FSetOEQ : FSET_FORMAT<setoeq, CmpEQ, CmpEQ_FTZ>;
1858defm FSetONE : FSET_FORMAT<setone, CmpNE, CmpNE_FTZ>;
1859
1860defm FSetUGT : FSET_FORMAT<setugt, CmpGTU, CmpGTU_FTZ>;
1861defm FSetULT : FSET_FORMAT<setult, CmpLTU, CmpLTU_FTZ>;
1862defm FSetUGE : FSET_FORMAT<setuge, CmpGEU, CmpGEU_FTZ>;
1863defm FSetULE : FSET_FORMAT<setule, CmpLEU, CmpLEU_FTZ>;
1864defm FSetUEQ : FSET_FORMAT<setueq, CmpEQU, CmpEQU_FTZ>;
1865defm FSetUNE : FSET_FORMAT<setune, CmpNEU, CmpNEU_FTZ>;
1866
1867defm FSetGT : FSET_FORMAT<setgt, CmpGT, CmpGT_FTZ>;
1868defm FSetLT : FSET_FORMAT<setlt, CmpLT, CmpLT_FTZ>;
1869defm FSetGE : FSET_FORMAT<setge, CmpGE, CmpGE_FTZ>;
1870defm FSetLE : FSET_FORMAT<setle, CmpLE, CmpLE_FTZ>;
1871defm FSetEQ : FSET_FORMAT<seteq, CmpEQ, CmpEQ_FTZ>;
1872defm FSetNE : FSET_FORMAT<setne, CmpNE, CmpNE_FTZ>;
1873
1874defm FSetNUM : FSET_FORMAT<seto, CmpNUM, CmpNUM_FTZ>;
1875defm FSetNAN : FSET_FORMAT<setuo, CmpNAN, CmpNAN_FTZ>;
1876
1877// FIXME: What is this doing here?  Can it be deleted?
1878// def ld_param         : SDNode<"NVPTXISD::LOAD_PARAM", SDTLoad,
1879//                         [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
1880
1881def SDTDeclareParamProfile :
1882  SDTypeProfile<0, 3, [SDTCisInt<0>, SDTCisInt<1>, SDTCisInt<2>]>;
1883def SDTDeclareScalarParamProfile :
1884  SDTypeProfile<0, 3, [SDTCisInt<0>, SDTCisInt<1>, SDTCisInt<2>]>;
1885def SDTLoadParamProfile : SDTypeProfile<1, 2, [SDTCisInt<1>, SDTCisInt<2>]>;
1886def SDTLoadParamV2Profile : SDTypeProfile<2, 2, [SDTCisSameAs<0, 1>, SDTCisInt<2>, SDTCisInt<3>]>;
1887def SDTLoadParamV4Profile : SDTypeProfile<4, 2, [SDTCisInt<4>, SDTCisInt<5>]>;
1888def SDTPrintCallProfile : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
1889def SDTPrintCallUniProfile : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
1890def SDTStoreParamProfile : SDTypeProfile<0, 3, [SDTCisInt<0>, SDTCisInt<1>]>;
1891def SDTStoreParamV2Profile : SDTypeProfile<0, 4, [SDTCisInt<0>, SDTCisInt<1>]>;
1892def SDTStoreParamV4Profile : SDTypeProfile<0, 6, [SDTCisInt<0>, SDTCisInt<1>]>;
1893def SDTStoreParam32Profile : SDTypeProfile<0, 3, [SDTCisInt<0>, SDTCisInt<1>]>;
1894def SDTCallArgProfile : SDTypeProfile<0, 2, [SDTCisInt<0>]>;
1895def SDTCallArgMarkProfile : SDTypeProfile<0, 0, []>;
1896def SDTCallVoidProfile : SDTypeProfile<0, 1, []>;
1897def SDTCallValProfile : SDTypeProfile<1, 0, []>;
1898def SDTMoveParamProfile : SDTypeProfile<1, 1, []>;
1899def SDTStoreRetvalProfile : SDTypeProfile<0, 2, [SDTCisInt<0>]>;
1900def SDTStoreRetvalV2Profile : SDTypeProfile<0, 3, [SDTCisInt<0>]>;
1901def SDTStoreRetvalV4Profile : SDTypeProfile<0, 5, [SDTCisInt<0>]>;
1902def SDTPseudoUseParamProfile : SDTypeProfile<0, 1, []>;
1903def SDTProxyRegProfile : SDTypeProfile<1, 1, []>;
1904
1905def DeclareParam :
1906  SDNode<"NVPTXISD::DeclareParam", SDTDeclareParamProfile,
1907         [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1908def DeclareScalarParam :
1909  SDNode<"NVPTXISD::DeclareScalarParam", SDTDeclareScalarParamProfile,
1910         [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1911def DeclareRetParam :
1912  SDNode<"NVPTXISD::DeclareRetParam", SDTDeclareParamProfile,
1913         [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1914def DeclareRet :
1915  SDNode<"NVPTXISD::DeclareRet", SDTDeclareScalarParamProfile,
1916         [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1917def LoadParam :
1918  SDNode<"NVPTXISD::LoadParam", SDTLoadParamProfile,
1919         [SDNPHasChain, SDNPMayLoad, SDNPOutGlue, SDNPInGlue]>;
1920def LoadParamV2 :
1921  SDNode<"NVPTXISD::LoadParamV2", SDTLoadParamV2Profile,
1922         [SDNPHasChain, SDNPMayLoad, SDNPOutGlue, SDNPInGlue]>;
1923def LoadParamV4 :
1924  SDNode<"NVPTXISD::LoadParamV4", SDTLoadParamV4Profile,
1925         [SDNPHasChain, SDNPMayLoad, SDNPOutGlue, SDNPInGlue]>;
1926def PrintCall :
1927  SDNode<"NVPTXISD::PrintCall", SDTPrintCallProfile,
1928         [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1929def PrintConvergentCall :
1930  SDNode<"NVPTXISD::PrintConvergentCall", SDTPrintCallProfile,
1931         [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1932def PrintCallUni :
1933  SDNode<"NVPTXISD::PrintCallUni", SDTPrintCallUniProfile,
1934         [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1935def PrintConvergentCallUni :
1936  SDNode<"NVPTXISD::PrintConvergentCallUni", SDTPrintCallUniProfile,
1937         [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1938def StoreParam :
1939  SDNode<"NVPTXISD::StoreParam", SDTStoreParamProfile,
1940         [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1941def StoreParamV2 :
1942  SDNode<"NVPTXISD::StoreParamV2", SDTStoreParamV2Profile,
1943         [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1944def StoreParamV4 :
1945  SDNode<"NVPTXISD::StoreParamV4", SDTStoreParamV4Profile,
1946         [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1947def StoreParamU32 :
1948  SDNode<"NVPTXISD::StoreParamU32", SDTStoreParam32Profile,
1949         [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1950def StoreParamS32 :
1951  SDNode<"NVPTXISD::StoreParamS32", SDTStoreParam32Profile,
1952         [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1953def CallArgBegin :
1954  SDNode<"NVPTXISD::CallArgBegin", SDTCallArgMarkProfile,
1955         [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1956def CallArg :
1957  SDNode<"NVPTXISD::CallArg", SDTCallArgProfile,
1958         [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1959def LastCallArg :
1960  SDNode<"NVPTXISD::LastCallArg", SDTCallArgProfile,
1961         [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1962def CallArgEnd :
1963  SDNode<"NVPTXISD::CallArgEnd", SDTCallVoidProfile,
1964         [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1965def CallVoid :
1966  SDNode<"NVPTXISD::CallVoid", SDTCallVoidProfile,
1967         [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1968def Prototype :
1969  SDNode<"NVPTXISD::Prototype", SDTCallVoidProfile,
1970         [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1971def CallVal :
1972  SDNode<"NVPTXISD::CallVal", SDTCallValProfile,
1973         [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1974def MoveParam :
1975  SDNode<"NVPTXISD::MoveParam", SDTMoveParamProfile, []>;
1976def StoreRetval :
1977  SDNode<"NVPTXISD::StoreRetval", SDTStoreRetvalProfile,
1978         [SDNPHasChain, SDNPSideEffect]>;
1979def StoreRetvalV2 :
1980  SDNode<"NVPTXISD::StoreRetvalV2", SDTStoreRetvalV2Profile,
1981         [SDNPHasChain, SDNPSideEffect]>;
1982def StoreRetvalV4 :
1983  SDNode<"NVPTXISD::StoreRetvalV4", SDTStoreRetvalV4Profile,
1984         [SDNPHasChain, SDNPSideEffect]>;
1985def PseudoUseParam :
1986  SDNode<"NVPTXISD::PseudoUseParam", SDTPseudoUseParamProfile,
1987         [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1988def RETURNNode :
1989  SDNode<"NVPTXISD::RETURN", SDTCallArgMarkProfile,
1990         [SDNPHasChain, SDNPSideEffect]>;
1991def ProxyReg :
1992  SDNode<"NVPTXISD::ProxyReg", SDTProxyRegProfile,
1993         [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1994
1995let mayLoad = true in {
1996  class LoadParamMemInst<NVPTXRegClass regclass, string opstr> :
1997        NVPTXInst<(outs regclass:$dst), (ins i32imm:$b),
1998                  !strconcat("ld.param", opstr, " \t$dst, [retval0+$b];"),
1999                  []>;
2000
2001  class LoadParamV2MemInst<NVPTXRegClass regclass, string opstr> :
2002        NVPTXInst<(outs regclass:$dst, regclass:$dst2), (ins i32imm:$b),
2003                  !strconcat("ld.param.v2", opstr,
2004                             " \t{{$dst, $dst2}}, [retval0+$b];"), []>;
2005
2006  class LoadParamV4MemInst<NVPTXRegClass regclass, string opstr> :
2007        NVPTXInst<(outs regclass:$dst, regclass:$dst2, regclass:$dst3,
2008                        regclass:$dst4),
2009                  (ins i32imm:$b),
2010                  !strconcat("ld.param.v4", opstr,
2011                             " \t{{$dst, $dst2, $dst3, $dst4}}, [retval0+$b];"),
2012                  []>;
2013}
2014
2015class LoadParamRegInst<NVPTXRegClass regclass, string opstr> :
2016      NVPTXInst<(outs regclass:$dst), (ins i32imm:$b),
2017                !strconcat("mov", opstr, " \t$dst, retval$b;"),
2018                [(set regclass:$dst, (LoadParam (i32 0), (i32 imm:$b)))]>;
2019
2020let mayStore = true in {
2021  class StoreParamInst<NVPTXRegClass regclass, string opstr> :
2022        NVPTXInst<(outs), (ins regclass:$val, i32imm:$a, i32imm:$b),
2023                  !strconcat("st.param", opstr, " \t[param$a+$b], $val;"),
2024                  []>;
2025
2026  class StoreParamV2Inst<NVPTXRegClass regclass, string opstr> :
2027        NVPTXInst<(outs), (ins regclass:$val, regclass:$val2,
2028                               i32imm:$a, i32imm:$b),
2029                  !strconcat("st.param.v2", opstr,
2030                             " \t[param$a+$b], {{$val, $val2}};"),
2031                  []>;
2032
2033  class StoreParamV4Inst<NVPTXRegClass regclass, string opstr> :
2034        NVPTXInst<(outs), (ins regclass:$val, regclass:$val2, regclass:$val3,
2035                               regclass:$val4, i32imm:$a,
2036                               i32imm:$b),
2037                  !strconcat("st.param.v4", opstr,
2038                             " \t[param$a+$b], {{$val, $val2, $val3, $val4}};"),
2039                  []>;
2040
2041  class StoreRetvalInst<NVPTXRegClass regclass, string opstr> :
2042        NVPTXInst<(outs), (ins regclass:$val, i32imm:$a),
2043                  !strconcat("st.param", opstr, " \t[func_retval0+$a], $val;"),
2044                  []>;
2045
2046  class StoreRetvalV2Inst<NVPTXRegClass regclass, string opstr> :
2047        NVPTXInst<(outs), (ins regclass:$val, regclass:$val2, i32imm:$a),
2048                  !strconcat("st.param.v2", opstr,
2049                             " \t[func_retval0+$a], {{$val, $val2}};"),
2050                  []>;
2051
2052  class StoreRetvalV4Inst<NVPTXRegClass regclass, string opstr> :
2053        NVPTXInst<(outs),
2054                  (ins regclass:$val, regclass:$val2, regclass:$val3,
2055                       regclass:$val4, i32imm:$a),
2056                  !strconcat("st.param.v4", opstr,
2057                             " \t[func_retval0+$a], {{$val, $val2, $val3, $val4}};"),
2058                  []>;
2059}
2060
2061let isCall=1 in {
2062  multiclass CALL<string OpcStr, SDNode OpNode> {
2063     def PrintCallNoRetInst : NVPTXInst<(outs), (ins),
2064       !strconcat(OpcStr, " "), [(OpNode (i32 0))]>;
2065     def PrintCallRetInst1 : NVPTXInst<(outs), (ins),
2066       !strconcat(OpcStr, " (retval0), "), [(OpNode (i32 1))]>;
2067     def PrintCallRetInst2 : NVPTXInst<(outs), (ins),
2068       !strconcat(OpcStr, " (retval0, retval1), "), [(OpNode (i32 2))]>;
2069     def PrintCallRetInst3 : NVPTXInst<(outs), (ins),
2070       !strconcat(OpcStr, " (retval0, retval1, retval2), "), [(OpNode (i32 3))]>;
2071     def PrintCallRetInst4 : NVPTXInst<(outs), (ins),
2072       !strconcat(OpcStr, " (retval0, retval1, retval2, retval3), "),
2073       [(OpNode (i32 4))]>;
2074     def PrintCallRetInst5 : NVPTXInst<(outs), (ins),
2075       !strconcat(OpcStr, " (retval0, retval1, retval2, retval3, retval4), "),
2076       [(OpNode (i32 5))]>;
2077     def PrintCallRetInst6 : NVPTXInst<(outs), (ins),
2078       !strconcat(OpcStr, " (retval0, retval1, retval2, retval3, retval4, "
2079                            "retval5), "),
2080       [(OpNode (i32 6))]>;
2081     def PrintCallRetInst7 : NVPTXInst<(outs), (ins),
2082       !strconcat(OpcStr, " (retval0, retval1, retval2, retval3, retval4, "
2083                            "retval5, retval6), "),
2084       [(OpNode (i32 7))]>;
2085     def PrintCallRetInst8 : NVPTXInst<(outs), (ins),
2086       !strconcat(OpcStr, " (retval0, retval1, retval2, retval3, retval4, "
2087                            "retval5, retval6, retval7), "),
2088       [(OpNode (i32 8))]>;
2089  }
2090}
2091
2092defm Call : CALL<"call", PrintCall>;
2093defm CallUni : CALL<"call.uni", PrintCallUni>;
2094
2095// Convergent call instructions.  These are identical to regular calls, except
2096// they have the isConvergent bit set.
2097let isConvergent=1 in {
2098  defm ConvergentCall : CALL<"call", PrintConvergentCall>;
2099  defm ConvergentCallUni : CALL<"call.uni", PrintConvergentCallUni>;
2100}
2101
2102def LoadParamMemI64    : LoadParamMemInst<Int64Regs, ".b64">;
2103def LoadParamMemI32    : LoadParamMemInst<Int32Regs, ".b32">;
2104def LoadParamMemI16    : LoadParamMemInst<Int16Regs, ".b16">;
2105def LoadParamMemI8     : LoadParamMemInst<Int16Regs, ".b8">;
2106def LoadParamMemV2I64  : LoadParamV2MemInst<Int64Regs, ".b64">;
2107def LoadParamMemV2I32  : LoadParamV2MemInst<Int32Regs, ".b32">;
2108def LoadParamMemV2I16  : LoadParamV2MemInst<Int16Regs, ".b16">;
2109def LoadParamMemV2I8   : LoadParamV2MemInst<Int16Regs, ".b8">;
2110def LoadParamMemV4I32  : LoadParamV4MemInst<Int32Regs, ".b32">;
2111def LoadParamMemV4I16  : LoadParamV4MemInst<Int16Regs, ".b16">;
2112def LoadParamMemV4I8   : LoadParamV4MemInst<Int16Regs, ".b8">;
2113def LoadParamMemF16    : LoadParamMemInst<Float16Regs, ".b16">;
2114def LoadParamMemF16x2  : LoadParamMemInst<Float16x2Regs, ".b32">;
2115def LoadParamMemF32    : LoadParamMemInst<Float32Regs, ".f32">;
2116def LoadParamMemF64    : LoadParamMemInst<Float64Regs, ".f64">;
2117def LoadParamMemV2F16  : LoadParamV2MemInst<Float16Regs, ".b16">;
2118def LoadParamMemV2F16x2: LoadParamV2MemInst<Float16x2Regs, ".b32">;
2119def LoadParamMemV2F32  : LoadParamV2MemInst<Float32Regs, ".f32">;
2120def LoadParamMemV2F64  : LoadParamV2MemInst<Float64Regs, ".f64">;
2121def LoadParamMemV4F16  : LoadParamV4MemInst<Float16Regs, ".b16">;
2122def LoadParamMemV4F16x2: LoadParamV4MemInst<Float16x2Regs, ".b32">;
2123def LoadParamMemV4F32  : LoadParamV4MemInst<Float32Regs, ".f32">;
2124
2125def StoreParamI64    : StoreParamInst<Int64Regs, ".b64">;
2126def StoreParamI32    : StoreParamInst<Int32Regs, ".b32">;
2127
2128def StoreParamI16    : StoreParamInst<Int16Regs, ".b16">;
2129def StoreParamI8     : StoreParamInst<Int16Regs, ".b8">;
2130def StoreParamV2I64  : StoreParamV2Inst<Int64Regs, ".b64">;
2131def StoreParamV2I32  : StoreParamV2Inst<Int32Regs, ".b32">;
2132def StoreParamV2I16  : StoreParamV2Inst<Int16Regs, ".b16">;
2133def StoreParamV2I8   : StoreParamV2Inst<Int16Regs, ".b8">;
2134
2135def StoreParamV4I32  : StoreParamV4Inst<Int32Regs, ".b32">;
2136def StoreParamV4I16  : StoreParamV4Inst<Int16Regs, ".b16">;
2137def StoreParamV4I8   : StoreParamV4Inst<Int16Regs, ".b8">;
2138
2139def StoreParamF16      : StoreParamInst<Float16Regs, ".b16">;
2140def StoreParamF16x2    : StoreParamInst<Float16x2Regs, ".b32">;
2141def StoreParamF32      : StoreParamInst<Float32Regs, ".f32">;
2142def StoreParamF64      : StoreParamInst<Float64Regs, ".f64">;
2143def StoreParamV2F16    : StoreParamV2Inst<Float16Regs, ".b16">;
2144def StoreParamV2F16x2  : StoreParamV2Inst<Float16x2Regs, ".b32">;
2145def StoreParamV2F32    : StoreParamV2Inst<Float32Regs, ".f32">;
2146def StoreParamV2F64    : StoreParamV2Inst<Float64Regs, ".f64">;
2147def StoreParamV4F16    : StoreParamV4Inst<Float16Regs, ".b16">;
2148def StoreParamV4F16x2  : StoreParamV4Inst<Float16x2Regs, ".b32">;
2149def StoreParamV4F32    : StoreParamV4Inst<Float32Regs, ".f32">;
2150
2151def StoreRetvalI64    : StoreRetvalInst<Int64Regs, ".b64">;
2152def StoreRetvalI32    : StoreRetvalInst<Int32Regs, ".b32">;
2153def StoreRetvalI16    : StoreRetvalInst<Int16Regs, ".b16">;
2154def StoreRetvalI8     : StoreRetvalInst<Int16Regs, ".b8">;
2155def StoreRetvalV2I64  : StoreRetvalV2Inst<Int64Regs, ".b64">;
2156def StoreRetvalV2I32  : StoreRetvalV2Inst<Int32Regs, ".b32">;
2157def StoreRetvalV2I16  : StoreRetvalV2Inst<Int16Regs, ".b16">;
2158def StoreRetvalV2I8   : StoreRetvalV2Inst<Int16Regs, ".b8">;
2159def StoreRetvalV4I32  : StoreRetvalV4Inst<Int32Regs, ".b32">;
2160def StoreRetvalV4I16  : StoreRetvalV4Inst<Int16Regs, ".b16">;
2161def StoreRetvalV4I8   : StoreRetvalV4Inst<Int16Regs, ".b8">;
2162
2163def StoreRetvalF64    : StoreRetvalInst<Float64Regs, ".f64">;
2164def StoreRetvalF32    : StoreRetvalInst<Float32Regs, ".f32">;
2165def StoreRetvalF16    : StoreRetvalInst<Float16Regs, ".b16">;
2166def StoreRetvalF16x2  : StoreRetvalInst<Float16x2Regs, ".b32">;
2167def StoreRetvalV2F64  : StoreRetvalV2Inst<Float64Regs, ".f64">;
2168def StoreRetvalV2F32  : StoreRetvalV2Inst<Float32Regs, ".f32">;
2169def StoreRetvalV2F16  : StoreRetvalV2Inst<Float16Regs, ".b16">;
2170def StoreRetvalV2F16x2: StoreRetvalV2Inst<Float16x2Regs, ".b32">;
2171def StoreRetvalV4F32  : StoreRetvalV4Inst<Float32Regs, ".f32">;
2172def StoreRetvalV4F16  : StoreRetvalV4Inst<Float16Regs, ".b16">;
2173def StoreRetvalV4F16x2: StoreRetvalV4Inst<Float16x2Regs, ".b32">;
2174
2175def CallArgBeginInst : NVPTXInst<(outs), (ins), "(", [(CallArgBegin)]>;
2176def CallArgEndInst1  : NVPTXInst<(outs), (ins), ");", [(CallArgEnd (i32 1))]>;
2177def CallArgEndInst0  : NVPTXInst<(outs), (ins), ")", [(CallArgEnd (i32 0))]>;
2178def RETURNInst       : NVPTXInst<(outs), (ins), "ret;", [(RETURNNode)]>;
2179
2180class CallArgInst<NVPTXRegClass regclass> :
2181  NVPTXInst<(outs), (ins regclass:$a), "$a, ",
2182            [(CallArg (i32 0), regclass:$a)]>;
2183
2184class LastCallArgInst<NVPTXRegClass regclass> :
2185  NVPTXInst<(outs), (ins regclass:$a), "$a",
2186            [(LastCallArg (i32 0), regclass:$a)]>;
2187
2188def CallArgI64     : CallArgInst<Int64Regs>;
2189def CallArgI32     : CallArgInst<Int32Regs>;
2190def CallArgI16     : CallArgInst<Int16Regs>;
2191def CallArgF64     : CallArgInst<Float64Regs>;
2192def CallArgF32     : CallArgInst<Float32Regs>;
2193
2194def LastCallArgI64 : LastCallArgInst<Int64Regs>;
2195def LastCallArgI32 : LastCallArgInst<Int32Regs>;
2196def LastCallArgI16 : LastCallArgInst<Int16Regs>;
2197def LastCallArgF64 : LastCallArgInst<Float64Regs>;
2198def LastCallArgF32 : LastCallArgInst<Float32Regs>;
2199
2200def CallArgI32imm : NVPTXInst<(outs), (ins i32imm:$a), "$a, ",
2201                              [(CallArg (i32 0), (i32 imm:$a))]>;
2202def LastCallArgI32imm : NVPTXInst<(outs), (ins i32imm:$a), "$a",
2203                                  [(LastCallArg (i32 0), (i32 imm:$a))]>;
2204
2205def CallArgParam : NVPTXInst<(outs), (ins i32imm:$a), "param$a, ",
2206                             [(CallArg (i32 1), (i32 imm:$a))]>;
2207def LastCallArgParam : NVPTXInst<(outs), (ins i32imm:$a), "param$a",
2208                                 [(LastCallArg (i32 1), (i32 imm:$a))]>;
2209
2210def CallVoidInst :      NVPTXInst<(outs), (ins imem:$addr), "$addr, ",
2211                                  [(CallVoid (Wrapper tglobaladdr:$addr))]>;
2212def CallVoidInstReg :   NVPTXInst<(outs), (ins Int32Regs:$addr), "$addr, ",
2213                                  [(CallVoid Int32Regs:$addr)]>;
2214def CallVoidInstReg64 : NVPTXInst<(outs), (ins Int64Regs:$addr), "$addr, ",
2215                                  [(CallVoid Int64Regs:$addr)]>;
2216def PrototypeInst :     NVPTXInst<(outs), (ins i32imm:$val), ", prototype_$val;",
2217                                  [(Prototype (i32 imm:$val))]>;
2218
2219def DeclareRetMemInst :
2220  NVPTXInst<(outs), (ins i32imm:$align, i32imm:$size, i32imm:$num),
2221            ".param .align $align .b8 retval$num[$size];",
2222            [(DeclareRetParam (i32 imm:$align), (i32 imm:$size), (i32 imm:$num))]>;
2223def DeclareRetScalarInst :
2224  NVPTXInst<(outs), (ins i32imm:$size, i32imm:$num),
2225            ".param .b$size retval$num;",
2226            [(DeclareRet (i32 1), (i32 imm:$size), (i32 imm:$num))]>;
2227def DeclareRetRegInst :
2228  NVPTXInst<(outs), (ins i32imm:$size, i32imm:$num),
2229            ".reg .b$size retval$num;",
2230            [(DeclareRet (i32 2), (i32 imm:$size), (i32 imm:$num))]>;
2231
2232def DeclareParamInst :
2233  NVPTXInst<(outs), (ins i32imm:$align, i32imm:$a, i32imm:$size),
2234            ".param .align $align .b8 param$a[$size];",
2235            [(DeclareParam (i32 imm:$align), (i32 imm:$a), (i32 imm:$size))]>;
2236def DeclareScalarParamInst :
2237  NVPTXInst<(outs), (ins i32imm:$a, i32imm:$size),
2238            ".param .b$size param$a;",
2239            [(DeclareScalarParam (i32 imm:$a), (i32 imm:$size), (i32 0))]>;
2240def DeclareScalarRegInst :
2241  NVPTXInst<(outs), (ins i32imm:$a, i32imm:$size),
2242            ".reg .b$size param$a;",
2243            [(DeclareScalarParam (i32 imm:$a), (i32 imm:$size), (i32 1))]>;
2244
2245class MoveParamInst<NVPTXRegClass regclass, string asmstr> :
2246  NVPTXInst<(outs regclass:$dst), (ins regclass:$src),
2247            !strconcat("mov", asmstr, " \t$dst, $src;"),
2248            [(set regclass:$dst, (MoveParam regclass:$src))]>;
2249
2250def MoveParamI64 : MoveParamInst<Int64Regs, ".b64">;
2251def MoveParamI32 : MoveParamInst<Int32Regs, ".b32">;
2252def MoveParamI16 :
2253  NVPTXInst<(outs Int16Regs:$dst), (ins Int16Regs:$src),
2254            "cvt.u16.u32 \t$dst, $src;",
2255            [(set Int16Regs:$dst, (MoveParam Int16Regs:$src))]>;
2256def MoveParamF64 : MoveParamInst<Float64Regs, ".f64">;
2257def MoveParamF32 : MoveParamInst<Float32Regs, ".f32">;
2258def MoveParamF16 : MoveParamInst<Float16Regs, ".f16">;
2259
2260class PseudoUseParamInst<NVPTXRegClass regclass> :
2261  NVPTXInst<(outs), (ins regclass:$src),
2262            "// Pseudo use of $src",
2263            [(PseudoUseParam regclass:$src)]>;
2264
2265def PseudoUseParamI64 : PseudoUseParamInst<Int64Regs>;
2266def PseudoUseParamI32 : PseudoUseParamInst<Int32Regs>;
2267def PseudoUseParamI16 : PseudoUseParamInst<Int16Regs>;
2268def PseudoUseParamF64 : PseudoUseParamInst<Float64Regs>;
2269def PseudoUseParamF32 : PseudoUseParamInst<Float32Regs>;
2270
2271class ProxyRegInst<string SzStr, NVPTXRegClass regclass> :
2272  NVPTXInst<(outs regclass:$dst), (ins regclass:$src),
2273            !strconcat("mov.", SzStr, " \t$dst, $src;"),
2274            [(set regclass:$dst, (ProxyReg regclass:$src))]>;
2275
2276let isCodeGenOnly=1, isPseudo=1 in {
2277  def ProxyRegI1    : ProxyRegInst<"pred", Int1Regs>;
2278  def ProxyRegI16   : ProxyRegInst<"b16",  Int16Regs>;
2279  def ProxyRegI32   : ProxyRegInst<"b32",  Int32Regs>;
2280  def ProxyRegI64   : ProxyRegInst<"b64",  Int64Regs>;
2281  def ProxyRegF16   : ProxyRegInst<"b16",  Float16Regs>;
2282  def ProxyRegF32   : ProxyRegInst<"f32",  Float32Regs>;
2283  def ProxyRegF64   : ProxyRegInst<"f64",  Float64Regs>;
2284  def ProxyRegF16x2 : ProxyRegInst<"b32",  Float16x2Regs>;
2285}
2286
2287//
2288// Load / Store Handling
2289//
2290multiclass LD<NVPTXRegClass regclass> {
2291  def _avar : NVPTXInst<
2292    (outs regclass:$dst),
2293    (ins LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
2294         i32imm:$fromWidth, imem:$addr),
2295    "ld${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
2296    "\t$dst, [$addr];", []>;
2297  def _areg : NVPTXInst<
2298    (outs regclass:$dst),
2299    (ins LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
2300         i32imm:$fromWidth, Int32Regs:$addr),
2301    "ld${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
2302    "\t$dst, [$addr];", []>;
2303  def _areg_64 : NVPTXInst<
2304    (outs regclass:$dst),
2305    (ins LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
2306         i32imm:$fromWidth, Int64Regs:$addr),
2307    "ld${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
2308    "\t$dst, [$addr];", []>;
2309  def _ari : NVPTXInst<
2310    (outs regclass:$dst),
2311    (ins LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
2312         i32imm:$fromWidth, Int32Regs:$addr, i32imm:$offset),
2313    "ld${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
2314    "\t$dst, [$addr+$offset];", []>;
2315  def _ari_64 : NVPTXInst<
2316    (outs regclass:$dst),
2317    (ins LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec,
2318         LdStCode:$Sign, i32imm:$fromWidth, Int64Regs:$addr, i32imm:$offset),
2319    "ld${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
2320    "\t$dst, [$addr+$offset];", []>;
2321  def _asi : NVPTXInst<
2322    (outs regclass:$dst),
2323    (ins LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec,
2324         LdStCode:$Sign, i32imm:$fromWidth, imem:$addr, i32imm:$offset),
2325    "ld${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
2326    "\t$dst, [$addr+$offset];", []>;
2327}
2328
2329let mayLoad=1, hasSideEffects=0 in {
2330  defm LD_i8  : LD<Int16Regs>;
2331  defm LD_i16 : LD<Int16Regs>;
2332  defm LD_i32 : LD<Int32Regs>;
2333  defm LD_i64 : LD<Int64Regs>;
2334  defm LD_f16 : LD<Float16Regs>;
2335  defm LD_f16x2 : LD<Float16x2Regs>;
2336  defm LD_f32 : LD<Float32Regs>;
2337  defm LD_f64 : LD<Float64Regs>;
2338}
2339
2340multiclass ST<NVPTXRegClass regclass> {
2341  def _avar : NVPTXInst<
2342    (outs),
2343    (ins regclass:$src, LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec,
2344         LdStCode:$Sign, i32imm:$toWidth, imem:$addr),
2345    "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$toWidth"
2346    " \t[$addr], $src;", []>;
2347  def _areg : NVPTXInst<
2348    (outs),
2349    (ins regclass:$src, LdStCode:$isVol, LdStCode:$addsp,
2350         LdStCode:$Vec, LdStCode:$Sign, i32imm:$toWidth, Int32Regs:$addr),
2351    "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$toWidth"
2352    " \t[$addr], $src;", []>;
2353  def _areg_64 : NVPTXInst<
2354    (outs),
2355    (ins regclass:$src, LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec,
2356         LdStCode:$Sign, i32imm:$toWidth, Int64Regs:$addr),
2357    "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$toWidth"
2358    " \t[$addr], $src;", []>;
2359  def _ari : NVPTXInst<
2360    (outs),
2361    (ins regclass:$src, LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec,
2362         LdStCode:$Sign, i32imm:$toWidth, Int32Regs:$addr, i32imm:$offset),
2363    "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$toWidth"
2364    " \t[$addr+$offset], $src;", []>;
2365  def _ari_64 : NVPTXInst<
2366    (outs),
2367    (ins regclass:$src, LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec,
2368         LdStCode:$Sign, i32imm:$toWidth, Int64Regs:$addr, i32imm:$offset),
2369    "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$toWidth"
2370    " \t[$addr+$offset], $src;", []>;
2371  def _asi : NVPTXInst<
2372    (outs),
2373    (ins regclass:$src, LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec,
2374         LdStCode:$Sign, i32imm:$toWidth, imem:$addr, i32imm:$offset),
2375    "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$toWidth"
2376    " \t[$addr+$offset], $src;", []>;
2377}
2378
2379let mayStore=1, hasSideEffects=0 in {
2380  defm ST_i8  : ST<Int16Regs>;
2381  defm ST_i16 : ST<Int16Regs>;
2382  defm ST_i32 : ST<Int32Regs>;
2383  defm ST_i64 : ST<Int64Regs>;
2384  defm ST_f16 : ST<Float16Regs>;
2385  defm ST_f16x2 : ST<Float16x2Regs>;
2386  defm ST_f32 : ST<Float32Regs>;
2387  defm ST_f64 : ST<Float64Regs>;
2388}
2389
2390// The following is used only in and after vector elementizations.  Vector
2391// elementization happens at the machine instruction level, so the following
2392// instructions never appear in the DAG.
2393multiclass LD_VEC<NVPTXRegClass regclass> {
2394  def _v2_avar : NVPTXInst<
2395    (outs regclass:$dst1, regclass:$dst2),
2396    (ins LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
2397         i32imm:$fromWidth, imem:$addr),
2398    "ld${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
2399    "\t{{$dst1, $dst2}}, [$addr];", []>;
2400  def _v2_areg : NVPTXInst<
2401    (outs regclass:$dst1, regclass:$dst2),
2402    (ins LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
2403         i32imm:$fromWidth, Int32Regs:$addr),
2404    "ld${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
2405    "\t{{$dst1, $dst2}}, [$addr];", []>;
2406  def _v2_areg_64 : NVPTXInst<
2407    (outs regclass:$dst1, regclass:$dst2),
2408    (ins LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
2409         i32imm:$fromWidth, Int64Regs:$addr),
2410    "ld${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
2411    "\t{{$dst1, $dst2}}, [$addr];", []>;
2412  def _v2_ari : NVPTXInst<
2413    (outs regclass:$dst1, regclass:$dst2),
2414    (ins LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
2415         i32imm:$fromWidth, Int32Regs:$addr, i32imm:$offset),
2416    "ld${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
2417    "\t{{$dst1, $dst2}}, [$addr+$offset];", []>;
2418  def _v2_ari_64 : NVPTXInst<
2419    (outs regclass:$dst1, regclass:$dst2),
2420    (ins LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
2421         i32imm:$fromWidth, Int64Regs:$addr, i32imm:$offset),
2422    "ld${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
2423    "\t{{$dst1, $dst2}}, [$addr+$offset];", []>;
2424  def _v2_asi : NVPTXInst<
2425    (outs regclass:$dst1, regclass:$dst2),
2426    (ins LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
2427         i32imm:$fromWidth, imem:$addr, i32imm:$offset),
2428    "ld${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
2429    "\t{{$dst1, $dst2}}, [$addr+$offset];", []>;
2430  def _v4_avar : NVPTXInst<
2431    (outs regclass:$dst1, regclass:$dst2, regclass:$dst3, regclass:$dst4),
2432    (ins LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
2433         i32imm:$fromWidth, imem:$addr),
2434    "ld${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
2435    "\t{{$dst1, $dst2, $dst3, $dst4}}, [$addr];", []>;
2436  def _v4_areg : NVPTXInst<
2437    (outs regclass:$dst1, regclass:$dst2, regclass:$dst3, regclass:$dst4),
2438    (ins LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
2439         i32imm:$fromWidth, Int32Regs:$addr),
2440    "ld${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
2441    "\t{{$dst1, $dst2, $dst3, $dst4}}, [$addr];", []>;
2442  def _v4_areg_64 : NVPTXInst<
2443    (outs regclass:$dst1, regclass:$dst2, regclass:$dst3, regclass:$dst4),
2444    (ins LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
2445         i32imm:$fromWidth, Int64Regs:$addr),
2446    "ld${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
2447    "\t{{$dst1, $dst2, $dst3, $dst4}}, [$addr];", []>;
2448  def _v4_ari : NVPTXInst<
2449    (outs regclass:$dst1, regclass:$dst2, regclass:$dst3, regclass:$dst4),
2450    (ins LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
2451         i32imm:$fromWidth, Int32Regs:$addr, i32imm:$offset),
2452    "ld${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
2453    "\t{{$dst1, $dst2, $dst3, $dst4}}, [$addr+$offset];", []>;
2454  def _v4_ari_64 : NVPTXInst<
2455    (outs regclass:$dst1, regclass:$dst2, regclass:$dst3, regclass:$dst4),
2456    (ins LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
2457         i32imm:$fromWidth, Int64Regs:$addr, i32imm:$offset),
2458    "ld${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
2459    "\t{{$dst1, $dst2, $dst3, $dst4}}, [$addr+$offset];", []>;
2460  def _v4_asi : NVPTXInst<
2461    (outs regclass:$dst1, regclass:$dst2, regclass:$dst3, regclass:$dst4),
2462    (ins LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
2463         i32imm:$fromWidth, imem:$addr, i32imm:$offset),
2464    "ld${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
2465    "\t{{$dst1, $dst2, $dst3, $dst4}}, [$addr+$offset];", []>;
2466}
2467let mayLoad=1, hasSideEffects=0 in {
2468  defm LDV_i8  : LD_VEC<Int16Regs>;
2469  defm LDV_i16 : LD_VEC<Int16Regs>;
2470  defm LDV_i32 : LD_VEC<Int32Regs>;
2471  defm LDV_i64 : LD_VEC<Int64Regs>;
2472  defm LDV_f16 : LD_VEC<Float16Regs>;
2473  defm LDV_f16x2 : LD_VEC<Float16x2Regs>;
2474  defm LDV_f32 : LD_VEC<Float32Regs>;
2475  defm LDV_f64 : LD_VEC<Float64Regs>;
2476}
2477
2478multiclass ST_VEC<NVPTXRegClass regclass> {
2479  def _v2_avar : NVPTXInst<
2480    (outs),
2481    (ins regclass:$src1, regclass:$src2, LdStCode:$isVol, LdStCode:$addsp,
2482         LdStCode:$Vec, LdStCode:$Sign, i32imm:$fromWidth, imem:$addr),
2483    "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
2484    "\t[$addr], {{$src1, $src2}};", []>;
2485  def _v2_areg : NVPTXInst<
2486    (outs),
2487    (ins regclass:$src1, regclass:$src2, LdStCode:$isVol, LdStCode:$addsp,
2488         LdStCode:$Vec, LdStCode:$Sign, i32imm:$fromWidth, Int32Regs:$addr),
2489    "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
2490    "\t[$addr], {{$src1, $src2}};", []>;
2491  def _v2_areg_64 : NVPTXInst<
2492    (outs),
2493    (ins regclass:$src1, regclass:$src2, LdStCode:$isVol, LdStCode:$addsp,
2494         LdStCode:$Vec, LdStCode:$Sign, i32imm:$fromWidth, Int64Regs:$addr),
2495    "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
2496    "\t[$addr], {{$src1, $src2}};", []>;
2497  def _v2_ari : NVPTXInst<
2498    (outs),
2499    (ins regclass:$src1, regclass:$src2, LdStCode:$isVol, LdStCode:$addsp,
2500         LdStCode:$Vec, LdStCode:$Sign, i32imm:$fromWidth, Int32Regs:$addr,
2501         i32imm:$offset),
2502    "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
2503    "\t[$addr+$offset], {{$src1, $src2}};", []>;
2504  def _v2_ari_64 : NVPTXInst<
2505    (outs),
2506    (ins regclass:$src1, regclass:$src2, LdStCode:$isVol, LdStCode:$addsp,
2507         LdStCode:$Vec, LdStCode:$Sign, i32imm:$fromWidth, Int64Regs:$addr,
2508         i32imm:$offset),
2509    "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
2510    "\t[$addr+$offset], {{$src1, $src2}};", []>;
2511  def _v2_asi : NVPTXInst<
2512    (outs),
2513    (ins regclass:$src1, regclass:$src2, LdStCode:$isVol, LdStCode:$addsp,
2514         LdStCode:$Vec, LdStCode:$Sign, i32imm:$fromWidth, imem:$addr,
2515         i32imm:$offset),
2516    "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
2517    "\t[$addr+$offset], {{$src1, $src2}};", []>;
2518  def _v4_avar : NVPTXInst<
2519    (outs),
2520    (ins regclass:$src1, regclass:$src2, regclass:$src3, regclass:$src4,
2521         LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
2522         i32imm:$fromWidth, imem:$addr),
2523    "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
2524    "\t[$addr], {{$src1, $src2, $src3, $src4}};", []>;
2525  def _v4_areg : NVPTXInst<
2526    (outs),
2527    (ins regclass:$src1, regclass:$src2, regclass:$src3, regclass:$src4,
2528         LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
2529         i32imm:$fromWidth, Int32Regs:$addr),
2530    "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
2531    "\t[$addr], {{$src1, $src2, $src3, $src4}};", []>;
2532  def _v4_areg_64 : NVPTXInst<
2533    (outs),
2534    (ins regclass:$src1, regclass:$src2, regclass:$src3, regclass:$src4,
2535         LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
2536         i32imm:$fromWidth, Int64Regs:$addr),
2537    "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
2538    "\t[$addr], {{$src1, $src2, $src3, $src4}};", []>;
2539  def _v4_ari : NVPTXInst<
2540    (outs),
2541    (ins regclass:$src1, regclass:$src2, regclass:$src3, regclass:$src4,
2542         LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
2543         i32imm:$fromWidth, Int32Regs:$addr, i32imm:$offset),
2544    "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
2545    "\t[$addr+$offset], {{$src1, $src2, $src3, $src4}};", []>;
2546  def _v4_ari_64 : NVPTXInst<
2547    (outs),
2548    (ins regclass:$src1, regclass:$src2, regclass:$src3, regclass:$src4,
2549         LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
2550         i32imm:$fromWidth, Int64Regs:$addr, i32imm:$offset),
2551    "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
2552    "\t[$addr+$offset], {{$src1, $src2, $src3, $src4}};", []>;
2553  def _v4_asi : NVPTXInst<
2554    (outs),
2555    (ins regclass:$src1, regclass:$src2, regclass:$src3, regclass:$src4,
2556         LdStCode:$isVol, LdStCode:$addsp, LdStCode:$Vec, LdStCode:$Sign,
2557         i32imm:$fromWidth, imem:$addr, i32imm:$offset),
2558    "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}"
2559    "$fromWidth \t[$addr+$offset], {{$src1, $src2, $src3, $src4}};", []>;
2560}
2561
2562let mayStore=1, hasSideEffects=0 in {
2563  defm STV_i8  : ST_VEC<Int16Regs>;
2564  defm STV_i16 : ST_VEC<Int16Regs>;
2565  defm STV_i32 : ST_VEC<Int32Regs>;
2566  defm STV_i64 : ST_VEC<Int64Regs>;
2567  defm STV_f16 : ST_VEC<Float16Regs>;
2568  defm STV_f16x2 : ST_VEC<Float16x2Regs>;
2569  defm STV_f32 : ST_VEC<Float32Regs>;
2570  defm STV_f64 : ST_VEC<Float64Regs>;
2571}
2572
2573//---- Conversion ----
2574
2575class F_BITCONVERT<string SzStr, NVPTXRegClass regclassIn,
2576  NVPTXRegClass regclassOut> :
2577           NVPTXInst<(outs regclassOut:$d), (ins regclassIn:$a),
2578           !strconcat("mov.b", SzStr, " \t$d, $a;"),
2579     [(set regclassOut:$d, (bitconvert regclassIn:$a))]>;
2580
2581def BITCONVERT_16_I2F : F_BITCONVERT<"16", Int16Regs, Float16Regs>;
2582def BITCONVERT_16_F2I : F_BITCONVERT<"16", Float16Regs, Int16Regs>;
2583def BITCONVERT_32_I2F : F_BITCONVERT<"32", Int32Regs, Float32Regs>;
2584def BITCONVERT_32_F2I : F_BITCONVERT<"32", Float32Regs, Int32Regs>;
2585def BITCONVERT_64_I2F : F_BITCONVERT<"64", Int64Regs, Float64Regs>;
2586def BITCONVERT_64_F2I : F_BITCONVERT<"64", Float64Regs, Int64Regs>;
2587def BITCONVERT_32_I2F16x2 : F_BITCONVERT<"32", Int32Regs, Float16x2Regs>;
2588def BITCONVERT_32_F16x22I : F_BITCONVERT<"32", Float16x2Regs, Int32Regs>;
2589
2590// NOTE: pred->fp are currently sub-optimal due to an issue in TableGen where
2591// we cannot specify floating-point literals in isel patterns.  Therefore, we
2592// use an integer selp to select either 1 or 0 and then cvt to floating-point.
2593
2594// sint -> f16
2595def : Pat<(f16 (sint_to_fp Int1Regs:$a)),
2596          (CVT_f16_s32 (SELP_u32ii 1, 0, Int1Regs:$a), CvtRN)>;
2597def : Pat<(f16 (sint_to_fp Int16Regs:$a)),
2598          (CVT_f16_s16 Int16Regs:$a, CvtRN)>;
2599def : Pat<(f16 (sint_to_fp Int32Regs:$a)),
2600          (CVT_f16_s32 Int32Regs:$a, CvtRN)>;
2601def : Pat<(f16 (sint_to_fp Int64Regs:$a)),
2602          (CVT_f16_s64 Int64Regs:$a, CvtRN)>;
2603
2604// uint -> f16
2605def : Pat<(f16 (uint_to_fp Int1Regs:$a)),
2606          (CVT_f16_u32 (SELP_u32ii 1, 0, Int1Regs:$a), CvtRN)>;
2607def : Pat<(f16 (uint_to_fp Int16Regs:$a)),
2608          (CVT_f16_u16 Int16Regs:$a, CvtRN)>;
2609def : Pat<(f16 (uint_to_fp Int32Regs:$a)),
2610          (CVT_f16_u32 Int32Regs:$a, CvtRN)>;
2611def : Pat<(f16 (uint_to_fp Int64Regs:$a)),
2612          (CVT_f16_u64 Int64Regs:$a, CvtRN)>;
2613
2614// sint -> f32
2615def : Pat<(f32 (sint_to_fp Int1Regs:$a)),
2616          (CVT_f32_s32 (SELP_u32ii 1, 0, Int1Regs:$a), CvtRN)>;
2617def : Pat<(f32 (sint_to_fp Int16Regs:$a)),
2618          (CVT_f32_s16 Int16Regs:$a, CvtRN)>;
2619def : Pat<(f32 (sint_to_fp Int32Regs:$a)),
2620          (CVT_f32_s32 Int32Regs:$a, CvtRN)>;
2621def : Pat<(f32 (sint_to_fp Int64Regs:$a)),
2622          (CVT_f32_s64 Int64Regs:$a, CvtRN)>;
2623
2624// uint -> f32
2625def : Pat<(f32 (uint_to_fp Int1Regs:$a)),
2626          (CVT_f32_u32 (SELP_u32ii 1, 0, Int1Regs:$a), CvtRN)>;
2627def : Pat<(f32 (uint_to_fp Int16Regs:$a)),
2628          (CVT_f32_u16 Int16Regs:$a, CvtRN)>;
2629def : Pat<(f32 (uint_to_fp Int32Regs:$a)),
2630          (CVT_f32_u32 Int32Regs:$a, CvtRN)>;
2631def : Pat<(f32 (uint_to_fp Int64Regs:$a)),
2632          (CVT_f32_u64 Int64Regs:$a, CvtRN)>;
2633
2634// sint -> f64
2635def : Pat<(f64 (sint_to_fp Int1Regs:$a)),
2636          (CVT_f64_s32 (SELP_u32ii 1, 0, Int1Regs:$a), CvtRN)>;
2637def : Pat<(f64 (sint_to_fp Int16Regs:$a)),
2638          (CVT_f64_s16 Int16Regs:$a, CvtRN)>;
2639def : Pat<(f64 (sint_to_fp Int32Regs:$a)),
2640          (CVT_f64_s32 Int32Regs:$a, CvtRN)>;
2641def : Pat<(f64 (sint_to_fp Int64Regs:$a)),
2642          (CVT_f64_s64 Int64Regs:$a, CvtRN)>;
2643
2644// uint -> f64
2645def : Pat<(f64 (uint_to_fp Int1Regs:$a)),
2646          (CVT_f64_u32 (SELP_u32ii 1, 0, Int1Regs:$a), CvtRN)>;
2647def : Pat<(f64 (uint_to_fp Int16Regs:$a)),
2648          (CVT_f64_u16 Int16Regs:$a, CvtRN)>;
2649def : Pat<(f64 (uint_to_fp Int32Regs:$a)),
2650          (CVT_f64_u32 Int32Regs:$a, CvtRN)>;
2651def : Pat<(f64 (uint_to_fp Int64Regs:$a)),
2652          (CVT_f64_u64 Int64Regs:$a, CvtRN)>;
2653
2654
2655// f16 -> sint
2656def : Pat<(i1 (fp_to_sint Float16Regs:$a)),
2657          (SETP_b16ri (BITCONVERT_16_F2I Float16Regs:$a), 0, CmpEQ)>;
2658def : Pat<(i16 (fp_to_sint Float16Regs:$a)),
2659          (CVT_s16_f16 Float16Regs:$a, CvtRZI)>;
2660def : Pat<(i32 (fp_to_sint Float16Regs:$a)),
2661          (CVT_s32_f16 Float16Regs:$a, CvtRZI)>;
2662def : Pat<(i64 (fp_to_sint Float16Regs:$a)),
2663          (CVT_s64_f16 Float16Regs:$a, CvtRZI)>;
2664
2665// f16 -> uint
2666def : Pat<(i1 (fp_to_uint Float16Regs:$a)),
2667          (SETP_b16ri (BITCONVERT_16_F2I Float16Regs:$a), 0, CmpEQ)>;
2668def : Pat<(i16 (fp_to_uint Float16Regs:$a)),
2669          (CVT_u16_f16 Float16Regs:$a, CvtRZI)>;
2670def : Pat<(i32 (fp_to_uint Float16Regs:$a)),
2671          (CVT_u32_f16 Float16Regs:$a, CvtRZI)>;
2672def : Pat<(i64 (fp_to_uint Float16Regs:$a)),
2673          (CVT_u64_f16 Float16Regs:$a, CvtRZI)>;
2674
2675// f32 -> sint
2676def : Pat<(i1 (fp_to_sint Float32Regs:$a)),
2677          (SETP_b32ri (BITCONVERT_32_F2I Float32Regs:$a), 0, CmpEQ)>;
2678def : Pat<(i16 (fp_to_sint Float32Regs:$a)),
2679          (CVT_s16_f32 Float32Regs:$a, CvtRZI_FTZ)>, Requires<[doF32FTZ]>;
2680def : Pat<(i16 (fp_to_sint Float32Regs:$a)),
2681          (CVT_s16_f32 Float32Regs:$a, CvtRZI)>;
2682def : Pat<(i32 (fp_to_sint Float32Regs:$a)),
2683          (CVT_s32_f32 Float32Regs:$a, CvtRZI_FTZ)>, Requires<[doF32FTZ]>;
2684def : Pat<(i32 (fp_to_sint Float32Regs:$a)),
2685          (CVT_s32_f32 Float32Regs:$a, CvtRZI)>;
2686def : Pat<(i64 (fp_to_sint Float32Regs:$a)),
2687          (CVT_s64_f32 Float32Regs:$a, CvtRZI_FTZ)>, Requires<[doF32FTZ]>;
2688def : Pat<(i64 (fp_to_sint Float32Regs:$a)),
2689          (CVT_s64_f32 Float32Regs:$a, CvtRZI)>;
2690
2691// f32 -> uint
2692def : Pat<(i1 (fp_to_uint Float32Regs:$a)),
2693          (SETP_b32ri (BITCONVERT_32_F2I Float32Regs:$a), 0, CmpEQ)>;
2694def : Pat<(i16 (fp_to_uint Float32Regs:$a)),
2695          (CVT_u16_f32 Float32Regs:$a, CvtRZI_FTZ)>, Requires<[doF32FTZ]>;
2696def : Pat<(i16 (fp_to_uint Float32Regs:$a)),
2697          (CVT_u16_f32 Float32Regs:$a, CvtRZI)>;
2698def : Pat<(i32 (fp_to_uint Float32Regs:$a)),
2699          (CVT_u32_f32 Float32Regs:$a, CvtRZI_FTZ)>, Requires<[doF32FTZ]>;
2700def : Pat<(i32 (fp_to_uint Float32Regs:$a)),
2701          (CVT_u32_f32 Float32Regs:$a, CvtRZI)>;
2702def : Pat<(i64 (fp_to_uint Float32Regs:$a)),
2703          (CVT_u64_f32 Float32Regs:$a, CvtRZI_FTZ)>, Requires<[doF32FTZ]>;
2704def : Pat<(i64 (fp_to_uint Float32Regs:$a)),
2705          (CVT_u64_f32 Float32Regs:$a, CvtRZI)>;
2706
2707// f64 -> sint
2708def : Pat<(i1 (fp_to_sint Float64Regs:$a)),
2709          (SETP_b64ri (BITCONVERT_64_F2I Float64Regs:$a), 0, CmpEQ)>;
2710def : Pat<(i16 (fp_to_sint Float64Regs:$a)),
2711          (CVT_s16_f64 Float64Regs:$a, CvtRZI)>;
2712def : Pat<(i32 (fp_to_sint Float64Regs:$a)),
2713          (CVT_s32_f64 Float64Regs:$a, CvtRZI)>;
2714def : Pat<(i64 (fp_to_sint Float64Regs:$a)),
2715          (CVT_s64_f64 Float64Regs:$a, CvtRZI)>;
2716
2717// f64 -> uint
2718def : Pat<(i1 (fp_to_uint Float64Regs:$a)),
2719          (SETP_b64ri (BITCONVERT_64_F2I Float64Regs:$a), 0, CmpEQ)>;
2720def : Pat<(i16 (fp_to_uint Float64Regs:$a)),
2721          (CVT_u16_f64 Float64Regs:$a, CvtRZI)>;
2722def : Pat<(i32 (fp_to_uint Float64Regs:$a)),
2723          (CVT_u32_f64 Float64Regs:$a, CvtRZI)>;
2724def : Pat<(i64 (fp_to_uint Float64Regs:$a)),
2725          (CVT_u64_f64 Float64Regs:$a, CvtRZI)>;
2726
2727// sext i1
2728def : Pat<(i16 (sext Int1Regs:$a)),
2729          (SELP_s16ii -1, 0, Int1Regs:$a)>;
2730def : Pat<(i32 (sext Int1Regs:$a)),
2731          (SELP_s32ii -1, 0, Int1Regs:$a)>;
2732def : Pat<(i64 (sext Int1Regs:$a)),
2733          (SELP_s64ii -1, 0, Int1Regs:$a)>;
2734
2735// zext i1
2736def : Pat<(i16 (zext Int1Regs:$a)),
2737          (SELP_u16ii 1, 0, Int1Regs:$a)>;
2738def : Pat<(i32 (zext Int1Regs:$a)),
2739          (SELP_u32ii 1, 0, Int1Regs:$a)>;
2740def : Pat<(i64 (zext Int1Regs:$a)),
2741          (SELP_u64ii 1, 0, Int1Regs:$a)>;
2742
2743// anyext i1
2744def : Pat<(i16 (anyext Int1Regs:$a)),
2745          (SELP_u16ii -1, 0, Int1Regs:$a)>;
2746def : Pat<(i32 (anyext Int1Regs:$a)),
2747          (SELP_u32ii -1, 0, Int1Regs:$a)>;
2748def : Pat<(i64 (anyext Int1Regs:$a)),
2749          (SELP_u64ii -1, 0, Int1Regs:$a)>;
2750
2751// sext i16
2752def : Pat<(i32 (sext Int16Regs:$a)),
2753          (CVT_s32_s16 Int16Regs:$a, CvtNONE)>;
2754def : Pat<(i64 (sext Int16Regs:$a)),
2755          (CVT_s64_s16 Int16Regs:$a, CvtNONE)>;
2756
2757// zext i16
2758def : Pat<(i32 (zext Int16Regs:$a)),
2759          (CVT_u32_u16 Int16Regs:$a, CvtNONE)>;
2760def : Pat<(i64 (zext Int16Regs:$a)),
2761          (CVT_u64_u16 Int16Regs:$a, CvtNONE)>;
2762
2763// anyext i16
2764def : Pat<(i32 (anyext Int16Regs:$a)),
2765          (CVT_u32_u16 Int16Regs:$a, CvtNONE)>;
2766def : Pat<(i64 (anyext Int16Regs:$a)),
2767          (CVT_u64_u16 Int16Regs:$a, CvtNONE)>;
2768
2769// sext i32
2770def : Pat<(i64 (sext Int32Regs:$a)),
2771          (CVT_s64_s32 Int32Regs:$a, CvtNONE)>;
2772
2773// zext i32
2774def : Pat<(i64 (zext Int32Regs:$a)),
2775          (CVT_u64_u32 Int32Regs:$a, CvtNONE)>;
2776
2777// anyext i32
2778def : Pat<(i64 (anyext Int32Regs:$a)),
2779          (CVT_u64_u32 Int32Regs:$a, CvtNONE)>;
2780
2781
2782// truncate i64
2783def : Pat<(i32 (trunc Int64Regs:$a)),
2784          (CVT_u32_u64 Int64Regs:$a, CvtNONE)>;
2785def : Pat<(i16 (trunc Int64Regs:$a)),
2786          (CVT_u16_u64 Int64Regs:$a, CvtNONE)>;
2787def : Pat<(i1 (trunc Int64Regs:$a)),
2788          (SETP_b64ri (ANDb64ri Int64Regs:$a, 1), 1, CmpEQ)>;
2789
2790// truncate i32
2791def : Pat<(i16 (trunc Int32Regs:$a)),
2792          (CVT_u16_u32 Int32Regs:$a, CvtNONE)>;
2793def : Pat<(i1 (trunc Int32Regs:$a)),
2794          (SETP_b32ri (ANDb32ri Int32Regs:$a, 1), 1, CmpEQ)>;
2795
2796// truncate i16
2797def : Pat<(i1 (trunc Int16Regs:$a)),
2798          (SETP_b16ri (ANDb16ri Int16Regs:$a, 1), 1, CmpEQ)>;
2799
2800// sext_inreg
2801def : Pat<(sext_inreg Int16Regs:$a, i8), (CVT_INREG_s16_s8 Int16Regs:$a)>;
2802def : Pat<(sext_inreg Int32Regs:$a, i8), (CVT_INREG_s32_s8 Int32Regs:$a)>;
2803def : Pat<(sext_inreg Int32Regs:$a, i16), (CVT_INREG_s32_s16 Int32Regs:$a)>;
2804def : Pat<(sext_inreg Int64Regs:$a, i8), (CVT_INREG_s64_s8 Int64Regs:$a)>;
2805def : Pat<(sext_inreg Int64Regs:$a, i16), (CVT_INREG_s64_s16 Int64Regs:$a)>;
2806def : Pat<(sext_inreg Int64Regs:$a, i32), (CVT_INREG_s64_s32 Int64Regs:$a)>;
2807
2808
2809// Select instructions with 32-bit predicates
2810def : Pat<(select Int32Regs:$pred, Int16Regs:$a, Int16Regs:$b),
2811          (SELP_b16rr Int16Regs:$a, Int16Regs:$b,
2812          (SETP_b32ri (ANDb32ri Int32Regs:$pred, 1), 1, CmpEQ))>;
2813def : Pat<(select Int32Regs:$pred, Int32Regs:$a, Int32Regs:$b),
2814          (SELP_b32rr Int32Regs:$a, Int32Regs:$b,
2815          (SETP_b32ri (ANDb32ri Int32Regs:$pred, 1), 1, CmpEQ))>;
2816def : Pat<(select Int32Regs:$pred, Int64Regs:$a, Int64Regs:$b),
2817          (SELP_b64rr Int64Regs:$a, Int64Regs:$b,
2818          (SETP_b32ri (ANDb32ri Int32Regs:$pred, 1), 1, CmpEQ))>;
2819def : Pat<(select Int32Regs:$pred, Float16Regs:$a, Float16Regs:$b),
2820          (SELP_f16rr Float16Regs:$a, Float16Regs:$b,
2821          (SETP_b32ri (ANDb32ri Int32Regs:$pred, 1), 1, CmpEQ))>;
2822def : Pat<(select Int32Regs:$pred, Float32Regs:$a, Float32Regs:$b),
2823          (SELP_f32rr Float32Regs:$a, Float32Regs:$b,
2824          (SETP_b32ri (ANDb32ri Int32Regs:$pred, 1), 1, CmpEQ))>;
2825def : Pat<(select Int32Regs:$pred, Float64Regs:$a, Float64Regs:$b),
2826          (SELP_f64rr Float64Regs:$a, Float64Regs:$b,
2827          (SETP_b32ri (ANDb32ri Int32Regs:$pred, 1), 1, CmpEQ))>;
2828
2829
2830let hasSideEffects = false in {
2831  // pack a set of smaller int registers to a larger int register
2832  def V4I16toI64 : NVPTXInst<(outs Int64Regs:$d),
2833                             (ins Int16Regs:$s1, Int16Regs:$s2,
2834                                  Int16Regs:$s3, Int16Regs:$s4),
2835                             "mov.b64 \t$d, {{$s1, $s2, $s3, $s4}};", []>;
2836  def V2I16toI32 : NVPTXInst<(outs Int32Regs:$d),
2837                             (ins Int16Regs:$s1, Int16Regs:$s2),
2838                             "mov.b32 \t$d, {{$s1, $s2}};", []>;
2839  def V2I32toI64 : NVPTXInst<(outs Int64Regs:$d),
2840                             (ins Int32Regs:$s1, Int32Regs:$s2),
2841                             "mov.b64 \t$d, {{$s1, $s2}};", []>;
2842  def V2F32toF64 : NVPTXInst<(outs Float64Regs:$d),
2843                             (ins Float32Regs:$s1, Float32Regs:$s2),
2844                             "mov.b64 \t$d, {{$s1, $s2}};", []>;
2845
2846  // unpack a larger int register to a set of smaller int registers
2847  def I64toV4I16 : NVPTXInst<(outs Int16Regs:$d1, Int16Regs:$d2,
2848                                   Int16Regs:$d3, Int16Regs:$d4),
2849                             (ins Int64Regs:$s),
2850                             "mov.b64 \t{{$d1, $d2, $d3, $d4}}, $s;", []>;
2851  def I32toV2I16 : NVPTXInst<(outs Int16Regs:$d1, Int16Regs:$d2),
2852                             (ins Int32Regs:$s),
2853                             "mov.b32 \t{{$d1, $d2}}, $s;", []>;
2854  def I64toV2I32 : NVPTXInst<(outs Int32Regs:$d1, Int32Regs:$d2),
2855                             (ins Int64Regs:$s),
2856                             "mov.b64 \t{{$d1, $d2}}, $s;", []>;
2857  def F64toV2F32 : NVPTXInst<(outs Float32Regs:$d1, Float32Regs:$d2),
2858                             (ins Float64Regs:$s),
2859                             "mov.b64 \t{{$d1, $d2}}, $s;", []>;
2860
2861}
2862
2863let hasSideEffects = false in {
2864  // Extract element of f16x2 register. PTX does not provide any way
2865  // to access elements of f16x2 vector directly, so we need to
2866  // extract it using a temporary register.
2867  def F16x2toF16_0 : NVPTXInst<(outs Float16Regs:$dst),
2868                               (ins Float16x2Regs:$src),
2869                               "{{ .reg .b16 \t%tmp_hi;\n\t"
2870                               "  mov.b32 \t{$dst, %tmp_hi}, $src; }}",
2871                               [(set Float16Regs:$dst,
2872                                 (extractelt (v2f16 Float16x2Regs:$src), 0))]>;
2873  def F16x2toF16_1 : NVPTXInst<(outs Float16Regs:$dst),
2874                               (ins Float16x2Regs:$src),
2875                               "{{ .reg .b16 \t%tmp_lo;\n\t"
2876                               "  mov.b32 \t{%tmp_lo, $dst}, $src; }}",
2877                               [(set Float16Regs:$dst,
2878                                 (extractelt (v2f16 Float16x2Regs:$src), 1))]>;
2879
2880  // Coalesce two f16 registers into f16x2
2881  def BuildF16x2 : NVPTXInst<(outs Float16x2Regs:$dst),
2882                             (ins Float16Regs:$a, Float16Regs:$b),
2883                             "mov.b32 \t$dst, {{$a, $b}};",
2884                             [(set Float16x2Regs:$dst,
2885                               (build_vector (f16 Float16Regs:$a), (f16 Float16Regs:$b)))]>;
2886
2887  // Directly initializing underlying the b32 register is one less SASS
2888  // instruction than than vector-packing move.
2889  def BuildF16x2i : NVPTXInst<(outs Float16x2Regs:$dst), (ins i32imm:$src),
2890                              "mov.b32 \t$dst, $src;",
2891                              []>;
2892
2893  // Split f16x2 into two f16 registers.
2894  def SplitF16x2  : NVPTXInst<(outs Float16Regs:$lo, Float16Regs:$hi),
2895                              (ins Float16x2Regs:$src),
2896                              "mov.b32 \t{{$lo, $hi}}, $src;",
2897                              []>;
2898  // Split an i32 into two f16
2899  def SplitI32toF16x2  : NVPTXInst<(outs Float16Regs:$lo, Float16Regs:$hi),
2900                                   (ins Int32Regs:$src),
2901                                   "mov.b32 \t{{$lo, $hi}}, $src;",
2902                                   []>;
2903}
2904
2905// Count leading zeros
2906let hasSideEffects = false in {
2907  def CLZr32 : NVPTXInst<(outs Int32Regs:$d), (ins Int32Regs:$a),
2908                         "clz.b32 \t$d, $a;", []>;
2909  def CLZr64 : NVPTXInst<(outs Int32Regs:$d), (ins Int64Regs:$a),
2910                         "clz.b64 \t$d, $a;", []>;
2911}
2912
2913// 32-bit has a direct PTX instruction
2914def : Pat<(ctlz Int32Regs:$a), (CLZr32 Int32Regs:$a)>;
2915
2916// The return type of the ctlz ISD node is the same as its input, but the PTX
2917// ctz instruction always returns a 32-bit value.  For ctlz.i64, convert the
2918// ptx value to 64 bits to match the ISD node's semantics, unless we know we're
2919// truncating back down to 32 bits.
2920def : Pat<(i64 (ctlz Int64Regs:$a)), (CVT_u64_u32 (CLZr64 Int64Regs:$a), CvtNONE)>;
2921def : Pat<(i32 (trunc (ctlz Int64Regs:$a))), (CLZr64 Int64Regs:$a)>;
2922
2923// For 16-bit ctlz, we zero-extend to 32-bit, perform the count, then trunc the
2924// result back to 16-bits if necessary.  We also need to subtract 16 because
2925// the high-order 16 zeros were counted.
2926//
2927// TODO: NVPTX has a mov.b32 b32reg, {imm, b16reg} instruction, which we could
2928// use to save one SASS instruction (on sm_35 anyway):
2929//
2930//   mov.b32 $tmp, {0xffff, $a}
2931//   ctlz.b32 $result, $tmp
2932//
2933// That is, instead of zero-extending the input to 32 bits, we'd "one-extend"
2934// and then ctlz that value.  This way we don't have to subtract 16 from the
2935// result.  Unfortunately today we don't have a way to generate
2936// "mov b32reg, {b16imm, b16reg}", so we don't do this optimization.
2937def : Pat<(i16 (ctlz Int16Regs:$a)),
2938          (SUBi16ri (CVT_u16_u32
2939           (CLZr32 (CVT_u32_u16 Int16Regs:$a, CvtNONE)), CvtNONE), 16)>;
2940def : Pat<(i32 (zext (i16 (ctlz Int16Regs:$a)))),
2941          (SUBi32ri (CLZr32 (CVT_u32_u16 Int16Regs:$a, CvtNONE)), 16)>;
2942
2943// Population count
2944let hasSideEffects = false in {
2945  def POPCr32 : NVPTXInst<(outs Int32Regs:$d), (ins Int32Regs:$a),
2946                          "popc.b32 \t$d, $a;", []>;
2947  def POPCr64 : NVPTXInst<(outs Int32Regs:$d), (ins Int64Regs:$a),
2948                          "popc.b64 \t$d, $a;", []>;
2949}
2950
2951// 32-bit has a direct PTX instruction
2952def : Pat<(ctpop Int32Regs:$a), (POPCr32 Int32Regs:$a)>;
2953
2954// For 64-bit, the result in PTX is actually 32-bit so we zero-extend to 64-bit
2955// to match the LLVM semantics.  Just as with ctlz.i64, we provide a second
2956// pattern that avoids the type conversion if we're truncating the result to
2957// i32 anyway.
2958def : Pat<(ctpop Int64Regs:$a), (CVT_u64_u32 (POPCr64 Int64Regs:$a), CvtNONE)>;
2959def : Pat<(i32 (trunc (ctpop Int64Regs:$a))), (POPCr64 Int64Regs:$a)>;
2960
2961// For 16-bit, we zero-extend to 32-bit, then trunc the result back to 16-bits.
2962// If we know that we're storing into an i32, we can avoid the final trunc.
2963def : Pat<(ctpop Int16Regs:$a),
2964          (CVT_u16_u32 (POPCr32 (CVT_u32_u16 Int16Regs:$a, CvtNONE)), CvtNONE)>;
2965def : Pat<(i32 (zext (i16 (ctpop Int16Regs:$a)))),
2966          (POPCr32 (CVT_u32_u16 Int16Regs:$a, CvtNONE))>;
2967
2968// fpround f32 -> f16
2969def : Pat<(f16 (fpround Float32Regs:$a)),
2970          (CVT_f16_f32 Float32Regs:$a, CvtRN)>;
2971
2972// fpround f64 -> f16
2973def : Pat<(f16 (fpround Float64Regs:$a)),
2974          (CVT_f16_f64 Float64Regs:$a, CvtRN)>;
2975
2976// fpround f64 -> f32
2977def : Pat<(f32 (fpround Float64Regs:$a)),
2978          (CVT_f32_f64 Float64Regs:$a, CvtRN_FTZ)>, Requires<[doF32FTZ]>;
2979def : Pat<(f32 (fpround Float64Regs:$a)),
2980          (CVT_f32_f64 Float64Regs:$a, CvtRN)>;
2981
2982// fpextend f16 -> f32
2983def : Pat<(f32 (fpextend Float16Regs:$a)),
2984          (CVT_f32_f16 Float16Regs:$a, CvtNONE_FTZ)>, Requires<[doF32FTZ]>;
2985def : Pat<(f32 (fpextend Float16Regs:$a)),
2986          (CVT_f32_f16 Float16Regs:$a, CvtNONE)>;
2987
2988// fpextend f16 -> f64
2989def : Pat<(f64 (fpextend Float16Regs:$a)),
2990          (CVT_f64_f16 Float16Regs:$a, CvtNONE)>;
2991
2992// fpextend f32 -> f64
2993def : Pat<(f64 (fpextend Float32Regs:$a)),
2994          (CVT_f64_f32 Float32Regs:$a, CvtNONE_FTZ)>, Requires<[doF32FTZ]>;
2995def : Pat<(f64 (fpextend Float32Regs:$a)),
2996          (CVT_f64_f32 Float32Regs:$a, CvtNONE)>;
2997
2998def retflag : SDNode<"NVPTXISD::RET_FLAG", SDTNone,
2999                     [SDNPHasChain, SDNPOptInGlue]>;
3000
3001// fceil, ffloor, fround, ftrunc.
3002
3003def : Pat<(fceil Float16Regs:$a),
3004          (CVT_f16_f16 Float16Regs:$a, CvtRPI)>;
3005def : Pat<(fceil Float32Regs:$a),
3006          (CVT_f32_f32 Float32Regs:$a, CvtRPI_FTZ)>, Requires<[doF32FTZ]>;
3007def : Pat<(fceil Float32Regs:$a),
3008          (CVT_f32_f32 Float32Regs:$a, CvtRPI)>, Requires<[doNoF32FTZ]>;
3009def : Pat<(fceil Float64Regs:$a),
3010          (CVT_f64_f64 Float64Regs:$a, CvtRPI)>;
3011
3012def : Pat<(ffloor Float16Regs:$a),
3013          (CVT_f16_f16 Float16Regs:$a, CvtRMI)>;
3014def : Pat<(ffloor Float32Regs:$a),
3015          (CVT_f32_f32 Float32Regs:$a, CvtRMI_FTZ)>, Requires<[doF32FTZ]>;
3016def : Pat<(ffloor Float32Regs:$a),
3017          (CVT_f32_f32 Float32Regs:$a, CvtRMI)>, Requires<[doNoF32FTZ]>;
3018def : Pat<(ffloor Float64Regs:$a),
3019          (CVT_f64_f64 Float64Regs:$a, CvtRMI)>;
3020
3021def : Pat<(ftrunc Float16Regs:$a),
3022          (CVT_f16_f16 Float16Regs:$a, CvtRZI)>;
3023def : Pat<(ftrunc Float32Regs:$a),
3024          (CVT_f32_f32 Float32Regs:$a, CvtRZI_FTZ)>, Requires<[doF32FTZ]>;
3025def : Pat<(ftrunc Float32Regs:$a),
3026          (CVT_f32_f32 Float32Regs:$a, CvtRZI)>, Requires<[doNoF32FTZ]>;
3027def : Pat<(ftrunc Float64Regs:$a),
3028          (CVT_f64_f64 Float64Regs:$a, CvtRZI)>;
3029
3030// nearbyint and rint are implemented as rounding to nearest even.  This isn't
3031// strictly correct, because it causes us to ignore the rounding mode.  But it
3032// matches what CUDA's "libm" does.
3033
3034def : Pat<(fnearbyint Float16Regs:$a),
3035          (CVT_f16_f16 Float16Regs:$a, CvtRNI)>;
3036def : Pat<(fnearbyint Float32Regs:$a),
3037          (CVT_f32_f32 Float32Regs:$a, CvtRNI_FTZ)>, Requires<[doF32FTZ]>;
3038def : Pat<(fnearbyint Float32Regs:$a),
3039          (CVT_f32_f32 Float32Regs:$a, CvtRNI)>, Requires<[doNoF32FTZ]>;
3040def : Pat<(fnearbyint Float64Regs:$a),
3041          (CVT_f64_f64 Float64Regs:$a, CvtRNI)>;
3042
3043def : Pat<(frint Float16Regs:$a),
3044          (CVT_f16_f16 Float16Regs:$a, CvtRNI)>;
3045def : Pat<(frint Float32Regs:$a),
3046          (CVT_f32_f32 Float32Regs:$a, CvtRNI_FTZ)>, Requires<[doF32FTZ]>;
3047def : Pat<(frint Float32Regs:$a),
3048          (CVT_f32_f32 Float32Regs:$a, CvtRNI)>, Requires<[doNoF32FTZ]>;
3049def : Pat<(frint Float64Regs:$a),
3050          (CVT_f64_f64 Float64Regs:$a, CvtRNI)>;
3051
3052
3053//-----------------------------------
3054// Control-flow
3055//-----------------------------------
3056
3057let isTerminator=1 in {
3058   let isReturn=1, isBarrier=1 in
3059      def Return : NVPTXInst<(outs), (ins), "ret;", [(retflag)]>;
3060
3061   let isBranch=1 in
3062      def CBranch : NVPTXInst<(outs), (ins Int1Regs:$a, brtarget:$target),
3063                              "@$a bra \t$target;",
3064                              [(brcond Int1Regs:$a, bb:$target)]>;
3065   let isBranch=1 in
3066      def CBranchOther : NVPTXInst<(outs), (ins Int1Regs:$a, brtarget:$target),
3067                                   "@!$a bra \t$target;", []>;
3068
3069   let isBranch=1, isBarrier=1 in
3070      def GOTO : NVPTXInst<(outs), (ins brtarget:$target),
3071                           "bra.uni \t$target;", [(br bb:$target)]>;
3072}
3073
3074def : Pat<(brcond Int32Regs:$a, bb:$target),
3075          (CBranch (SETP_u32ri Int32Regs:$a, 0, CmpNE), bb:$target)>;
3076
3077// SelectionDAGBuilder::visitSWitchCase() will invert the condition of a
3078// conditional branch if the target block is the next block so that the code
3079// can fall through to the target block.  The invertion is done by 'xor
3080// condition, 1', which will be translated to (setne condition, -1).  Since ptx
3081// supports '@!pred bra target', we should use it.
3082def : Pat<(brcond (i1 (setne Int1Regs:$a, -1)), bb:$target),
3083          (CBranchOther Int1Regs:$a, bb:$target)>;
3084
3085// Call
3086def SDT_NVPTXCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>,
3087                                            SDTCisVT<1, i32>]>;
3088def SDT_NVPTXCallSeqEnd   : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
3089
3090def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_NVPTXCallSeqStart,
3091                           [SDNPHasChain, SDNPOutGlue, SDNPSideEffect]>;
3092def callseq_end   : SDNode<"ISD::CALLSEQ_END", SDT_NVPTXCallSeqEnd,
3093                           [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
3094                            SDNPSideEffect]>;
3095
3096def SDT_NVPTXCall : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
3097def call          : SDNode<"NVPTXISD::CALL", SDT_NVPTXCall,
3098                           [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
3099def calltarget : Operand<i32>;
3100let isCall=1 in {
3101   def CALL : NVPTXInst<(outs), (ins calltarget:$dst), "call \t$dst, (1);", []>;
3102}
3103
3104def : Pat<(call tglobaladdr:$dst), (CALL tglobaladdr:$dst)>;
3105def : Pat<(call texternalsym:$dst), (CALL texternalsym:$dst)>;
3106
3107// Pseudo instructions.
3108class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
3109   : NVPTXInst<outs, ins, asmstr, pattern>;
3110
3111def Callseq_Start :
3112  NVPTXInst<(outs), (ins i32imm:$amt1, i32imm:$amt2),
3113            "\\{ // callseq $amt1, $amt2\n"
3114            "\t.reg .b32 temp_param_reg;",
3115            [(callseq_start timm:$amt1, timm:$amt2)]>;
3116def Callseq_End :
3117  NVPTXInst<(outs), (ins i32imm:$amt1, i32imm:$amt2),
3118            "\\} // callseq $amt1",
3119            [(callseq_end timm:$amt1, timm:$amt2)]>;
3120
3121// trap instruction
3122def trapinst : NVPTXInst<(outs), (ins), "trap;", [(trap)]>;
3123
3124// Call prototype wrapper
3125def SDTCallPrototype : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
3126def CallPrototype :
3127  SDNode<"NVPTXISD::CallPrototype", SDTCallPrototype,
3128         [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
3129def ProtoIdent : Operand<i32> {
3130  let PrintMethod = "printProtoIdent";
3131}
3132def CALL_PROTOTYPE :
3133  NVPTXInst<(outs), (ins ProtoIdent:$ident),
3134            "$ident", [(CallPrototype (i32 texternalsym:$ident))]>;
3135
3136
3137include "NVPTXIntrinsics.td"
3138
3139
3140//-----------------------------------
3141// Notes
3142//-----------------------------------
3143// BSWAP is currently expanded. The following is a more efficient
3144// - for < sm_20, use vector scalar mov, as tesla support native 16-bit register
3145// - for sm_20, use pmpt (use vector scalar mov to get the pack and
3146//   unpack). sm_20 supports native 32-bit register, but not native 16-bit
3147// register.
3148