blob: 3fdfcdf57498e3da133624b7b634ff7f10e282ad [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>();
Justin Holewinski27f08fc2011-09-23 14:18:22 +0000202 PTXParamManager &PM = MFI->getParamManager();
Che-Liang Chiou3278c422010-11-08 03:00:52 +0000203
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000204 switch (CallConv) {
205 default:
206 llvm_unreachable("Unsupported calling convention");
207 break;
208 case CallingConv::PTX_Kernel:
Che-Liang Chiou8e5d01c2011-02-10 12:01:24 +0000209 MFI->setKernel(true);
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000210 break;
211 case CallingConv::PTX_Device:
Che-Liang Chiou3278c422010-11-08 03:00:52 +0000212 MFI->setKernel(false);
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000213 break;
214 }
215
Justin Holewinski67a91842011-06-23 18:10:03 +0000216 // We do one of two things here:
217 // IsKernel || SM >= 2.0 -> Use param space for arguments
218 // SM < 2.0 -> Use registers for arguments
Justin Holewinski35f4fb32011-06-24 16:27:49 +0000219 if (MFI->isKernel() || ST.useParamSpaceForDeviceArgs()) {
Justin Holewinskia5ccb4e2011-06-23 18:10:05 +0000220 // We just need to emit the proper LOAD_PARAM ISDs
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000221 for (unsigned i = 0, e = Ins.size(); i != e; ++i) {
Justin Holewinski67a91842011-06-23 18:10:03 +0000222 assert((!MFI->isKernel() || Ins[i].VT != MVT::i1) &&
223 "Kernels cannot take pred operands");
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000224
Justin Holewinski27f08fc2011-09-23 14:18:22 +0000225 unsigned ParamSize = Ins[i].VT.getStoreSizeInBits();
226 unsigned Param = PM.addArgumentParam(ParamSize);
Justin Holewinskia5ccb4e2011-06-23 18:10:05 +0000227 SDValue ArgValue = DAG.getNode(PTXISD::LOAD_PARAM, dl, Ins[i].VT, Chain,
Justin Holewinski27f08fc2011-09-23 14:18:22 +0000228 DAG.getTargetConstant(Param, MVT::i32));
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000229 InVals.push_back(ArgValue);
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000230
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000231 // Instead of storing a physical register in our argument list, we just
232 // store the total size of the parameter, in bits. The ASM printer
233 // knows how to process this.
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000234 MFI->addArgParam(Ins[i].VT.getStoreSizeInBits());
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000235 }
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000236 }
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000237 else {
238 // For device functions, we use the PTX calling convention to do register
239 // assignments then create CopyFromReg ISDs for the allocated registers
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000240
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000241 //SmallVector<CCValAssign, 16> ArgLocs;
242 //CCState CCInfo(CallConv, isVarArg, MF, getTargetMachine(), ArgLocs,
243 // *DAG.getContext());
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000244
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000245 //CCInfo.AnalyzeFormalArguments(Ins, CC_PTX);
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000246
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000247 //for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
248 for (unsigned i = 0, e = Ins.size(); i != e; ++i) {
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000249
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000250 EVT RegVT = Ins[i].VT;
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000251 TargetRegisterClass* TRC = 0;
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000252 int OpCode;
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000253
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000254 //assert(VA.isRegLoc() && "CCValAssign must be RegLoc");
255
256 // Determine which register class we need
257 if (RegVT == MVT::i1) {
258 TRC = PTX::RegPredRegisterClass;
259 OpCode = PTX::READPARAMPRED;
260 }
261 else if (RegVT == MVT::i16) {
262 TRC = PTX::RegI16RegisterClass;
263 OpCode = PTX::READPARAMI16;
264 }
265 else if (RegVT == MVT::i32) {
266 TRC = PTX::RegI32RegisterClass;
267 OpCode = PTX::READPARAMI32;
268 }
269 else if (RegVT == MVT::i64) {
270 TRC = PTX::RegI64RegisterClass;
271 OpCode = PTX::READPARAMI64;
272 }
273 else if (RegVT == MVT::f32) {
274 TRC = PTX::RegF32RegisterClass;
275 OpCode = PTX::READPARAMF32;
276 }
277 else if (RegVT == MVT::f64) {
278 TRC = PTX::RegF64RegisterClass;
279 OpCode = PTX::READPARAMF64;
280 }
281 else {
282 llvm_unreachable("Unknown parameter type");
283 }
284
285 // Use a unique index in the instruction to prevent instruction folding.
286 // Yes, this is a hack.
287 SDValue Index = DAG.getTargetConstant(i, MVT::i32);
288 unsigned Reg = MF.getRegInfo().createVirtualRegister(TRC);
289 SDValue ArgValue = DAG.getNode(PTXISD::READ_PARAM, dl, RegVT, Chain,
290 Index);
291
292 SDValue Flag = ArgValue.getValue(1);
293
294 SDValue Copy = DAG.getCopyFromReg(Chain, dl, Reg, RegVT);
295 SDValue RegValue = DAG.getRegister(Reg, RegVT);
296 InVals.push_back(ArgValue);
297
298 MFI->addArgReg(Reg);
299 }
300 }
301
302 return Chain;
303}
304
305SDValue PTXTargetLowering::
306 LowerReturn(SDValue Chain,
307 CallingConv::ID CallConv,
308 bool isVarArg,
309 const SmallVectorImpl<ISD::OutputArg> &Outs,
310 const SmallVectorImpl<SDValue> &OutVals,
311 DebugLoc dl,
312 SelectionDAG &DAG) const {
313 if (isVarArg) llvm_unreachable("PTX does not support varargs");
314
315 switch (CallConv) {
316 default:
317 llvm_unreachable("Unsupported calling convention.");
318 case CallingConv::PTX_Kernel:
319 assert(Outs.size() == 0 && "Kernel must return void.");
320 return DAG.getNode(PTXISD::EXIT, dl, MVT::Other, Chain);
321 case CallingConv::PTX_Device:
322 assert(Outs.size() <= 1 && "Can at most return one value.");
323 break;
324 }
325
326 MachineFunction& MF = DAG.getMachineFunction();
327 PTXMachineFunctionInfo *MFI = MF.getInfo<PTXMachineFunctionInfo>();
Justin Holewinski27f08fc2011-09-23 14:18:22 +0000328 PTXParamManager &PM = MFI->getParamManager();
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000329
330 SDValue Flag;
331
332 // Even though we could use the .param space for return arguments for
333 // device functions if SM >= 2.0 and the number of return arguments is
334 // only 1, we just always use registers since this makes the codegen
335 // easier.
336
337 const PTXSubtarget& ST = getTargetMachine().getSubtarget<PTXSubtarget>();
338
339 if (ST.useParamSpaceForDeviceArgs()) {
340 assert(Outs.size() < 2 && "Device functions can return at most one value");
341
342 if (Outs.size() == 1) {
Justin Holewinski27f08fc2011-09-23 14:18:22 +0000343 unsigned ParamSize = OutVals[0].getValueType().getSizeInBits();
344 unsigned Param = PM.addReturnParam(ParamSize);
345 SDValue ParamIndex = DAG.getTargetConstant(Param, MVT::i32);
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000346 Chain = DAG.getNode(PTXISD::STORE_PARAM, dl, MVT::Other, Chain,
Justin Holewinski27f08fc2011-09-23 14:18:22 +0000347 ParamIndex, OutVals[0]);
348
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000349
350 //Flag = Chain.getValue(1);
Justin Holewinski27f08fc2011-09-23 14:18:22 +0000351 //MFI->setRetParamSize(Outs[0].VT.getStoreSizeInBits());
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000352 }
353 } else {
354 //SmallVector<CCValAssign, 16> RVLocs;
355 //CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
356 //getTargetMachine(), RVLocs, *DAG.getContext());
357
358 //CCInfo.AnalyzeReturn(Outs, RetCC_PTX);
359
360 //for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) {
361 //CCValAssign& VA = RVLocs[i];
362
363 for (unsigned i = 0, e = Outs.size(); i != e; ++i) {
364
365 //assert(VA.isRegLoc() && "CCValAssign must be RegLoc");
366
367 //unsigned Reg = VA.getLocReg();
368
369 EVT RegVT = Outs[i].VT;
370 TargetRegisterClass* TRC = 0;
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000371
372 // Determine which register class we need
373 if (RegVT == MVT::i1) {
374 TRC = PTX::RegPredRegisterClass;
375 }
376 else if (RegVT == MVT::i16) {
377 TRC = PTX::RegI16RegisterClass;
378 }
379 else if (RegVT == MVT::i32) {
380 TRC = PTX::RegI32RegisterClass;
381 }
382 else if (RegVT == MVT::i64) {
383 TRC = PTX::RegI64RegisterClass;
384 }
385 else if (RegVT == MVT::f32) {
386 TRC = PTX::RegF32RegisterClass;
387 }
388 else if (RegVT == MVT::f64) {
389 TRC = PTX::RegF64RegisterClass;
390 }
391 else {
392 llvm_unreachable("Unknown parameter type");
393 }
394
395 unsigned Reg = MF.getRegInfo().createVirtualRegister(TRC);
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000396
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000397 //DAG.getMachineFunction().getRegInfo().addLiveOut(Reg);
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000398
Justin Holewinski5422a0f2011-09-22 16:45:46 +0000399 //Chain = DAG.getCopyToReg(Chain, dl, Reg, OutVals[i], Flag);
400 //SDValue Copy = DAG.getCopyToReg(Chain, dl, Reg, OutVals[i]/*, Flag*/);
401
402 // Guarantee that all emitted copies are stuck together,
403 // avoiding something bad
404 //Flag = Chain.getValue(1);
405
406 SDValue Copy = DAG.getCopyToReg(Chain, dl, Reg, OutVals[i]/*, Flag*/);
407 SDValue OutReg = DAG.getRegister(Reg, RegVT);
408
409 Chain = DAG.getNode(PTXISD::WRITE_PARAM, dl, MVT::Other, Copy, OutReg);
410 //Flag = Chain.getValue(1);
411
412 MFI->addRetReg(Reg);
413
414 //MFI->addRetReg(Reg);
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000415 }
416 }
Che-Liang Chiou3278c422010-11-08 03:00:52 +0000417
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000418 if (Flag.getNode() == 0) {
419 return DAG.getNode(PTXISD::RET, dl, MVT::Other, Chain);
Che-Liang Chiouf7172022011-02-28 06:34:09 +0000420 }
421 else {
Justin Holewinskie0aef2d2011-06-16 17:50:00 +0000422 return DAG.getNode(PTXISD::RET, dl, MVT::Other, Chain, Flag);
Che-Liang Chiouf7172022011-02-28 06:34:09 +0000423 }
Eric Christopher50880d02010-09-18 18:52:28 +0000424}
Justin Holewinski4bdd4ed2011-08-09 17:36:31 +0000425
426SDValue
427PTXTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
428 CallingConv::ID CallConv, bool isVarArg,
429 bool &isTailCall,
430 const SmallVectorImpl<ISD::OutputArg> &Outs,
431 const SmallVectorImpl<SDValue> &OutVals,
432 const SmallVectorImpl<ISD::InputArg> &Ins,
433 DebugLoc dl, SelectionDAG &DAG,
434 SmallVectorImpl<SDValue> &InVals) const {
435
436 MachineFunction& MF = DAG.getMachineFunction();
437 PTXMachineFunctionInfo *MFI = MF.getInfo<PTXMachineFunctionInfo>();
Justin Holewinskie953a642011-09-23 14:31:12 +0000438 PTXParamManager &PM = MFI->getParamManager();
Justin Holewinski4bdd4ed2011-08-09 17:36:31 +0000439
Duncan Sands1f6a3292011-08-12 14:54:45 +0000440 assert(getTargetMachine().getSubtarget<PTXSubtarget>().callsAreHandled() &&
441 "Calls are not handled for the target device");
Justin Holewinski4bdd4ed2011-08-09 17:36:31 +0000442
443 // Is there a more "LLVM"-way to create a variable-length array of values?
444 SDValue* ops = new SDValue[OutVals.size() + 2];
445
446 ops[0] = Chain;
447
448 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
449 const GlobalValue *GV = G->getGlobal();
450 Callee = DAG.getTargetGlobalAddress(GV, dl, getPointerTy());
451 ops[1] = Callee;
452 } else {
453 assert(false && "Function must be a GlobalAddressSDNode");
454 }
455
456 for (unsigned i = 0; i != OutVals.size(); ++i) {
457 unsigned Size = OutVals[i].getValueType().getSizeInBits();
Justin Holewinskie953a642011-09-23 14:31:12 +0000458 unsigned Param = PM.addLocalParam(Size);
459 SDValue Index = DAG.getTargetConstant(Param, MVT::i32);
Justin Holewinski4bdd4ed2011-08-09 17:36:31 +0000460 Chain = DAG.getNode(PTXISD::STORE_PARAM, dl, MVT::Other, Chain,
461 Index, OutVals[i]);
462 ops[i+2] = Index;
463 }
464
465 ops[0] = Chain;
466
467 Chain = DAG.getNode(PTXISD::CALL, dl, MVT::Other, ops, OutVals.size()+2);
468
469 delete [] ops;
470
471 return Chain;
472}