[ARM] MVE integer min and max
[llvm-complete.git] / lib / Target / NVPTX / NVPTXInstrInfo.td
blob62da3c79f4659145b80e5abf274da6acb6976715
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.
11 //===----------------------------------------------------------------------===//
13 include "NVPTXInstrFormats.td"
15 // A NOP instruction
16 let hasSideEffects = 0 in {
17   def NOP : NVPTXInst<(outs), (ins), "", []>;
20 let OperandType = "OPERAND_IMMEDIATE" in {
21   def f16imm : Operand<f16>;
24 // List of vector specific properties
25 def isVecLD      : VecInstTypeEnum<1>;
26 def isVecST      : VecInstTypeEnum<2>;
27 def isVecBuild   : VecInstTypeEnum<3>;
28 def isVecShuffle : VecInstTypeEnum<4>;
29 def isVecExtract : VecInstTypeEnum<5>;
30 def isVecInsert  : VecInstTypeEnum<6>;
31 def isVecDest    : VecInstTypeEnum<7>;
32 def isVecOther   : VecInstTypeEnum<15>;
34 //===----------------------------------------------------------------------===//
35 // NVPTX Operand Definitions.
36 //===----------------------------------------------------------------------===//
38 def brtarget    : Operand<OtherVT>;
40 // CVT conversion modes
41 // These must match the enum in NVPTX.h
42 def CvtNONE : PatLeaf<(i32 0x0)>;
43 def CvtRNI  : PatLeaf<(i32 0x1)>;
44 def CvtRZI  : PatLeaf<(i32 0x2)>;
45 def CvtRMI  : PatLeaf<(i32 0x3)>;
46 def CvtRPI  : PatLeaf<(i32 0x4)>;
47 def CvtRN   : PatLeaf<(i32 0x5)>;
48 def CvtRZ   : PatLeaf<(i32 0x6)>;
49 def CvtRM   : PatLeaf<(i32 0x7)>;
50 def CvtRP   : PatLeaf<(i32 0x8)>;
52 def CvtNONE_FTZ : PatLeaf<(i32 0x10)>;
53 def CvtRNI_FTZ  : PatLeaf<(i32 0x11)>;
54 def CvtRZI_FTZ  : PatLeaf<(i32 0x12)>;
55 def CvtRMI_FTZ  : PatLeaf<(i32 0x13)>;
56 def CvtRPI_FTZ  : PatLeaf<(i32 0x14)>;
57 def CvtRN_FTZ   : PatLeaf<(i32 0x15)>;
58 def CvtRZ_FTZ   : PatLeaf<(i32 0x16)>;
59 def CvtRM_FTZ   : PatLeaf<(i32 0x17)>;
60 def CvtRP_FTZ   : PatLeaf<(i32 0x18)>;
62 def CvtSAT      : PatLeaf<(i32 0x20)>;
63 def CvtSAT_FTZ  : PatLeaf<(i32 0x30)>;
65 def CvtMode : Operand<i32> {
66   let PrintMethod = "printCvtMode";
69 // Compare modes
70 // These must match the enum in NVPTX.h
71 def CmpEQ   : PatLeaf<(i32 0)>;
72 def CmpNE   : PatLeaf<(i32 1)>;
73 def CmpLT   : PatLeaf<(i32 2)>;
74 def CmpLE   : PatLeaf<(i32 3)>;
75 def CmpGT   : PatLeaf<(i32 4)>;
76 def CmpGE   : PatLeaf<(i32 5)>;
77 def CmpEQU  : PatLeaf<(i32 10)>;
78 def CmpNEU  : PatLeaf<(i32 11)>;
79 def CmpLTU  : PatLeaf<(i32 12)>;
80 def CmpLEU  : PatLeaf<(i32 13)>;
81 def CmpGTU  : PatLeaf<(i32 14)>;
82 def CmpGEU  : PatLeaf<(i32 15)>;
83 def CmpNUM  : PatLeaf<(i32 16)>;
84 def CmpNAN  : PatLeaf<(i32 17)>;
86 def CmpEQ_FTZ   : PatLeaf<(i32 0x100)>;
87 def CmpNE_FTZ   : PatLeaf<(i32 0x101)>;
88 def CmpLT_FTZ   : PatLeaf<(i32 0x102)>;
89 def CmpLE_FTZ   : PatLeaf<(i32 0x103)>;
90 def CmpGT_FTZ   : PatLeaf<(i32 0x104)>;
91 def CmpGE_FTZ   : PatLeaf<(i32 0x105)>;
92 def CmpEQU_FTZ  : PatLeaf<(i32 0x10A)>;
93 def CmpNEU_FTZ  : PatLeaf<(i32 0x10B)>;
94 def CmpLTU_FTZ  : PatLeaf<(i32 0x10C)>;
95 def CmpLEU_FTZ  : PatLeaf<(i32 0x10D)>;
96 def CmpGTU_FTZ  : PatLeaf<(i32 0x10E)>;
97 def CmpGEU_FTZ  : PatLeaf<(i32 0x10F)>;
98 def CmpNUM_FTZ  : PatLeaf<(i32 0x110)>;
99 def CmpNAN_FTZ  : PatLeaf<(i32 0x111)>;
101 def CmpMode : Operand<i32> {
102   let PrintMethod = "printCmpMode";
104 def VecElement : Operand<i32> {
105   let PrintMethod = "printVecElement";
108 //===----------------------------------------------------------------------===//
109 // NVPTX Instruction Predicate Definitions
110 //===----------------------------------------------------------------------===//
113 def hasAtomAddF64 : Predicate<"Subtarget->hasAtomAddF64()">;
114 def hasAtomScope : Predicate<"Subtarget->hasAtomScope()">;
115 def hasAtomBitwise64 : Predicate<"Subtarget->hasAtomBitwise64()">;
116 def hasAtomMinMax64 : Predicate<"Subtarget->hasAtomMinMax64()">;
117 def hasVote : Predicate<"Subtarget->hasVote()">;
118 def hasDouble : Predicate<"Subtarget->hasDouble()">;
119 def hasLDG : Predicate<"Subtarget->hasLDG()">;
120 def hasLDU : Predicate<"Subtarget->hasLDU()">;
122 def doF32FTZ : Predicate<"useF32FTZ()">;
123 def doNoF32FTZ : Predicate<"!useF32FTZ()">;
125 def doMulWide      : Predicate<"doMulWide">;
127 def allowFMA : Predicate<"allowFMA()">;
128 def noFMA : Predicate<"!allowFMA()">;
129 def allowUnsafeFPMath : Predicate<"allowUnsafeFPMath()">;
131 def do_DIVF32_APPROX : Predicate<"getDivF32Level()==0">;
132 def do_DIVF32_FULL : Predicate<"getDivF32Level()==1">;
134 def do_SQRTF32_APPROX : Predicate<"!usePrecSqrtF32()">;
135 def do_SQRTF32_RN : Predicate<"usePrecSqrtF32()">;
137 def hasHWROT32 : Predicate<"Subtarget->hasHWROT32()">;
138 def noHWROT32 : Predicate<"!Subtarget->hasHWROT32()">;
140 def true : Predicate<"true">;
142 def hasPTX31 : Predicate<"Subtarget->getPTXVersion() >= 31">;
143 def hasPTX60 : Predicate<"Subtarget->getPTXVersion() >= 60">;
144 def hasPTX61 : Predicate<"Subtarget->getPTXVersion() >= 61">;
145 def hasPTX63 : Predicate<"Subtarget->getPTXVersion() >= 63">;
147 def hasSM30 : Predicate<"Subtarget->getSmVersion() >= 30">;
148 def hasSM70 : Predicate<"Subtarget->getSmVersion() >= 70">;
149 def hasSM72 : Predicate<"Subtarget->getSmVersion() >= 72">;
150 def hasSM75 : Predicate<"Subtarget->getSmVersion() >= 75">;
152 def useShortPtr : Predicate<"useShortPointers()">;
153 def useFP16Math: Predicate<"Subtarget->allowFP16Math()">;
155 //===----------------------------------------------------------------------===//
156 // Some Common Instruction Class Templates
157 //===----------------------------------------------------------------------===//
159 // Template for instructions which take three int64, int32, or int16 args.
160 // The instructions are named "<OpcStr><Width>" (e.g. "add.s64").
161 multiclass 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))]>;
188 // Template for instructions which take 3 int32 args.  The instructions are
189 // named "<OpcStr>.s32" (e.g. "addc.cc.s32").
190 multiclass 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))]>;
201 // Template for instructions which take three fp64 or fp32 args.  The
202 // instructions are named "<OpcStr>.f<Width>" (e.g. "min.f64").
204 // Also defines ftz (flush subnormal inputs and results to sign-preserving
205 // zero) variants for fp32 functions.
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.
210 multiclass 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))]>;
245 // Template for instructions which take three FP args.  The
246 // instructions are named "<OpcStr>.f<Width>" (e.g. "add.f64").
248 // Also defines ftz (flush subnormal inputs and results to sign-preserving
249 // zero) variants for fp32/fp16 functions.
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.
254 multiclass 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]>;
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]>;
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]>;
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]>;
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).
384 multiclass 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))]>;
397 //===----------------------------------------------------------------------===//
398 // NVPTX Instructions.
399 //===----------------------------------------------------------------------===//
401 //-----------------------------------
402 // Type Conversion
403 //-----------------------------------
405 let 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   }
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>;
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;", []>;
496 //-----------------------------------
497 // Integer Arithmetic
498 //-----------------------------------
500 // Template for xor masquerading as int1 arithmetic.
501 multiclass 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))]>;
510 // int1 addition and subtraction are both just xor.
511 defm ADD_i1 : ADD_SUB_i1<add>;
512 defm SUB_i1 : ADD_SUB_i1<sub>;
514 // int16, int32, and int64 signed addition.  Since nvptx is 2's complement, we
515 // also use these for unsigned arithmetic.
516 defm ADD : I3<"add.s", add>;
517 defm SUB : I3<"sub.s", sub>;
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?).
521 defm ADDCC : ADD_SUB_INT_32<"add.cc", addc>;
522 defm SUBCC : ADD_SUB_INT_32<"sub.cc", subc>;
524 // int32 addition and subtraction with carry-in and carry-out.
525 defm ADDCCC : ADD_SUB_INT_32<"addc.cc", adde>;
526 defm SUBCCC : ADD_SUB_INT_32<"subc.cc", sube>;
528 defm MULT : I3<"mul.lo.s", mul>;
530 defm MULTHS : I3<"mul.hi.s", mulhs>;
531 defm MULTHU : I3<"mul.hi.u", mulhu>;
533 defm SDIV : I3<"div.s", sdiv>;
534 defm UDIV : I3<"div.u", udiv>;
536 // The ri versions of rem.s and rem.u won't be selected; DAGCombiner::visitSREM
537 // will lower it.
538 defm SREM : I3<"rem.s", srem>;
539 defm UREM : I3<"rem.u", urem>;
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.
544 multiclass 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))]>;
549 defm ABS_16 : ABS<Int16Regs, ".s16">;
550 defm ABS_32 : ABS<Int32Regs, ".s32">;
551 defm ABS_64 : ABS<Int64Regs, ".s64">;
553 // Integer min/max.
554 defm SMAX : I3<"max.s", smax>;
555 defm UMAX : I3<"max.u", umax>;
556 defm SMIN : I3<"min.s", smin>;
557 defm UMIN : I3<"min.u", umin>;
560 // Wide multiplication
562 def MULWIDES64 :
563   NVPTXInst<(outs Int64Regs:$dst), (ins Int32Regs:$a, Int32Regs:$b),
564             "mul.wide.s32 \t$dst, $a, $b;", []>;
565 def MULWIDES64Imm :
566   NVPTXInst<(outs Int64Regs:$dst), (ins Int32Regs:$a, i32imm:$b),
567             "mul.wide.s32 \t$dst, $a, $b;", []>;
568 def MULWIDES64Imm64 :
569   NVPTXInst<(outs Int64Regs:$dst), (ins Int32Regs:$a, i64imm:$b),
570             "mul.wide.s32 \t$dst, $a, $b;", []>;
572 def MULWIDEU64 :
573   NVPTXInst<(outs Int64Regs:$dst), (ins Int32Regs:$a, Int32Regs:$b),
574             "mul.wide.u32 \t$dst, $a, $b;", []>;
575 def MULWIDEU64Imm :
576   NVPTXInst<(outs Int64Regs:$dst), (ins Int32Regs:$a, i32imm:$b),
577             "mul.wide.u32 \t$dst, $a, $b;", []>;
578 def MULWIDEU64Imm64 :
579   NVPTXInst<(outs Int64Regs:$dst), (ins Int32Regs:$a, i64imm:$b),
580             "mul.wide.u32 \t$dst, $a, $b;", []>;
582 def MULWIDES32 :
583   NVPTXInst<(outs Int32Regs:$dst), (ins Int16Regs:$a, Int16Regs:$b),
584             "mul.wide.s16 \t$dst, $a, $b;", []>;
585 def MULWIDES32Imm :
586   NVPTXInst<(outs Int32Regs:$dst), (ins Int16Regs:$a, i16imm:$b),
587             "mul.wide.s16 \t$dst, $a, $b;", []>;
588 def MULWIDES32Imm32 :
589   NVPTXInst<(outs Int32Regs:$dst), (ins Int16Regs:$a, i32imm:$b),
590             "mul.wide.s16 \t$dst, $a, $b;", []>;
592 def MULWIDEU32 :
593   NVPTXInst<(outs Int32Regs:$dst), (ins Int16Regs:$a, Int16Regs:$b),
594             "mul.wide.u16 \t$dst, $a, $b;", []>;
595 def MULWIDEU32Imm :
596   NVPTXInst<(outs Int32Regs:$dst), (ins Int16Regs:$a, i16imm:$b),
597             "mul.wide.u16 \t$dst, $a, $b;", []>;
598 def MULWIDEU32Imm32 :
599   NVPTXInst<(outs Int32Regs:$dst), (ins Int16Regs:$a, i32imm:$b),
600             "mul.wide.u16 \t$dst, $a, $b;", []>;
602 def SDTMulWide : SDTypeProfile<1, 2, [SDTCisSameAs<1, 2>]>;
603 def mul_wide_signed : SDNode<"NVPTXISD::MUL_WIDE_SIGNED", SDTMulWide>;
604 def mul_wide_unsigned : SDNode<"NVPTXISD::MUL_WIDE_UNSIGNED", SDTMulWide>;
606 // Matchers for signed, unsigned mul.wide ISD nodes.
607 def : Pat<(i32 (mul_wide_signed Int16Regs:$a, Int16Regs:$b)),
608           (MULWIDES32 Int16Regs:$a, Int16Regs:$b)>,
609       Requires<[doMulWide]>;
610 def : Pat<(i32 (mul_wide_signed Int16Regs:$a, imm:$b)),
611           (MULWIDES32Imm Int16Regs:$a, imm:$b)>,
612       Requires<[doMulWide]>;
613 def : Pat<(i32 (mul_wide_unsigned Int16Regs:$a, Int16Regs:$b)),
614           (MULWIDEU32 Int16Regs:$a, Int16Regs:$b)>,
615       Requires<[doMulWide]>;
616 def : Pat<(i32 (mul_wide_unsigned Int16Regs:$a, imm:$b)),
617           (MULWIDEU32Imm Int16Regs:$a, imm:$b)>,
618       Requires<[doMulWide]>;
620 def : Pat<(i64 (mul_wide_signed Int32Regs:$a, Int32Regs:$b)),
621           (MULWIDES64 Int32Regs:$a, Int32Regs:$b)>,
622       Requires<[doMulWide]>;
623 def : Pat<(i64 (mul_wide_signed Int32Regs:$a, imm:$b)),
624           (MULWIDES64Imm Int32Regs:$a, imm:$b)>,
625       Requires<[doMulWide]>;
626 def : Pat<(i64 (mul_wide_unsigned Int32Regs:$a, Int32Regs:$b)),
627           (MULWIDEU64 Int32Regs:$a, Int32Regs:$b)>,
628       Requires<[doMulWide]>;
629 def : Pat<(i64 (mul_wide_unsigned Int32Regs:$a, imm:$b)),
630           (MULWIDEU64Imm Int32Regs:$a, imm:$b)>,
631       Requires<[doMulWide]>;
633 // Predicates used for converting some patterns to mul.wide.
634 def SInt32Const : PatLeaf<(imm), [{
635   const APInt &v = N->getAPIntValue();
636   return v.isSignedIntN(32);
637 }]>;
639 def UInt32Const : PatLeaf<(imm), [{
640   const APInt &v = N->getAPIntValue();
641   return v.isIntN(32);
642 }]>;
644 def SInt16Const : PatLeaf<(imm), [{
645   const APInt &v = N->getAPIntValue();
646   return v.isSignedIntN(16);
647 }]>;
649 def UInt16Const : PatLeaf<(imm), [{
650   const APInt &v = N->getAPIntValue();
651   return v.isIntN(16);
652 }]>;
654 def 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 }]>;
660 def 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 }]>;
666 def 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 }]>;
672 def 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 }]>;
678 // Convert "sign/zero-extend, then shift left by an immediate" to mul.wide.
679 def : Pat<(shl (sext Int32Regs:$a), (i32 Int5Const:$b)),
680           (MULWIDES64Imm Int32Regs:$a, (SHL2MUL32 node:$b))>,
681       Requires<[doMulWide]>;
682 def : Pat<(shl (zext Int32Regs:$a), (i32 Int5Const:$b)),
683           (MULWIDEU64Imm Int32Regs:$a, (SHL2MUL32 node:$b))>,
684       Requires<[doMulWide]>;
686 def : Pat<(shl (sext Int16Regs:$a), (i16 Int4Const:$b)),
687           (MULWIDES32Imm Int16Regs:$a, (SHL2MUL16 node:$b))>,
688       Requires<[doMulWide]>;
689 def : Pat<(shl (zext Int16Regs:$a), (i16 Int4Const:$b)),
690           (MULWIDEU32Imm Int16Regs:$a, (SHL2MUL16 node:$b))>,
691       Requires<[doMulWide]>;
693 // Convert "sign/zero-extend then multiply" to mul.wide.
694 def : Pat<(mul (sext Int32Regs:$a), (sext Int32Regs:$b)),
695           (MULWIDES64 Int32Regs:$a, Int32Regs:$b)>,
696       Requires<[doMulWide]>;
697 def : Pat<(mul (sext Int32Regs:$a), (i64 SInt32Const:$b)),
698           (MULWIDES64Imm64 Int32Regs:$a, (i64 SInt32Const:$b))>,
699       Requires<[doMulWide]>;
701 def : Pat<(mul (zext Int32Regs:$a), (zext Int32Regs:$b)),
702           (MULWIDEU64 Int32Regs:$a, Int32Regs:$b)>,
703       Requires<[doMulWide]>;
704 def : Pat<(mul (zext Int32Regs:$a), (i64 UInt32Const:$b)),
705           (MULWIDEU64Imm64 Int32Regs:$a, (i64 UInt32Const:$b))>,
706       Requires<[doMulWide]>;
708 def : Pat<(mul (sext Int16Regs:$a), (sext Int16Regs:$b)),
709           (MULWIDES32 Int16Regs:$a, Int16Regs:$b)>,
710       Requires<[doMulWide]>;
711 def : Pat<(mul (sext Int16Regs:$a), (i32 SInt16Const:$b)),
712           (MULWIDES32Imm32 Int16Regs:$a, (i32 SInt16Const:$b))>,
713       Requires<[doMulWide]>;
715 def : Pat<(mul (zext Int16Regs:$a), (zext Int16Regs:$b)),
716           (MULWIDEU32 Int16Regs:$a, Int16Regs:$b)>,
717       Requires<[doMulWide]>;
718 def : Pat<(mul (zext Int16Regs:$a), (i32 UInt16Const:$b)),
719           (MULWIDEU32Imm32 Int16Regs:$a, (i32 UInt16Const:$b))>,
720       Requires<[doMulWide]>;
723 // Integer multiply-add
725 def SDTIMAD :
726   SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisInt<2>,
727                        SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>]>;
728 def imad : SDNode<"NVPTXISD::IMAD", SDTIMAD>;
730 def 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))]>;
735 def 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))]>;
740 def 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))]>;
745 def 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))]>;
751 def 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))]>;
756 def 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))]>;
761 def 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))]>;
766 def 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))]>;
772 def 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))]>;
777 def 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))]>;
782 def 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))]>;
787 def 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))]>;
793 def INEG16 :
794   NVPTXInst<(outs Int16Regs:$dst), (ins Int16Regs:$src),
795             "neg.s16 \t$dst, $src;",
796             [(set Int16Regs:$dst, (ineg Int16Regs:$src))]>;
797 def INEG32 :
798   NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$src),
799             "neg.s32 \t$dst, $src;",
800             [(set Int32Regs:$dst, (ineg Int32Regs:$src))]>;
801 def INEG64 :
802   NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$src),
803             "neg.s64 \t$dst, $src;",
804             [(set Int64Regs:$dst, (ineg Int64Regs:$src))]>;
806 //-----------------------------------
807 // Floating Point Arithmetic
808 //-----------------------------------
810 // Constant 1.0f
811 def FloatConst1 : PatLeaf<(fpimm), [{
812   return &N->getValueAPF().getSemantics() == &llvm::APFloat::IEEEsingle() &&
813          N->getValueAPF().convertToFloat() == 1.0f;
814 }]>;
815 // Constant 1.0 (double)
816 def DoubleConst1 : PatLeaf<(fpimm), [{
817   return &N->getValueAPF().getSemantics() == &llvm::APFloat::IEEEdouble() &&
818          N->getValueAPF().convertToDouble() == 1.0;
819 }]>;
821 // Loads FP16 constant into a register.
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.
826 def LOAD_CONST_F16 :
827   NVPTXInst<(outs Float16Regs:$dst), (ins f16imm:$a),
828             "mov.b16 \t$dst, $a;", []>;
830 defm FADD : F3_fma_component<"add", fadd>;
831 defm FSUB : F3_fma_component<"sub", fsub>;
832 defm FMUL : F3_fma_component<"mul", fmul>;
834 defm FMIN : F3<"min", fminnum>;
835 defm FMAX : F3<"max", fmaxnum>;
837 defm FABS  : F2<"abs", fabs>;
838 defm FNEG  : F2<"neg", fneg>;
839 defm FSQRT : F2<"sqrt.rn", fsqrt>;
842 // F64 division
844 def 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))]>;
849 def 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))]>;
854 def 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))]>;
861 // F32 Approximate reciprocal
863 def 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]>;
869 def 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]>;
876 // F32 Approximate division
878 def 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]>;
884 def 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]>;
890 def 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]>;
896 def 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]>;
903 // F32 Semi-accurate reciprocal
905 // rcp.approx gives the same result as div.full(1.0f, a) and is faster.
907 def 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]>;
913 def 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]>;
920 // F32 Semi-accurate division
922 def 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]>;
928 def 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]>;
934 def 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]>;
940 def 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]>;
947 // F32 Accurate reciprocal
949 def 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]>;
955 def 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))]>;
961 // F32 Accurate division
963 def 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]>;
969 def 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]>;
975 def 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))]>;
980 def 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))]>;
987 // FMA
990 multiclass 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]>;
1012 multiclass 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]>;
1019 defm FMA16_ftz : FMA_F16<"fma.rn.ftz.f16", Float16Regs, doF32FTZ>;
1020 defm FMA16     : FMA_F16<"fma.rn.f16", Float16Regs, true>;
1021 defm FMA16x2_ftz : FMA_F16<"fma.rn.ftz.f16x2", Float16x2Regs, doF32FTZ>;
1022 defm FMA16x2     : FMA_F16<"fma.rn.f16x2", Float16x2Regs, true>;
1023 defm FMA32_ftz : FMA<"fma.rn.ftz.f32", Float32Regs, f32imm, doF32FTZ>;
1024 defm FMA32     : FMA<"fma.rn.f32", Float32Regs, f32imm, true>;
1025 defm FMA64     : FMA<"fma.rn.f64", Float64Regs, f64imm, true>;
1027 // sin/cos
1028 def 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]>;
1032 def 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]>;
1037 // Lower (frem x, y) into (sub x, (mul (floor (div x, y)) y)),
1038 // i.e. "poor man's fmod()"
1040 // frem - f32 FTZ
1041 def : 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]>;
1046 def : 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]>;
1052 // frem - f32
1053 def : 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))>;
1057 def : 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))>;
1062 // frem - f64
1063 def : Pat<(frem Float64Regs:$x, Float64Regs:$y),
1064           (FSUBf64rr Float64Regs:$x, (FMULf64rr (CVT_f64_f64
1065             (FDIV64rr Float64Regs:$x, Float64Regs:$y), CvtRMI),
1066              Float64Regs:$y))>;
1067 def : Pat<(frem Float64Regs:$x, fpimm:$y),
1068           (FSUBf64rr Float64Regs:$x, (FMULf64ri (CVT_f64_f64
1069             (FDIV64ri Float64Regs:$x, fpimm:$y), CvtRMI),
1070              fpimm:$y))>;
1072 //-----------------------------------
1073 // Bitwise operations
1074 //-----------------------------------
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.
1078 multiclass 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))]>;
1113 defm OR  : BITWISE<"or", or>;
1114 defm AND : BITWISE<"and", and>;
1115 defm XOR : BITWISE<"xor", xor>;
1117 def NOT1  : NVPTXInst<(outs Int1Regs:$dst), (ins Int1Regs:$src),
1118                       "not.pred \t$dst, $src;",
1119                       [(set Int1Regs:$dst, (not Int1Regs:$src))]>;
1120 def NOT16 : NVPTXInst<(outs Int16Regs:$dst), (ins Int16Regs:$src),
1121                       "not.b16 \t$dst, $src;",
1122                       [(set Int16Regs:$dst, (not Int16Regs:$src))]>;
1123 def NOT32 : NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$src),
1124                       "not.b32 \t$dst, $src;",
1125                       [(set Int32Regs:$dst, (not Int32Regs:$src))]>;
1126 def NOT64 : NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$src),
1127                        "not.b64 \t$dst, $src;",
1128                        [(set Int64Regs:$dst, (not Int64Regs:$src))]>;
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.
1134 // This template also defines a 32-bit shift (imm, imm) instruction.
1135 multiclass 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)))]>;
1166 defm SHL : SHIFT<"shl.b", shl>;
1167 defm SRA : SHIFT<"shr.s", sra>;
1168 defm SRL : SHIFT<"shr.u", srl>;
1170 // Bit-reverse
1171 def BREV32 :
1172   NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$a),
1173              "brev.b32 \t$dst, $a;",
1174              [(set Int32Regs:$dst, (bitreverse Int32Regs:$a))]>;
1175 def BREV64 :
1176   NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$a),
1177              "brev.b64 \t$dst, $a;",
1178              [(set Int64Regs:$dst, (bitreverse Int64Regs:$a))]>;
1181 // Rotate: Use ptx shf instruction if available.
1184 // 32 bit r2 = rotl r1, n
1185 //    =>
1186 //        r2 = shf.l r1, r1, n
1187 def 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]>;
1193 def 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]>;
1199 // 32 bit r2 = rotr r1, n
1200 //    =>
1201 //        r2 = shf.r r1, r1, n
1202 def 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]>;
1208 def 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]>;
1214 // 32-bit software rotate by immediate.  $amt2 should equal 32 - $amt1.
1215 def 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             []>;
1227 def SUB_FRM_32 : SDNodeXForm<imm, [{
1228   return CurDAG->getTargetConstant(32 - N->getZExtValue(), SDLoc(N), MVT::i32);
1229 }]>;
1231 def : Pat<(rotl Int32Regs:$src, (i32 imm:$amt)),
1232           (ROT32imm_sw Int32Regs:$src, imm:$amt, (SUB_FRM_32 node:$amt))>,
1233       Requires<[noHWROT32]>;
1234 def : Pat<(rotr Int32Regs:$src, (i32 imm:$amt)),
1235           (ROT32imm_sw Int32Regs:$src, (SUB_FRM_32 node:$amt), imm:$amt)>,
1236       Requires<[noHWROT32]>;
1238 // 32-bit software rotate left by register.
1239 def 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]>;
1253 // 32-bit software rotate right by register.
1254 def 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]>;
1268 // 64-bit software rotate by immediate.  $amt2 should equal 64 - $amt1.
1269 def 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             []>;
1281 def SUB_FRM_64 : SDNodeXForm<imm, [{
1282     return CurDAG->getTargetConstant(64-N->getZExtValue(), SDLoc(N), MVT::i32);
1283 }]>;
1285 def : Pat<(rotl Int64Regs:$src, (i32 imm:$amt)),
1286           (ROT64imm_sw Int64Regs:$src, imm:$amt, (SUB_FRM_64 node:$amt))>;
1287 def : Pat<(rotr Int64Regs:$src, (i32 imm:$amt)),
1288           (ROT64imm_sw Int64Regs:$src, (SUB_FRM_64 node:$amt), imm:$amt)>;
1290 // 64-bit software rotate left by register.
1291 def 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))]>;
1304 def 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))]>;
1318 // Funnnel shift in clamp mode
1321 // Create SDNodes so they can be used in the DAG code, e.g.
1322 // NVPTXISelLowering (LowerShiftLeftParts and LowerShiftRightParts)
1323 def FUN_SHFL_CLAMP : SDNode<"NVPTXISD::FUN_SHFL_CLAMP", SDTIntShiftDOp, []>;
1324 def FUN_SHFR_CLAMP : SDNode<"NVPTXISD::FUN_SHFR_CLAMP", SDTIntShiftDOp, []>;
1326 def 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))]>;
1333 def 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))]>;
1341 // BFE - bit-field extract
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?
1349 // dest and src may be int32 or int64, but start and end are always int32.
1350 multiclass 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;"), []>;
1365 let 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>;
1372 //-----------------------------------
1373 // Comparison instructions (setp, set)
1374 //-----------------------------------
1376 // FIXME: This doesn't cover versions of set and setp that combine with a
1377 // boolean predicate, e.g. setp.eq.and.b16.
1379 let 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   }
1396 defm SETP_b16 : SETP<"b16", Int16Regs, i16imm>;
1397 defm SETP_s16 : SETP<"s16", Int16Regs, i16imm>;
1398 defm SETP_u16 : SETP<"u16", Int16Regs, i16imm>;
1399 defm SETP_b32 : SETP<"b32", Int32Regs, i32imm>;
1400 defm SETP_s32 : SETP<"s32", Int32Regs, i32imm>;
1401 defm SETP_u32 : SETP<"u32", Int32Regs, i32imm>;
1402 defm SETP_b64 : SETP<"b64", Int64Regs, i64imm>;
1403 defm SETP_s64 : SETP<"s64", Int64Regs, i64imm>;
1404 defm SETP_u64 : SETP<"u64", Int64Regs, i64imm>;
1405 defm SETP_f32 : SETP<"f32", Float32Regs, f32imm>;
1406 defm SETP_f64 : SETP<"f64", Float64Regs, f64imm>;
1407 def 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]>;
1413 def 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]>;
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.
1425 let 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   }
1439 defm SET_b16 : SET<"b16", Int16Regs, i16imm>;
1440 defm SET_s16 : SET<"s16", Int16Regs, i16imm>;
1441 defm SET_u16 : SET<"u16", Int16Regs, i16imm>;
1442 defm SET_b32 : SET<"b32", Int32Regs, i32imm>;
1443 defm SET_s32 : SET<"s32", Int32Regs, i32imm>;
1444 defm SET_u32 : SET<"u32", Int32Regs, i32imm>;
1445 defm SET_b64 : SET<"b64", Int64Regs, i64imm>;
1446 defm SET_s64 : SET<"s64", Int64Regs, i64imm>;
1447 defm SET_u64 : SET<"u64", Int64Regs, i64imm>;
1448 defm SET_f16 : SET<"f16", Float16Regs, f16imm>;
1449 defm SET_f32 : SET<"f32", Float32Regs, f32imm>;
1450 defm SET_f64 : SET<"f64", Float64Regs, f64imm>;
1452 //-----------------------------------
1453 // Selection instructions (selp)
1454 //-----------------------------------
1456 // FIXME: Missing slct
1458 // selp instructions that don't have any pattern matches; we explicitly use
1459 // them within this file.
1460 let 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   }
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   }
1501 // Don't pattern match on selp.{s,u}{16,32,64} -- selp.b{16,32,64} is just as
1502 // good.
1503 defm SELP_b16 : SELP_PATTERN<"b16", Int16Regs, i16imm, imm>;
1504 defm SELP_s16 : SELP<"s16", Int16Regs, i16imm>;
1505 defm SELP_u16 : SELP<"u16", Int16Regs, i16imm>;
1506 defm SELP_b32 : SELP_PATTERN<"b32", Int32Regs, i32imm, imm>;
1507 defm SELP_s32 : SELP<"s32", Int32Regs, i32imm>;
1508 defm SELP_u32 : SELP<"u32", Int32Regs, i32imm>;
1509 defm SELP_b64 : SELP_PATTERN<"b64", Int64Regs, i64imm, imm>;
1510 defm SELP_s64 : SELP<"s64", Int64Regs, i64imm>;
1511 defm SELP_u64 : SELP<"u64", Int64Regs, i64imm>;
1512 defm SELP_f16 : SELP_PATTERN<"b16", Float16Regs, f16imm, fpimm>;
1513 defm SELP_f32 : SELP_PATTERN<"f32", Float32Regs, f32imm, fpimm>;
1514 defm SELP_f64 : SELP_PATTERN<"f64", Float64Regs, f64imm, fpimm>;
1516 def 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))]>;
1523 //-----------------------------------
1524 // Data Movement (Load / Store, Move)
1525 //-----------------------------------
1527 def ADDRri : ComplexPattern<i32, 2, "SelectADDRri", [frameindex],
1528                             [SDNPWantRoot]>;
1529 def ADDRri64 : ComplexPattern<i64, 2, "SelectADDRri64", [frameindex],
1530                               [SDNPWantRoot]>;
1531 def ADDRvar : ComplexPattern<iPTR, 1, "SelectDirectAddr", [], []>;
1533 def MEMri : Operand<i32> {
1534   let PrintMethod = "printMemOperand";
1535   let MIOperandInfo = (ops Int32Regs, i32imm);
1537 def MEMri64 : Operand<i64> {
1538   let PrintMethod = "printMemOperand";
1539   let MIOperandInfo = (ops Int64Regs, i64imm);
1542 def imem : Operand<iPTR> {
1543   let PrintMethod = "printOperand";
1546 def imemAny : Operand<iPTRAny> {
1547   let PrintMethod = "printOperand";
1550 def LdStCode : Operand<i32> {
1551   let PrintMethod = "printLdStCode";
1554 def MmaCode : Operand<i32> {
1555   let PrintMethod = "printMmaCode";
1558 def SDTWrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>;
1559 def Wrapper    : SDNode<"NVPTXISD::Wrapper", SDTWrapper>;
1561 // Load a memory address into a u32 or u64 register.
1562 def MOV_ADDR : NVPTXInst<(outs Int32Regs:$dst), (ins imem:$a),
1563                          "mov.u32 \t$dst, $a;",
1564                          [(set Int32Regs:$dst, (Wrapper tglobaladdr:$a))]>;
1565 def MOV_ADDR64 : NVPTXInst<(outs Int64Regs:$dst), (ins imem:$a),
1566                            "mov.u64 \t$dst, $a;",
1567                            [(set Int64Regs:$dst, (Wrapper tglobaladdr:$a))]>;
1569 // Get pointer to local stack.
1570 let 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;", []>;
1578 // copyPhysreg is hard-coded in NVPTXInstrInfo.cpp
1579 let 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;", []>;
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;", []>;
1598 def IMOV1ri : NVPTXInst<(outs Int1Regs:$dst), (ins i1imm:$src),
1599                         "mov.pred \t$dst, $src;",
1600                         [(set Int1Regs:$dst, imm:$src)]>;
1601 def IMOV16ri : NVPTXInst<(outs Int16Regs:$dst), (ins i16imm:$src),
1602                          "mov.u16 \t$dst, $src;",
1603                          [(set Int16Regs:$dst, imm:$src)]>;
1604 def IMOV32ri : NVPTXInst<(outs Int32Regs:$dst), (ins i32imm:$src),
1605                          "mov.u32 \t$dst, $src;",
1606                          [(set Int32Regs:$dst, imm:$src)]>;
1607 def IMOV64i : NVPTXInst<(outs Int64Regs:$dst), (ins i64imm:$src),
1608                         "mov.u64 \t$dst, $src;",
1609                         [(set Int64Regs:$dst, imm:$src)]>;
1611 def FMOV32ri : NVPTXInst<(outs Float32Regs:$dst), (ins f32imm:$src),
1612                          "mov.f32 \t$dst, $src;",
1613                          [(set Float32Regs:$dst, fpimm:$src)]>;
1614 def FMOV64ri : NVPTXInst<(outs Float64Regs:$dst), (ins f64imm:$src),
1615                          "mov.f64 \t$dst, $src;",
1616                          [(set Float64Regs:$dst, fpimm:$src)]>;
1618 def : Pat<(i32 (Wrapper texternalsym:$dst)), (IMOV32ri texternalsym:$dst)>;
1620 //---- Copy Frame Index ----
1621 def LEA_ADDRi :   NVPTXInst<(outs Int32Regs:$dst), (ins MEMri:$addr),
1622                             "add.u32 \t$dst, ${addr:add};",
1623                             [(set Int32Regs:$dst, ADDRri:$addr)]>;
1624 def LEA_ADDRi64 : NVPTXInst<(outs Int64Regs:$dst), (ins MEMri64:$addr),
1625                             "add.u64 \t$dst, ${addr:add};",
1626                             [(set Int64Regs:$dst, ADDRri64:$addr)]>;
1628 //-----------------------------------
1629 // Comparison and Selection
1630 //-----------------------------------
1632 multiclass 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)>;
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)>;
1696 multiclass 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)>;
1708 multiclass 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)>;
1720 defm : ISET_FORMAT_SIGNED<setgt, CmpGT>;
1721 defm : ISET_FORMAT_SIGNED<setlt, CmpLT>;
1722 defm : ISET_FORMAT_SIGNED<setge, CmpGE>;
1723 defm : ISET_FORMAT_SIGNED<setle, CmpLE>;
1724 defm : ISET_FORMAT_SIGNED<seteq, CmpEQ>;
1725 defm : ISET_FORMAT_SIGNED<setne, CmpNE>;
1726 defm : ISET_FORMAT_UNSIGNED<setugt, CmpGT>;
1727 defm : ISET_FORMAT_UNSIGNED<setult, CmpLT>;
1728 defm : ISET_FORMAT_UNSIGNED<setuge, CmpGE>;
1729 defm : ISET_FORMAT_UNSIGNED<setule, CmpLE>;
1730 defm : ISET_FORMAT_UNSIGNED<setueq, CmpEQ>;
1731 defm : ISET_FORMAT_UNSIGNED<setune, CmpNE>;
1733 // i1 compares
1734 def : Pat<(setne Int1Regs:$a, Int1Regs:$b),
1735           (XORb1rr Int1Regs:$a, Int1Regs:$b)>;
1736 def : Pat<(setune Int1Regs:$a, Int1Regs:$b),
1737           (XORb1rr Int1Regs:$a, Int1Regs:$b)>;
1739 def : Pat<(seteq Int1Regs:$a, Int1Regs:$b),
1740           (NOT1 (XORb1rr Int1Regs:$a, Int1Regs:$b))>;
1741 def : Pat<(setueq Int1Regs:$a, Int1Regs:$b),
1742           (NOT1 (XORb1rr Int1Regs:$a, Int1Regs:$b))>;
1744 // i1 compare -> i32
1745 def : Pat<(i32 (setne Int1Regs:$a, Int1Regs:$b)),
1746           (SELP_u32ii -1, 0, (XORb1rr Int1Regs:$a, Int1Regs:$b))>;
1747 def : Pat<(i32 (setne Int1Regs:$a, Int1Regs:$b)),
1748           (SELP_u32ii 0, -1, (XORb1rr Int1Regs:$a, Int1Regs:$b))>;
1752 multiclass 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]>;
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)>;
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)>;
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]>;
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)>;
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)>;
1844 defm FSetOGT : FSET_FORMAT<setogt, CmpGT, CmpGT_FTZ>;
1845 defm FSetOLT : FSET_FORMAT<setolt, CmpLT, CmpLT_FTZ>;
1846 defm FSetOGE : FSET_FORMAT<setoge, CmpGE, CmpGE_FTZ>;
1847 defm FSetOLE : FSET_FORMAT<setole, CmpLE, CmpLE_FTZ>;
1848 defm FSetOEQ : FSET_FORMAT<setoeq, CmpEQ, CmpEQ_FTZ>;
1849 defm FSetONE : FSET_FORMAT<setone, CmpNE, CmpNE_FTZ>;
1851 defm FSetUGT : FSET_FORMAT<setugt, CmpGTU, CmpGTU_FTZ>;
1852 defm FSetULT : FSET_FORMAT<setult, CmpLTU, CmpLTU_FTZ>;
1853 defm FSetUGE : FSET_FORMAT<setuge, CmpGEU, CmpGEU_FTZ>;
1854 defm FSetULE : FSET_FORMAT<setule, CmpLEU, CmpLEU_FTZ>;
1855 defm FSetUEQ : FSET_FORMAT<setueq, CmpEQU, CmpEQU_FTZ>;
1856 defm FSetUNE : FSET_FORMAT<setune, CmpNEU, CmpNEU_FTZ>;
1858 defm FSetGT : FSET_FORMAT<setgt, CmpGT, CmpGT_FTZ>;
1859 defm FSetLT : FSET_FORMAT<setlt, CmpLT, CmpLT_FTZ>;
1860 defm FSetGE : FSET_FORMAT<setge, CmpGE, CmpGE_FTZ>;
1861 defm FSetLE : FSET_FORMAT<setle, CmpLE, CmpLE_FTZ>;
1862 defm FSetEQ : FSET_FORMAT<seteq, CmpEQ, CmpEQ_FTZ>;
1863 defm FSetNE : FSET_FORMAT<setne, CmpNE, CmpNE_FTZ>;
1865 defm FSetNUM : FSET_FORMAT<seto, CmpNUM, CmpNUM_FTZ>;
1866 defm FSetNAN : FSET_FORMAT<setuo, CmpNAN, CmpNAN_FTZ>;
1868 // FIXME: What is this doing here?  Can it be deleted?
1869 // def ld_param         : SDNode<"NVPTXISD::LOAD_PARAM", SDTLoad,
1870 //                         [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
1872 def SDTDeclareParamProfile :
1873   SDTypeProfile<0, 3, [SDTCisInt<0>, SDTCisInt<1>, SDTCisInt<2>]>;
1874 def SDTDeclareScalarParamProfile :
1875   SDTypeProfile<0, 3, [SDTCisInt<0>, SDTCisInt<1>, SDTCisInt<2>]>;
1876 def SDTLoadParamProfile : SDTypeProfile<1, 2, [SDTCisInt<1>, SDTCisInt<2>]>;
1877 def SDTLoadParamV2Profile : SDTypeProfile<2, 2, [SDTCisSameAs<0, 1>, SDTCisInt<2>, SDTCisInt<3>]>;
1878 def SDTLoadParamV4Profile : SDTypeProfile<4, 2, [SDTCisInt<4>, SDTCisInt<5>]>;
1879 def SDTPrintCallProfile : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
1880 def SDTPrintCallUniProfile : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
1881 def SDTStoreParamProfile : SDTypeProfile<0, 3, [SDTCisInt<0>, SDTCisInt<1>]>;
1882 def SDTStoreParamV2Profile : SDTypeProfile<0, 4, [SDTCisInt<0>, SDTCisInt<1>]>;
1883 def SDTStoreParamV4Profile : SDTypeProfile<0, 6, [SDTCisInt<0>, SDTCisInt<1>]>;
1884 def SDTStoreParam32Profile : SDTypeProfile<0, 3, [SDTCisInt<0>, SDTCisInt<1>]>;
1885 def SDTCallArgProfile : SDTypeProfile<0, 2, [SDTCisInt<0>]>;
1886 def SDTCallArgMarkProfile : SDTypeProfile<0, 0, []>;
1887 def SDTCallVoidProfile : SDTypeProfile<0, 1, []>;
1888 def SDTCallValProfile : SDTypeProfile<1, 0, []>;
1889 def SDTMoveParamProfile : SDTypeProfile<1, 1, []>;
1890 def SDTStoreRetvalProfile : SDTypeProfile<0, 2, [SDTCisInt<0>]>;
1891 def SDTStoreRetvalV2Profile : SDTypeProfile<0, 3, [SDTCisInt<0>]>;
1892 def SDTStoreRetvalV4Profile : SDTypeProfile<0, 5, [SDTCisInt<0>]>;
1893 def SDTPseudoUseParamProfile : SDTypeProfile<0, 1, []>;
1894 def SDTProxyRegProfile : SDTypeProfile<1, 1, []>;
1896 def DeclareParam :
1897   SDNode<"NVPTXISD::DeclareParam", SDTDeclareParamProfile,
1898          [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1899 def DeclareScalarParam :
1900   SDNode<"NVPTXISD::DeclareScalarParam", SDTDeclareScalarParamProfile,
1901          [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1902 def DeclareRetParam :
1903   SDNode<"NVPTXISD::DeclareRetParam", SDTDeclareParamProfile,
1904          [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1905 def DeclareRet :
1906   SDNode<"NVPTXISD::DeclareRet", SDTDeclareScalarParamProfile,
1907          [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1908 def LoadParam :
1909   SDNode<"NVPTXISD::LoadParam", SDTLoadParamProfile,
1910          [SDNPHasChain, SDNPMayLoad, SDNPOutGlue, SDNPInGlue]>;
1911 def LoadParamV2 :
1912   SDNode<"NVPTXISD::LoadParamV2", SDTLoadParamV2Profile,
1913          [SDNPHasChain, SDNPMayLoad, SDNPOutGlue, SDNPInGlue]>;
1914 def LoadParamV4 :
1915   SDNode<"NVPTXISD::LoadParamV4", SDTLoadParamV4Profile,
1916          [SDNPHasChain, SDNPMayLoad, SDNPOutGlue, SDNPInGlue]>;
1917 def PrintCall :
1918   SDNode<"NVPTXISD::PrintCall", SDTPrintCallProfile,
1919          [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1920 def PrintConvergentCall :
1921   SDNode<"NVPTXISD::PrintConvergentCall", SDTPrintCallProfile,
1922          [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1923 def PrintCallUni :
1924   SDNode<"NVPTXISD::PrintCallUni", SDTPrintCallUniProfile,
1925          [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1926 def PrintConvergentCallUni :
1927   SDNode<"NVPTXISD::PrintConvergentCallUni", SDTPrintCallUniProfile,
1928          [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1929 def StoreParam :
1930   SDNode<"NVPTXISD::StoreParam", SDTStoreParamProfile,
1931          [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1932 def StoreParamV2 :
1933   SDNode<"NVPTXISD::StoreParamV2", SDTStoreParamV2Profile,
1934          [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1935 def StoreParamV4 :
1936   SDNode<"NVPTXISD::StoreParamV4", SDTStoreParamV4Profile,
1937          [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1938 def StoreParamU32 :
1939   SDNode<"NVPTXISD::StoreParamU32", SDTStoreParam32Profile,
1940          [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1941 def StoreParamS32 :
1942   SDNode<"NVPTXISD::StoreParamS32", SDTStoreParam32Profile,
1943          [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1944 def CallArgBegin :
1945   SDNode<"NVPTXISD::CallArgBegin", SDTCallArgMarkProfile,
1946          [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1947 def CallArg :
1948   SDNode<"NVPTXISD::CallArg", SDTCallArgProfile,
1949          [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1950 def LastCallArg :
1951   SDNode<"NVPTXISD::LastCallArg", SDTCallArgProfile,
1952          [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1953 def CallArgEnd :
1954   SDNode<"NVPTXISD::CallArgEnd", SDTCallVoidProfile,
1955          [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1956 def CallVoid :
1957   SDNode<"NVPTXISD::CallVoid", SDTCallVoidProfile,
1958          [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1959 def Prototype :
1960   SDNode<"NVPTXISD::Prototype", SDTCallVoidProfile,
1961          [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1962 def CallVal :
1963   SDNode<"NVPTXISD::CallVal", SDTCallValProfile,
1964          [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1965 def MoveParam :
1966   SDNode<"NVPTXISD::MoveParam", SDTMoveParamProfile, []>;
1967 def StoreRetval :
1968   SDNode<"NVPTXISD::StoreRetval", SDTStoreRetvalProfile,
1969          [SDNPHasChain, SDNPSideEffect]>;
1970 def StoreRetvalV2 :
1971   SDNode<"NVPTXISD::StoreRetvalV2", SDTStoreRetvalV2Profile,
1972          [SDNPHasChain, SDNPSideEffect]>;
1973 def StoreRetvalV4 :
1974   SDNode<"NVPTXISD::StoreRetvalV4", SDTStoreRetvalV4Profile,
1975          [SDNPHasChain, SDNPSideEffect]>;
1976 def PseudoUseParam :
1977   SDNode<"NVPTXISD::PseudoUseParam", SDTPseudoUseParamProfile,
1978          [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1979 def RETURNNode :
1980   SDNode<"NVPTXISD::RETURN", SDTCallArgMarkProfile,
1981          [SDNPHasChain, SDNPSideEffect]>;
1982 def ProxyReg :
1983   SDNode<"NVPTXISD::ProxyReg", SDTProxyRegProfile,
1984          [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1986 let 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                   []>;
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];"), []>;
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                   []>;
2006 class 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)))]>;
2011 let 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                   []>;
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                   []>;
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                   []>;
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                   []>;
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                   []>;
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                   []>;
2052 let 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   }
2083 defm Call : CALL<"call", PrintCall>;
2084 defm CallUni : CALL<"call.uni", PrintCallUni>;
2086 // Convergent call instructions.  These are identical to regular calls, except
2087 // they have the isConvergent bit set.
2088 let isConvergent=1 in {
2089   defm ConvergentCall : CALL<"call", PrintConvergentCall>;
2090   defm ConvergentCallUni : CALL<"call.uni", PrintConvergentCallUni>;
2093 def LoadParamMemI64    : LoadParamMemInst<Int64Regs, ".b64">;
2094 def LoadParamMemI32    : LoadParamMemInst<Int32Regs, ".b32">;
2095 def LoadParamMemI16    : LoadParamMemInst<Int16Regs, ".b16">;
2096 def LoadParamMemI8     : LoadParamMemInst<Int16Regs, ".b8">;
2097 def LoadParamMemV2I64  : LoadParamV2MemInst<Int64Regs, ".b64">;
2098 def LoadParamMemV2I32  : LoadParamV2MemInst<Int32Regs, ".b32">;
2099 def LoadParamMemV2I16  : LoadParamV2MemInst<Int16Regs, ".b16">;
2100 def LoadParamMemV2I8   : LoadParamV2MemInst<Int16Regs, ".b8">;
2101 def LoadParamMemV4I32  : LoadParamV4MemInst<Int32Regs, ".b32">;
2102 def LoadParamMemV4I16  : LoadParamV4MemInst<Int16Regs, ".b16">;
2103 def LoadParamMemV4I8   : LoadParamV4MemInst<Int16Regs, ".b8">;
2104 def LoadParamMemF16    : LoadParamMemInst<Float16Regs, ".b16">;
2105 def LoadParamMemF16x2  : LoadParamMemInst<Float16x2Regs, ".b32">;
2106 def LoadParamMemF32    : LoadParamMemInst<Float32Regs, ".f32">;
2107 def LoadParamMemF64    : LoadParamMemInst<Float64Regs, ".f64">;
2108 def LoadParamMemV2F16  : LoadParamV2MemInst<Float16Regs, ".b16">;
2109 def LoadParamMemV2F16x2: LoadParamV2MemInst<Float16x2Regs, ".b32">;
2110 def LoadParamMemV2F32  : LoadParamV2MemInst<Float32Regs, ".f32">;
2111 def LoadParamMemV2F64  : LoadParamV2MemInst<Float64Regs, ".f64">;
2112 def LoadParamMemV4F16  : LoadParamV4MemInst<Float16Regs, ".b16">;
2113 def LoadParamMemV4F16x2: LoadParamV4MemInst<Float16x2Regs, ".b32">;
2114 def LoadParamMemV4F32  : LoadParamV4MemInst<Float32Regs, ".f32">;
2116 def StoreParamI64    : StoreParamInst<Int64Regs, ".b64">;
2117 def StoreParamI32    : StoreParamInst<Int32Regs, ".b32">;
2119 def StoreParamI16    : StoreParamInst<Int16Regs, ".b16">;
2120 def StoreParamI8     : StoreParamInst<Int16Regs, ".b8">;
2121 def StoreParamV2I64  : StoreParamV2Inst<Int64Regs, ".b64">;
2122 def StoreParamV2I32  : StoreParamV2Inst<Int32Regs, ".b32">;
2123 def StoreParamV2I16  : StoreParamV2Inst<Int16Regs, ".b16">;
2124 def StoreParamV2I8   : StoreParamV2Inst<Int16Regs, ".b8">;
2126 def StoreParamV4I32  : StoreParamV4Inst<Int32Regs, ".b32">;
2127 def StoreParamV4I16  : StoreParamV4Inst<Int16Regs, ".b16">;
2128 def StoreParamV4I8   : StoreParamV4Inst<Int16Regs, ".b8">;
2130 def StoreParamF16      : StoreParamInst<Float16Regs, ".b16">;
2131 def StoreParamF16x2    : StoreParamInst<Float16x2Regs, ".b32">;
2132 def StoreParamF32      : StoreParamInst<Float32Regs, ".f32">;
2133 def StoreParamF64      : StoreParamInst<Float64Regs, ".f64">;
2134 def StoreParamV2F16    : StoreParamV2Inst<Float16Regs, ".b16">;
2135 def StoreParamV2F16x2  : StoreParamV2Inst<Float16x2Regs, ".b32">;
2136 def StoreParamV2F32    : StoreParamV2Inst<Float32Regs, ".f32">;
2137 def StoreParamV2F64    : StoreParamV2Inst<Float64Regs, ".f64">;
2138 def StoreParamV4F16    : StoreParamV4Inst<Float16Regs, ".b16">;
2139 def StoreParamV4F16x2  : StoreParamV4Inst<Float16x2Regs, ".b32">;
2140 def StoreParamV4F32    : StoreParamV4Inst<Float32Regs, ".f32">;
2142 def StoreRetvalI64    : StoreRetvalInst<Int64Regs, ".b64">;
2143 def StoreRetvalI32    : StoreRetvalInst<Int32Regs, ".b32">;
2144 def StoreRetvalI16    : StoreRetvalInst<Int16Regs, ".b16">;
2145 def StoreRetvalI8     : StoreRetvalInst<Int16Regs, ".b8">;
2146 def StoreRetvalV2I64  : StoreRetvalV2Inst<Int64Regs, ".b64">;
2147 def StoreRetvalV2I32  : StoreRetvalV2Inst<Int32Regs, ".b32">;
2148 def StoreRetvalV2I16  : StoreRetvalV2Inst<Int16Regs, ".b16">;
2149 def StoreRetvalV2I8   : StoreRetvalV2Inst<Int16Regs, ".b8">;
2150 def StoreRetvalV4I32  : StoreRetvalV4Inst<Int32Regs, ".b32">;
2151 def StoreRetvalV4I16  : StoreRetvalV4Inst<Int16Regs, ".b16">;
2152 def StoreRetvalV4I8   : StoreRetvalV4Inst<Int16Regs, ".b8">;
2154 def StoreRetvalF64    : StoreRetvalInst<Float64Regs, ".f64">;
2155 def StoreRetvalF32    : StoreRetvalInst<Float32Regs, ".f32">;
2156 def StoreRetvalF16    : StoreRetvalInst<Float16Regs, ".b16">;
2157 def StoreRetvalF16x2  : StoreRetvalInst<Float16x2Regs, ".b32">;
2158 def StoreRetvalV2F64  : StoreRetvalV2Inst<Float64Regs, ".f64">;
2159 def StoreRetvalV2F32  : StoreRetvalV2Inst<Float32Regs, ".f32">;
2160 def StoreRetvalV2F16  : StoreRetvalV2Inst<Float16Regs, ".b16">;
2161 def StoreRetvalV2F16x2: StoreRetvalV2Inst<Float16x2Regs, ".b32">;
2162 def StoreRetvalV4F32  : StoreRetvalV4Inst<Float32Regs, ".f32">;
2163 def StoreRetvalV4F16  : StoreRetvalV4Inst<Float16Regs, ".b16">;
2164 def StoreRetvalV4F16x2: StoreRetvalV4Inst<Float16x2Regs, ".b32">;
2166 def CallArgBeginInst : NVPTXInst<(outs), (ins), "(", [(CallArgBegin)]>;
2167 def CallArgEndInst1  : NVPTXInst<(outs), (ins), ");", [(CallArgEnd (i32 1))]>;
2168 def CallArgEndInst0  : NVPTXInst<(outs), (ins), ")", [(CallArgEnd (i32 0))]>;
2169 def RETURNInst       : NVPTXInst<(outs), (ins), "ret;", [(RETURNNode)]>;
2171 class CallArgInst<NVPTXRegClass regclass> :
2172   NVPTXInst<(outs), (ins regclass:$a), "$a, ",
2173             [(CallArg (i32 0), regclass:$a)]>;
2175 class LastCallArgInst<NVPTXRegClass regclass> :
2176   NVPTXInst<(outs), (ins regclass:$a), "$a",
2177             [(LastCallArg (i32 0), regclass:$a)]>;
2179 def CallArgI64     : CallArgInst<Int64Regs>;
2180 def CallArgI32     : CallArgInst<Int32Regs>;
2181 def CallArgI16     : CallArgInst<Int16Regs>;
2182 def CallArgF64     : CallArgInst<Float64Regs>;
2183 def CallArgF32     : CallArgInst<Float32Regs>;
2185 def LastCallArgI64 : LastCallArgInst<Int64Regs>;
2186 def LastCallArgI32 : LastCallArgInst<Int32Regs>;
2187 def LastCallArgI16 : LastCallArgInst<Int16Regs>;
2188 def LastCallArgF64 : LastCallArgInst<Float64Regs>;
2189 def LastCallArgF32 : LastCallArgInst<Float32Regs>;
2191 def CallArgI32imm : NVPTXInst<(outs), (ins i32imm:$a), "$a, ",
2192                               [(CallArg (i32 0), (i32 imm:$a))]>;
2193 def LastCallArgI32imm : NVPTXInst<(outs), (ins i32imm:$a), "$a",
2194                                   [(LastCallArg (i32 0), (i32 imm:$a))]>;
2196 def CallArgParam : NVPTXInst<(outs), (ins i32imm:$a), "param$a, ",
2197                              [(CallArg (i32 1), (i32 imm:$a))]>;
2198 def LastCallArgParam : NVPTXInst<(outs), (ins i32imm:$a), "param$a",
2199                                  [(LastCallArg (i32 1), (i32 imm:$a))]>;
2201 def CallVoidInst :      NVPTXInst<(outs), (ins imem:$addr), "$addr, ",
2202                                   [(CallVoid (Wrapper tglobaladdr:$addr))]>;
2203 def CallVoidInstReg :   NVPTXInst<(outs), (ins Int32Regs:$addr), "$addr, ",
2204                                   [(CallVoid Int32Regs:$addr)]>;
2205 def CallVoidInstReg64 : NVPTXInst<(outs), (ins Int64Regs:$addr), "$addr, ",
2206                                   [(CallVoid Int64Regs:$addr)]>;
2207 def PrototypeInst :     NVPTXInst<(outs), (ins i32imm:$val), ", prototype_$val;",
2208                                   [(Prototype (i32 imm:$val))]>;
2210 def 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))]>;
2214 def 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))]>;
2218 def 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))]>;
2223 def 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))]>;
2227 def 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))]>;
2231 def 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))]>;
2236 class 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))]>;
2241 def MoveParamI64 : MoveParamInst<Int64Regs, ".b64">;
2242 def MoveParamI32 : MoveParamInst<Int32Regs, ".b32">;
2243 def MoveParamI16 :
2244   NVPTXInst<(outs Int16Regs:$dst), (ins Int16Regs:$src),
2245             "cvt.u16.u32 \t$dst, $src;",
2246             [(set Int16Regs:$dst, (MoveParam Int16Regs:$src))]>;
2247 def MoveParamF64 : MoveParamInst<Float64Regs, ".f64">;
2248 def MoveParamF32 : MoveParamInst<Float32Regs, ".f32">;
2249 def MoveParamF16 : MoveParamInst<Float16Regs, ".f16">;
2251 class PseudoUseParamInst<NVPTXRegClass regclass> :
2252   NVPTXInst<(outs), (ins regclass:$src),
2253             "// Pseudo use of $src",
2254             [(PseudoUseParam regclass:$src)]>;
2256 def PseudoUseParamI64 : PseudoUseParamInst<Int64Regs>;
2257 def PseudoUseParamI32 : PseudoUseParamInst<Int32Regs>;
2258 def PseudoUseParamI16 : PseudoUseParamInst<Int16Regs>;
2259 def PseudoUseParamF64 : PseudoUseParamInst<Float64Regs>;
2260 def PseudoUseParamF32 : PseudoUseParamInst<Float32Regs>;
2262 class 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))]>;
2267 let 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>;
2279 // Load / Store Handling
2281 multiclass 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];", []>;
2320 let 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>;
2331 multiclass 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;", []>;
2370 let 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>;
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.
2384 multiclass 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];", []>;
2458 let 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>;
2469 multiclass 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}};", []>;
2553 let 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>;
2564 //---- Conversion ----
2566 class 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))]>;
2572 def BITCONVERT_16_I2F : F_BITCONVERT<"16", Int16Regs, Float16Regs>;
2573 def BITCONVERT_16_F2I : F_BITCONVERT<"16", Float16Regs, Int16Regs>;
2574 def BITCONVERT_32_I2F : F_BITCONVERT<"32", Int32Regs, Float32Regs>;
2575 def BITCONVERT_32_F2I : F_BITCONVERT<"32", Float32Regs, Int32Regs>;
2576 def BITCONVERT_64_I2F : F_BITCONVERT<"64", Int64Regs, Float64Regs>;
2577 def BITCONVERT_64_F2I : F_BITCONVERT<"64", Float64Regs, Int64Regs>;
2578 def BITCONVERT_32_I2F16x2 : F_BITCONVERT<"32", Int32Regs, Float16x2Regs>;
2579 def BITCONVERT_32_F16x22I : F_BITCONVERT<"32", Float16x2Regs, Int32Regs>;
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.
2585 // sint -> f16
2586 def : Pat<(f16 (sint_to_fp Int1Regs:$a)),
2587           (CVT_f16_s32 (SELP_u32ii 1, 0, Int1Regs:$a), CvtRN)>;
2588 def : Pat<(f16 (sint_to_fp Int16Regs:$a)),
2589           (CVT_f16_s16 Int16Regs:$a, CvtRN)>;
2590 def : Pat<(f16 (sint_to_fp Int32Regs:$a)),
2591           (CVT_f16_s32 Int32Regs:$a, CvtRN)>;
2592 def : Pat<(f16 (sint_to_fp Int64Regs:$a)),
2593           (CVT_f16_s64 Int64Regs:$a, CvtRN)>;
2595 // uint -> f16
2596 def : Pat<(f16 (uint_to_fp Int1Regs:$a)),
2597           (CVT_f16_u32 (SELP_u32ii 1, 0, Int1Regs:$a), CvtRN)>;
2598 def : Pat<(f16 (uint_to_fp Int16Regs:$a)),
2599           (CVT_f16_u16 Int16Regs:$a, CvtRN)>;
2600 def : Pat<(f16 (uint_to_fp Int32Regs:$a)),
2601           (CVT_f16_u32 Int32Regs:$a, CvtRN)>;
2602 def : Pat<(f16 (uint_to_fp Int64Regs:$a)),
2603           (CVT_f16_u64 Int64Regs:$a, CvtRN)>;
2605 // sint -> f32
2606 def : Pat<(f32 (sint_to_fp Int1Regs:$a)),
2607           (CVT_f32_s32 (SELP_u32ii 1, 0, Int1Regs:$a), CvtRN)>;
2608 def : Pat<(f32 (sint_to_fp Int16Regs:$a)),
2609           (CVT_f32_s16 Int16Regs:$a, CvtRN)>;
2610 def : Pat<(f32 (sint_to_fp Int32Regs:$a)),
2611           (CVT_f32_s32 Int32Regs:$a, CvtRN)>;
2612 def : Pat<(f32 (sint_to_fp Int64Regs:$a)),
2613           (CVT_f32_s64 Int64Regs:$a, CvtRN)>;
2615 // uint -> f32
2616 def : Pat<(f32 (uint_to_fp Int1Regs:$a)),
2617           (CVT_f32_u32 (SELP_u32ii 1, 0, Int1Regs:$a), CvtRN)>;
2618 def : Pat<(f32 (uint_to_fp Int16Regs:$a)),
2619           (CVT_f32_u16 Int16Regs:$a, CvtRN)>;
2620 def : Pat<(f32 (uint_to_fp Int32Regs:$a)),
2621           (CVT_f32_u32 Int32Regs:$a, CvtRN)>;
2622 def : Pat<(f32 (uint_to_fp Int64Regs:$a)),
2623           (CVT_f32_u64 Int64Regs:$a, CvtRN)>;
2625 // sint -> f64
2626 def : Pat<(f64 (sint_to_fp Int1Regs:$a)),
2627           (CVT_f64_s32 (SELP_u32ii 1, 0, Int1Regs:$a), CvtRN)>;
2628 def : Pat<(f64 (sint_to_fp Int16Regs:$a)),
2629           (CVT_f64_s16 Int16Regs:$a, CvtRN)>;
2630 def : Pat<(f64 (sint_to_fp Int32Regs:$a)),
2631           (CVT_f64_s32 Int32Regs:$a, CvtRN)>;
2632 def : Pat<(f64 (sint_to_fp Int64Regs:$a)),
2633           (CVT_f64_s64 Int64Regs:$a, CvtRN)>;
2635 // uint -> f64
2636 def : Pat<(f64 (uint_to_fp Int1Regs:$a)),
2637           (CVT_f64_u32 (SELP_u32ii 1, 0, Int1Regs:$a), CvtRN)>;
2638 def : Pat<(f64 (uint_to_fp Int16Regs:$a)),
2639           (CVT_f64_u16 Int16Regs:$a, CvtRN)>;
2640 def : Pat<(f64 (uint_to_fp Int32Regs:$a)),
2641           (CVT_f64_u32 Int32Regs:$a, CvtRN)>;
2642 def : Pat<(f64 (uint_to_fp Int64Regs:$a)),
2643           (CVT_f64_u64 Int64Regs:$a, CvtRN)>;
2646 // f16 -> sint
2647 def : Pat<(i1 (fp_to_sint Float16Regs:$a)),
2648           (SETP_b16ri (BITCONVERT_16_F2I Float16Regs:$a), 0, CmpEQ)>;
2649 def : Pat<(i16 (fp_to_sint Float16Regs:$a)),
2650           (CVT_s16_f16 Float16Regs:$a, CvtRZI)>;
2651 def : Pat<(i32 (fp_to_sint Float16Regs:$a)),
2652           (CVT_s32_f16 Float16Regs:$a, CvtRZI)>;
2653 def : Pat<(i64 (fp_to_sint Float16Regs:$a)),
2654           (CVT_s64_f16 Float16Regs:$a, CvtRZI)>;
2656 // f16 -> uint
2657 def : Pat<(i1 (fp_to_uint Float16Regs:$a)),
2658           (SETP_b16ri (BITCONVERT_16_F2I Float16Regs:$a), 0, CmpEQ)>;
2659 def : Pat<(i16 (fp_to_uint Float16Regs:$a)),
2660           (CVT_u16_f16 Float16Regs:$a, CvtRZI)>;
2661 def : Pat<(i32 (fp_to_uint Float16Regs:$a)),
2662           (CVT_u32_f16 Float16Regs:$a, CvtRZI)>;
2663 def : Pat<(i64 (fp_to_uint Float16Regs:$a)),
2664           (CVT_u64_f16 Float16Regs:$a, CvtRZI)>;
2666 // f32 -> sint
2667 def : Pat<(i1 (fp_to_sint Float32Regs:$a)),
2668           (SETP_b32ri (BITCONVERT_32_F2I Float32Regs:$a), 0, CmpEQ)>;
2669 def : Pat<(i16 (fp_to_sint Float32Regs:$a)),
2670           (CVT_s16_f32 Float32Regs:$a, CvtRZI_FTZ)>, Requires<[doF32FTZ]>;
2671 def : Pat<(i16 (fp_to_sint Float32Regs:$a)),
2672           (CVT_s16_f32 Float32Regs:$a, CvtRZI)>;
2673 def : Pat<(i32 (fp_to_sint Float32Regs:$a)),
2674           (CVT_s32_f32 Float32Regs:$a, CvtRZI_FTZ)>, Requires<[doF32FTZ]>;
2675 def : Pat<(i32 (fp_to_sint Float32Regs:$a)),
2676           (CVT_s32_f32 Float32Regs:$a, CvtRZI)>;
2677 def : Pat<(i64 (fp_to_sint Float32Regs:$a)),
2678           (CVT_s64_f32 Float32Regs:$a, CvtRZI_FTZ)>, Requires<[doF32FTZ]>;
2679 def : Pat<(i64 (fp_to_sint Float32Regs:$a)),
2680           (CVT_s64_f32 Float32Regs:$a, CvtRZI)>;
2682 // f32 -> uint
2683 def : Pat<(i1 (fp_to_uint Float32Regs:$a)),
2684           (SETP_b32ri (BITCONVERT_32_F2I Float32Regs:$a), 0, CmpEQ)>;
2685 def : Pat<(i16 (fp_to_uint Float32Regs:$a)),
2686           (CVT_u16_f32 Float32Regs:$a, CvtRZI_FTZ)>, Requires<[doF32FTZ]>;
2687 def : Pat<(i16 (fp_to_uint Float32Regs:$a)),
2688           (CVT_u16_f32 Float32Regs:$a, CvtRZI)>;
2689 def : Pat<(i32 (fp_to_uint Float32Regs:$a)),
2690           (CVT_u32_f32 Float32Regs:$a, CvtRZI_FTZ)>, Requires<[doF32FTZ]>;
2691 def : Pat<(i32 (fp_to_uint Float32Regs:$a)),
2692           (CVT_u32_f32 Float32Regs:$a, CvtRZI)>;
2693 def : Pat<(i64 (fp_to_uint Float32Regs:$a)),
2694           (CVT_u64_f32 Float32Regs:$a, CvtRZI_FTZ)>, Requires<[doF32FTZ]>;
2695 def : Pat<(i64 (fp_to_uint Float32Regs:$a)),
2696           (CVT_u64_f32 Float32Regs:$a, CvtRZI)>;
2698 // f64 -> sint
2699 def : Pat<(i1 (fp_to_sint Float64Regs:$a)),
2700           (SETP_b64ri (BITCONVERT_64_F2I Float64Regs:$a), 0, CmpEQ)>;
2701 def : Pat<(i16 (fp_to_sint Float64Regs:$a)),
2702           (CVT_s16_f64 Float64Regs:$a, CvtRZI)>;
2703 def : Pat<(i32 (fp_to_sint Float64Regs:$a)),
2704           (CVT_s32_f64 Float64Regs:$a, CvtRZI)>;
2705 def : Pat<(i64 (fp_to_sint Float64Regs:$a)),
2706           (CVT_s64_f64 Float64Regs:$a, CvtRZI)>;
2708 // f64 -> uint
2709 def : Pat<(i1 (fp_to_uint Float64Regs:$a)),
2710           (SETP_b64ri (BITCONVERT_64_F2I Float64Regs:$a), 0, CmpEQ)>;
2711 def : Pat<(i16 (fp_to_uint Float64Regs:$a)),
2712           (CVT_u16_f64 Float64Regs:$a, CvtRZI)>;
2713 def : Pat<(i32 (fp_to_uint Float64Regs:$a)),
2714           (CVT_u32_f64 Float64Regs:$a, CvtRZI)>;
2715 def : Pat<(i64 (fp_to_uint Float64Regs:$a)),
2716           (CVT_u64_f64 Float64Regs:$a, CvtRZI)>;
2718 // sext i1
2719 def : Pat<(i16 (sext Int1Regs:$a)),
2720           (SELP_s16ii -1, 0, Int1Regs:$a)>;
2721 def : Pat<(i32 (sext Int1Regs:$a)),
2722           (SELP_s32ii -1, 0, Int1Regs:$a)>;
2723 def : Pat<(i64 (sext Int1Regs:$a)),
2724           (SELP_s64ii -1, 0, Int1Regs:$a)>;
2726 // zext i1
2727 def : Pat<(i16 (zext Int1Regs:$a)),
2728           (SELP_u16ii 1, 0, Int1Regs:$a)>;
2729 def : Pat<(i32 (zext Int1Regs:$a)),
2730           (SELP_u32ii 1, 0, Int1Regs:$a)>;
2731 def : Pat<(i64 (zext Int1Regs:$a)),
2732           (SELP_u64ii 1, 0, Int1Regs:$a)>;
2734 // anyext i1
2735 def : Pat<(i16 (anyext Int1Regs:$a)),
2736           (SELP_u16ii -1, 0, Int1Regs:$a)>;
2737 def : Pat<(i32 (anyext Int1Regs:$a)),
2738           (SELP_u32ii -1, 0, Int1Regs:$a)>;
2739 def : Pat<(i64 (anyext Int1Regs:$a)),
2740           (SELP_u64ii -1, 0, Int1Regs:$a)>;
2742 // sext i16
2743 def : Pat<(i32 (sext Int16Regs:$a)),
2744           (CVT_s32_s16 Int16Regs:$a, CvtNONE)>;
2745 def : Pat<(i64 (sext Int16Regs:$a)),
2746           (CVT_s64_s16 Int16Regs:$a, CvtNONE)>;
2748 // zext i16
2749 def : Pat<(i32 (zext Int16Regs:$a)),
2750           (CVT_u32_u16 Int16Regs:$a, CvtNONE)>;
2751 def : Pat<(i64 (zext Int16Regs:$a)),
2752           (CVT_u64_u16 Int16Regs:$a, CvtNONE)>;
2754 // anyext i16
2755 def : Pat<(i32 (anyext Int16Regs:$a)),
2756           (CVT_u32_u16 Int16Regs:$a, CvtNONE)>;
2757 def : Pat<(i64 (anyext Int16Regs:$a)),
2758           (CVT_u64_u16 Int16Regs:$a, CvtNONE)>;
2760 // sext i32
2761 def : Pat<(i64 (sext Int32Regs:$a)),
2762           (CVT_s64_s32 Int32Regs:$a, CvtNONE)>;
2764 // zext i32
2765 def : Pat<(i64 (zext Int32Regs:$a)),
2766           (CVT_u64_u32 Int32Regs:$a, CvtNONE)>;
2768 // anyext i32
2769 def : Pat<(i64 (anyext Int32Regs:$a)),
2770           (CVT_u64_u32 Int32Regs:$a, CvtNONE)>;
2773 // truncate i64
2774 def : Pat<(i32 (trunc Int64Regs:$a)),
2775           (CVT_u32_u64 Int64Regs:$a, CvtNONE)>;
2776 def : Pat<(i16 (trunc Int64Regs:$a)),
2777           (CVT_u16_u64 Int64Regs:$a, CvtNONE)>;
2778 def : Pat<(i1 (trunc Int64Regs:$a)),
2779           (SETP_b64ri (ANDb64ri Int64Regs:$a, 1), 1, CmpEQ)>;
2781 // truncate i32
2782 def : Pat<(i16 (trunc Int32Regs:$a)),
2783           (CVT_u16_u32 Int32Regs:$a, CvtNONE)>;
2784 def : Pat<(i1 (trunc Int32Regs:$a)),
2785           (SETP_b32ri (ANDb32ri Int32Regs:$a, 1), 1, CmpEQ)>;
2787 // truncate i16
2788 def : Pat<(i1 (trunc Int16Regs:$a)),
2789           (SETP_b16ri (ANDb16ri Int16Regs:$a, 1), 1, CmpEQ)>;
2791 // sext_inreg
2792 def : Pat<(sext_inreg Int16Regs:$a, i8), (CVT_INREG_s16_s8 Int16Regs:$a)>;
2793 def : Pat<(sext_inreg Int32Regs:$a, i8), (CVT_INREG_s32_s8 Int32Regs:$a)>;
2794 def : Pat<(sext_inreg Int32Regs:$a, i16), (CVT_INREG_s32_s16 Int32Regs:$a)>;
2795 def : Pat<(sext_inreg Int64Regs:$a, i8), (CVT_INREG_s64_s8 Int64Regs:$a)>;
2796 def : Pat<(sext_inreg Int64Regs:$a, i16), (CVT_INREG_s64_s16 Int64Regs:$a)>;
2797 def : Pat<(sext_inreg Int64Regs:$a, i32), (CVT_INREG_s64_s32 Int64Regs:$a)>;
2800 // Select instructions with 32-bit predicates
2801 def : Pat<(select Int32Regs:$pred, Int16Regs:$a, Int16Regs:$b),
2802           (SELP_b16rr Int16Regs:$a, Int16Regs:$b,
2803           (SETP_b32ri (ANDb32ri Int32Regs:$pred, 1), 1, CmpEQ))>;
2804 def : Pat<(select Int32Regs:$pred, Int32Regs:$a, Int32Regs:$b),
2805           (SELP_b32rr Int32Regs:$a, Int32Regs:$b,
2806           (SETP_b32ri (ANDb32ri Int32Regs:$pred, 1), 1, CmpEQ))>;
2807 def : Pat<(select Int32Regs:$pred, Int64Regs:$a, Int64Regs:$b),
2808           (SELP_b64rr Int64Regs:$a, Int64Regs:$b,
2809           (SETP_b32ri (ANDb32ri Int32Regs:$pred, 1), 1, CmpEQ))>;
2810 def : Pat<(select Int32Regs:$pred, Float16Regs:$a, Float16Regs:$b),
2811           (SELP_f16rr Float16Regs:$a, Float16Regs:$b,
2812           (SETP_b32ri (ANDb32ri Int32Regs:$pred, 1), 1, CmpEQ))>;
2813 def : Pat<(select Int32Regs:$pred, Float32Regs:$a, Float32Regs:$b),
2814           (SELP_f32rr Float32Regs:$a, Float32Regs:$b,
2815           (SETP_b32ri (ANDb32ri Int32Regs:$pred, 1), 1, CmpEQ))>;
2816 def : Pat<(select Int32Regs:$pred, Float64Regs:$a, Float64Regs:$b),
2817           (SELP_f64rr Float64Regs:$a, Float64Regs:$b,
2818           (SETP_b32ri (ANDb32ri Int32Regs:$pred, 1), 1, CmpEQ))>;
2821 let 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}};", []>;
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;", []>;
2854 let 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))]>;
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)))]>;
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                               []>;
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                                    []>;
2896 // Count leading zeros
2897 let 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;", []>;
2904 // 32-bit has a direct PTX instruction
2905 def : Pat<(ctlz Int32Regs:$a), (CLZr32 Int32Regs:$a)>;
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.
2911 def : Pat<(ctlz Int64Regs:$a), (CVT_u64_u32 (CLZr64 Int64Regs:$a), CvtNONE)>;
2912 def : Pat<(i32 (trunc (ctlz Int64Regs:$a))), (CLZr64 Int64Regs:$a)>;
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.
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):
2921 //   mov.b32 $tmp, {0xffff, $a}
2922 //   ctlz.b32 $result, $tmp
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.
2928 def : Pat<(ctlz Int16Regs:$a),
2929           (SUBi16ri (CVT_u16_u32
2930            (CLZr32 (CVT_u32_u16 Int16Regs:$a, CvtNONE)), CvtNONE), 16)>;
2931 def : Pat<(i32 (zext (ctlz Int16Regs:$a))),
2932           (SUBi32ri (CLZr32 (CVT_u32_u16 Int16Regs:$a, CvtNONE)), 16)>;
2934 // Population count
2935 let 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;", []>;
2942 // 32-bit has a direct PTX instruction
2943 def : Pat<(ctpop Int32Regs:$a), (POPCr32 Int32Regs:$a)>;
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.
2949 def : Pat<(ctpop Int64Regs:$a), (CVT_u64_u32 (POPCr64 Int64Regs:$a), CvtNONE)>;
2950 def : Pat<(i32 (trunc (ctpop Int64Regs:$a))), (POPCr64 Int64Regs:$a)>;
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.
2954 def : Pat<(ctpop Int16Regs:$a),
2955           (CVT_u16_u32 (POPCr32 (CVT_u32_u16 Int16Regs:$a, CvtNONE)), CvtNONE)>;
2956 def : Pat<(i32 (zext (ctpop Int16Regs:$a))),
2957           (POPCr32 (CVT_u32_u16 Int16Regs:$a, CvtNONE))>;
2959 // fpround f32 -> f16
2960 def : Pat<(f16 (fpround Float32Regs:$a)),
2961           (CVT_f16_f32 Float32Regs:$a, CvtRN)>;
2963 // fpround f64 -> f16
2964 def : Pat<(f16 (fpround Float64Regs:$a)),
2965           (CVT_f16_f64 Float64Regs:$a, CvtRN)>;
2967 // fpround f64 -> f32
2968 def : Pat<(f32 (fpround Float64Regs:$a)),
2969           (CVT_f32_f64 Float64Regs:$a, CvtRN_FTZ)>, Requires<[doF32FTZ]>;
2970 def : Pat<(f32 (fpround Float64Regs:$a)),
2971           (CVT_f32_f64 Float64Regs:$a, CvtRN)>;
2973 // fpextend f16 -> f32
2974 def : Pat<(f32 (fpextend Float16Regs:$a)),
2975           (CVT_f32_f16 Float16Regs:$a, CvtNONE_FTZ)>, Requires<[doF32FTZ]>;
2976 def : Pat<(f32 (fpextend Float16Regs:$a)),
2977           (CVT_f32_f16 Float16Regs:$a, CvtNONE)>;
2979 // fpextend f16 -> f64
2980 def : Pat<(f64 (fpextend Float16Regs:$a)),
2981           (CVT_f64_f16 Float16Regs:$a, CvtNONE)>;
2983 // fpextend f32 -> f64
2984 def : Pat<(f64 (fpextend Float32Regs:$a)),
2985           (CVT_f64_f32 Float32Regs:$a, CvtNONE_FTZ)>, Requires<[doF32FTZ]>;
2986 def : Pat<(f64 (fpextend Float32Regs:$a)),
2987           (CVT_f64_f32 Float32Regs:$a, CvtNONE)>;
2989 def retflag : SDNode<"NVPTXISD::RET_FLAG", SDTNone,
2990                      [SDNPHasChain, SDNPOptInGlue]>;
2992 // fceil, ffloor, fround, ftrunc.
2994 def : Pat<(fceil Float16Regs:$a),
2995           (CVT_f16_f16 Float16Regs:$a, CvtRPI)>;
2996 def : Pat<(fceil Float32Regs:$a),
2997           (CVT_f32_f32 Float32Regs:$a, CvtRPI_FTZ)>, Requires<[doF32FTZ]>;
2998 def : Pat<(fceil Float32Regs:$a),
2999           (CVT_f32_f32 Float32Regs:$a, CvtRPI)>, Requires<[doNoF32FTZ]>;
3000 def : Pat<(fceil Float64Regs:$a),
3001           (CVT_f64_f64 Float64Regs:$a, CvtRPI)>;
3003 def : Pat<(ffloor Float16Regs:$a),
3004           (CVT_f16_f16 Float16Regs:$a, CvtRMI)>;
3005 def : Pat<(ffloor Float32Regs:$a),
3006           (CVT_f32_f32 Float32Regs:$a, CvtRMI_FTZ)>, Requires<[doF32FTZ]>;
3007 def : Pat<(ffloor Float32Regs:$a),
3008           (CVT_f32_f32 Float32Regs:$a, CvtRMI)>, Requires<[doNoF32FTZ]>;
3009 def : Pat<(ffloor Float64Regs:$a),
3010           (CVT_f64_f64 Float64Regs:$a, CvtRMI)>;
3012 def : Pat<(ftrunc Float16Regs:$a),
3013           (CVT_f16_f16 Float16Regs:$a, CvtRZI)>;
3014 def : Pat<(ftrunc Float32Regs:$a),
3015           (CVT_f32_f32 Float32Regs:$a, CvtRZI_FTZ)>, Requires<[doF32FTZ]>;
3016 def : Pat<(ftrunc Float32Regs:$a),
3017           (CVT_f32_f32 Float32Regs:$a, CvtRZI)>, Requires<[doNoF32FTZ]>;
3018 def : Pat<(ftrunc Float64Regs:$a),
3019           (CVT_f64_f64 Float64Regs:$a, CvtRZI)>;
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.
3025 def : Pat<(fnearbyint Float16Regs:$a),
3026           (CVT_f16_f16 Float16Regs:$a, CvtRNI)>;
3027 def : Pat<(fnearbyint Float32Regs:$a),
3028           (CVT_f32_f32 Float32Regs:$a, CvtRNI_FTZ)>, Requires<[doF32FTZ]>;
3029 def : Pat<(fnearbyint Float32Regs:$a),
3030           (CVT_f32_f32 Float32Regs:$a, CvtRNI)>, Requires<[doNoF32FTZ]>;
3031 def : Pat<(fnearbyint Float64Regs:$a),
3032           (CVT_f64_f64 Float64Regs:$a, CvtRNI)>;
3034 def : Pat<(frint Float16Regs:$a),
3035           (CVT_f16_f16 Float16Regs:$a, CvtRNI)>;
3036 def : Pat<(frint Float32Regs:$a),
3037           (CVT_f32_f32 Float32Regs:$a, CvtRNI_FTZ)>, Requires<[doF32FTZ]>;
3038 def : Pat<(frint Float32Regs:$a),
3039           (CVT_f32_f32 Float32Regs:$a, CvtRNI)>, Requires<[doNoF32FTZ]>;
3040 def : Pat<(frint Float64Regs:$a),
3041           (CVT_f64_f64 Float64Regs:$a, CvtRNI)>;
3044 //-----------------------------------
3045 // Control-flow
3046 //-----------------------------------
3048 let isTerminator=1 in {
3049    let isReturn=1, isBarrier=1 in
3050       def Return : NVPTXInst<(outs), (ins), "ret;", [(retflag)]>;
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;", []>;
3060    let isBranch=1, isBarrier=1 in
3061       def GOTO : NVPTXInst<(outs), (ins brtarget:$target),
3062                            "bra.uni \t$target;", [(br bb:$target)]>;
3065 def : Pat<(brcond Int32Regs:$a, bb:$target),
3066           (CBranch (SETP_u32ri Int32Regs:$a, 0, CmpNE), bb:$target)>;
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.
3073 def : Pat<(brcond (i1 (setne Int1Regs:$a, -1)), bb:$target),
3074           (CBranchOther Int1Regs:$a, bb:$target)>;
3076 // Call
3077 def SDT_NVPTXCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>,
3078                                             SDTCisVT<1, i32>]>;
3079 def SDT_NVPTXCallSeqEnd   : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
3081 def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_NVPTXCallSeqStart,
3082                            [SDNPHasChain, SDNPOutGlue, SDNPSideEffect]>;
3083 def callseq_end   : SDNode<"ISD::CALLSEQ_END", SDT_NVPTXCallSeqEnd,
3084                            [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
3085                             SDNPSideEffect]>;
3087 def SDT_NVPTXCall : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
3088 def call          : SDNode<"NVPTXISD::CALL", SDT_NVPTXCall,
3089                            [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
3090 def calltarget : Operand<i32>;
3091 let isCall=1 in {
3092    def CALL : NVPTXInst<(outs), (ins calltarget:$dst), "call \t$dst, (1);", []>;
3095 def : Pat<(call tglobaladdr:$dst), (CALL tglobaladdr:$dst)>;
3096 def : Pat<(call texternalsym:$dst), (CALL texternalsym:$dst)>;
3098 // Pseudo instructions.
3099 class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
3100    : NVPTXInst<outs, ins, asmstr, pattern>;
3102 def 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)]>;
3107 def Callseq_End :
3108   NVPTXInst<(outs), (ins i32imm:$amt1, i32imm:$amt2),
3109             "\\} // callseq $amt1",
3110             [(callseq_end timm:$amt1, timm:$amt2)]>;
3112 // trap instruction
3113 def trapinst : NVPTXInst<(outs), (ins), "trap;", [(trap)]>;
3115 // Call prototype wrapper
3116 def SDTCallPrototype : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
3117 def CallPrototype :
3118   SDNode<"NVPTXISD::CallPrototype", SDTCallPrototype,
3119          [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
3120 def ProtoIdent : Operand<i32> {
3121   let PrintMethod = "printProtoIdent";
3123 def CALL_PROTOTYPE :
3124   NVPTXInst<(outs), (ins ProtoIdent:$ident),
3125             "$ident", [(CallPrototype (i32 texternalsym:$ident))]>;
3128 include "NVPTXIntrinsics.td"
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.