1 //===- NVPTXInstrInfo.td - NVPTX Instruction defs -------------*- tblgen-*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file describes the PTX instructions in TableGen format.
11 //===----------------------------------------------------------------------===//
13 include "NVPTXInstrFormats.td"
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";
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> {
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))]>;
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))]>;
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))]>;
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))]>;
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))]>;
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> {
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))]>;
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
210 multiclass F3<string OpcStr, SDNode OpNode> {
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))]>;
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))]>;
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]>;
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]>;
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))]>;
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> {
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]>;
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]>;
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]>;
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]>;
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]>;
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]>;
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]>;
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]>;
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]>;
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.
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))]>,
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))]>,
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]>;
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]>;
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))]>,
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))]>,
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]>;
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]>;
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]>;
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 //-----------------------------------
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> {
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;"), []>;
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;"), []>;
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;"), []>;
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;"), []>;
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;"), []>;
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;"), []>;
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;"), []>;
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;"), []>;
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;"), []>;
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;"), []>;
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;"), []>;
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
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">;
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
563 NVPTXInst<(outs Int64Regs:$dst), (ins Int32Regs:$a, Int32Regs:$b),
564 "mul.wide.s32 \t$dst, $a, $b;", []>;
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;", []>;
573 NVPTXInst<(outs Int64Regs:$dst), (ins Int32Regs:$a, Int32Regs:$b),
574 "mul.wide.u32 \t$dst, $a, $b;", []>;
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;", []>;
583 NVPTXInst<(outs Int32Regs:$dst), (ins Int16Regs:$a, Int16Regs:$b),
584 "mul.wide.s16 \t$dst, $a, $b;", []>;
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;", []>;
593 NVPTXInst<(outs Int32Regs:$dst), (ins Int16Regs:$a, Int16Regs:$b),
594 "mul.wide.u16 \t$dst, $a, $b;", []>;
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);
639 def UInt32Const : PatLeaf<(imm), [{
640 const APInt &v = N->getAPIntValue();
644 def SInt16Const : PatLeaf<(imm), [{
645 const APInt &v = N->getAPIntValue();
646 return v.isSignedIntN(16);
649 def UInt16Const : PatLeaf<(imm), [{
650 const APInt &v = N->getAPIntValue();
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);
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);
666 def SHL2MUL32 : SDNodeXForm<imm, [{
667 const APInt &v = N->getAPIntValue();
669 return CurDAG->getTargetConstant(temp.shl(v), SDLoc(N), MVT::i32);
672 def SHL2MUL16 : SDNodeXForm<imm, [{
673 const APInt &v = N->getAPIntValue();
675 return CurDAG->getTargetConstant(temp.shl(v), SDLoc(N), MVT::i16);
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
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>;
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))]>;
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))]>;
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))]>;
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))]>;
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))]>;
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))]>;
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))]>;
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))]>;
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))]>;
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))]>;
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))]>;
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))]>;
794 NVPTXInst<(outs Int16Regs:$dst), (ins Int16Regs:$src),
795 "neg.s16 \t$dst, $src;",
796 [(set Int16Regs:$dst, (ineg Int16Regs:$src))]>;
798 NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$src),
799 "neg.s32 \t$dst, $src;",
800 [(set Int32Regs:$dst, (ineg Int32Regs:$src))]>;
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 //-----------------------------------
811 def FloatConst1 : PatLeaf<(fpimm), [{
812 return &N->getValueAPF().getSemantics() == &llvm::APFloat::IEEEsingle() &&
813 N->getValueAPF().convertToFloat() == 1.0f;
815 // Constant 1.0 (double)
816 def DoubleConst1 : PatLeaf<(fpimm), [{
817 return &N->getValueAPF().getSemantics() == &llvm::APFloat::IEEEdouble() &&
818 N->getValueAPF().convertToDouble() == 1.0;
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.
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>;
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))]>;
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))]>;
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
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]>;
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]>;
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]>;
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
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]>;
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]>;
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]>;
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]>;
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]>;
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))]>;
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))]>;
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))]>,
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))]>,
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))]>,
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))]>,
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>;
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()"
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),
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),
1050 Requires<[doF32FTZ]>;
1053 def : Pat<(frem Float32Regs:$x, Float32Regs:$y),
1054 (FSUBf32rr Float32Regs:$x, (FMULf32rr (CVT_f32_f32
1055 (FDIV32rr_prec Float32Regs:$x, Float32Regs:$y), CvtRMI),
1057 def : Pat<(frem Float32Regs:$x, fpimm:$y),
1058 (FSUBf32rr Float32Regs:$x, (FMULf32ri (CVT_f32_f32
1059 (FDIV32ri_prec Float32Regs:$x, fpimm:$y), CvtRMI),
1063 def : Pat<(frem Float64Regs:$x, Float64Regs:$y),
1064 (FSUBf64rr Float64Regs:$x, (FMULf64rr (CVT_f64_f64
1065 (FDIV64rr Float64Regs:$x, Float64Regs:$y), CvtRMI),
1067 def : Pat<(frem Float64Regs:$x, fpimm:$y),
1068 (FSUBf64rr Float64Regs:$x, (FMULf64ri (CVT_f64_f64
1069 (FDIV64ri Float64Regs:$x, fpimm:$y), CvtRMI),
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> {
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))]>;
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))]>;
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))]>;
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))]>;
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))]>;
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))]>;
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))]>;
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> {
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))]>;
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)))]>;
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))]>;
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)))]>;
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)))]>;
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))]>;
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>;
1172 NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$a),
1173 "brev.b32 \t$dst, $a;",
1174 [(set Int32Regs:$dst, (bitreverse Int32Regs:$a))]>;
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
1186 // r2 = shf.l r1, r1, n
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]>;
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
1201 // r2 = shf.r r1, r1, n
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]>;
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.
1216 NVPTXInst<(outs Int32Regs:$dst),
1217 (ins Int32Regs:$src, i32imm:$amt1, i32imm:$amt2),
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"
1227 def SUB_FRM_32 : SDNodeXForm<imm, [{
1228 return CurDAG->getTargetConstant(32 - N->getZExtValue(), SDLoc(N), MVT::i32);
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.
1240 NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$src, Int32Regs:$amt),
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"
1250 [(set Int32Regs:$dst, (rotl Int32Regs:$src, Int32Regs:$amt))]>,
1251 Requires<[noHWROT32]>;
1253 // 32-bit software rotate right by register.
1255 NVPTXInst<(outs Int32Regs:$dst), (ins Int32Regs:$src, Int32Regs:$amt),
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"
1265 [(set Int32Regs:$dst, (rotr Int32Regs:$src, Int32Regs:$amt))]>,
1266 Requires<[noHWROT32]>;
1268 // 64-bit software rotate by immediate. $amt2 should equal 64 - $amt1.
1270 NVPTXInst<(outs Int64Regs:$dst),
1271 (ins Int64Regs:$src, i32imm:$amt1, i32imm:$amt2),
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"
1281 def SUB_FRM_64 : SDNodeXForm<imm, [{
1282 return CurDAG->getTargetConstant(64-N->getZExtValue(), SDLoc(N), MVT::i32);
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.
1292 NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$src, Int32Regs:$amt),
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"
1302 [(set Int64Regs:$dst, (rotl Int64Regs:$src, Int32Regs:$amt))]>;
1305 NVPTXInst<(outs Int64Regs:$dst), (ins Int64Regs:$src, Int32Regs:$amt),
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"
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, []>;
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))]>;
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> {
1352 : NVPTXInst<(outs RC:$d),
1353 (ins RC:$a, Int32Regs:$b, Int32Regs:$c),
1354 !strconcat("bfe.", TyStr, " \t$d, $a, $b, $c;"), []>;
1356 : NVPTXInst<(outs RC:$d),
1357 (ins RC:$a, Int32Regs:$b, i32imm:$c),
1358 !strconcat("bfe.", TyStr, " \t$d, $a, $b, $c;"), []>;
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> {
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;"), []>;
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;"), []>;
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;"), []>;
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>;
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]>;
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;",
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;"), []>;
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;"), []>;
1476 multiclass SELP_PATTERN<string TypeStr, RegisterClass RC, Operand ImmCls,
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))]>;
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))]>;
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))]>;
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))]>;
1501 // Don't pattern match on selp.{s,u}{16,32,64} -- selp.b{16,32,64} is just as
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>;
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],
1529 def ADDRri64 : ComplexPattern<i64, 2, "SelectADDRri64", [frameindex],
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> {
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)>;
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)>;
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)>;
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)>;
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)>;
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>;
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> {
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]>;
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)>;
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)>;
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]>;
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)>;
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, []>;
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]>;
1906 SDNode<"NVPTXISD::DeclareRet", SDTDeclareScalarParamProfile,
1907 [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1909 SDNode<"NVPTXISD::LoadParam", SDTLoadParamProfile,
1910 [SDNPHasChain, SDNPMayLoad, SDNPOutGlue, SDNPInGlue]>;
1912 SDNode<"NVPTXISD::LoadParamV2", SDTLoadParamV2Profile,
1913 [SDNPHasChain, SDNPMayLoad, SDNPOutGlue, SDNPInGlue]>;
1915 SDNode<"NVPTXISD::LoadParamV4", SDTLoadParamV4Profile,
1916 [SDNPHasChain, SDNPMayLoad, SDNPOutGlue, SDNPInGlue]>;
1918 SDNode<"NVPTXISD::PrintCall", SDTPrintCallProfile,
1919 [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1920 def PrintConvergentCall :
1921 SDNode<"NVPTXISD::PrintConvergentCall", SDTPrintCallProfile,
1922 [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1924 SDNode<"NVPTXISD::PrintCallUni", SDTPrintCallUniProfile,
1925 [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1926 def PrintConvergentCallUni :
1927 SDNode<"NVPTXISD::PrintConvergentCallUni", SDTPrintCallUniProfile,
1928 [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1930 SDNode<"NVPTXISD::StoreParam", SDTStoreParamProfile,
1931 [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1933 SDNode<"NVPTXISD::StoreParamV2", SDTStoreParamV2Profile,
1934 [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1936 SDNode<"NVPTXISD::StoreParamV4", SDTStoreParamV4Profile,
1937 [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1939 SDNode<"NVPTXISD::StoreParamU32", SDTStoreParam32Profile,
1940 [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1942 SDNode<"NVPTXISD::StoreParamS32", SDTStoreParam32Profile,
1943 [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1945 SDNode<"NVPTXISD::CallArgBegin", SDTCallArgMarkProfile,
1946 [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1948 SDNode<"NVPTXISD::CallArg", SDTCallArgProfile,
1949 [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1951 SDNode<"NVPTXISD::LastCallArg", SDTCallArgProfile,
1952 [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1954 SDNode<"NVPTXISD::CallArgEnd", SDTCallVoidProfile,
1955 [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1957 SDNode<"NVPTXISD::CallVoid", SDTCallVoidProfile,
1958 [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1960 SDNode<"NVPTXISD::Prototype", SDTCallVoidProfile,
1961 [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1963 SDNode<"NVPTXISD::CallVal", SDTCallValProfile,
1964 [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1966 SDNode<"NVPTXISD::MoveParam", SDTMoveParamProfile, []>;
1968 SDNode<"NVPTXISD::StoreRetval", SDTStoreRetvalProfile,
1969 [SDNPHasChain, SDNPSideEffect]>;
1971 SDNode<"NVPTXISD::StoreRetvalV2", SDTStoreRetvalV2Profile,
1972 [SDNPHasChain, SDNPSideEffect]>;
1974 SDNode<"NVPTXISD::StoreRetvalV4", SDTStoreRetvalV4Profile,
1975 [SDNPHasChain, SDNPSideEffect]>;
1976 def PseudoUseParam :
1977 SDNode<"NVPTXISD::PseudoUseParam", SDTPseudoUseParamProfile,
1978 [SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
1980 SDNode<"NVPTXISD::RETURN", SDTCallArgMarkProfile,
1981 [SDNPHasChain, SDNPSideEffect]>;
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];"),
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,
2001 !strconcat("ld.param.v4", opstr,
2002 " \t{{$dst, $dst2, $dst3, $dst4}}, [retval0+$b];"),
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;"),
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}};"),
2024 class StoreParamV4Inst<NVPTXRegClass regclass, string opstr> :
2025 NVPTXInst<(outs), (ins regclass:$val, regclass:$val2, regclass:$val3,
2026 regclass:$val4, i32imm:$a,
2028 !strconcat("st.param.v4", opstr,
2029 " \t[param$a+$b], {{$val, $val2, $val3, $val4}};"),
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;"),
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}};"),
2043 class StoreRetvalV4Inst<NVPTXRegClass regclass, string opstr> :
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}};"),
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, "
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))]>;
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">;
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<
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<
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<
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<
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<
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<
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<
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<
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<
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<
2490 (ins regclass:$src1, regclass:$src2, LdStCode:$isVol, LdStCode:$addsp,
2491 LdStCode:$Vec, LdStCode:$Sign, i32imm:$fromWidth, Int32Regs:$addr,
2493 "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
2494 "\t[$addr+$offset], {{$src1, $src2}};", []>;
2495 def _v2_ari_64 : NVPTXInst<
2497 (ins regclass:$src1, regclass:$src2, LdStCode:$isVol, LdStCode:$addsp,
2498 LdStCode:$Vec, LdStCode:$Sign, i32imm:$fromWidth, Int64Regs:$addr,
2500 "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
2501 "\t[$addr+$offset], {{$src1, $src2}};", []>;
2502 def _v2_asi : NVPTXInst<
2504 (ins regclass:$src1, regclass:$src2, LdStCode:$isVol, LdStCode:$addsp,
2505 LdStCode:$Vec, LdStCode:$Sign, i32imm:$fromWidth, imem:$addr,
2507 "st${isVol:volatile}${addsp:addsp}${Vec:vec}.${Sign:sign}$fromWidth "
2508 "\t[$addr+$offset], {{$src1, $src2}};", []>;
2509 def _v4_avar : NVPTXInst<
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<
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<
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<
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<
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<
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.
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)>;
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)>;
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)>;
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)>;
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)>;
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)>;
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)>;
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)>;
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)>;
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)>;
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)>;
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)>;
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)>;
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)>;
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)>;
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)>;
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)>;
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)>;
2761 def : Pat<(i64 (sext Int32Regs:$a)),
2762 (CVT_s64_s32 Int32Regs:$a, CvtNONE)>;
2765 def : Pat<(i64 (zext Int32Regs:$a)),
2766 (CVT_u64_u32 Int32Regs:$a, CvtNONE)>;
2769 def : Pat<(i64 (anyext Int32Regs:$a)),
2770 (CVT_u64_u32 Int32Regs:$a, CvtNONE)>;
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)>;
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)>;
2788 def : Pat<(i1 (trunc Int16Regs:$a)),
2789 (SETP_b16ri (ANDb16ri Int16Regs:$a, 1), 1, CmpEQ)>;
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),
2841 "mov.b64 \t{{$d1, $d2, $d3, $d4}}, $s;", []>;
2842 def I32toV2I16 : NVPTXInst<(outs Int16Regs:$d1, Int16Regs:$d2),
2844 "mov.b32 \t{{$d1, $d2}}, $s;", []>;
2845 def I64toV2I32 : NVPTXInst<(outs Int32Regs:$d1, Int32Regs:$d2),
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;",
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;",
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;",
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)>;
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
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 //-----------------------------------
3046 //-----------------------------------
3048 let isTerminator=1 in {
3049 let isReturn=1, isBarrier=1 in
3050 def Return : NVPTXInst<(outs), (ins), "ret;", [(retflag)]>;
3053 def CBranch : NVPTXInst<(outs), (ins Int1Regs:$a, brtarget:$target),
3054 "@$a bra \t$target;",
3055 [(brcond Int1Regs:$a, bb:$target)]>;
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)>;
3077 def SDT_NVPTXCallSeqStart : SDCallSeqStart<[SDTCisVT<0, 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,
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>;
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>;
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)]>;
3108 NVPTXInst<(outs), (ins i32imm:$amt1, i32imm:$amt2),
3109 "\\} // callseq $amt1",
3110 [(callseq_end timm:$amt1, timm:$amt2)]>;
3113 def trapinst : NVPTXInst<(outs), (ins), "trap;", [(trap)]>;
3115 // Call prototype wrapper
3116 def SDTCallPrototype : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
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 //-----------------------------------
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