1 //===- PTXInstrLoadStore.td - PTX Load/Store Instruction Defs -*- tblgen-*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file describes the PTX load/store instructions in TableGen format.
12 //===----------------------------------------------------------------------===//
15 // Addressing Predicates
16 // We have to differentiate between 32- and 64-bit pointer types
17 def Use32BitAddresses : Predicate<"!getSubtarget().is64Bit()">;
18 def Use64BitAddresses : Predicate<"getSubtarget().is64Bit()">;
20 //===----------------------------------------------------------------------===//
21 // Pattern Fragments for Loads/Stores
22 //===----------------------------------------------------------------------===//
24 def load_global : PatFrag<(ops node:$ptr), (load node:$ptr), [{
26 const PointerType *PT;
27 if ((Src = cast<LoadSDNode>(N)->getSrcValue()) &&
28 (PT = dyn_cast<PointerType>(Src->getType())))
29 return PT->getAddressSpace() == PTXStateSpace::Global;
33 def load_constant : PatFrag<(ops node:$ptr), (load node:$ptr), [{
35 const PointerType *PT;
36 if ((Src = cast<LoadSDNode>(N)->getSrcValue()) &&
37 (PT = dyn_cast<PointerType>(Src->getType())))
38 return PT->getAddressSpace() == PTXStateSpace::Constant;
42 def load_shared : PatFrag<(ops node:$ptr), (load node:$ptr), [{
44 const PointerType *PT;
45 if ((Src = cast<LoadSDNode>(N)->getSrcValue()) &&
46 (PT = dyn_cast<PointerType>(Src->getType())))
47 return PT->getAddressSpace() == PTXStateSpace::Shared;
52 : PatFrag<(ops node:$d, node:$ptr), (store node:$d, node:$ptr), [{
54 const PointerType *PT;
55 if ((Src = cast<StoreSDNode>(N)->getSrcValue()) &&
56 (PT = dyn_cast<PointerType>(Src->getType())))
57 return PT->getAddressSpace() == PTXStateSpace::Global;
62 : PatFrag<(ops node:$d, node:$ptr), (store node:$d, node:$ptr), [{
64 const PointerType *PT;
65 if ((Src = cast<StoreSDNode>(N)->getSrcValue()) &&
66 (PT = dyn_cast<PointerType>(Src->getType())))
67 return PT->getAddressSpace() == PTXStateSpace::Shared;
72 def ADDRrr32 : ComplexPattern<i32, 2, "SelectADDRrr", [], []>;
73 def ADDRrr64 : ComplexPattern<i64, 2, "SelectADDRrr", [], []>;
74 def ADDRri32 : ComplexPattern<i32, 2, "SelectADDRri", [], []>;
75 def ADDRri64 : ComplexPattern<i64, 2, "SelectADDRri", [], []>;
76 def ADDRii32 : ComplexPattern<i32, 2, "SelectADDRii", [], []>;
77 def ADDRii64 : ComplexPattern<i64, 2, "SelectADDRii", [], []>;
78 def ADDRlocal32 : ComplexPattern<i32, 2, "SelectADDRlocal", [], []>;
79 def ADDRlocal64 : ComplexPattern<i64, 2, "SelectADDRlocal", [], []>;
82 def MEMri32 : Operand<i32> {
83 let PrintMethod = "printMemOperand";
84 let MIOperandInfo = (ops RegI32, i32imm);
86 def MEMri64 : Operand<i64> {
87 let PrintMethod = "printMemOperand";
88 let MIOperandInfo = (ops RegI64, i64imm);
90 def LOCALri32 : Operand<i32> {
91 let PrintMethod = "printMemOperand";
92 let MIOperandInfo = (ops i32imm, i32imm);
94 def LOCALri64 : Operand<i64> {
95 let PrintMethod = "printMemOperand";
96 let MIOperandInfo = (ops i64imm, i64imm);
98 def MEMii32 : Operand<i32> {
99 let PrintMethod = "printMemOperand";
100 let MIOperandInfo = (ops i32imm, i32imm);
102 def MEMii64 : Operand<i64> {
103 let PrintMethod = "printMemOperand";
104 let MIOperandInfo = (ops i64imm, i64imm);
106 // The operand here does not correspond to an actual address, so we
107 // can use i32 in 64-bit address modes.
108 def MEMpi : Operand<i32> {
109 let PrintMethod = "printParamOperand";
110 let MIOperandInfo = (ops i32imm);
112 def MEMret : Operand<i32> {
113 let PrintMethod = "printReturnOperand";
114 let MIOperandInfo = (ops i32imm);
118 // Load/store .param space
120 : SDNode<"PTXISD::LOAD_PARAM", SDTypeProfile<1, 1, [SDTCisPtrTy<1>]>,
121 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue]>;
123 : SDNode<"PTXISD::STORE_PARAM", SDTypeProfile<0, 2, [SDTCisVT<0, i32>]>,
124 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue]>;
127 : SDNode<"PTXISD::READ_PARAM", SDTypeProfile<1, 1, [SDTCisVT<1, i32>]>,
128 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue]>;
130 : SDNode<"PTXISD::WRITE_PARAM", SDTypeProfile<0, 1, []>,
131 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue]>;
135 //===----------------------------------------------------------------------===//
136 // Classes for loads/stores
137 //===----------------------------------------------------------------------===//
138 multiclass PTX_LD<string opstr, string typestr,
139 RegisterClass RC, PatFrag pat_load> {
140 def rr32 : InstPTX<(outs RC:$d),
142 !strconcat(opstr, !strconcat(typestr, "\t$d, [$a]")),
143 [(set RC:$d, (pat_load ADDRrr32:$a))]>,
144 Requires<[Use32BitAddresses]>;
145 def rr64 : InstPTX<(outs RC:$d),
147 !strconcat(opstr, !strconcat(typestr, "\t$d, [$a]")),
148 [(set RC:$d, (pat_load ADDRrr64:$a))]>,
149 Requires<[Use64BitAddresses]>;
150 def ri32 : InstPTX<(outs RC:$d),
152 !strconcat(opstr, !strconcat(typestr, "\t$d, [$a]")),
153 [(set RC:$d, (pat_load ADDRri32:$a))]>,
154 Requires<[Use32BitAddresses]>;
155 def ri64 : InstPTX<(outs RC:$d),
157 !strconcat(opstr, !strconcat(typestr, "\t$d, [$a]")),
158 [(set RC:$d, (pat_load ADDRri64:$a))]>,
159 Requires<[Use64BitAddresses]>;
160 def ii32 : InstPTX<(outs RC:$d),
162 !strconcat(opstr, !strconcat(typestr, "\t$d, [$a]")),
163 [(set RC:$d, (pat_load ADDRii32:$a))]>,
164 Requires<[Use32BitAddresses]>;
165 def ii64 : InstPTX<(outs RC:$d),
167 !strconcat(opstr, !strconcat(typestr, "\t$d, [$a]")),
168 [(set RC:$d, (pat_load ADDRii64:$a))]>,
169 Requires<[Use64BitAddresses]>;
172 multiclass PTX_ST<string opstr, string typestr, RegisterClass RC,
174 def rr32 : InstPTX<(outs),
175 (ins RC:$d, MEMri32:$a),
176 !strconcat(opstr, !strconcat(typestr, "\t[$a], $d")),
177 [(pat_store RC:$d, ADDRrr32:$a)]>,
178 Requires<[Use32BitAddresses]>;
179 def rr64 : InstPTX<(outs),
180 (ins RC:$d, MEMri64:$a),
181 !strconcat(opstr, !strconcat(typestr, "\t[$a], $d")),
182 [(pat_store RC:$d, ADDRrr64:$a)]>,
183 Requires<[Use64BitAddresses]>;
184 def ri32 : InstPTX<(outs),
185 (ins RC:$d, MEMri32:$a),
186 !strconcat(opstr, !strconcat(typestr, "\t[$a], $d")),
187 [(pat_store RC:$d, ADDRri32:$a)]>,
188 Requires<[Use32BitAddresses]>;
189 def ri64 : InstPTX<(outs),
190 (ins RC:$d, MEMri64:$a),
191 !strconcat(opstr, !strconcat(typestr, "\t[$a], $d")),
192 [(pat_store RC:$d, ADDRri64:$a)]>,
193 Requires<[Use64BitAddresses]>;
194 def ii32 : InstPTX<(outs),
195 (ins RC:$d, MEMii32:$a),
196 !strconcat(opstr, !strconcat(typestr, "\t[$a], $d")),
197 [(pat_store RC:$d, ADDRii32:$a)]>,
198 Requires<[Use32BitAddresses]>;
199 def ii64 : InstPTX<(outs),
200 (ins RC:$d, MEMii64:$a),
201 !strconcat(opstr, !strconcat(typestr, "\t[$a], $d")),
202 [(pat_store RC:$d, ADDRii64:$a)]>,
203 Requires<[Use64BitAddresses]>;
206 multiclass PTX_LOCAL_LD_ST<string typestr, RegisterClass RC> {
207 def LDri32 : InstPTX<(outs RC:$d), (ins LOCALri32:$a),
208 !strconcat("ld.local", !strconcat(typestr, "\t$d, [$a]")),
209 [(set RC:$d, (load_global ADDRlocal32:$a))]>;
210 def LDri64 : InstPTX<(outs RC:$d), (ins LOCALri64:$a),
211 !strconcat("ld.local", !strconcat(typestr, "\t$d, [$a]")),
212 [(set RC:$d, (load_global ADDRlocal64:$a))]>;
213 def STri32 : InstPTX<(outs), (ins RC:$d, LOCALri32:$a),
214 !strconcat("st.local", !strconcat(typestr, "\t[$a], $d")),
215 [(store_global RC:$d, ADDRlocal32:$a)]>;
216 def STri64 : InstPTX<(outs), (ins RC:$d, LOCALri64:$a),
217 !strconcat("st.local", !strconcat(typestr, "\t[$a], $d")),
218 [(store_global RC:$d, ADDRlocal64:$a)]>;
221 multiclass PTX_PARAM_LD_ST<string typestr, RegisterClass RC> {
222 let hasSideEffects = 1 in {
223 def LDpi : InstPTX<(outs RC:$d), (ins i32imm:$a),
224 !strconcat("ld.param", !strconcat(typestr, "\t$d, [$a]")),
225 [(set RC:$d, (PTXloadparam texternalsym:$a))]>;
226 def STpi : InstPTX<(outs), (ins i32imm:$d, RC:$a),
227 !strconcat("st.param", !strconcat(typestr, "\t[$d], $a")),
228 [(PTXstoreparam texternalsym:$d, RC:$a)]>;
232 multiclass PTX_LD_ALL<string opstr, PatFrag pat_load> {
233 defm u16 : PTX_LD<opstr, ".u16", RegI16, pat_load>;
234 defm u32 : PTX_LD<opstr, ".u32", RegI32, pat_load>;
235 defm u64 : PTX_LD<opstr, ".u64", RegI64, pat_load>;
236 defm f32 : PTX_LD<opstr, ".f32", RegF32, pat_load>;
237 defm f64 : PTX_LD<opstr, ".f64", RegF64, pat_load>;
240 multiclass PTX_ST_ALL<string opstr, PatFrag pat_store> {
241 defm u16 : PTX_ST<opstr, ".u16", RegI16, pat_store>;
242 defm u32 : PTX_ST<opstr, ".u32", RegI32, pat_store>;
243 defm u64 : PTX_ST<opstr, ".u64", RegI64, pat_store>;
244 defm f32 : PTX_ST<opstr, ".f32", RegF32, pat_store>;
245 defm f64 : PTX_ST<opstr, ".f64", RegF64, pat_store>;
250 //===----------------------------------------------------------------------===//
251 // Instruction definitions for loads/stores
252 //===----------------------------------------------------------------------===//
254 // Global/shared stores
255 defm STg : PTX_ST_ALL<"st.global", store_global>;
256 defm STs : PTX_ST_ALL<"st.shared", store_shared>;
258 // Global/shared/constant loads
259 defm LDg : PTX_LD_ALL<"ld.global", load_global>;
260 defm LDc : PTX_LD_ALL<"ld.const", load_constant>;
261 defm LDs : PTX_LD_ALL<"ld.shared", load_shared>;
263 // Param loads/stores
264 defm PARAMPRED : PTX_PARAM_LD_ST<".pred", RegPred>;
265 defm PARAMU16 : PTX_PARAM_LD_ST<".u16", RegI16>;
266 defm PARAMU32 : PTX_PARAM_LD_ST<".u32", RegI32>;
267 defm PARAMU64 : PTX_PARAM_LD_ST<".u64", RegI64>;
268 defm PARAMF32 : PTX_PARAM_LD_ST<".f32", RegF32>;
269 defm PARAMF64 : PTX_PARAM_LD_ST<".f64", RegF64>;
271 // Local loads/stores
272 defm LOCALPRED : PTX_LOCAL_LD_ST<".pred", RegPred>;
273 defm LOCALU16 : PTX_LOCAL_LD_ST<".u16", RegI16>;
274 defm LOCALU32 : PTX_LOCAL_LD_ST<".u32", RegI32>;
275 defm LOCALU64 : PTX_LOCAL_LD_ST<".u64", RegI64>;
276 defm LOCALF32 : PTX_LOCAL_LD_ST<".f32", RegF32>;
277 defm LOCALF64 : PTX_LOCAL_LD_ST<".f64", RegF64>;