blob: 053e140efe8e0dfbadce8335f53b035533beafb3 [file] [log] [blame]
Eric Christopher50880d02010-09-18 18:52:28 +00001//===-- PTXISelLowering.cpp - PTX DAG Lowering Implementation -------------===//
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 implements the PTXTargetLowering class.
11//
12//===----------------------------------------------------------------------===//
13
Che-Liang Chioub48f2c22010-10-19 13:14:40 +000014#include "PTX.h"
Eric Christopher50880d02010-09-18 18:52:28 +000015#include "PTXISelLowering.h"
Che-Liang Chiou3278c422010-11-08 03:00:52 +000016#include "PTXMachineFunctionInfo.h"
Eric Christopher50880d02010-09-18 18:52:28 +000017#include "PTXRegisterInfo.h"
Justin Holewinski67a91842011-06-23 18:10:03 +000018#include "PTXSubtarget.h"
Justin Holewinski75d80952011-09-23 16:48:41 +000019#include "llvm/Function.h"
Eric Christopher50880d02010-09-18 18:52:28 +000020#include "llvm/Support/ErrorHandling.h"
Justin Holewinskie0aef2d2011-06-16 17:50:00 +000021#include "llvm/CodeGen/CallingConvLower.h"
Che-Liang Chioub48f2c22010-10-19 13:14:40 +000022#include "llvm/CodeGen/MachineFunction.h"
23#include "llvm/CodeGen/MachineRegisterInfo.h"
Eric Christopher50880d02010-09-18 18:52:28 +000024#include "llvm/CodeGen/SelectionDAG.h"
25#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
Justin Holewinski4bdd4ed2011-08-09 17:36:31 +000026#include "llvm/Support/Debug.h"
Che-Liang Chioufd8978b2011-03-02 03:20:28 +000027#include "llvm/Support/raw_ostream.h"
Eric Christopher50880d02010-09-18 18:52:28 +000028
29using namespace llvm;
30
Justin Holewinskie0aef2d2011-06-16 17:50:00 +000031//===----------------------------------------------------------------------===//
Justin Holewinskie0aef2d2011-06-16 17:50:00 +000032// TargetLowering Implementation
33//===----------------------------------------------------------------------===//
34
Eric Christopher50880d02010-09-18 18:52:28 +000035PTXTargetLowering::PTXTargetLowering(TargetMachine &TM)
36 : TargetLowering(TM, new TargetLoweringObjectFileELF()) {
37 // Set up the register classes.
Justin Holewinski1b91bcd2011-06-16 17:49:58 +000038 addRegisterClass(MVT::i1, PTX::RegPredRegisterClass);
39 addRegisterClass(MVT::i16, PTX::RegI16RegisterClass);
40 addRegisterClass(MVT::i32, PTX::RegI32RegisterClass);
41 addRegisterClass(MVT::i64, PTX::RegI64RegisterClass);
42 addRegisterClass(MVT::f32, PTX::RegF32RegisterClass);
43 addRegisterClass(MVT::f64, PTX::RegF64RegisterClass);
Che-Liang Chioufd8978b2011-03-02 03:20:28 +000044
Justin Holewinski4fea05a2011-04-28 00:19:52 +000045 setBooleanContents(ZeroOrOneBooleanContent);
Duncan Sands28b77e92011-09-06 19:07:46 +000046 setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct?
Dan Bailey84149462011-06-25 18:16:28 +000047 setMinFunctionAlignment(2);
Justin Holewinski05591be2011-09-22 16:45:43 +000048
Dan Bailey84149462011-06-25 18:16:28 +000049 ////////////////////////////////////
50 /////////// Expansion //////////////
51 ////////////////////////////////////
Justin Holewinski05591be2011-09-22 16:45:43 +000052
Dan Bailey84149462011-06-25 18:16:28 +000053 // (any/zero/sign) extload => load + (any/zero/sign) extend
Justin Holewinski05591be2011-09-22 16:45:43 +000054
Justin Holewinski4fea05a2011-04-28 00:19:52 +000055 setLoadExtAction(ISD::EXTLOAD, MVT::i16, Expand);
56 setLoadExtAction(ISD::ZEXTLOAD, MVT::i16, Expand);
Dan Baileyb05a8a82011-06-24 19:27:10 +000057 setLoadExtAction(ISD::SEXTLOAD, MVT::i16, Expand);
Justin Holewinski05591be2011-09-22 16:45:43 +000058
Dan Bailey84149462011-06-25 18:16:28 +000059 // f32 extload => load + fextend
Justin Holewinski05591be2011-09-22 16:45:43 +000060
61 setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand);
62
Dan Bailey84149462011-06-25 18:16:28 +000063 // f64 truncstore => trunc + store
Justin Holewinski05591be2011-09-22 16:45:43 +000064
65 setTruncStoreAction(MVT::f64, MVT::f32, Expand);
66
Dan Bailey84149462011-06-25 18:16:28 +000067 // sign_extend_inreg => sign_extend
Justin Holewinski05591be2011-09-22 16:45:43 +000068
Dan Bailey84149462011-06-25 18:16:28 +000069 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
Justin Holewinski05591be2011-09-22 16:45:43 +000070
Dan Bailey84149462011-06-25 18:16:28 +000071 // br_cc => brcond
Justin Holewinski05591be2011-09-22 16:45:43 +000072
Che-Liang Chiou88d33672011-03-18 11:08:52 +000073 setOperationAction(ISD::BR_CC, MVT::Other, Expand);
74
Dan Bailey84149462011-06-25 18:16:28 +000075 // select_cc => setcc
Justin Holewinski05591be2011-09-22 16:45:43 +000076
Justin Holewinski2d525c52011-04-28 00:19:56 +000077 setOperationAction(ISD::SELECT_CC, MVT::Other, Expand);
78 setOperationAction(ISD::SELECT_CC, MVT::f32, Expand);
79 setOperationAction(ISD::SELECT_CC, MVT::f64, Expand);
Justin Holewinski05591be2011-09-22 16:45:43 +000080
Dan Bailey84149462011-06-25 18:16:28 +000081 ////////////////////////////////////
82 //////////// Legal /////////////////
83 ////////////////////////////////////
Justin Holewinski05591be2011-09-22 16:45:43 +000084
Dan Bailey84149462011-06-25 18:16:28 +000085 setOperationAction(ISD::ConstantFP, MVT::f32, Legal);
86 setOperationAction(ISD::ConstantFP, MVT::f64, Legal);
Justin Holewinski05591be2011-09-22 16:45:43 +000087
Dan Bailey84149462011-06-25 18:16:28 +000088 ////////////////////////////////////
89 //////////// Custom ////////////////
90 ////////////////////////////////////
Justin Holewinski05591be2011-09-22 16:45:43 +000091
Dan Bailey84149462011-06-25 18:16:28 +000092 // customise setcc to use bitwise logic if possible
Justin Holewinski05591be2011-09-22 16:45:43 +000093
Justin Holewinski2d525c52011-04-28 00:19:56 +000094 setOperationAction(ISD::SETCC, MVT::i1, Custom);
Eli Friedmanfc5d3052011-05-06 20:34:06 +000095
Dan Bailey84149462011-06-25 18:16:28 +000096 // customize translation of memory addresses
Justin Holewinski05591be2011-09-22 16:45:43 +000097
Dan Bailey84149462011-06-25 18:16:28 +000098 setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
99 setOperationAction(ISD::GlobalAddress, MVT::i64, Custom);
Eli Friedmanfc5d3052011-05-06 20:34:06 +0000100
Eric Christopher50880d02010-09-18 18:52:28 +0000101 // Compute derived properties from the register classes
102 computeRegisterProperties();
103}
104
Duncan Sands28b77e92011-09-06 19:07:46 +0000105EVT PTXTargetLowering::getSetCCResultType(EVT VT) const {
Justin Holewinski2d525c52011-04-28 00:19:56 +0000106 return MVT::i1;
107}
108
Che-Liang Chioufc7072c2010-12-22 10:38:51 +0000109SDValue PTXTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
110 switch (Op.getOpcode()) {
Che-Liang Chiou88d33672011-03-18 11:08:52 +0000111 default:
112 llvm_unreachable("Unimplemented operand");
Justin Holewinski2d525c52011-04-28 00:19:56 +0000113 case ISD::SETCC:
114 return LowerSETCC(Op, DAG);
Che-Liang Chiou88d33672011-03-18 11:08:52 +0000115 case ISD::GlobalAddress:
116 return LowerGlobalAddress(Op, DAG);
Che-Liang Chioufc7072c2010-12-22 10:38:51 +0000117 }
118}
119
Eric Christopher50880d02010-09-18 18:52:28 +0000120const char *PTXTargetLowering::getTargetNodeName(unsigned Opcode) const {
121 switch (Opcode) {
Che-Liang Chiou8e5d01c2011-02-10 12:01:24 +0000122 default:
123 llvm_unreachable("Unknown opcode");
Justin Holewinski8af78c92011-03-18 19:24:28 +0000124 case PTXISD::COPY_ADDRESS:
125 return "PTXISD::COPY_ADDRESS";
Justin Holewinskia5ccb4e2011-06-23 18:10:05 +0000126 case PTXISD::LOAD_PARAM:
127 return "PTXISD::LOAD_PARAM";
Justin Holewinski67a91842011-06-23 18:10:03 +0000128 case PTXISD::STORE_PARAM:
129 return "PTXISD::STORE_PARAM";
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000130 case PTXISD::READ_PARAM:
131 return "PTXISD::READ_PARAM";
132 case PTXISD::WRITE_PARAM:
133 return "PTXISD::WRITE_PARAM";
Che-Liang Chiou8e5d01c2011-02-10 12:01:24 +0000134 case PTXISD::EXIT:
135 return "PTXISD::EXIT";
136 case PTXISD::RET:
137 return "PTXISD::RET";
Justin Holewinski4bdd4ed2011-08-09 17:36:31 +0000138 case PTXISD::CALL:
139 return "PTXISD::CALL";
Eric Christopher50880d02010-09-18 18:52:28 +0000140 }
141}
142
143//===----------------------------------------------------------------------===//
Che-Liang Chioufc7072c2010-12-22 10:38:51 +0000144// Custom Lower Operation
145//===----------------------------------------------------------------------===//
146
Justin Holewinski2d525c52011-04-28 00:19:56 +0000147SDValue PTXTargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const {
148 assert(Op.getValueType() == MVT::i1 && "SetCC type must be 1-bit integer");
149 SDValue Op0 = Op.getOperand(0);
150 SDValue Op1 = Op.getOperand(1);
151 SDValue Op2 = Op.getOperand(2);
152 DebugLoc dl = Op.getDebugLoc();
153 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
Justin Holewinskiec3141b2011-06-16 15:17:11 +0000154
Justin Holewinski05591be2011-09-22 16:45:43 +0000155 // Look for X == 0, X == 1, X != 0, or X != 1
Justin Holewinski2d525c52011-04-28 00:19:56 +0000156 // We can simplify these to bitwise logic
Justin Holewinskiec3141b2011-06-16 15:17:11 +0000157
Justin Holewinski2d525c52011-04-28 00:19:56 +0000158 if (Op1.getOpcode() == ISD::Constant &&
159 (cast<ConstantSDNode>(Op1)->getZExtValue() == 1 ||
160 cast<ConstantSDNode>(Op1)->isNullValue()) &&
161 (CC == ISD::SETEQ || CC == ISD::SETNE)) {
162
Justin Holewinskiec3141b2011-06-16 15:17:11 +0000163 return DAG.getNode(ISD::AND, dl, MVT::i1, Op0, Op1);
Justin Holewinski2d525c52011-04-28 00:19:56 +0000164 }
Justin Holewinskiec3141b2011-06-16 15:17:11 +0000165
Justin Holewinski2d525c52011-04-28 00:19:56 +0000166 return DAG.getNode(ISD::SETCC, dl, MVT::i1, Op0, Op1, Op2);
167}
168
Che-Liang Chioufc7072c2010-12-22 10:38:51 +0000169SDValue PTXTargetLowering::
170LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const {
171 EVT PtrVT = getPointerTy();
172 DebugLoc dl = Op.getDebugLoc();
173 const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
Justin Holewinski8af78c92011-03-18 19:24:28 +0000174
Justin Holewinskid6625762011-03-23 16:58:51 +0000175 assert(PtrVT.isSimple() && "Pointer must be to primitive type.");
176
Justin Holewinski8af78c92011-03-18 19:24:28 +0000177 SDValue targetGlobal = DAG.getTargetGlobalAddress(GV, dl, PtrVT);
178 SDValue movInstr = DAG.getNode(PTXISD::COPY_ADDRESS,
179 dl,
Justin Holewinskid6625762011-03-23 16:58:51 +0000180 PtrVT.getSimpleVT(),
Justin Holewinski8af78c92011-03-18 19:24:28 +0000181 targetGlobal);
182
183 return movInstr;
Che-Liang Chioufc7072c2010-12-22 10:38:51 +0000184}
185
186//===----------------------------------------------------------------------===//
Eric Christopher50880d02010-09-18 18:52:28 +0000187// Calling Convention Implementation
188//===----------------------------------------------------------------------===//
189
190SDValue PTXTargetLowering::
191 LowerFormalArguments(SDValue Chain,
192 CallingConv::ID CallConv,
193 bool isVarArg,
194 const SmallVectorImpl<ISD::InputArg> &Ins,
195 DebugLoc dl,
196 SelectionDAG &DAG,
197 SmallVectorImpl<SDValue> &InVals) const {
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000198 if (isVarArg) llvm_unreachable("PTX does not support varargs");
199
Che-Liang Chiou3278c422010-11-08 03:00:52 +0000200 MachineFunction &MF = DAG.getMachineFunction();
Justin Holewinski67a91842011-06-23 18:10:03 +0000201 const PTXSubtarget& ST = getTargetMachine().getSubtarget<PTXSubtarget>();
Che-Liang Chiou3278c422010-11-08 03:00:52 +0000202 PTXMachineFunctionInfo *MFI = MF.getInfo<PTXMachineFunctionInfo>();
Justin Holewinski27f08fc2011-09-23 14:18:22 +0000203 PTXParamManager &PM = MFI->getParamManager();
Che-Liang Chiou3278c422010-11-08 03:00:52 +0000204
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000205 switch (CallConv) {
206 default:
207 llvm_unreachable("Unsupported calling convention");
208 break;
209 case CallingConv::PTX_Kernel:
Che-Liang Chiou8e5d01c2011-02-10 12:01:24 +0000210 MFI->setKernel(true);
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000211 break;
212 case CallingConv::PTX_Device:
Che-Liang Chiou3278c422010-11-08 03:00:52 +0000213 MFI->setKernel(false);
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000214 break;
215 }
216
Justin Holewinski67a91842011-06-23 18:10:03 +0000217 // We do one of two things here:
218 // IsKernel || SM >= 2.0 -> Use param space for arguments
219 // SM < 2.0 -> Use registers for arguments
Justin Holewinski35f4fb32011-06-24 16:27:49 +0000220 if (MFI->isKernel() || ST.useParamSpaceForDeviceArgs()) {
Justin Holewinskia5ccb4e2011-06-23 18:10:05 +0000221 // We just need to emit the proper LOAD_PARAM ISDs
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000222 for (unsigned i = 0, e = Ins.size(); i != e; ++i) {
Justin Holewinski67a91842011-06-23 18:10:03 +0000223 assert((!MFI->isKernel() || Ins[i].VT != MVT::i1) &&
224 "Kernels cannot take pred operands");
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000225
Justin Holewinski27f08fc2011-09-23 14:18:22 +0000226 unsigned ParamSize = Ins[i].VT.getStoreSizeInBits();
227 unsigned Param = PM.addArgumentParam(ParamSize);
Justin Holewinskia5ccb4e2011-06-23 18:10:05 +0000228 SDValue ArgValue = DAG.getNode(PTXISD::LOAD_PARAM, dl, Ins[i].VT, Chain,
Justin Holewinski27f08fc2011-09-23 14:18:22 +0000229 DAG.getTargetConstant(Param, MVT::i32));
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000230 InVals.push_back(ArgValue);
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000231
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000232 // Instead of storing a physical register in our argument list, we just
233 // store the total size of the parameter, in bits. The ASM printer
234 // knows how to process this.
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000235 MFI->addArgParam(Ins[i].VT.getStoreSizeInBits());
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000236 }
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000237 }
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000238 else {
239 // For device functions, we use the PTX calling convention to do register
240 // assignments then create CopyFromReg ISDs for the allocated registers
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000241
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000242 //SmallVector<CCValAssign, 16> ArgLocs;
243 //CCState CCInfo(CallConv, isVarArg, MF, getTargetMachine(), ArgLocs,
244 // *DAG.getContext());
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000245
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000246 //CCInfo.AnalyzeFormalArguments(Ins, CC_PTX);
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000247
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000248 //for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
249 for (unsigned i = 0, e = Ins.size(); i != e; ++i) {
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000250
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000251 EVT RegVT = Ins[i].VT;
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000252 TargetRegisterClass* TRC = 0;
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000253 int OpCode;
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000254
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000255 //assert(VA.isRegLoc() && "CCValAssign must be RegLoc");
256
257 // Determine which register class we need
258 if (RegVT == MVT::i1) {
259 TRC = PTX::RegPredRegisterClass;
260 OpCode = PTX::READPARAMPRED;
261 }
262 else if (RegVT == MVT::i16) {
263 TRC = PTX::RegI16RegisterClass;
264 OpCode = PTX::READPARAMI16;
265 }
266 else if (RegVT == MVT::i32) {
267 TRC = PTX::RegI32RegisterClass;
268 OpCode = PTX::READPARAMI32;
269 }
270 else if (RegVT == MVT::i64) {
271 TRC = PTX::RegI64RegisterClass;
272 OpCode = PTX::READPARAMI64;
273 }
274 else if (RegVT == MVT::f32) {
275 TRC = PTX::RegF32RegisterClass;
276 OpCode = PTX::READPARAMF32;
277 }
278 else if (RegVT == MVT::f64) {
279 TRC = PTX::RegF64RegisterClass;
280 OpCode = PTX::READPARAMF64;
281 }
282 else {
283 llvm_unreachable("Unknown parameter type");
284 }
285
286 // Use a unique index in the instruction to prevent instruction folding.
287 // Yes, this is a hack.
288 SDValue Index = DAG.getTargetConstant(i, MVT::i32);
289 unsigned Reg = MF.getRegInfo().createVirtualRegister(TRC);
290 SDValue ArgValue = DAG.getNode(PTXISD::READ_PARAM, dl, RegVT, Chain,
291 Index);
292
293 SDValue Flag = ArgValue.getValue(1);
294
295 SDValue Copy = DAG.getCopyFromReg(Chain, dl, Reg, RegVT);
296 SDValue RegValue = DAG.getRegister(Reg, RegVT);
297 InVals.push_back(ArgValue);
298
299 MFI->addArgReg(Reg);
300 }
301 }
302
303 return Chain;
304}
305
306SDValue PTXTargetLowering::
307 LowerReturn(SDValue Chain,
308 CallingConv::ID CallConv,
309 bool isVarArg,
310 const SmallVectorImpl<ISD::OutputArg> &Outs,
311 const SmallVectorImpl<SDValue> &OutVals,
312 DebugLoc dl,
313 SelectionDAG &DAG) const {
314 if (isVarArg) llvm_unreachable("PTX does not support varargs");
315
316 switch (CallConv) {
317 default:
318 llvm_unreachable("Unsupported calling convention.");
319 case CallingConv::PTX_Kernel:
320 assert(Outs.size() == 0 && "Kernel must return void.");
321 return DAG.getNode(PTXISD::EXIT, dl, MVT::Other, Chain);
322 case CallingConv::PTX_Device:
323 assert(Outs.size() <= 1 && "Can at most return one value.");
324 break;
325 }
326
327 MachineFunction& MF = DAG.getMachineFunction();
328 PTXMachineFunctionInfo *MFI = MF.getInfo<PTXMachineFunctionInfo>();
Justin Holewinski27f08fc2011-09-23 14:18:22 +0000329 PTXParamManager &PM = MFI->getParamManager();
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000330
331 SDValue Flag;
332
333 // Even though we could use the .param space for return arguments for
334 // device functions if SM >= 2.0 and the number of return arguments is
335 // only 1, we just always use registers since this makes the codegen
336 // easier.
337
338 const PTXSubtarget& ST = getTargetMachine().getSubtarget<PTXSubtarget>();
339
340 if (ST.useParamSpaceForDeviceArgs()) {
341 assert(Outs.size() < 2 && "Device functions can return at most one value");
342
343 if (Outs.size() == 1) {
Justin Holewinski27f08fc2011-09-23 14:18:22 +0000344 unsigned ParamSize = OutVals[0].getValueType().getSizeInBits();
345 unsigned Param = PM.addReturnParam(ParamSize);
346 SDValue ParamIndex = DAG.getTargetConstant(Param, MVT::i32);
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000347 Chain = DAG.getNode(PTXISD::STORE_PARAM, dl, MVT::Other, Chain,
Justin Holewinski27f08fc2011-09-23 14:18:22 +0000348 ParamIndex, OutVals[0]);
349
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000350
351 //Flag = Chain.getValue(1);
Justin Holewinski27f08fc2011-09-23 14:18:22 +0000352 //MFI->setRetParamSize(Outs[0].VT.getStoreSizeInBits());
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000353 }
354 } else {
355 //SmallVector<CCValAssign, 16> RVLocs;
356 //CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
357 //getTargetMachine(), RVLocs, *DAG.getContext());
358
359 //CCInfo.AnalyzeReturn(Outs, RetCC_PTX);
360
361 //for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) {
362 //CCValAssign& VA = RVLocs[i];
363
364 for (unsigned i = 0, e = Outs.size(); i != e; ++i) {
365
366 //assert(VA.isRegLoc() && "CCValAssign must be RegLoc");
367
368 //unsigned Reg = VA.getLocReg();
369
370 EVT RegVT = Outs[i].VT;
371 TargetRegisterClass* TRC = 0;
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000372
373 // Determine which register class we need
374 if (RegVT == MVT::i1) {
375 TRC = PTX::RegPredRegisterClass;
376 }
377 else if (RegVT == MVT::i16) {
378 TRC = PTX::RegI16RegisterClass;
379 }
380 else if (RegVT == MVT::i32) {
381 TRC = PTX::RegI32RegisterClass;
382 }
383 else if (RegVT == MVT::i64) {
384 TRC = PTX::RegI64RegisterClass;
385 }
386 else if (RegVT == MVT::f32) {
387 TRC = PTX::RegF32RegisterClass;
388 }
389 else if (RegVT == MVT::f64) {
390 TRC = PTX::RegF64RegisterClass;
391 }
392 else {
393 llvm_unreachable("Unknown parameter type");
394 }
395
396 unsigned Reg = MF.getRegInfo().createVirtualRegister(TRC);
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000397
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000398 //DAG.getMachineFunction().getRegInfo().addLiveOut(Reg);
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000399
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000400 //Chain = DAG.getCopyToReg(Chain, dl, Reg, OutVals[i], Flag);
401 //SDValue Copy = DAG.getCopyToReg(Chain, dl, Reg, OutVals[i]/*, Flag*/);
402
403 // Guarantee that all emitted copies are stuck together,
404 // avoiding something bad
405 //Flag = Chain.getValue(1);
406
407 SDValue Copy = DAG.getCopyToReg(Chain, dl, Reg, OutVals[i]/*, Flag*/);
408 SDValue OutReg = DAG.getRegister(Reg, RegVT);
409
410 Chain = DAG.getNode(PTXISD::WRITE_PARAM, dl, MVT::Other, Copy, OutReg);
411 //Flag = Chain.getValue(1);
412
413 MFI->addRetReg(Reg);
414
415 //MFI->addRetReg(Reg);
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000416 }
417 }
Che-Liang Chiou3278c422010-11-08 03:00:52 +0000418
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000419 if (Flag.getNode() == 0) {
420 return DAG.getNode(PTXISD::RET, dl, MVT::Other, Chain);
Che-Liang Chiouf7172022011-02-28 06:34:09 +0000421 }
422 else {
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000423 return DAG.getNode(PTXISD::RET, dl, MVT::Other, Chain, Flag);
Che-Liang Chiouf7172022011-02-28 06:34:09 +0000424 }
Eric Christopher50880d02010-09-18 18:52:28 +0000425}
Justin Holewinski4bdd4ed2011-08-09 17:36:31 +0000426
427SDValue
428PTXTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
429 CallingConv::ID CallConv, bool isVarArg,
430 bool &isTailCall,
431 const SmallVectorImpl<ISD::OutputArg> &Outs,
432 const SmallVectorImpl<SDValue> &OutVals,
433 const SmallVectorImpl<ISD::InputArg> &Ins,
434 DebugLoc dl, SelectionDAG &DAG,
435 SmallVectorImpl<SDValue> &InVals) const {
436
437 MachineFunction& MF = DAG.getMachineFunction();
438 PTXMachineFunctionInfo *MFI = MF.getInfo<PTXMachineFunctionInfo>();
Justin Holewinskie953a642011-09-23 14:31:12 +0000439 PTXParamManager &PM = MFI->getParamManager();
Justin Holewinski4bdd4ed2011-08-09 17:36:31 +0000440
Duncan Sands1f6a3292011-08-12 14:54:45 +0000441 assert(getTargetMachine().getSubtarget<PTXSubtarget>().callsAreHandled() &&
442 "Calls are not handled for the target device");
Justin Holewinski4bdd4ed2011-08-09 17:36:31 +0000443
Justin Holewinski75d80952011-09-23 16:48:41 +0000444 std::vector<SDValue> Ops;
445 // The layout of the ops will be [Chain, Ins, Callee, Outs]
446 Ops.resize(Outs.size() + Ins.size() + 2);
Justin Holewinski4bdd4ed2011-08-09 17:36:31 +0000447
Justin Holewinski75d80952011-09-23 16:48:41 +0000448 Ops[0] = Chain;
Justin Holewinski4bdd4ed2011-08-09 17:36:31 +0000449
450 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
451 const GlobalValue *GV = G->getGlobal();
Justin Holewinski75d80952011-09-23 16:48:41 +0000452 if (const Function *F = dyn_cast<Function>(GV)) {
453 assert(F->getCallingConv() == CallingConv::PTX_Device &&
454 "PTX function calls must be to PTX device functions");
455 Callee = DAG.getTargetGlobalAddress(GV, dl, getPointerTy());
456 Ops[Ins.size()+1] = Callee;
457 } else {
458 assert(false && "GlobalValue is not a function");
459 }
Justin Holewinski4bdd4ed2011-08-09 17:36:31 +0000460 } else {
461 assert(false && "Function must be a GlobalAddressSDNode");
462 }
463
464 for (unsigned i = 0; i != OutVals.size(); ++i) {
465 unsigned Size = OutVals[i].getValueType().getSizeInBits();
Justin Holewinskie953a642011-09-23 14:31:12 +0000466 unsigned Param = PM.addLocalParam(Size);
467 SDValue Index = DAG.getTargetConstant(Param, MVT::i32);
Justin Holewinski4bdd4ed2011-08-09 17:36:31 +0000468 Chain = DAG.getNode(PTXISD::STORE_PARAM, dl, MVT::Other, Chain,
469 Index, OutVals[i]);
Justin Holewinski75d80952011-09-23 16:48:41 +0000470 Ops[i+Ins.size()+2] = Index;
Justin Holewinski4bdd4ed2011-08-09 17:36:31 +0000471 }
472
Justin Holewinski75d80952011-09-23 16:48:41 +0000473 std::vector<unsigned> InParams;
Justin Holewinski4bdd4ed2011-08-09 17:36:31 +0000474
Justin Holewinski75d80952011-09-23 16:48:41 +0000475 for (unsigned i = 0; i < Ins.size(); ++i) {
476 unsigned Size = Ins[i].VT.getStoreSizeInBits();
477 unsigned Param = PM.addLocalParam(Size);
478 SDValue Index = DAG.getTargetConstant(Param, MVT::i32);
479 Ops[i+1] = Index;
480 InParams.push_back(Param);
481 }
Justin Holewinski4bdd4ed2011-08-09 17:36:31 +0000482
Justin Holewinski75d80952011-09-23 16:48:41 +0000483 Ops[0] = Chain;
484
485 Chain = DAG.getNode(PTXISD::CALL, dl, MVT::Other, &Ops[0], Ops.size());
486
487 for (unsigned i = 0; i < Ins.size(); ++i) {
488 SDValue Index = DAG.getTargetConstant(InParams[i], MVT::i32);
489 SDValue Load = DAG.getNode(PTXISD::LOAD_PARAM, dl, Ins[i].VT, Chain, Index);
490 InVals.push_back(Load);
491 }
Justin Holewinski4bdd4ed2011-08-09 17:36:31 +0000492
493 return Chain;
494}