• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
17def Use32BitAddresses : Predicate<"!getSubtarget().is64Bit()">;
18def Use64BitAddresses : Predicate<"getSubtarget().is64Bit()">;
19
20//===----------------------------------------------------------------------===//
21// Pattern Fragments for Loads/Stores
22//===----------------------------------------------------------------------===//
23
24def 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
33def 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
42def 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
51def 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
61def 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.
72def ADDRrr32    : ComplexPattern<i32, 2, "SelectADDRrr", [], []>;
73def ADDRrr64    : ComplexPattern<i64, 2, "SelectADDRrr", [], []>;
74def ADDRri32    : ComplexPattern<i32, 2, "SelectADDRri", [], []>;
75def ADDRri64    : ComplexPattern<i64, 2, "SelectADDRri", [], []>;
76def ADDRii32    : ComplexPattern<i32, 2, "SelectADDRii", [], []>;
77def ADDRii64    : ComplexPattern<i64, 2, "SelectADDRii", [], []>;
78def ADDRlocal32 : ComplexPattern<i32, 2, "SelectADDRlocal", [], []>;
79def ADDRlocal64 : ComplexPattern<i64, 2, "SelectADDRlocal", [], []>;
80
81// Address operands
82def MEMri32 : Operand<i32> {
83  let PrintMethod = "printMemOperand";
84  let MIOperandInfo = (ops RegI32, i32imm);
85}
86def MEMri64 : Operand<i64> {
87  let PrintMethod = "printMemOperand";
88  let MIOperandInfo = (ops RegI64, i64imm);
89}
90def LOCALri32 : Operand<i32> {
91  let PrintMethod = "printMemOperand";
92  let MIOperandInfo = (ops i32imm, i32imm);
93}
94def LOCALri64 : Operand<i64> {
95  let PrintMethod = "printMemOperand";
96  let MIOperandInfo = (ops i64imm, i64imm);
97}
98def MEMii32 : Operand<i32> {
99  let PrintMethod = "printMemOperand";
100  let MIOperandInfo = (ops i32imm, i32imm);
101}
102def 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.
108def MEMpi : Operand<i32> {
109  let PrintMethod = "printParamOperand";
110  let MIOperandInfo = (ops i32imm);
111}
112def MEMret : Operand<i32> {
113  let PrintMethod = "printReturnOperand";
114  let MIOperandInfo = (ops i32imm);
115}
116
117
118// Load/store .param space
119def PTXloadparam
120  : SDNode<"PTXISD::LOAD_PARAM", SDTypeProfile<1, 1, [SDTCisPtrTy<1>]>,
121           [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue]>;
122def PTXstoreparam
123  : SDNode<"PTXISD::STORE_PARAM", SDTypeProfile<0, 2, [SDTCisVT<0, i32>]>,
124           [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue]>;
125
126def PTXreadparam
127  : SDNode<"PTXISD::READ_PARAM", SDTypeProfile<1, 1, [SDTCisVT<1, i32>]>,
128      [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue]>;
129def PTXwriteparam
130  : SDNode<"PTXISD::WRITE_PARAM", SDTypeProfile<0, 1, []>,
131      [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue]>;
132
133
134
135//===----------------------------------------------------------------------===//
136// Classes for loads/stores
137//===----------------------------------------------------------------------===//
138multiclass 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
172multiclass 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
206multiclass 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
221multiclass 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
232multiclass 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
240multiclass 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
255defm STg : PTX_ST_ALL<"st.global", store_global>;
256defm STs : PTX_ST_ALL<"st.shared", store_shared>;
257
258// Global/shared/constant loads
259defm LDg : PTX_LD_ALL<"ld.global", load_global>;
260defm LDc : PTX_LD_ALL<"ld.const",  load_constant>;
261defm LDs : PTX_LD_ALL<"ld.shared", load_shared>;
262
263// Param loads/stores
264defm PARAMPRED : PTX_PARAM_LD_ST<".pred", RegPred>;
265defm PARAMU16  : PTX_PARAM_LD_ST<".u16", RegI16>;
266defm PARAMU32  : PTX_PARAM_LD_ST<".u32", RegI32>;
267defm PARAMU64  : PTX_PARAM_LD_ST<".u64", RegI64>;
268defm PARAMF32  : PTX_PARAM_LD_ST<".f32", RegF32>;
269defm PARAMF64  : PTX_PARAM_LD_ST<".f64", RegF64>;
270
271// Local loads/stores
272defm LOCALPRED : PTX_LOCAL_LD_ST<".pred", RegPred>;
273defm LOCALU16  : PTX_LOCAL_LD_ST<".u16", RegI16>;
274defm LOCALU32  : PTX_LOCAL_LD_ST<".u32", RegI32>;
275defm LOCALU64  : PTX_LOCAL_LD_ST<".u64", RegI64>;
276defm LOCALF32  : PTX_LOCAL_LD_ST<".f32", RegF32>;
277defm LOCALF64  : PTX_LOCAL_LD_ST<".f64", RegF64>;
278
279