Fixed some bugs.
[llvm/zpu.git] / lib / Target / PTX / PTXISelLowering.cpp
blob5bd722188a086e6a868d6208b4d47aa4194090b0
1 //===-- 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.
12 //===----------------------------------------------------------------------===//
14 #include "PTX.h"
15 #include "PTXISelLowering.h"
16 #include "PTXRegisterInfo.h"
17 #include "llvm/Support/ErrorHandling.h"
18 #include "llvm/CodeGen/MachineFunction.h"
19 #include "llvm/CodeGen/MachineRegisterInfo.h"
20 #include "llvm/CodeGen/SelectionDAG.h"
21 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
23 using namespace llvm;
25 PTXTargetLowering::PTXTargetLowering(TargetMachine &TM)
26 : TargetLowering(TM, new TargetLoweringObjectFileELF()) {
27 // Set up the register classes.
28 addRegisterClass(MVT::i1, PTX::PredsRegisterClass);
29 addRegisterClass(MVT::i32, PTX::RRegs32RegisterClass);
31 // Compute derived properties from the register classes
32 computeRegisterProperties();
35 const char *PTXTargetLowering::getTargetNodeName(unsigned Opcode) const {
36 switch (Opcode) {
37 default: llvm_unreachable("Unknown opcode");
38 case PTXISD::EXIT: return "PTXISD::EXIT";
39 case PTXISD::RET: return "PTXISD::RET";
43 //===----------------------------------------------------------------------===//
44 // Calling Convention Implementation
45 //===----------------------------------------------------------------------===//
47 namespace {
48 struct argmap_entry {
49 MVT::SimpleValueType VT;
50 TargetRegisterClass *RC;
51 TargetRegisterClass::iterator loc;
53 argmap_entry(MVT::SimpleValueType _VT, TargetRegisterClass *_RC)
54 : VT(_VT), RC(_RC), loc(_RC->begin()) {}
56 void reset() { loc = RC->begin(); }
57 bool operator==(MVT::SimpleValueType _VT) const { return VT == _VT; }
58 } argmap[] = {
59 argmap_entry(MVT::i1, PTX::PredsRegisterClass),
60 argmap_entry(MVT::i32, PTX::RRegs32RegisterClass)
62 } // end anonymous namespace
64 static SDValue lower_kernel_argument(int i,
65 SDValue Chain,
66 DebugLoc dl,
67 MVT::SimpleValueType VT,
68 argmap_entry *entry,
69 SelectionDAG &DAG,
70 unsigned *argreg) {
71 // TODO
72 llvm_unreachable("Not implemented yet");
75 static SDValue lower_device_argument(int i,
76 SDValue Chain,
77 DebugLoc dl,
78 MVT::SimpleValueType VT,
79 argmap_entry *entry,
80 SelectionDAG &DAG,
81 unsigned *argreg) {
82 MachineRegisterInfo &RegInfo = DAG.getMachineFunction().getRegInfo();
84 unsigned preg = *++(entry->loc); // allocate start from register 1
85 unsigned vreg = RegInfo.createVirtualRegister(entry->RC);
86 RegInfo.addLiveIn(preg, vreg);
88 *argreg = preg;
89 return DAG.getCopyFromReg(Chain, dl, vreg, VT);
92 typedef SDValue (*lower_argument_func)(int i,
93 SDValue Chain,
94 DebugLoc dl,
95 MVT::SimpleValueType VT,
96 argmap_entry *entry,
97 SelectionDAG &DAG,
98 unsigned *argreg);
100 SDValue PTXTargetLowering::
101 LowerFormalArguments(SDValue Chain,
102 CallingConv::ID CallConv,
103 bool isVarArg,
104 const SmallVectorImpl<ISD::InputArg> &Ins,
105 DebugLoc dl,
106 SelectionDAG &DAG,
107 SmallVectorImpl<SDValue> &InVals) const {
108 if (isVarArg) llvm_unreachable("PTX does not support varargs");
110 lower_argument_func lower_argument;
112 switch (CallConv) {
113 default:
114 llvm_unreachable("Unsupported calling convention");
115 break;
116 case CallingConv::PTX_Kernel:
117 lower_argument = lower_kernel_argument;
118 break;
119 case CallingConv::PTX_Device:
120 lower_argument = lower_device_argument;
121 break;
124 // Reset argmap before allocation
125 for (struct argmap_entry *i = argmap, *e = argmap + array_lengthof(argmap);
126 i != e; ++ i)
127 i->reset();
129 for (int i = 0, e = Ins.size(); i != e; ++ i) {
130 MVT::SimpleValueType VT = Ins[i].VT.SimpleTy;
132 struct argmap_entry *entry = std::find(argmap,
133 argmap + array_lengthof(argmap), VT);
134 if (entry == argmap + array_lengthof(argmap))
135 llvm_unreachable("Type of argument is not supported");
137 unsigned reg;
138 SDValue arg = lower_argument(i, Chain, dl, VT, entry, DAG, &reg);
139 InVals.push_back(arg);
142 return Chain;
145 SDValue PTXTargetLowering::
146 LowerReturn(SDValue Chain,
147 CallingConv::ID CallConv,
148 bool isVarArg,
149 const SmallVectorImpl<ISD::OutputArg> &Outs,
150 const SmallVectorImpl<SDValue> &OutVals,
151 DebugLoc dl,
152 SelectionDAG &DAG) const {
153 if (isVarArg) llvm_unreachable("PTX does not support varargs");
155 switch (CallConv) {
156 default:
157 llvm_unreachable("Unsupported calling convention.");
158 case CallingConv::PTX_Kernel:
159 assert(Outs.size() == 0 && "Kernel must return void.");
160 return DAG.getNode(PTXISD::EXIT, dl, MVT::Other, Chain);
161 case CallingConv::PTX_Device:
162 assert(Outs.size() <= 1 && "Can at most return one value.");
163 break;
166 // PTX_Device
168 // return void
169 if (Outs.size() == 0)
170 return DAG.getNode(PTXISD::RET, dl, MVT::Other, Chain);
172 assert(Outs[0].VT == MVT::i32 && "Can return only basic types");
174 SDValue Flag;
175 unsigned reg = PTX::R0;
177 // If this is the first return lowered for this function, add the regs to the
178 // liveout set for the function
179 if (DAG.getMachineFunction().getRegInfo().liveout_empty())
180 DAG.getMachineFunction().getRegInfo().addLiveOut(reg);
182 // Copy the result values into the output registers
183 Chain = DAG.getCopyToReg(Chain, dl, reg, OutVals[0], Flag);
185 // Guarantee that all emitted copies are stuck together,
186 // avoiding something bad
187 Flag = Chain.getValue(1);
189 return DAG.getNode(PTXISD::RET, dl, MVT::Other, Chain, Flag);