9b4f56cf25c698ec4182bf06fd8631d7aa2d37dc
[oota-llvm.git] / lib / Target / PTX / PTXInstrLoadStore.td
1 //===- PTXInstrLoadStore.td - PTX Load/Store Instruction Defs -*- tblgen-*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file describes the PTX load/store instructions in TableGen format.
11 //
12 //===----------------------------------------------------------------------===//
13
14
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()">;
19
20 //===----------------------------------------------------------------------===//
21 // Pattern Fragments for Loads/Stores
22 //===----------------------------------------------------------------------===//
23
24 def load_global : PatFrag<(ops node:$ptr), (load node:$ptr), [{
25   const Value *Src;
26   const PointerType *PT;
27   if ((Src = cast<LoadSDNode>(N)->getSrcValue()) &&
28       (PT = dyn_cast<PointerType>(Src->getType())))
29     return PT->getAddressSpace() == PTXStateSpace::Global;
30   return false;
31 }]>;
32
33 def load_constant : PatFrag<(ops node:$ptr), (load node:$ptr), [{
34   const Value *Src;
35   const PointerType *PT;
36   if ((Src = cast<LoadSDNode>(N)->getSrcValue()) &&
37       (PT = dyn_cast<PointerType>(Src->getType())))
38     return PT->getAddressSpace() == PTXStateSpace::Constant;
39   return false;
40 }]>;
41
42 def load_shared : PatFrag<(ops node:$ptr), (load node:$ptr), [{
43   const Value *Src;
44   const PointerType *PT;
45   if ((Src = cast<LoadSDNode>(N)->getSrcValue()) &&
46       (PT = dyn_cast<PointerType>(Src->getType())))
47     return PT->getAddressSpace() == PTXStateSpace::Shared;
48   return false;
49 }]>;
50
51 def store_global
52   : PatFrag<(ops node:$d, node:$ptr), (store node:$d, node:$ptr), [{
53   const Value *Src;
54   const PointerType *PT;
55   if ((Src = cast<StoreSDNode>(N)->getSrcValue()) &&
56       (PT = dyn_cast<PointerType>(Src->getType())))
57     return PT->getAddressSpace() == PTXStateSpace::Global;
58   return false;
59 }]>;
60
61 def store_shared
62   : PatFrag<(ops node:$d, node:$ptr), (store node:$d, node:$ptr), [{
63   const Value *Src;
64   const PointerType *PT;
65   if ((Src = cast<StoreSDNode>(N)->getSrcValue()) &&
66       (PT = dyn_cast<PointerType>(Src->getType())))
67     return PT->getAddressSpace() == PTXStateSpace::Shared;
68   return false;
69 }]>;
70
71 // Addressing modes.
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", [], []>;
80
81 // Address operands
82 def MEMri32 : Operand<i32> {
83   let PrintMethod = "printMemOperand";
84   let MIOperandInfo = (ops RegI32, i32imm);
85 }
86 def MEMri64 : Operand<i64> {
87   let PrintMethod = "printMemOperand";
88   let MIOperandInfo = (ops RegI64, i64imm);
89 }
90 def LOCALri32 : Operand<i32> {
91   let PrintMethod = "printMemOperand";
92   let MIOperandInfo = (ops i32imm, i32imm);
93 }
94 def LOCALri64 : Operand<i64> {
95   let PrintMethod = "printMemOperand";
96   let MIOperandInfo = (ops i64imm, i64imm);
97 }
98 def MEMii32 : Operand<i32> {
99   let PrintMethod = "printMemOperand";
100   let MIOperandInfo = (ops i32imm, i32imm);
101 }
102 def MEMii64 : Operand<i64> {
103   let PrintMethod = "printMemOperand";
104   let MIOperandInfo = (ops i64imm, i64imm);
105 }
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);
111 }
112 def MEMret : Operand<i32> {
113   let PrintMethod = "printReturnOperand";
114   let MIOperandInfo = (ops i32imm);
115 }
116
117
118 // Load/store .param space
119 def PTXloadparam
120   : SDNode<"PTXISD::LOAD_PARAM", SDTypeProfile<1, 1, [SDTCisPtrTy<1>]>,
121            [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue]>;
122 def PTXstoreparam
123   : SDNode<"PTXISD::STORE_PARAM", SDTypeProfile<0, 2, [SDTCisVT<0, i32>]>,
124            [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue]>;
125
126 def PTXreadparam
127   : SDNode<"PTXISD::READ_PARAM", SDTypeProfile<1, 1, [SDTCisVT<1, i32>]>,
128       [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue]>;
129 def PTXwriteparam
130   : SDNode<"PTXISD::WRITE_PARAM", SDTypeProfile<0, 1, []>,
131       [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue]>;
132
133
134
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),
141                      (ins MEMri32:$a),
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),
146                      (ins MEMri64:$a),
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),
151                      (ins MEMri32:$a),
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),
156                      (ins MEMri64:$a),
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),
161                      (ins MEMii32:$a),
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),
166                      (ins MEMii64:$a),
167                      !strconcat(opstr, !strconcat(typestr, "\t$d, [$a]")),
168                      [(set RC:$d, (pat_load ADDRii64:$a))]>,
169                      Requires<[Use64BitAddresses]>;
170 }
171
172 multiclass PTX_ST<string opstr, string typestr, RegisterClass RC,
173                   PatFrag pat_store> {
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]>;
204 }
205
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)]>;
219 }
220
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)]>;
229   }
230 }
231
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>;
238 }
239
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>;
246 }
247
248
249
250 //===----------------------------------------------------------------------===//
251 // Instruction definitions for loads/stores
252 //===----------------------------------------------------------------------===//
253
254 // Global/shared stores
255 defm STg : PTX_ST_ALL<"st.global", store_global>;
256 defm STs : PTX_ST_ALL<"st.shared", store_shared>;
257
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>;
262
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>;
270
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>;
278