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