blob: 2d7756e214e14e6f2c334f953749aa1ca34a3465 [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"
Eric Christopher50880d02010-09-18 18:52:28 +000019#include "llvm/Support/ErrorHandling.h"
Justin Holewinskie0aef2d2011-06-16 17:50:00 +000020#include "llvm/CodeGen/CallingConvLower.h"
Che-Liang Chioub48f2c22010-10-19 13:14:40 +000021#include "llvm/CodeGen/MachineFunction.h"
22#include "llvm/CodeGen/MachineRegisterInfo.h"
Eric Christopher50880d02010-09-18 18:52:28 +000023#include "llvm/CodeGen/SelectionDAG.h"
24#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
Justin Holewinski4bdd4ed2011-08-09 17:36:31 +000025#include "llvm/Support/Debug.h"
Che-Liang Chioufd8978b2011-03-02 03:20:28 +000026#include "llvm/Support/raw_ostream.h"
Eric Christopher50880d02010-09-18 18:52:28 +000027
28using namespace llvm;
29
Justin Holewinskie0aef2d2011-06-16 17:50:00 +000030//===----------------------------------------------------------------------===//
Justin Holewinskie0aef2d2011-06-16 17:50:00 +000031// TargetLowering Implementation
32//===----------------------------------------------------------------------===//
33
Eric Christopher50880d02010-09-18 18:52:28 +000034PTXTargetLowering::PTXTargetLowering(TargetMachine &TM)
35 : TargetLowering(TM, new TargetLoweringObjectFileELF()) {
36 // Set up the register classes.
Justin Holewinski1b91bcd2011-06-16 17:49:58 +000037 addRegisterClass(MVT::i1, PTX::RegPredRegisterClass);
38 addRegisterClass(MVT::i16, PTX::RegI16RegisterClass);
39 addRegisterClass(MVT::i32, PTX::RegI32RegisterClass);
40 addRegisterClass(MVT::i64, PTX::RegI64RegisterClass);
41 addRegisterClass(MVT::f32, PTX::RegF32RegisterClass);
42 addRegisterClass(MVT::f64, PTX::RegF64RegisterClass);
Che-Liang Chioufd8978b2011-03-02 03:20:28 +000043
Justin Holewinski4fea05a2011-04-28 00:19:52 +000044 setBooleanContents(ZeroOrOneBooleanContent);
Duncan Sands28b77e92011-09-06 19:07:46 +000045 setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct?
Dan Bailey84149462011-06-25 18:16:28 +000046 setMinFunctionAlignment(2);
Justin Holewinski05591be2011-09-22 16:45:43 +000047
Dan Bailey84149462011-06-25 18:16:28 +000048 ////////////////////////////////////
49 /////////// Expansion //////////////
50 ////////////////////////////////////
Justin Holewinski05591be2011-09-22 16:45:43 +000051
Dan Bailey84149462011-06-25 18:16:28 +000052 // (any/zero/sign) extload => load + (any/zero/sign) extend
Justin Holewinski05591be2011-09-22 16:45:43 +000053
Justin Holewinski4fea05a2011-04-28 00:19:52 +000054 setLoadExtAction(ISD::EXTLOAD, MVT::i16, Expand);
55 setLoadExtAction(ISD::ZEXTLOAD, MVT::i16, Expand);
Dan Baileyb05a8a82011-06-24 19:27:10 +000056 setLoadExtAction(ISD::SEXTLOAD, MVT::i16, Expand);
Justin Holewinski05591be2011-09-22 16:45:43 +000057
Dan Bailey84149462011-06-25 18:16:28 +000058 // f32 extload => load + fextend
Justin Holewinski05591be2011-09-22 16:45:43 +000059
60 setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand);
61
Dan Bailey84149462011-06-25 18:16:28 +000062 // f64 truncstore => trunc + store
Justin Holewinski05591be2011-09-22 16:45:43 +000063
64 setTruncStoreAction(MVT::f64, MVT::f32, Expand);
65
Dan Bailey84149462011-06-25 18:16:28 +000066 // sign_extend_inreg => sign_extend
Justin Holewinski05591be2011-09-22 16:45:43 +000067
Dan Bailey84149462011-06-25 18:16:28 +000068 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
Justin Holewinski05591be2011-09-22 16:45:43 +000069
Dan Bailey84149462011-06-25 18:16:28 +000070 // br_cc => brcond
Justin Holewinski05591be2011-09-22 16:45:43 +000071
Che-Liang Chiou88d33672011-03-18 11:08:52 +000072 setOperationAction(ISD::BR_CC, MVT::Other, Expand);
73
Dan Bailey84149462011-06-25 18:16:28 +000074 // select_cc => setcc
Justin Holewinski05591be2011-09-22 16:45:43 +000075
Justin Holewinski2d525c52011-04-28 00:19:56 +000076 setOperationAction(ISD::SELECT_CC, MVT::Other, Expand);
77 setOperationAction(ISD::SELECT_CC, MVT::f32, Expand);
78 setOperationAction(ISD::SELECT_CC, MVT::f64, Expand);
Justin Holewinski05591be2011-09-22 16:45:43 +000079
Dan Bailey84149462011-06-25 18:16:28 +000080 ////////////////////////////////////
81 //////////// Legal /////////////////
82 ////////////////////////////////////
Justin Holewinski05591be2011-09-22 16:45:43 +000083
Dan Bailey84149462011-06-25 18:16:28 +000084 setOperationAction(ISD::ConstantFP, MVT::f32, Legal);
85 setOperationAction(ISD::ConstantFP, MVT::f64, Legal);
Justin Holewinski05591be2011-09-22 16:45:43 +000086
Dan Bailey84149462011-06-25 18:16:28 +000087 ////////////////////////////////////
88 //////////// Custom ////////////////
89 ////////////////////////////////////
Justin Holewinski05591be2011-09-22 16:45:43 +000090
Dan Bailey84149462011-06-25 18:16:28 +000091 // customise setcc to use bitwise logic if possible
Justin Holewinski05591be2011-09-22 16:45:43 +000092
Justin Holewinski2d525c52011-04-28 00:19:56 +000093 setOperationAction(ISD::SETCC, MVT::i1, Custom);
Eli Friedmanfc5d3052011-05-06 20:34:06 +000094
Dan Bailey84149462011-06-25 18:16:28 +000095 // customize translation of memory addresses
Justin Holewinski05591be2011-09-22 16:45:43 +000096
Dan Bailey84149462011-06-25 18:16:28 +000097 setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
98 setOperationAction(ISD::GlobalAddress, MVT::i64, Custom);
Eli Friedmanfc5d3052011-05-06 20:34:06 +000099
Eric Christopher50880d02010-09-18 18:52:28 +0000100 // Compute derived properties from the register classes
101 computeRegisterProperties();
102}
103
Duncan Sands28b77e92011-09-06 19:07:46 +0000104EVT PTXTargetLowering::getSetCCResultType(EVT VT) const {
Justin Holewinski2d525c52011-04-28 00:19:56 +0000105 return MVT::i1;
106}
107
Che-Liang Chioufc7072c2010-12-22 10:38:51 +0000108SDValue PTXTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
109 switch (Op.getOpcode()) {
Che-Liang Chiou88d33672011-03-18 11:08:52 +0000110 default:
111 llvm_unreachable("Unimplemented operand");
Justin Holewinski2d525c52011-04-28 00:19:56 +0000112 case ISD::SETCC:
113 return LowerSETCC(Op, DAG);
Che-Liang Chiou88d33672011-03-18 11:08:52 +0000114 case ISD::GlobalAddress:
115 return LowerGlobalAddress(Op, DAG);
Che-Liang Chioufc7072c2010-12-22 10:38:51 +0000116 }
117}
118
Eric Christopher50880d02010-09-18 18:52:28 +0000119const char *PTXTargetLowering::getTargetNodeName(unsigned Opcode) const {
120 switch (Opcode) {
Che-Liang Chiou8e5d01c2011-02-10 12:01:24 +0000121 default:
122 llvm_unreachable("Unknown opcode");
Justin Holewinski8af78c92011-03-18 19:24:28 +0000123 case PTXISD::COPY_ADDRESS:
124 return "PTXISD::COPY_ADDRESS";
Justin Holewinskia5ccb4e2011-06-23 18:10:05 +0000125 case PTXISD::LOAD_PARAM:
126 return "PTXISD::LOAD_PARAM";
Justin Holewinski67a91842011-06-23 18:10:03 +0000127 case PTXISD::STORE_PARAM:
128 return "PTXISD::STORE_PARAM";
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000129 case PTXISD::READ_PARAM:
130 return "PTXISD::READ_PARAM";
131 case PTXISD::WRITE_PARAM:
132 return "PTXISD::WRITE_PARAM";
Che-Liang Chiou8e5d01c2011-02-10 12:01:24 +0000133 case PTXISD::EXIT:
134 return "PTXISD::EXIT";
135 case PTXISD::RET:
136 return "PTXISD::RET";
Justin Holewinski4bdd4ed2011-08-09 17:36:31 +0000137 case PTXISD::CALL:
138 return "PTXISD::CALL";
Eric Christopher50880d02010-09-18 18:52:28 +0000139 }
140}
141
142//===----------------------------------------------------------------------===//
Che-Liang Chioufc7072c2010-12-22 10:38:51 +0000143// Custom Lower Operation
144//===----------------------------------------------------------------------===//
145
Justin Holewinski2d525c52011-04-28 00:19:56 +0000146SDValue PTXTargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const {
147 assert(Op.getValueType() == MVT::i1 && "SetCC type must be 1-bit integer");
148 SDValue Op0 = Op.getOperand(0);
149 SDValue Op1 = Op.getOperand(1);
150 SDValue Op2 = Op.getOperand(2);
151 DebugLoc dl = Op.getDebugLoc();
152 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
Justin Holewinskiec3141b2011-06-16 15:17:11 +0000153
Justin Holewinski05591be2011-09-22 16:45:43 +0000154 // Look for X == 0, X == 1, X != 0, or X != 1
Justin Holewinski2d525c52011-04-28 00:19:56 +0000155 // We can simplify these to bitwise logic
Justin Holewinskiec3141b2011-06-16 15:17:11 +0000156
Justin Holewinski2d525c52011-04-28 00:19:56 +0000157 if (Op1.getOpcode() == ISD::Constant &&
158 (cast<ConstantSDNode>(Op1)->getZExtValue() == 1 ||
159 cast<ConstantSDNode>(Op1)->isNullValue()) &&
160 (CC == ISD::SETEQ || CC == ISD::SETNE)) {
161
Justin Holewinskiec3141b2011-06-16 15:17:11 +0000162 return DAG.getNode(ISD::AND, dl, MVT::i1, Op0, Op1);
Justin Holewinski2d525c52011-04-28 00:19:56 +0000163 }
Justin Holewinskiec3141b2011-06-16 15:17:11 +0000164
Justin Holewinski2d525c52011-04-28 00:19:56 +0000165 return DAG.getNode(ISD::SETCC, dl, MVT::i1, Op0, Op1, Op2);
166}
167
Che-Liang Chioufc7072c2010-12-22 10:38:51 +0000168SDValue PTXTargetLowering::
169LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const {
170 EVT PtrVT = getPointerTy();
171 DebugLoc dl = Op.getDebugLoc();
172 const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
Justin Holewinski8af78c92011-03-18 19:24:28 +0000173
Justin Holewinskid6625762011-03-23 16:58:51 +0000174 assert(PtrVT.isSimple() && "Pointer must be to primitive type.");
175
Justin Holewinski8af78c92011-03-18 19:24:28 +0000176 SDValue targetGlobal = DAG.getTargetGlobalAddress(GV, dl, PtrVT);
177 SDValue movInstr = DAG.getNode(PTXISD::COPY_ADDRESS,
178 dl,
Justin Holewinskid6625762011-03-23 16:58:51 +0000179 PtrVT.getSimpleVT(),
Justin Holewinski8af78c92011-03-18 19:24:28 +0000180 targetGlobal);
181
182 return movInstr;
Che-Liang Chioufc7072c2010-12-22 10:38:51 +0000183}
184
185//===----------------------------------------------------------------------===//
Eric Christopher50880d02010-09-18 18:52:28 +0000186// Calling Convention Implementation
187//===----------------------------------------------------------------------===//
188
189SDValue PTXTargetLowering::
190 LowerFormalArguments(SDValue Chain,
191 CallingConv::ID CallConv,
192 bool isVarArg,
193 const SmallVectorImpl<ISD::InputArg> &Ins,
194 DebugLoc dl,
195 SelectionDAG &DAG,
196 SmallVectorImpl<SDValue> &InVals) const {
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000197 if (isVarArg) llvm_unreachable("PTX does not support varargs");
198
Che-Liang Chiou3278c422010-11-08 03:00:52 +0000199 MachineFunction &MF = DAG.getMachineFunction();
Justin Holewinski67a91842011-06-23 18:10:03 +0000200 const PTXSubtarget& ST = getTargetMachine().getSubtarget<PTXSubtarget>();
Che-Liang Chiou3278c422010-11-08 03:00:52 +0000201 PTXMachineFunctionInfo *MFI = MF.getInfo<PTXMachineFunctionInfo>();
202
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000203 switch (CallConv) {
204 default:
205 llvm_unreachable("Unsupported calling convention");
206 break;
207 case CallingConv::PTX_Kernel:
Che-Liang Chiou8e5d01c2011-02-10 12:01:24 +0000208 MFI->setKernel(true);
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000209 break;
210 case CallingConv::PTX_Device:
Che-Liang Chiou3278c422010-11-08 03:00:52 +0000211 MFI->setKernel(false);
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000212 break;
213 }
214
Justin Holewinski67a91842011-06-23 18:10:03 +0000215 // We do one of two things here:
216 // IsKernel || SM >= 2.0 -> Use param space for arguments
217 // SM < 2.0 -> Use registers for arguments
Justin Holewinski35f4fb32011-06-24 16:27:49 +0000218 if (MFI->isKernel() || ST.useParamSpaceForDeviceArgs()) {
Justin Holewinskia5ccb4e2011-06-23 18:10:05 +0000219 // We just need to emit the proper LOAD_PARAM ISDs
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000220 for (unsigned i = 0, e = Ins.size(); i != e; ++i) {
Justin Holewinski67a91842011-06-23 18:10:03 +0000221 assert((!MFI->isKernel() || Ins[i].VT != MVT::i1) &&
222 "Kernels cannot take pred operands");
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000223
Justin Holewinskia5ccb4e2011-06-23 18:10:05 +0000224 SDValue ArgValue = DAG.getNode(PTXISD::LOAD_PARAM, dl, Ins[i].VT, Chain,
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000225 DAG.getTargetConstant(i, MVT::i32));
226 InVals.push_back(ArgValue);
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000227
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000228 // Instead of storing a physical register in our argument list, we just
229 // store the total size of the parameter, in bits. The ASM printer
230 // knows how to process this.
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000231 MFI->addArgParam(Ins[i].VT.getStoreSizeInBits());
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000232 }
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000233 }
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000234 else {
235 // For device functions, we use the PTX calling convention to do register
236 // assignments then create CopyFromReg ISDs for the allocated registers
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000237
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000238 //SmallVector<CCValAssign, 16> ArgLocs;
239 //CCState CCInfo(CallConv, isVarArg, MF, getTargetMachine(), ArgLocs,
240 // *DAG.getContext());
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000241
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000242 //CCInfo.AnalyzeFormalArguments(Ins, CC_PTX);
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000243
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000244 //for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
245 for (unsigned i = 0, e = Ins.size(); i != e; ++i) {
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000246
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000247 EVT RegVT = Ins[i].VT;
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000248 TargetRegisterClass* TRC = 0;
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000249 int OpCode;
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000250
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000251 //assert(VA.isRegLoc() && "CCValAssign must be RegLoc");
252
253 // Determine which register class we need
254 if (RegVT == MVT::i1) {
255 TRC = PTX::RegPredRegisterClass;
256 OpCode = PTX::READPARAMPRED;
257 }
258 else if (RegVT == MVT::i16) {
259 TRC = PTX::RegI16RegisterClass;
260 OpCode = PTX::READPARAMI16;
261 }
262 else if (RegVT == MVT::i32) {
263 TRC = PTX::RegI32RegisterClass;
264 OpCode = PTX::READPARAMI32;
265 }
266 else if (RegVT == MVT::i64) {
267 TRC = PTX::RegI64RegisterClass;
268 OpCode = PTX::READPARAMI64;
269 }
270 else if (RegVT == MVT::f32) {
271 TRC = PTX::RegF32RegisterClass;
272 OpCode = PTX::READPARAMF32;
273 }
274 else if (RegVT == MVT::f64) {
275 TRC = PTX::RegF64RegisterClass;
276 OpCode = PTX::READPARAMF64;
277 }
278 else {
279 llvm_unreachable("Unknown parameter type");
280 }
281
282 // Use a unique index in the instruction to prevent instruction folding.
283 // Yes, this is a hack.
284 SDValue Index = DAG.getTargetConstant(i, MVT::i32);
285 unsigned Reg = MF.getRegInfo().createVirtualRegister(TRC);
286 SDValue ArgValue = DAG.getNode(PTXISD::READ_PARAM, dl, RegVT, Chain,
287 Index);
288
289 SDValue Flag = ArgValue.getValue(1);
290
291 SDValue Copy = DAG.getCopyFromReg(Chain, dl, Reg, RegVT);
292 SDValue RegValue = DAG.getRegister(Reg, RegVT);
293 InVals.push_back(ArgValue);
294
295 MFI->addArgReg(Reg);
296 }
297 }
298
299 return Chain;
300}
301
302SDValue PTXTargetLowering::
303 LowerReturn(SDValue Chain,
304 CallingConv::ID CallConv,
305 bool isVarArg,
306 const SmallVectorImpl<ISD::OutputArg> &Outs,
307 const SmallVectorImpl<SDValue> &OutVals,
308 DebugLoc dl,
309 SelectionDAG &DAG) const {
310 if (isVarArg) llvm_unreachable("PTX does not support varargs");
311
312 switch (CallConv) {
313 default:
314 llvm_unreachable("Unsupported calling convention.");
315 case CallingConv::PTX_Kernel:
316 assert(Outs.size() == 0 && "Kernel must return void.");
317 return DAG.getNode(PTXISD::EXIT, dl, MVT::Other, Chain);
318 case CallingConv::PTX_Device:
319 assert(Outs.size() <= 1 && "Can at most return one value.");
320 break;
321 }
322
323 MachineFunction& MF = DAG.getMachineFunction();
324 PTXMachineFunctionInfo *MFI = MF.getInfo<PTXMachineFunctionInfo>();
325
326 SDValue Flag;
327
328 // Even though we could use the .param space for return arguments for
329 // device functions if SM >= 2.0 and the number of return arguments is
330 // only 1, we just always use registers since this makes the codegen
331 // easier.
332
333 const PTXSubtarget& ST = getTargetMachine().getSubtarget<PTXSubtarget>();
334
335 if (ST.useParamSpaceForDeviceArgs()) {
336 assert(Outs.size() < 2 && "Device functions can return at most one value");
337
338 if (Outs.size() == 1) {
339 unsigned Size = OutVals[0].getValueType().getSizeInBits();
340 SDValue Index = DAG.getTargetConstant(MFI->getNextParam(Size), MVT::i32);
341 Chain = DAG.getNode(PTXISD::STORE_PARAM, dl, MVT::Other, Chain,
342 Index, OutVals[0]);
343
344 //Flag = Chain.getValue(1);
345 MFI->setRetParamSize(Outs[0].VT.getStoreSizeInBits());
346 }
347 } else {
348 //SmallVector<CCValAssign, 16> RVLocs;
349 //CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
350 //getTargetMachine(), RVLocs, *DAG.getContext());
351
352 //CCInfo.AnalyzeReturn(Outs, RetCC_PTX);
353
354 //for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) {
355 //CCValAssign& VA = RVLocs[i];
356
357 for (unsigned i = 0, e = Outs.size(); i != e; ++i) {
358
359 //assert(VA.isRegLoc() && "CCValAssign must be RegLoc");
360
361 //unsigned Reg = VA.getLocReg();
362
363 EVT RegVT = Outs[i].VT;
364 TargetRegisterClass* TRC = 0;
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000365
366 // Determine which register class we need
367 if (RegVT == MVT::i1) {
368 TRC = PTX::RegPredRegisterClass;
369 }
370 else if (RegVT == MVT::i16) {
371 TRC = PTX::RegI16RegisterClass;
372 }
373 else if (RegVT == MVT::i32) {
374 TRC = PTX::RegI32RegisterClass;
375 }
376 else if (RegVT == MVT::i64) {
377 TRC = PTX::RegI64RegisterClass;
378 }
379 else if (RegVT == MVT::f32) {
380 TRC = PTX::RegF32RegisterClass;
381 }
382 else if (RegVT == MVT::f64) {
383 TRC = PTX::RegF64RegisterClass;
384 }
385 else {
386 llvm_unreachable("Unknown parameter type");
387 }
388
389 unsigned Reg = MF.getRegInfo().createVirtualRegister(TRC);
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000390
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000391 //DAG.getMachineFunction().getRegInfo().addLiveOut(Reg);
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000392
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000393 //Chain = DAG.getCopyToReg(Chain, dl, Reg, OutVals[i], Flag);
394 //SDValue Copy = DAG.getCopyToReg(Chain, dl, Reg, OutVals[i]/*, Flag*/);
395
396 // Guarantee that all emitted copies are stuck together,
397 // avoiding something bad
398 //Flag = Chain.getValue(1);
399
400 SDValue Copy = DAG.getCopyToReg(Chain, dl, Reg, OutVals[i]/*, Flag*/);
401 SDValue OutReg = DAG.getRegister(Reg, RegVT);
402
403 Chain = DAG.getNode(PTXISD::WRITE_PARAM, dl, MVT::Other, Copy, OutReg);
404 //Flag = Chain.getValue(1);
405
406 MFI->addRetReg(Reg);
407
408 //MFI->addRetReg(Reg);
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000409 }
410 }
Che-Liang Chiou3278c422010-11-08 03:00:52 +0000411
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000412 if (Flag.getNode() == 0) {
413 return DAG.getNode(PTXISD::RET, dl, MVT::Other, Chain);
Che-Liang Chiouf7172022011-02-28 06:34:09 +0000414 }
415 else {
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000416 return DAG.getNode(PTXISD::RET, dl, MVT::Other, Chain, Flag);
Che-Liang Chiouf7172022011-02-28 06:34:09 +0000417 }
Eric Christopher50880d02010-09-18 18:52:28 +0000418}
Justin Holewinski4bdd4ed2011-08-09 17:36:31 +0000419
420SDValue
421PTXTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
422 CallingConv::ID CallConv, bool isVarArg,
423 bool &isTailCall,
424 const SmallVectorImpl<ISD::OutputArg> &Outs,
425 const SmallVectorImpl<SDValue> &OutVals,
426 const SmallVectorImpl<ISD::InputArg> &Ins,
427 DebugLoc dl, SelectionDAG &DAG,
428 SmallVectorImpl<SDValue> &InVals) const {
429
430 MachineFunction& MF = DAG.getMachineFunction();
431 PTXMachineFunctionInfo *MFI = MF.getInfo<PTXMachineFunctionInfo>();
Justin Holewinski4bdd4ed2011-08-09 17:36:31 +0000432
Duncan Sands1f6a3292011-08-12 14:54:45 +0000433 assert(getTargetMachine().getSubtarget<PTXSubtarget>().callsAreHandled() &&
434 "Calls are not handled for the target device");
Justin Holewinski4bdd4ed2011-08-09 17:36:31 +0000435
436 // Is there a more "LLVM"-way to create a variable-length array of values?
437 SDValue* ops = new SDValue[OutVals.size() + 2];
438
439 ops[0] = Chain;
440
441 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
442 const GlobalValue *GV = G->getGlobal();
443 Callee = DAG.getTargetGlobalAddress(GV, dl, getPointerTy());
444 ops[1] = Callee;
445 } else {
446 assert(false && "Function must be a GlobalAddressSDNode");
447 }
448
449 for (unsigned i = 0; i != OutVals.size(); ++i) {
450 unsigned Size = OutVals[i].getValueType().getSizeInBits();
451 SDValue Index = DAG.getTargetConstant(MFI->getNextParam(Size), MVT::i32);
452 Chain = DAG.getNode(PTXISD::STORE_PARAM, dl, MVT::Other, Chain,
453 Index, OutVals[i]);
454 ops[i+2] = Index;
455 }
456
457 ops[0] = Chain;
458
459 Chain = DAG.getNode(PTXISD::CALL, dl, MVT::Other, ops, OutVals.size()+2);
460
461 delete [] ops;
462
463 return Chain;
464}