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