blob: 4f5060ed990ae090d37da3471de876c2a1a08611 [file] [log] [blame]
Chris Lattnerd23405e2008-03-17 03:21:36 +00001//===-- SparcISelLowering.cpp - Sparc 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 interfaces that Sparc uses to lower LLVM code into a
11// selection DAG.
12//
13//===----------------------------------------------------------------------===//
14
15#include "SparcISelLowering.h"
16#include "SparcTargetMachine.h"
Chris Lattnerd23405e2008-03-17 03:21:36 +000017#include "llvm/Function.h"
Chris Lattner5a65b922008-03-17 05:41:48 +000018#include "llvm/CodeGen/CallingConvLower.h"
Chris Lattnerd23405e2008-03-17 03:21:36 +000019#include "llvm/CodeGen/MachineFrameInfo.h"
20#include "llvm/CodeGen/MachineFunction.h"
21#include "llvm/CodeGen/MachineInstrBuilder.h"
22#include "llvm/CodeGen/MachineRegisterInfo.h"
23#include "llvm/CodeGen/SelectionDAG.h"
Anton Korobeynikov0eefda12008-10-10 20:28:10 +000024#include "llvm/ADT/VectorExtras.h"
Torok Edwinc25e7582009-07-11 20:10:48 +000025#include "llvm/Support/ErrorHandling.h"
Chris Lattnerd23405e2008-03-17 03:21:36 +000026using namespace llvm;
27
Chris Lattner5a65b922008-03-17 05:41:48 +000028
29//===----------------------------------------------------------------------===//
30// Calling Convention Implementation
31//===----------------------------------------------------------------------===//
32
33#include "SparcGenCallingConv.inc"
34
Dan Gohman475871a2008-07-27 21:46:04 +000035static SDValue LowerRET(SDValue Op, SelectionDAG &DAG) {
Chris Lattner5a65b922008-03-17 05:41:48 +000036 // CCValAssign - represent the assignment of the return value to locations.
37 SmallVector<CCValAssign, 16> RVLocs;
Chris Lattner98949a62008-03-17 06:01:07 +000038 unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv();
Chris Lattner5a65b922008-03-17 05:41:48 +000039 bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg();
Dale Johannesena05dca42009-02-04 23:02:30 +000040 DebugLoc dl = Op.getDebugLoc();
Anton Korobeynikov53835702008-10-10 20:27:31 +000041
Chris Lattner5a65b922008-03-17 05:41:48 +000042 // CCState - Info about the registers and stack slot.
Owen Andersond1474d02009-07-09 17:57:24 +000043 CCState CCInfo(CC, isVarArg, DAG.getTarget(), RVLocs, DAG.getContext());
Anton Korobeynikov53835702008-10-10 20:27:31 +000044
Chris Lattner5a65b922008-03-17 05:41:48 +000045 // Analize return values of ISD::RET
Gabor Greifba36cb52008-08-28 21:40:38 +000046 CCInfo.AnalyzeReturn(Op.getNode(), RetCC_Sparc32);
Anton Korobeynikov53835702008-10-10 20:27:31 +000047
Chris Lattner5a65b922008-03-17 05:41:48 +000048 // If this is the first return lowered for this function, add the regs to the
49 // liveout set for the function.
50 if (DAG.getMachineFunction().getRegInfo().liveout_empty()) {
51 for (unsigned i = 0; i != RVLocs.size(); ++i)
52 if (RVLocs[i].isRegLoc())
53 DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg());
54 }
Anton Korobeynikov53835702008-10-10 20:27:31 +000055
Dan Gohman475871a2008-07-27 21:46:04 +000056 SDValue Chain = Op.getOperand(0);
57 SDValue Flag;
Chris Lattner5a65b922008-03-17 05:41:48 +000058
59 // Copy the result values into the output registers.
60 for (unsigned i = 0; i != RVLocs.size(); ++i) {
61 CCValAssign &VA = RVLocs[i];
62 assert(VA.isRegLoc() && "Can only return in registers!");
Anton Korobeynikov53835702008-10-10 20:27:31 +000063
Chris Lattner5a65b922008-03-17 05:41:48 +000064 // ISD::RET => ret chain, (regnum1,val1), ...
65 // So i*2+1 index only the regnums.
Dale Johannesena05dca42009-02-04 23:02:30 +000066 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
67 Op.getOperand(i*2+1), Flag);
Anton Korobeynikov53835702008-10-10 20:27:31 +000068
Chris Lattner5a65b922008-03-17 05:41:48 +000069 // Guarantee that all emitted copies are stuck together with flags.
70 Flag = Chain.getValue(1);
71 }
Anton Korobeynikov53835702008-10-10 20:27:31 +000072
Gabor Greifba36cb52008-08-28 21:40:38 +000073 if (Flag.getNode())
Dale Johannesena05dca42009-02-04 23:02:30 +000074 return DAG.getNode(SPISD::RET_FLAG, dl, MVT::Other, Chain, Flag);
75 return DAG.getNode(SPISD::RET_FLAG, dl, MVT::Other, Chain);
Chris Lattner5a65b922008-03-17 05:41:48 +000076}
77
78/// LowerArguments - V8 uses a very simple ABI, where all values are passed in
79/// either one or two GPRs, including FP values. TODO: we should pass FP values
80/// in FP registers for fastcc functions.
Dan Gohmana44b6742008-06-30 20:31:15 +000081void
82SparcTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG,
Dale Johannesen7d2ad622009-01-30 23:10:59 +000083 SmallVectorImpl<SDValue> &ArgValues,
84 DebugLoc dl) {
Chris Lattner5a65b922008-03-17 05:41:48 +000085 MachineFunction &MF = DAG.getMachineFunction();
86 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Anton Korobeynikov53835702008-10-10 20:27:31 +000087
Chris Lattner5a65b922008-03-17 05:41:48 +000088 static const unsigned ArgRegs[] = {
89 SP::I0, SP::I1, SP::I2, SP::I3, SP::I4, SP::I5
90 };
Anton Korobeynikov53835702008-10-10 20:27:31 +000091
Chris Lattner5a65b922008-03-17 05:41:48 +000092 const unsigned *CurArgReg = ArgRegs, *ArgRegEnd = ArgRegs+6;
93 unsigned ArgOffset = 68;
Anton Korobeynikov53835702008-10-10 20:27:31 +000094
Dan Gohman475871a2008-07-27 21:46:04 +000095 SDValue Root = DAG.getRoot();
96 std::vector<SDValue> OutChains;
Chris Lattner5a65b922008-03-17 05:41:48 +000097
98 for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) {
Duncan Sands83ec4b62008-06-06 12:08:01 +000099 MVT ObjectVT = getValueType(I->getType());
Anton Korobeynikov53835702008-10-10 20:27:31 +0000100
Duncan Sands83ec4b62008-06-06 12:08:01 +0000101 switch (ObjectVT.getSimpleVT()) {
Torok Edwinc25e7582009-07-11 20:10:48 +0000102 default: LLVM_UNREACHABLE("Unhandled argument type!");
Chris Lattner5a65b922008-03-17 05:41:48 +0000103 case MVT::i1:
104 case MVT::i8:
105 case MVT::i16:
106 case MVT::i32:
107 if (I->use_empty()) { // Argument is dead.
108 if (CurArgReg < ArgRegEnd) ++CurArgReg;
Dale Johannesene8d72302009-02-06 23:05:02 +0000109 ArgValues.push_back(DAG.getUNDEF(ObjectVT));
Chris Lattner5a65b922008-03-17 05:41:48 +0000110 } else if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR
111 unsigned VReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
112 MF.getRegInfo().addLiveIn(*CurArgReg++, VReg);
Dale Johannesen39355f92009-02-04 02:34:38 +0000113 SDValue Arg = DAG.getCopyFromReg(Root, dl, VReg, MVT::i32);
Chris Lattner5a65b922008-03-17 05:41:48 +0000114 if (ObjectVT != MVT::i32) {
115 unsigned AssertOp = ISD::AssertSext;
Dale Johannesen39355f92009-02-04 02:34:38 +0000116 Arg = DAG.getNode(AssertOp, dl, MVT::i32, Arg,
Chris Lattner5a65b922008-03-17 05:41:48 +0000117 DAG.getValueType(ObjectVT));
Dale Johannesen39355f92009-02-04 02:34:38 +0000118 Arg = DAG.getNode(ISD::TRUNCATE, dl, ObjectVT, Arg);
Chris Lattner5a65b922008-03-17 05:41:48 +0000119 }
120 ArgValues.push_back(Arg);
121 } else {
122 int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset);
Dan Gohman475871a2008-07-27 21:46:04 +0000123 SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
124 SDValue Load;
Chris Lattner5a65b922008-03-17 05:41:48 +0000125 if (ObjectVT == MVT::i32) {
Dale Johannesen39355f92009-02-04 02:34:38 +0000126 Load = DAG.getLoad(MVT::i32, dl, Root, FIPtr, NULL, 0);
Chris Lattner5a65b922008-03-17 05:41:48 +0000127 } else {
128 ISD::LoadExtType LoadOp = ISD::SEXTLOAD;
129
130 // Sparc is big endian, so add an offset based on the ObjectVT.
Duncan Sands83ec4b62008-06-06 12:08:01 +0000131 unsigned Offset = 4-std::max(1U, ObjectVT.getSizeInBits()/8);
Dale Johannesen39355f92009-02-04 02:34:38 +0000132 FIPtr = DAG.getNode(ISD::ADD, dl, MVT::i32, FIPtr,
Chris Lattner5a65b922008-03-17 05:41:48 +0000133 DAG.getConstant(Offset, MVT::i32));
Dale Johannesen39355f92009-02-04 02:34:38 +0000134 Load = DAG.getExtLoad(LoadOp, dl, MVT::i32, Root, FIPtr,
Chris Lattner5a65b922008-03-17 05:41:48 +0000135 NULL, 0, ObjectVT);
Dale Johannesen39355f92009-02-04 02:34:38 +0000136 Load = DAG.getNode(ISD::TRUNCATE, dl, ObjectVT, Load);
Chris Lattner5a65b922008-03-17 05:41:48 +0000137 }
138 ArgValues.push_back(Load);
139 }
Anton Korobeynikov53835702008-10-10 20:27:31 +0000140
Chris Lattner5a65b922008-03-17 05:41:48 +0000141 ArgOffset += 4;
142 break;
143 case MVT::f32:
144 if (I->use_empty()) { // Argument is dead.
145 if (CurArgReg < ArgRegEnd) ++CurArgReg;
Dale Johannesene8d72302009-02-06 23:05:02 +0000146 ArgValues.push_back(DAG.getUNDEF(ObjectVT));
Chris Lattner5a65b922008-03-17 05:41:48 +0000147 } else if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR
148 // FP value is passed in an integer register.
149 unsigned VReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
150 MF.getRegInfo().addLiveIn(*CurArgReg++, VReg);
Dale Johannesen39355f92009-02-04 02:34:38 +0000151 SDValue Arg = DAG.getCopyFromReg(Root, dl, VReg, MVT::i32);
Chris Lattner5a65b922008-03-17 05:41:48 +0000152
Dale Johannesen39355f92009-02-04 02:34:38 +0000153 Arg = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, Arg);
Chris Lattner5a65b922008-03-17 05:41:48 +0000154 ArgValues.push_back(Arg);
155 } else {
156 int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset);
Dan Gohman475871a2008-07-27 21:46:04 +0000157 SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
Dale Johannesen39355f92009-02-04 02:34:38 +0000158 SDValue Load = DAG.getLoad(MVT::f32, dl, Root, FIPtr, NULL, 0);
Chris Lattner5a65b922008-03-17 05:41:48 +0000159 ArgValues.push_back(Load);
160 }
161 ArgOffset += 4;
162 break;
163
164 case MVT::i64:
165 case MVT::f64:
166 if (I->use_empty()) { // Argument is dead.
167 if (CurArgReg < ArgRegEnd) ++CurArgReg;
168 if (CurArgReg < ArgRegEnd) ++CurArgReg;
Dale Johannesene8d72302009-02-06 23:05:02 +0000169 ArgValues.push_back(DAG.getUNDEF(ObjectVT));
Chris Lattner5a65b922008-03-17 05:41:48 +0000170 } else {
Dan Gohman475871a2008-07-27 21:46:04 +0000171 SDValue HiVal;
Chris Lattner5a65b922008-03-17 05:41:48 +0000172 if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR
173 unsigned VRegHi = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
174 MF.getRegInfo().addLiveIn(*CurArgReg++, VRegHi);
Dale Johannesen39355f92009-02-04 02:34:38 +0000175 HiVal = DAG.getCopyFromReg(Root, dl, VRegHi, MVT::i32);
Chris Lattner5a65b922008-03-17 05:41:48 +0000176 } else {
177 int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset);
Dan Gohman475871a2008-07-27 21:46:04 +0000178 SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
Dale Johannesen39355f92009-02-04 02:34:38 +0000179 HiVal = DAG.getLoad(MVT::i32, dl, Root, FIPtr, NULL, 0);
Chris Lattner5a65b922008-03-17 05:41:48 +0000180 }
Anton Korobeynikov53835702008-10-10 20:27:31 +0000181
Dan Gohman475871a2008-07-27 21:46:04 +0000182 SDValue LoVal;
Chris Lattner5a65b922008-03-17 05:41:48 +0000183 if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR
184 unsigned VRegLo = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
185 MF.getRegInfo().addLiveIn(*CurArgReg++, VRegLo);
Dale Johannesen39355f92009-02-04 02:34:38 +0000186 LoVal = DAG.getCopyFromReg(Root, dl, VRegLo, MVT::i32);
Chris Lattner5a65b922008-03-17 05:41:48 +0000187 } else {
188 int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset+4);
Dan Gohman475871a2008-07-27 21:46:04 +0000189 SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
Dale Johannesen39355f92009-02-04 02:34:38 +0000190 LoVal = DAG.getLoad(MVT::i32, dl, Root, FIPtr, NULL, 0);
Chris Lattner5a65b922008-03-17 05:41:48 +0000191 }
Anton Korobeynikov53835702008-10-10 20:27:31 +0000192
Chris Lattner5a65b922008-03-17 05:41:48 +0000193 // Compose the two halves together into an i64 unit.
Anton Korobeynikov53835702008-10-10 20:27:31 +0000194 SDValue WholeValue =
Dale Johannesen39355f92009-02-04 02:34:38 +0000195 DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, LoVal, HiVal);
Anton Korobeynikov53835702008-10-10 20:27:31 +0000196
Chris Lattner5a65b922008-03-17 05:41:48 +0000197 // If we want a double, do a bit convert.
198 if (ObjectVT == MVT::f64)
Dale Johannesen39355f92009-02-04 02:34:38 +0000199 WholeValue = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f64, WholeValue);
Anton Korobeynikov53835702008-10-10 20:27:31 +0000200
Chris Lattner5a65b922008-03-17 05:41:48 +0000201 ArgValues.push_back(WholeValue);
202 }
203 ArgOffset += 8;
204 break;
205 }
206 }
Anton Korobeynikov53835702008-10-10 20:27:31 +0000207
Chris Lattner5a65b922008-03-17 05:41:48 +0000208 // Store remaining ArgRegs to the stack if this is a varargs function.
209 if (F.isVarArg()) {
210 // Remember the vararg offset for the va_start implementation.
211 VarArgsFrameOffset = ArgOffset;
Anton Korobeynikov53835702008-10-10 20:27:31 +0000212
Chris Lattner5a65b922008-03-17 05:41:48 +0000213 for (; CurArgReg != ArgRegEnd; ++CurArgReg) {
214 unsigned VReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
215 MF.getRegInfo().addLiveIn(*CurArgReg, VReg);
Dale Johannesen39355f92009-02-04 02:34:38 +0000216 SDValue Arg = DAG.getCopyFromReg(DAG.getRoot(), dl, VReg, MVT::i32);
Chris Lattner5a65b922008-03-17 05:41:48 +0000217
218 int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset);
Dan Gohman475871a2008-07-27 21:46:04 +0000219 SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
Chris Lattner5a65b922008-03-17 05:41:48 +0000220
Dale Johannesen39355f92009-02-04 02:34:38 +0000221 OutChains.push_back(DAG.getStore(DAG.getRoot(), dl, Arg, FIPtr, NULL, 0));
Chris Lattner5a65b922008-03-17 05:41:48 +0000222 ArgOffset += 4;
223 }
224 }
Anton Korobeynikov53835702008-10-10 20:27:31 +0000225
Chris Lattner5a65b922008-03-17 05:41:48 +0000226 if (!OutChains.empty())
Dale Johannesen39355f92009-02-04 02:34:38 +0000227 DAG.setRoot(DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
Chris Lattner5a65b922008-03-17 05:41:48 +0000228 &OutChains[0], OutChains.size()));
Chris Lattner5a65b922008-03-17 05:41:48 +0000229}
230
Dan Gohman475871a2008-07-27 21:46:04 +0000231static SDValue LowerCALL(SDValue Op, SelectionDAG &DAG) {
Dan Gohman095cc292008-09-13 01:54:27 +0000232 CallSDNode *TheCall = cast<CallSDNode>(Op.getNode());
233 unsigned CallingConv = TheCall->getCallingConv();
234 SDValue Chain = TheCall->getChain();
235 SDValue Callee = TheCall->getCallee();
236 bool isVarArg = TheCall->isVarArg();
Dale Johannesen33c960f2009-02-04 20:06:27 +0000237 DebugLoc dl = TheCall->getDebugLoc();
Chris Lattner98949a62008-03-17 06:01:07 +0000238
Chris Lattner315123f2008-03-17 06:58:37 +0000239#if 0
240 // Analyze operands of the call, assigning locations to each operand.
241 SmallVector<CCValAssign, 16> ArgLocs;
242 CCState CCInfo(CallingConv, isVarArg, DAG.getTarget(), ArgLocs);
Gabor Greifba36cb52008-08-28 21:40:38 +0000243 CCInfo.AnalyzeCallOperands(Op.getNode(), CC_Sparc32);
Anton Korobeynikov53835702008-10-10 20:27:31 +0000244
Chris Lattner315123f2008-03-17 06:58:37 +0000245 // Get the size of the outgoing arguments stack space requirement.
246 unsigned ArgsSize = CCInfo.getNextStackOffset();
247 // FIXME: We can't use this until f64 is known to take two GPRs.
248#else
249 (void)CC_Sparc32;
Anton Korobeynikov53835702008-10-10 20:27:31 +0000250
Chris Lattner5a65b922008-03-17 05:41:48 +0000251 // Count the size of the outgoing arguments.
252 unsigned ArgsSize = 0;
Dan Gohman095cc292008-09-13 01:54:27 +0000253 for (unsigned i = 0, e = TheCall->getNumArgs(); i != e; ++i) {
254 switch (TheCall->getArg(i).getValueType().getSimpleVT()) {
Torok Edwinc25e7582009-07-11 20:10:48 +0000255 default: LLVM_UNREACHABLE("Unknown value type!");
Chris Lattner315123f2008-03-17 06:58:37 +0000256 case MVT::i1:
257 case MVT::i8:
258 case MVT::i16:
259 case MVT::i32:
260 case MVT::f32:
261 ArgsSize += 4;
262 break;
263 case MVT::i64:
264 case MVT::f64:
265 ArgsSize += 8;
266 break;
Chris Lattner5a65b922008-03-17 05:41:48 +0000267 }
268 }
269 if (ArgsSize > 4*6)
270 ArgsSize -= 4*6; // Space for first 6 arguments is prereserved.
271 else
272 ArgsSize = 0;
Anton Korobeynikov53835702008-10-10 20:27:31 +0000273#endif
274
Chris Lattner5a65b922008-03-17 05:41:48 +0000275 // Keep stack frames 8-byte aligned.
276 ArgsSize = (ArgsSize+7) & ~7;
277
Chris Lattnere563bbc2008-10-11 22:08:30 +0000278 Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(ArgsSize, true));
Anton Korobeynikov53835702008-10-10 20:27:31 +0000279
Dan Gohman475871a2008-07-27 21:46:04 +0000280 SmallVector<std::pair<unsigned, SDValue>, 8> RegsToPass;
281 SmallVector<SDValue, 8> MemOpChains;
Anton Korobeynikov53835702008-10-10 20:27:31 +0000282
Chris Lattner315123f2008-03-17 06:58:37 +0000283#if 0
284 // Walk the register/memloc assignments, inserting copies/loads.
285 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
286 CCValAssign &VA = ArgLocs[i];
Anton Korobeynikov53835702008-10-10 20:27:31 +0000287
Chris Lattner315123f2008-03-17 06:58:37 +0000288 // Arguments start after the 5 first operands of ISD::CALL
Dan Gohman095cc292008-09-13 01:54:27 +0000289 SDValue Arg = TheCall->getArg(i);
Chris Lattner315123f2008-03-17 06:58:37 +0000290
291 // Promote the value if needed.
292 switch (VA.getLocInfo()) {
Torok Edwinc25e7582009-07-11 20:10:48 +0000293 default: LLVM_UNREACHABLE("Unknown loc info!");
Chris Lattner315123f2008-03-17 06:58:37 +0000294 case CCValAssign::Full: break;
295 case CCValAssign::SExt:
296 Arg = DAG.getNode(ISD::SIGN_EXTEND, VA.getLocVT(), Arg);
297 break;
298 case CCValAssign::ZExt:
299 Arg = DAG.getNode(ISD::ZERO_EXTEND, VA.getLocVT(), Arg);
300 break;
301 case CCValAssign::AExt:
302 Arg = DAG.getNode(ISD::ANY_EXTEND, VA.getLocVT(), Arg);
303 break;
304 }
Anton Korobeynikov53835702008-10-10 20:27:31 +0000305
306 // Arguments that can be passed on register must be kept at
Chris Lattner315123f2008-03-17 06:58:37 +0000307 // RegsToPass vector
308 if (VA.isRegLoc()) {
309 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
310 continue;
311 }
Anton Korobeynikov53835702008-10-10 20:27:31 +0000312
Chris Lattner315123f2008-03-17 06:58:37 +0000313 assert(VA.isMemLoc());
Anton Korobeynikov53835702008-10-10 20:27:31 +0000314
Chris Lattner315123f2008-03-17 06:58:37 +0000315 // Create a store off the stack pointer for this argument.
Dan Gohman475871a2008-07-27 21:46:04 +0000316 SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32);
Chris Lattner315123f2008-03-17 06:58:37 +0000317 // FIXME: VERIFY THAT 68 IS RIGHT.
Dan Gohman475871a2008-07-27 21:46:04 +0000318 SDValue PtrOff = DAG.getIntPtrConstant(VA.getLocMemOffset()+68);
Chris Lattner315123f2008-03-17 06:58:37 +0000319 PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff);
320 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
321 }
Anton Korobeynikov53835702008-10-10 20:27:31 +0000322
323#else
Chris Lattner315123f2008-03-17 06:58:37 +0000324 static const unsigned ArgRegs[] = {
325 SP::I0, SP::I1, SP::I2, SP::I3, SP::I4, SP::I5
326 };
Chris Lattner5a65b922008-03-17 05:41:48 +0000327 unsigned ArgOffset = 68;
Chris Lattner315123f2008-03-17 06:58:37 +0000328
Dan Gohman095cc292008-09-13 01:54:27 +0000329 for (unsigned i = 0, e = TheCall->getNumArgs(); i != e; ++i) {
330 SDValue Val = TheCall->getArg(i);
Duncan Sands83ec4b62008-06-06 12:08:01 +0000331 MVT ObjectVT = Val.getValueType();
Dan Gohman475871a2008-07-27 21:46:04 +0000332 SDValue ValToStore(0, 0);
Chris Lattner5a65b922008-03-17 05:41:48 +0000333 unsigned ObjSize;
Duncan Sands83ec4b62008-06-06 12:08:01 +0000334 switch (ObjectVT.getSimpleVT()) {
Torok Edwinc25e7582009-07-11 20:10:48 +0000335 default: LLVM_UNREACHABLE("Unhandled argument type!");
Chris Lattner5a65b922008-03-17 05:41:48 +0000336 case MVT::i32:
337 ObjSize = 4;
338
Chris Lattner315123f2008-03-17 06:58:37 +0000339 if (RegsToPass.size() >= 6) {
Chris Lattner5a65b922008-03-17 05:41:48 +0000340 ValToStore = Val;
341 } else {
Chris Lattner315123f2008-03-17 06:58:37 +0000342 RegsToPass.push_back(std::make_pair(ArgRegs[RegsToPass.size()], Val));
Chris Lattner5a65b922008-03-17 05:41:48 +0000343 }
344 break;
345 case MVT::f32:
346 ObjSize = 4;
Chris Lattner315123f2008-03-17 06:58:37 +0000347 if (RegsToPass.size() >= 6) {
Chris Lattner5a65b922008-03-17 05:41:48 +0000348 ValToStore = Val;
349 } else {
350 // Convert this to a FP value in an int reg.
Dale Johannesen33c960f2009-02-04 20:06:27 +0000351 Val = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, Val);
Chris Lattner315123f2008-03-17 06:58:37 +0000352 RegsToPass.push_back(std::make_pair(ArgRegs[RegsToPass.size()], Val));
Chris Lattner5a65b922008-03-17 05:41:48 +0000353 }
354 break;
Duncan Sands8c0f2442008-12-12 08:05:40 +0000355 case MVT::f64: {
Chris Lattner5a65b922008-03-17 05:41:48 +0000356 ObjSize = 8;
Duncan Sands8c0f2442008-12-12 08:05:40 +0000357 if (RegsToPass.size() >= 6) {
358 ValToStore = Val; // Whole thing is passed in memory.
359 break;
360 }
361
362 // Break into top and bottom parts by storing to the stack and loading
363 // out the parts as integers. Top part goes in a reg.
364 SDValue StackPtr = DAG.CreateStackTemporary(MVT::f64, MVT::i32);
Dale Johannesen33c960f2009-02-04 20:06:27 +0000365 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl,
366 Val, StackPtr, NULL, 0);
Duncan Sands8c0f2442008-12-12 08:05:40 +0000367 // Sparc is big-endian, so the high part comes first.
Dale Johannesen33c960f2009-02-04 20:06:27 +0000368 SDValue Hi = DAG.getLoad(MVT::i32, dl, Store, StackPtr, NULL, 0, 0);
Duncan Sands8c0f2442008-12-12 08:05:40 +0000369 // Increment the pointer to the other half.
Dale Johannesen33c960f2009-02-04 20:06:27 +0000370 StackPtr = DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), StackPtr,
Duncan Sands8c0f2442008-12-12 08:05:40 +0000371 DAG.getIntPtrConstant(4));
372 // Load the low part.
Dale Johannesen33c960f2009-02-04 20:06:27 +0000373 SDValue Lo = DAG.getLoad(MVT::i32, dl, Store, StackPtr, NULL, 0, 0);
Duncan Sands8c0f2442008-12-12 08:05:40 +0000374
375 RegsToPass.push_back(std::make_pair(ArgRegs[RegsToPass.size()], Hi));
376
377 if (RegsToPass.size() >= 6) {
378 ValToStore = Lo;
379 ArgOffset += 4;
380 ObjSize = 4;
381 } else {
382 RegsToPass.push_back(std::make_pair(ArgRegs[RegsToPass.size()], Lo));
383 }
384 break;
385 }
386 case MVT::i64: {
Chris Lattner5a65b922008-03-17 05:41:48 +0000387 ObjSize = 8;
Chris Lattner315123f2008-03-17 06:58:37 +0000388 if (RegsToPass.size() >= 6) {
Chris Lattner5a65b922008-03-17 05:41:48 +0000389 ValToStore = Val; // Whole thing is passed in memory.
390 break;
391 }
Anton Korobeynikov53835702008-10-10 20:27:31 +0000392
Chris Lattner5a65b922008-03-17 05:41:48 +0000393 // Split the value into top and bottom part. Top part goes in a reg.
Dale Johannesen33c960f2009-02-04 20:06:27 +0000394 SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, Val,
Chris Lattner5a65b922008-03-17 05:41:48 +0000395 DAG.getConstant(1, MVT::i32));
Dale Johannesen33c960f2009-02-04 20:06:27 +0000396 SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, Val,
Chris Lattner5a65b922008-03-17 05:41:48 +0000397 DAG.getConstant(0, MVT::i32));
Chris Lattner315123f2008-03-17 06:58:37 +0000398 RegsToPass.push_back(std::make_pair(ArgRegs[RegsToPass.size()], Hi));
Anton Korobeynikov53835702008-10-10 20:27:31 +0000399
Chris Lattner315123f2008-03-17 06:58:37 +0000400 if (RegsToPass.size() >= 6) {
Chris Lattner5a65b922008-03-17 05:41:48 +0000401 ValToStore = Lo;
402 ArgOffset += 4;
403 ObjSize = 4;
404 } else {
Chris Lattner315123f2008-03-17 06:58:37 +0000405 RegsToPass.push_back(std::make_pair(ArgRegs[RegsToPass.size()], Lo));
Chris Lattner5a65b922008-03-17 05:41:48 +0000406 }
407 break;
408 }
Duncan Sands8c0f2442008-12-12 08:05:40 +0000409 }
Anton Korobeynikov53835702008-10-10 20:27:31 +0000410
Gabor Greifba36cb52008-08-28 21:40:38 +0000411 if (ValToStore.getNode()) {
Dan Gohman475871a2008-07-27 21:46:04 +0000412 SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32);
413 SDValue PtrOff = DAG.getConstant(ArgOffset, MVT::i32);
Dale Johannesen33c960f2009-02-04 20:06:27 +0000414 PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff);
415 MemOpChains.push_back(DAG.getStore(Chain, dl, ValToStore,
416 PtrOff, NULL, 0));
Chris Lattner5a65b922008-03-17 05:41:48 +0000417 }
418 ArgOffset += ObjSize;
419 }
Chris Lattner315123f2008-03-17 06:58:37 +0000420#endif
Anton Korobeynikov53835702008-10-10 20:27:31 +0000421
Chris Lattner5a65b922008-03-17 05:41:48 +0000422 // Emit all stores, make sure the occur before any copies into physregs.
Chris Lattner315123f2008-03-17 06:58:37 +0000423 if (!MemOpChains.empty())
Dale Johannesen33c960f2009-02-04 20:06:27 +0000424 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
Chris Lattner315123f2008-03-17 06:58:37 +0000425 &MemOpChains[0], MemOpChains.size());
Anton Korobeynikov53835702008-10-10 20:27:31 +0000426
427 // Build a sequence of copy-to-reg nodes chained together with token
Chris Lattner315123f2008-03-17 06:58:37 +0000428 // chain and flag operands which copy the outgoing args into registers.
429 // The InFlag in necessary since all emited instructions must be
430 // stuck together.
Dan Gohman475871a2008-07-27 21:46:04 +0000431 SDValue InFlag;
Chris Lattner315123f2008-03-17 06:58:37 +0000432 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
433 unsigned Reg = RegsToPass[i].first;
434 // Remap I0->I7 -> O0->O7.
435 if (Reg >= SP::I0 && Reg <= SP::I7)
436 Reg = Reg-SP::I0+SP::O0;
437
Dale Johannesen33c960f2009-02-04 20:06:27 +0000438 Chain = DAG.getCopyToReg(Chain, dl, Reg, RegsToPass[i].second, InFlag);
Chris Lattner5a65b922008-03-17 05:41:48 +0000439 InFlag = Chain.getValue(1);
440 }
441
442 // If the callee is a GlobalAddress node (quite common, every direct call is)
443 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
Bill Wendling056292f2008-09-16 21:48:12 +0000444 // Likewise ExternalSymbol -> TargetExternalSymbol.
Chris Lattner5a65b922008-03-17 05:41:48 +0000445 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
446 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), MVT::i32);
Bill Wendling056292f2008-09-16 21:48:12 +0000447 else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee))
448 Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i32);
Chris Lattner5a65b922008-03-17 05:41:48 +0000449
Duncan Sands83ec4b62008-06-06 12:08:01 +0000450 std::vector<MVT> NodeTys;
Chris Lattner5a65b922008-03-17 05:41:48 +0000451 NodeTys.push_back(MVT::Other); // Returns a chain
452 NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use.
Dan Gohman475871a2008-07-27 21:46:04 +0000453 SDValue Ops[] = { Chain, Callee, InFlag };
Dale Johannesen33c960f2009-02-04 20:06:27 +0000454 Chain = DAG.getNode(SPISD::CALL, dl, NodeTys, Ops, InFlag.getNode() ? 3 : 2);
Chris Lattner5a65b922008-03-17 05:41:48 +0000455 InFlag = Chain.getValue(1);
Anton Korobeynikov53835702008-10-10 20:27:31 +0000456
Chris Lattnere563bbc2008-10-11 22:08:30 +0000457 Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(ArgsSize, true),
458 DAG.getIntPtrConstant(0, true), InFlag);
Chris Lattner98949a62008-03-17 06:01:07 +0000459 InFlag = Chain.getValue(1);
Anton Korobeynikov53835702008-10-10 20:27:31 +0000460
Chris Lattner98949a62008-03-17 06:01:07 +0000461 // Assign locations to each value returned by this call.
462 SmallVector<CCValAssign, 16> RVLocs;
Owen Andersond1474d02009-07-09 17:57:24 +0000463 CCState RVInfo(CallingConv, isVarArg, DAG.getTarget(),
464 RVLocs, DAG.getContext());
Anton Korobeynikov53835702008-10-10 20:27:31 +0000465
Dan Gohman095cc292008-09-13 01:54:27 +0000466 RVInfo.AnalyzeCallResult(TheCall, RetCC_Sparc32);
Dan Gohman475871a2008-07-27 21:46:04 +0000467 SmallVector<SDValue, 8> ResultVals;
Anton Korobeynikov53835702008-10-10 20:27:31 +0000468
Chris Lattner98949a62008-03-17 06:01:07 +0000469 // Copy all of the result registers out of their specified physreg.
470 for (unsigned i = 0; i != RVLocs.size(); ++i) {
471 unsigned Reg = RVLocs[i].getLocReg();
Anton Korobeynikov53835702008-10-10 20:27:31 +0000472
Chris Lattner98949a62008-03-17 06:01:07 +0000473 // Remap I0->I7 -> O0->O7.
474 if (Reg >= SP::I0 && Reg <= SP::I7)
475 Reg = Reg-SP::I0+SP::O0;
Anton Korobeynikov53835702008-10-10 20:27:31 +0000476
Dale Johannesen33c960f2009-02-04 20:06:27 +0000477 Chain = DAG.getCopyFromReg(Chain, dl, Reg,
Chris Lattner98949a62008-03-17 06:01:07 +0000478 RVLocs[i].getValVT(), InFlag).getValue(1);
479 InFlag = Chain.getValue(2);
480 ResultVals.push_back(Chain.getValue(0));
Chris Lattner5a65b922008-03-17 05:41:48 +0000481 }
Anton Korobeynikov53835702008-10-10 20:27:31 +0000482
Chris Lattner98949a62008-03-17 06:01:07 +0000483 ResultVals.push_back(Chain);
Duncan Sands4bdcb612008-07-02 17:40:58 +0000484
Chris Lattner98949a62008-03-17 06:01:07 +0000485 // Merge everything together with a MERGE_VALUES node.
Dale Johannesen33c960f2009-02-04 20:06:27 +0000486 return DAG.getNode(ISD::MERGE_VALUES, dl,
487 TheCall->getVTList(), &ResultVals[0],
Duncan Sandsaaffa052008-12-01 11:41:29 +0000488 ResultVals.size());
Chris Lattner5a65b922008-03-17 05:41:48 +0000489}
490
491
492
Chris Lattnerd23405e2008-03-17 03:21:36 +0000493//===----------------------------------------------------------------------===//
494// TargetLowering Implementation
495//===----------------------------------------------------------------------===//
496
497/// IntCondCCodeToICC - Convert a DAG integer condition code to a SPARC ICC
498/// condition.
499static SPCC::CondCodes IntCondCCodeToICC(ISD::CondCode CC) {
500 switch (CC) {
Torok Edwinc25e7582009-07-11 20:10:48 +0000501 default: LLVM_UNREACHABLE("Unknown integer condition code!");
Chris Lattnerd23405e2008-03-17 03:21:36 +0000502 case ISD::SETEQ: return SPCC::ICC_E;
503 case ISD::SETNE: return SPCC::ICC_NE;
504 case ISD::SETLT: return SPCC::ICC_L;
505 case ISD::SETGT: return SPCC::ICC_G;
506 case ISD::SETLE: return SPCC::ICC_LE;
507 case ISD::SETGE: return SPCC::ICC_GE;
508 case ISD::SETULT: return SPCC::ICC_CS;
509 case ISD::SETULE: return SPCC::ICC_LEU;
510 case ISD::SETUGT: return SPCC::ICC_GU;
511 case ISD::SETUGE: return SPCC::ICC_CC;
512 }
513}
514
515/// FPCondCCodeToFCC - Convert a DAG floatingp oint condition code to a SPARC
516/// FCC condition.
517static SPCC::CondCodes FPCondCCodeToFCC(ISD::CondCode CC) {
518 switch (CC) {
Torok Edwinc25e7582009-07-11 20:10:48 +0000519 default: LLVM_UNREACHABLE("Unknown fp condition code!");
Chris Lattnerd23405e2008-03-17 03:21:36 +0000520 case ISD::SETEQ:
521 case ISD::SETOEQ: return SPCC::FCC_E;
522 case ISD::SETNE:
523 case ISD::SETUNE: return SPCC::FCC_NE;
524 case ISD::SETLT:
525 case ISD::SETOLT: return SPCC::FCC_L;
526 case ISD::SETGT:
527 case ISD::SETOGT: return SPCC::FCC_G;
528 case ISD::SETLE:
529 case ISD::SETOLE: return SPCC::FCC_LE;
530 case ISD::SETGE:
531 case ISD::SETOGE: return SPCC::FCC_GE;
532 case ISD::SETULT: return SPCC::FCC_UL;
533 case ISD::SETULE: return SPCC::FCC_ULE;
534 case ISD::SETUGT: return SPCC::FCC_UG;
535 case ISD::SETUGE: return SPCC::FCC_UGE;
536 case ISD::SETUO: return SPCC::FCC_U;
537 case ISD::SETO: return SPCC::FCC_O;
538 case ISD::SETONE: return SPCC::FCC_LG;
539 case ISD::SETUEQ: return SPCC::FCC_UE;
540 }
541}
542
543
544SparcTargetLowering::SparcTargetLowering(TargetMachine &TM)
545 : TargetLowering(TM) {
Anton Korobeynikov53835702008-10-10 20:27:31 +0000546
Chris Lattnerd23405e2008-03-17 03:21:36 +0000547 // Set up the register classes.
548 addRegisterClass(MVT::i32, SP::IntRegsRegisterClass);
549 addRegisterClass(MVT::f32, SP::FPRegsRegisterClass);
550 addRegisterClass(MVT::f64, SP::DFPRegsRegisterClass);
551
552 // Turn FP extload into load/fextend
Evan Cheng03294662008-10-14 21:26:46 +0000553 setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand);
Chris Lattnerd23405e2008-03-17 03:21:36 +0000554 // Sparc doesn't have i1 sign extending load
Evan Cheng03294662008-10-14 21:26:46 +0000555 setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote);
Chris Lattnerd23405e2008-03-17 03:21:36 +0000556 // Turn FP truncstore into trunc + store.
557 setTruncStoreAction(MVT::f64, MVT::f32, Expand);
558
559 // Custom legalize GlobalAddress nodes into LO/HI parts.
560 setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
561 setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom);
562 setOperationAction(ISD::ConstantPool , MVT::i32, Custom);
Anton Korobeynikov53835702008-10-10 20:27:31 +0000563
Chris Lattnerd23405e2008-03-17 03:21:36 +0000564 // Sparc doesn't have sext_inreg, replace them with shl/sra
565 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand);
566 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8 , Expand);
567 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1 , Expand);
568
569 // Sparc has no REM or DIVREM operations.
570 setOperationAction(ISD::UREM, MVT::i32, Expand);
571 setOperationAction(ISD::SREM, MVT::i32, Expand);
572 setOperationAction(ISD::SDIVREM, MVT::i32, Expand);
573 setOperationAction(ISD::UDIVREM, MVT::i32, Expand);
574
575 // Custom expand fp<->sint
576 setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
577 setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
578
579 // Expand fp<->uint
580 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand);
581 setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand);
Anton Korobeynikov53835702008-10-10 20:27:31 +0000582
Chris Lattnerd23405e2008-03-17 03:21:36 +0000583 setOperationAction(ISD::BIT_CONVERT, MVT::f32, Expand);
584 setOperationAction(ISD::BIT_CONVERT, MVT::i32, Expand);
Anton Korobeynikov53835702008-10-10 20:27:31 +0000585
Chris Lattnerd23405e2008-03-17 03:21:36 +0000586 // Sparc has no select or setcc: expand to SELECT_CC.
587 setOperationAction(ISD::SELECT, MVT::i32, Expand);
588 setOperationAction(ISD::SELECT, MVT::f32, Expand);
589 setOperationAction(ISD::SELECT, MVT::f64, Expand);
590 setOperationAction(ISD::SETCC, MVT::i32, Expand);
591 setOperationAction(ISD::SETCC, MVT::f32, Expand);
592 setOperationAction(ISD::SETCC, MVT::f64, Expand);
Anton Korobeynikov53835702008-10-10 20:27:31 +0000593
Chris Lattnerd23405e2008-03-17 03:21:36 +0000594 // Sparc doesn't have BRCOND either, it has BR_CC.
595 setOperationAction(ISD::BRCOND, MVT::Other, Expand);
596 setOperationAction(ISD::BRIND, MVT::Other, Expand);
597 setOperationAction(ISD::BR_JT, MVT::Other, Expand);
598 setOperationAction(ISD::BR_CC, MVT::i32, Custom);
599 setOperationAction(ISD::BR_CC, MVT::f32, Custom);
600 setOperationAction(ISD::BR_CC, MVT::f64, Custom);
Anton Korobeynikov53835702008-10-10 20:27:31 +0000601
Chris Lattnerd23405e2008-03-17 03:21:36 +0000602 setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);
603 setOperationAction(ISD::SELECT_CC, MVT::f32, Custom);
604 setOperationAction(ISD::SELECT_CC, MVT::f64, Custom);
Anton Korobeynikov53835702008-10-10 20:27:31 +0000605
Chris Lattnerd23405e2008-03-17 03:21:36 +0000606 // SPARC has no intrinsics for these particular operations.
Chris Lattnerd23405e2008-03-17 03:21:36 +0000607 setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand);
608
609 setOperationAction(ISD::FSIN , MVT::f64, Expand);
610 setOperationAction(ISD::FCOS , MVT::f64, Expand);
611 setOperationAction(ISD::FREM , MVT::f64, Expand);
612 setOperationAction(ISD::FSIN , MVT::f32, Expand);
613 setOperationAction(ISD::FCOS , MVT::f32, Expand);
614 setOperationAction(ISD::FREM , MVT::f32, Expand);
615 setOperationAction(ISD::CTPOP, MVT::i32, Expand);
616 setOperationAction(ISD::CTTZ , MVT::i32, Expand);
617 setOperationAction(ISD::CTLZ , MVT::i32, Expand);
618 setOperationAction(ISD::ROTL , MVT::i32, Expand);
619 setOperationAction(ISD::ROTR , MVT::i32, Expand);
620 setOperationAction(ISD::BSWAP, MVT::i32, Expand);
621 setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand);
622 setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand);
623 setOperationAction(ISD::FPOW , MVT::f64, Expand);
624 setOperationAction(ISD::FPOW , MVT::f32, Expand);
625
626 setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand);
627 setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand);
628 setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand);
629
630 // FIXME: Sparc provides these multiplies, but we don't have them yet.
631 setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand);
Anton Korobeynikov4b58b6a2008-10-10 20:29:31 +0000632 setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand);
Anton Korobeynikov53835702008-10-10 20:27:31 +0000633
Chris Lattnerd23405e2008-03-17 03:21:36 +0000634 // We don't have line number support yet.
Dan Gohman7f460202008-06-30 20:59:49 +0000635 setOperationAction(ISD::DBG_STOPPOINT, MVT::Other, Expand);
Chris Lattnerd23405e2008-03-17 03:21:36 +0000636 setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
Dan Gohman44066042008-07-01 00:05:16 +0000637 setOperationAction(ISD::DBG_LABEL, MVT::Other, Expand);
638 setOperationAction(ISD::EH_LABEL, MVT::Other, Expand);
Chris Lattnerd23405e2008-03-17 03:21:36 +0000639
640 // RET must be custom lowered, to meet ABI requirements
641 setOperationAction(ISD::RET , MVT::Other, Custom);
642
643 // VASTART needs to be custom lowered to use the VarArgsFrameIndex.
644 setOperationAction(ISD::VASTART , MVT::Other, Custom);
645 // VAARG needs to be lowered to not do unaligned accesses for doubles.
646 setOperationAction(ISD::VAARG , MVT::Other, Custom);
Anton Korobeynikov53835702008-10-10 20:27:31 +0000647
Chris Lattnerd23405e2008-03-17 03:21:36 +0000648 // Use the default implementation.
649 setOperationAction(ISD::VACOPY , MVT::Other, Expand);
650 setOperationAction(ISD::VAEND , MVT::Other, Expand);
Anton Korobeynikov53835702008-10-10 20:27:31 +0000651 setOperationAction(ISD::STACKSAVE , MVT::Other, Expand);
Chris Lattnerd23405e2008-03-17 03:21:36 +0000652 setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand);
653 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Custom);
654
655 // No debug info support yet.
Dan Gohman7f460202008-06-30 20:59:49 +0000656 setOperationAction(ISD::DBG_STOPPOINT, MVT::Other, Expand);
Dan Gohman44066042008-07-01 00:05:16 +0000657 setOperationAction(ISD::DBG_LABEL, MVT::Other, Expand);
658 setOperationAction(ISD::EH_LABEL, MVT::Other, Expand);
Chris Lattnerd23405e2008-03-17 03:21:36 +0000659 setOperationAction(ISD::DECLARE, MVT::Other, Expand);
Anton Korobeynikov53835702008-10-10 20:27:31 +0000660
Chris Lattnerd23405e2008-03-17 03:21:36 +0000661 setStackPointerRegisterToSaveRestore(SP::O6);
662
663 if (TM.getSubtarget<SparcSubtarget>().isV9())
664 setOperationAction(ISD::CTPOP, MVT::i32, Legal);
Anton Korobeynikov53835702008-10-10 20:27:31 +0000665
Chris Lattnerd23405e2008-03-17 03:21:36 +0000666 computeRegisterProperties();
667}
668
669const char *SparcTargetLowering::getTargetNodeName(unsigned Opcode) const {
670 switch (Opcode) {
671 default: return 0;
672 case SPISD::CMPICC: return "SPISD::CMPICC";
673 case SPISD::CMPFCC: return "SPISD::CMPFCC";
674 case SPISD::BRICC: return "SPISD::BRICC";
675 case SPISD::BRFCC: return "SPISD::BRFCC";
676 case SPISD::SELECT_ICC: return "SPISD::SELECT_ICC";
677 case SPISD::SELECT_FCC: return "SPISD::SELECT_FCC";
678 case SPISD::Hi: return "SPISD::Hi";
679 case SPISD::Lo: return "SPISD::Lo";
680 case SPISD::FTOI: return "SPISD::FTOI";
681 case SPISD::ITOF: return "SPISD::ITOF";
682 case SPISD::CALL: return "SPISD::CALL";
683 case SPISD::RET_FLAG: return "SPISD::RET_FLAG";
684 }
685}
686
687/// isMaskedValueZeroForTargetNode - Return true if 'Op & Mask' is known to
688/// be zero. Op is expected to be a target specific node. Used by DAG
689/// combiner.
Dan Gohman475871a2008-07-27 21:46:04 +0000690void SparcTargetLowering::computeMaskedBitsForTargetNode(const SDValue Op,
Chris Lattnerd23405e2008-03-17 03:21:36 +0000691 const APInt &Mask,
Anton Korobeynikov53835702008-10-10 20:27:31 +0000692 APInt &KnownZero,
Chris Lattnerd23405e2008-03-17 03:21:36 +0000693 APInt &KnownOne,
694 const SelectionDAG &DAG,
695 unsigned Depth) const {
696 APInt KnownZero2, KnownOne2;
697 KnownZero = KnownOne = APInt(Mask.getBitWidth(), 0); // Don't know anything.
Anton Korobeynikov53835702008-10-10 20:27:31 +0000698
Chris Lattnerd23405e2008-03-17 03:21:36 +0000699 switch (Op.getOpcode()) {
700 default: break;
701 case SPISD::SELECT_ICC:
702 case SPISD::SELECT_FCC:
703 DAG.ComputeMaskedBits(Op.getOperand(1), Mask, KnownZero, KnownOne,
704 Depth+1);
705 DAG.ComputeMaskedBits(Op.getOperand(0), Mask, KnownZero2, KnownOne2,
706 Depth+1);
Anton Korobeynikov53835702008-10-10 20:27:31 +0000707 assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
708 assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
709
Chris Lattnerd23405e2008-03-17 03:21:36 +0000710 // Only known if known in both the LHS and RHS.
711 KnownOne &= KnownOne2;
712 KnownZero &= KnownZero2;
713 break;
714 }
715}
716
Chris Lattnerd23405e2008-03-17 03:21:36 +0000717// Look at LHS/RHS/CC and see if they are a lowered setcc instruction. If so
718// set LHS/RHS and SPCC to the LHS/RHS of the setcc and SPCC to the condition.
Dan Gohman475871a2008-07-27 21:46:04 +0000719static void LookThroughSetCC(SDValue &LHS, SDValue &RHS,
Chris Lattnerd23405e2008-03-17 03:21:36 +0000720 ISD::CondCode CC, unsigned &SPCC) {
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +0000721 if (isa<ConstantSDNode>(RHS) &&
722 cast<ConstantSDNode>(RHS)->getZExtValue() == 0 &&
Anton Korobeynikov53835702008-10-10 20:27:31 +0000723 CC == ISD::SETNE &&
Chris Lattnerd23405e2008-03-17 03:21:36 +0000724 ((LHS.getOpcode() == SPISD::SELECT_ICC &&
725 LHS.getOperand(3).getOpcode() == SPISD::CMPICC) ||
726 (LHS.getOpcode() == SPISD::SELECT_FCC &&
727 LHS.getOperand(3).getOpcode() == SPISD::CMPFCC)) &&
728 isa<ConstantSDNode>(LHS.getOperand(0)) &&
729 isa<ConstantSDNode>(LHS.getOperand(1)) &&
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +0000730 cast<ConstantSDNode>(LHS.getOperand(0))->getZExtValue() == 1 &&
731 cast<ConstantSDNode>(LHS.getOperand(1))->getZExtValue() == 0) {
Dan Gohman475871a2008-07-27 21:46:04 +0000732 SDValue CMPCC = LHS.getOperand(3);
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +0000733 SPCC = cast<ConstantSDNode>(LHS.getOperand(2))->getZExtValue();
Chris Lattnerd23405e2008-03-17 03:21:36 +0000734 LHS = CMPCC.getOperand(0);
735 RHS = CMPCC.getOperand(1);
736 }
737}
738
Dan Gohman475871a2008-07-27 21:46:04 +0000739static SDValue LowerGLOBALADDRESS(SDValue Op, SelectionDAG &DAG) {
Chris Lattnerd23405e2008-03-17 03:21:36 +0000740 GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
Dale Johannesende064702009-02-06 21:50:26 +0000741 // FIXME there isn't really any debug info here
742 DebugLoc dl = Op.getDebugLoc();
Dan Gohman475871a2008-07-27 21:46:04 +0000743 SDValue GA = DAG.getTargetGlobalAddress(GV, MVT::i32);
Dale Johannesende064702009-02-06 21:50:26 +0000744 SDValue Hi = DAG.getNode(SPISD::Hi, dl, MVT::i32, GA);
745 SDValue Lo = DAG.getNode(SPISD::Lo, dl, MVT::i32, GA);
746 return DAG.getNode(ISD::ADD, dl, MVT::i32, Lo, Hi);
Chris Lattnerd23405e2008-03-17 03:21:36 +0000747}
748
Dan Gohman475871a2008-07-27 21:46:04 +0000749static SDValue LowerCONSTANTPOOL(SDValue Op, SelectionDAG &DAG) {
Chris Lattnerd23405e2008-03-17 03:21:36 +0000750 ConstantPoolSDNode *N = cast<ConstantPoolSDNode>(Op);
Dale Johannesende064702009-02-06 21:50:26 +0000751 // FIXME there isn't really any debug info here
752 DebugLoc dl = Op.getDebugLoc();
Chris Lattnerd23405e2008-03-17 03:21:36 +0000753 Constant *C = N->getConstVal();
Dan Gohman475871a2008-07-27 21:46:04 +0000754 SDValue CP = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment());
Dale Johannesende064702009-02-06 21:50:26 +0000755 SDValue Hi = DAG.getNode(SPISD::Hi, dl, MVT::i32, CP);
756 SDValue Lo = DAG.getNode(SPISD::Lo, dl, MVT::i32, CP);
757 return DAG.getNode(ISD::ADD, dl, MVT::i32, Lo, Hi);
Chris Lattnerd23405e2008-03-17 03:21:36 +0000758}
759
Dan Gohman475871a2008-07-27 21:46:04 +0000760static SDValue LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) {
Dale Johannesenb300d2a2009-02-07 00:55:49 +0000761 DebugLoc dl = Op.getDebugLoc();
Chris Lattnerd23405e2008-03-17 03:21:36 +0000762 // Convert the fp value to integer in an FP register.
763 assert(Op.getValueType() == MVT::i32);
Dale Johannesenb300d2a2009-02-07 00:55:49 +0000764 Op = DAG.getNode(SPISD::FTOI, dl, MVT::f32, Op.getOperand(0));
765 return DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, Op);
Chris Lattnerd23405e2008-03-17 03:21:36 +0000766}
767
Dan Gohman475871a2008-07-27 21:46:04 +0000768static SDValue LowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG) {
Dale Johannesenb300d2a2009-02-07 00:55:49 +0000769 DebugLoc dl = Op.getDebugLoc();
Chris Lattnerd23405e2008-03-17 03:21:36 +0000770 assert(Op.getOperand(0).getValueType() == MVT::i32);
Dale Johannesenb300d2a2009-02-07 00:55:49 +0000771 SDValue Tmp = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, Op.getOperand(0));
Chris Lattnerd23405e2008-03-17 03:21:36 +0000772 // Convert the int value to FP in an FP register.
Dale Johannesenb300d2a2009-02-07 00:55:49 +0000773 return DAG.getNode(SPISD::ITOF, dl, Op.getValueType(), Tmp);
Chris Lattnerd23405e2008-03-17 03:21:36 +0000774}
775
Dan Gohman475871a2008-07-27 21:46:04 +0000776static SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) {
777 SDValue Chain = Op.getOperand(0);
Chris Lattnerd23405e2008-03-17 03:21:36 +0000778 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
Dan Gohman475871a2008-07-27 21:46:04 +0000779 SDValue LHS = Op.getOperand(2);
780 SDValue RHS = Op.getOperand(3);
781 SDValue Dest = Op.getOperand(4);
Dale Johannesen3484c092009-02-05 22:07:54 +0000782 DebugLoc dl = Op.getDebugLoc();
Chris Lattnerd23405e2008-03-17 03:21:36 +0000783 unsigned Opc, SPCC = ~0U;
Anton Korobeynikov53835702008-10-10 20:27:31 +0000784
Chris Lattnerd23405e2008-03-17 03:21:36 +0000785 // If this is a br_cc of a "setcc", and if the setcc got lowered into
786 // an CMP[IF]CC/SELECT_[IF]CC pair, find the original compared values.
787 LookThroughSetCC(LHS, RHS, CC, SPCC);
Anton Korobeynikov53835702008-10-10 20:27:31 +0000788
Chris Lattnerd23405e2008-03-17 03:21:36 +0000789 // Get the condition flag.
Dan Gohman475871a2008-07-27 21:46:04 +0000790 SDValue CompareFlag;
Chris Lattnerd23405e2008-03-17 03:21:36 +0000791 if (LHS.getValueType() == MVT::i32) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000792 std::vector<MVT> VTs;
Chris Lattnerd23405e2008-03-17 03:21:36 +0000793 VTs.push_back(MVT::i32);
794 VTs.push_back(MVT::Flag);
Dan Gohman475871a2008-07-27 21:46:04 +0000795 SDValue Ops[2] = { LHS, RHS };
Dale Johannesen3484c092009-02-05 22:07:54 +0000796 CompareFlag = DAG.getNode(SPISD::CMPICC, dl, VTs, Ops, 2).getValue(1);
Chris Lattnerd23405e2008-03-17 03:21:36 +0000797 if (SPCC == ~0U) SPCC = IntCondCCodeToICC(CC);
798 Opc = SPISD::BRICC;
799 } else {
Dale Johannesen3484c092009-02-05 22:07:54 +0000800 CompareFlag = DAG.getNode(SPISD::CMPFCC, dl, MVT::Flag, LHS, RHS);
Chris Lattnerd23405e2008-03-17 03:21:36 +0000801 if (SPCC == ~0U) SPCC = FPCondCCodeToFCC(CC);
802 Opc = SPISD::BRFCC;
803 }
Dale Johannesen3484c092009-02-05 22:07:54 +0000804 return DAG.getNode(Opc, dl, MVT::Other, Chain, Dest,
Chris Lattnerd23405e2008-03-17 03:21:36 +0000805 DAG.getConstant(SPCC, MVT::i32), CompareFlag);
806}
807
Dan Gohman475871a2008-07-27 21:46:04 +0000808static SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) {
809 SDValue LHS = Op.getOperand(0);
810 SDValue RHS = Op.getOperand(1);
Chris Lattnerd23405e2008-03-17 03:21:36 +0000811 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
Dan Gohman475871a2008-07-27 21:46:04 +0000812 SDValue TrueVal = Op.getOperand(2);
813 SDValue FalseVal = Op.getOperand(3);
Dale Johannesen3484c092009-02-05 22:07:54 +0000814 DebugLoc dl = Op.getDebugLoc();
Chris Lattnerd23405e2008-03-17 03:21:36 +0000815 unsigned Opc, SPCC = ~0U;
Anton Korobeynikov53835702008-10-10 20:27:31 +0000816
Chris Lattnerd23405e2008-03-17 03:21:36 +0000817 // If this is a select_cc of a "setcc", and if the setcc got lowered into
818 // an CMP[IF]CC/SELECT_[IF]CC pair, find the original compared values.
819 LookThroughSetCC(LHS, RHS, CC, SPCC);
Anton Korobeynikov53835702008-10-10 20:27:31 +0000820
Dan Gohman475871a2008-07-27 21:46:04 +0000821 SDValue CompareFlag;
Chris Lattnerd23405e2008-03-17 03:21:36 +0000822 if (LHS.getValueType() == MVT::i32) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000823 std::vector<MVT> VTs;
Chris Lattnerd23405e2008-03-17 03:21:36 +0000824 VTs.push_back(LHS.getValueType()); // subcc returns a value
825 VTs.push_back(MVT::Flag);
Dan Gohman475871a2008-07-27 21:46:04 +0000826 SDValue Ops[2] = { LHS, RHS };
Dale Johannesen3484c092009-02-05 22:07:54 +0000827 CompareFlag = DAG.getNode(SPISD::CMPICC, dl, VTs, Ops, 2).getValue(1);
Chris Lattnerd23405e2008-03-17 03:21:36 +0000828 Opc = SPISD::SELECT_ICC;
829 if (SPCC == ~0U) SPCC = IntCondCCodeToICC(CC);
830 } else {
Dale Johannesen3484c092009-02-05 22:07:54 +0000831 CompareFlag = DAG.getNode(SPISD::CMPFCC, dl, MVT::Flag, LHS, RHS);
Chris Lattnerd23405e2008-03-17 03:21:36 +0000832 Opc = SPISD::SELECT_FCC;
833 if (SPCC == ~0U) SPCC = FPCondCCodeToFCC(CC);
834 }
Dale Johannesen3484c092009-02-05 22:07:54 +0000835 return DAG.getNode(Opc, dl, TrueVal.getValueType(), TrueVal, FalseVal,
Chris Lattnerd23405e2008-03-17 03:21:36 +0000836 DAG.getConstant(SPCC, MVT::i32), CompareFlag);
837}
838
Dan Gohman475871a2008-07-27 21:46:04 +0000839static SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG,
Chris Lattnerd23405e2008-03-17 03:21:36 +0000840 SparcTargetLowering &TLI) {
841 // vastart just stores the address of the VarArgsFrameIndex slot into the
842 // memory location argument.
Dale Johannesen6f38cb62009-02-07 19:59:05 +0000843 DebugLoc dl = Op.getDebugLoc();
Dale Johannesen33c960f2009-02-04 20:06:27 +0000844 SDValue Offset = DAG.getNode(ISD::ADD, dl, MVT::i32,
Chris Lattnerd23405e2008-03-17 03:21:36 +0000845 DAG.getRegister(SP::I6, MVT::i32),
846 DAG.getConstant(TLI.getVarArgsFrameOffset(),
847 MVT::i32));
848 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
Dale Johannesen33c960f2009-02-04 20:06:27 +0000849 return DAG.getStore(Op.getOperand(0), dl, Offset, Op.getOperand(1), SV, 0);
Chris Lattnerd23405e2008-03-17 03:21:36 +0000850}
851
Dan Gohman475871a2008-07-27 21:46:04 +0000852static SDValue LowerVAARG(SDValue Op, SelectionDAG &DAG) {
Gabor Greifba36cb52008-08-28 21:40:38 +0000853 SDNode *Node = Op.getNode();
Duncan Sands83ec4b62008-06-06 12:08:01 +0000854 MVT VT = Node->getValueType(0);
Dan Gohman475871a2008-07-27 21:46:04 +0000855 SDValue InChain = Node->getOperand(0);
856 SDValue VAListPtr = Node->getOperand(1);
Chris Lattnerd23405e2008-03-17 03:21:36 +0000857 const Value *SV = cast<SrcValueSDNode>(Node->getOperand(2))->getValue();
Dale Johannesen33c960f2009-02-04 20:06:27 +0000858 DebugLoc dl = Node->getDebugLoc();
859 SDValue VAList = DAG.getLoad(MVT::i32, dl, InChain, VAListPtr, SV, 0);
Chris Lattnerd23405e2008-03-17 03:21:36 +0000860 // Increment the pointer, VAList, to the next vaarg
Dale Johannesen33c960f2009-02-04 20:06:27 +0000861 SDValue NextPtr = DAG.getNode(ISD::ADD, dl, MVT::i32, VAList,
Duncan Sands83ec4b62008-06-06 12:08:01 +0000862 DAG.getConstant(VT.getSizeInBits()/8,
Chris Lattnerd23405e2008-03-17 03:21:36 +0000863 MVT::i32));
864 // Store the incremented VAList to the legalized pointer
Dale Johannesen33c960f2009-02-04 20:06:27 +0000865 InChain = DAG.getStore(VAList.getValue(1), dl, NextPtr,
Chris Lattnerd23405e2008-03-17 03:21:36 +0000866 VAListPtr, SV, 0);
867 // Load the actual argument out of the pointer VAList, unless this is an
868 // f64 load.
869 if (VT != MVT::f64)
Dale Johannesen33c960f2009-02-04 20:06:27 +0000870 return DAG.getLoad(VT, dl, InChain, VAList, NULL, 0);
Anton Korobeynikov53835702008-10-10 20:27:31 +0000871
Chris Lattnerd23405e2008-03-17 03:21:36 +0000872 // Otherwise, load it as i64, then do a bitconvert.
Dale Johannesen33c960f2009-02-04 20:06:27 +0000873 SDValue V = DAG.getLoad(MVT::i64, dl, InChain, VAList, NULL, 0);
Anton Korobeynikov53835702008-10-10 20:27:31 +0000874
Chris Lattnerd23405e2008-03-17 03:21:36 +0000875 // Bit-Convert the value to f64.
Dan Gohman475871a2008-07-27 21:46:04 +0000876 SDValue Ops[2] = {
Dale Johannesen33c960f2009-02-04 20:06:27 +0000877 DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f64, V),
Chris Lattnerd23405e2008-03-17 03:21:36 +0000878 V.getValue(1)
879 };
Dale Johannesen33c960f2009-02-04 20:06:27 +0000880 return DAG.getMergeValues(Ops, 2, dl);
Chris Lattnerd23405e2008-03-17 03:21:36 +0000881}
882
Dan Gohman475871a2008-07-27 21:46:04 +0000883static SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) {
884 SDValue Chain = Op.getOperand(0); // Legalize the chain.
885 SDValue Size = Op.getOperand(1); // Legalize the size.
Dale Johannesena05dca42009-02-04 23:02:30 +0000886 DebugLoc dl = Op.getDebugLoc();
Anton Korobeynikov53835702008-10-10 20:27:31 +0000887
Chris Lattnerd23405e2008-03-17 03:21:36 +0000888 unsigned SPReg = SP::O6;
Dale Johannesena05dca42009-02-04 23:02:30 +0000889 SDValue SP = DAG.getCopyFromReg(Chain, dl, SPReg, MVT::i32);
890 SDValue NewSP = DAG.getNode(ISD::SUB, dl, MVT::i32, SP, Size); // Value
891 Chain = DAG.getCopyToReg(SP.getValue(1), dl, SPReg, NewSP); // Output chain
Anton Korobeynikov53835702008-10-10 20:27:31 +0000892
Chris Lattnerd23405e2008-03-17 03:21:36 +0000893 // The resultant pointer is actually 16 words from the bottom of the stack,
894 // to provide a register spill area.
Dale Johannesena05dca42009-02-04 23:02:30 +0000895 SDValue NewVal = DAG.getNode(ISD::ADD, dl, MVT::i32, NewSP,
Chris Lattnerd23405e2008-03-17 03:21:36 +0000896 DAG.getConstant(96, MVT::i32));
Dan Gohman475871a2008-07-27 21:46:04 +0000897 SDValue Ops[2] = { NewVal, Chain };
Dale Johannesena05dca42009-02-04 23:02:30 +0000898 return DAG.getMergeValues(Ops, 2, dl);
Chris Lattnerd23405e2008-03-17 03:21:36 +0000899}
900
Chris Lattnerd23405e2008-03-17 03:21:36 +0000901
Dan Gohman475871a2008-07-27 21:46:04 +0000902SDValue SparcTargetLowering::
903LowerOperation(SDValue Op, SelectionDAG &DAG) {
Chris Lattnerd23405e2008-03-17 03:21:36 +0000904 switch (Op.getOpcode()) {
Torok Edwinc25e7582009-07-11 20:10:48 +0000905 default: LLVM_UNREACHABLE("Should not custom lower this!");
Chris Lattnerd23405e2008-03-17 03:21:36 +0000906 // Frame & Return address. Currently unimplemented
Dan Gohman475871a2008-07-27 21:46:04 +0000907 case ISD::RETURNADDR: return SDValue();
908 case ISD::FRAMEADDR: return SDValue();
Chris Lattnerd23405e2008-03-17 03:21:36 +0000909 case ISD::GlobalTLSAddress:
Torok Edwinc25e7582009-07-11 20:10:48 +0000910 LLVM_UNREACHABLE("TLS not implemented for Sparc.");
Chris Lattnerd23405e2008-03-17 03:21:36 +0000911 case ISD::GlobalAddress: return LowerGLOBALADDRESS(Op, DAG);
912 case ISD::ConstantPool: return LowerCONSTANTPOOL(Op, DAG);
913 case ISD::FP_TO_SINT: return LowerFP_TO_SINT(Op, DAG);
914 case ISD::SINT_TO_FP: return LowerSINT_TO_FP(Op, DAG);
915 case ISD::BR_CC: return LowerBR_CC(Op, DAG);
916 case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
917 case ISD::VASTART: return LowerVASTART(Op, DAG, *this);
918 case ISD::VAARG: return LowerVAARG(Op, DAG);
919 case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG);
Chris Lattner98949a62008-03-17 06:01:07 +0000920 case ISD::CALL: return LowerCALL(Op, DAG);
Chris Lattnerd23405e2008-03-17 03:21:36 +0000921 case ISD::RET: return LowerRET(Op, DAG);
922 }
923}
924
925MachineBasicBlock *
926SparcTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
Dan Gohman1fdbc1d2009-02-07 16:15:20 +0000927 MachineBasicBlock *BB) const {
Chris Lattnerd23405e2008-03-17 03:21:36 +0000928 const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo();
929 unsigned BROpcode;
930 unsigned CC;
Dale Johannesend552eee2009-02-13 02:31:35 +0000931 DebugLoc dl = MI->getDebugLoc();
Chris Lattnerd23405e2008-03-17 03:21:36 +0000932 // Figure out the conditional branch opcode to use for this select_cc.
933 switch (MI->getOpcode()) {
Torok Edwinc25e7582009-07-11 20:10:48 +0000934 default: LLVM_UNREACHABLE("Unknown SELECT_CC!");
Chris Lattnerd23405e2008-03-17 03:21:36 +0000935 case SP::SELECT_CC_Int_ICC:
936 case SP::SELECT_CC_FP_ICC:
937 case SP::SELECT_CC_DFP_ICC:
938 BROpcode = SP::BCOND;
939 break;
940 case SP::SELECT_CC_Int_FCC:
941 case SP::SELECT_CC_FP_FCC:
942 case SP::SELECT_CC_DFP_FCC:
943 BROpcode = SP::FBCOND;
944 break;
945 }
946
947 CC = (SPCC::CondCodes)MI->getOperand(3).getImm();
Anton Korobeynikov53835702008-10-10 20:27:31 +0000948
Chris Lattnerd23405e2008-03-17 03:21:36 +0000949 // To "insert" a SELECT_CC instruction, we actually have to insert the diamond
950 // control-flow pattern. The incoming instruction knows the destination vreg
951 // to set, the condition code register to branch on, the true/false values to
952 // select between, and a branch opcode to use.
953 const BasicBlock *LLVM_BB = BB->getBasicBlock();
Dan Gohman8e5f2c62008-07-07 23:14:23 +0000954 MachineFunction::iterator It = BB;
Chris Lattnerd23405e2008-03-17 03:21:36 +0000955 ++It;
Anton Korobeynikov53835702008-10-10 20:27:31 +0000956
Chris Lattnerd23405e2008-03-17 03:21:36 +0000957 // thisMBB:
958 // ...
959 // TrueVal = ...
960 // [f]bCC copy1MBB
961 // fallthrough --> copy0MBB
962 MachineBasicBlock *thisMBB = BB;
Chris Lattnerd23405e2008-03-17 03:21:36 +0000963 MachineFunction *F = BB->getParent();
Dan Gohman8e5f2c62008-07-07 23:14:23 +0000964 MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
965 MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
Dale Johannesend552eee2009-02-13 02:31:35 +0000966 BuildMI(BB, dl, TII.get(BROpcode)).addMBB(sinkMBB).addImm(CC);
Dan Gohman8e5f2c62008-07-07 23:14:23 +0000967 F->insert(It, copy0MBB);
968 F->insert(It, sinkMBB);
Dan Gohman0011dc42008-06-21 20:21:19 +0000969 // Update machine-CFG edges by transferring all successors of the current
Chris Lattnerd23405e2008-03-17 03:21:36 +0000970 // block to the new block which will contain the Phi node for the select.
Dan Gohman0011dc42008-06-21 20:21:19 +0000971 sinkMBB->transferSuccessors(BB);
972 // Next, add the true and fallthrough blocks as its successors.
Chris Lattnerd23405e2008-03-17 03:21:36 +0000973 BB->addSuccessor(copy0MBB);
974 BB->addSuccessor(sinkMBB);
Anton Korobeynikov53835702008-10-10 20:27:31 +0000975
Chris Lattnerd23405e2008-03-17 03:21:36 +0000976 // copy0MBB:
977 // %FalseValue = ...
978 // # fallthrough to sinkMBB
979 BB = copy0MBB;
Anton Korobeynikov53835702008-10-10 20:27:31 +0000980
Chris Lattnerd23405e2008-03-17 03:21:36 +0000981 // Update machine-CFG edges
982 BB->addSuccessor(sinkMBB);
Anton Korobeynikov53835702008-10-10 20:27:31 +0000983
Chris Lattnerd23405e2008-03-17 03:21:36 +0000984 // sinkMBB:
985 // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
986 // ...
987 BB = sinkMBB;
Dale Johannesend552eee2009-02-13 02:31:35 +0000988 BuildMI(BB, dl, TII.get(SP::PHI), MI->getOperand(0).getReg())
Chris Lattnerd23405e2008-03-17 03:21:36 +0000989 .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB)
990 .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB);
Anton Korobeynikov53835702008-10-10 20:27:31 +0000991
Dan Gohman8e5f2c62008-07-07 23:14:23 +0000992 F->DeleteMachineInstr(MI); // The pseudo instruction is gone now.
Chris Lattnerd23405e2008-03-17 03:21:36 +0000993 return BB;
994}
Anton Korobeynikov0eefda12008-10-10 20:28:10 +0000995
996//===----------------------------------------------------------------------===//
997// Sparc Inline Assembly Support
998//===----------------------------------------------------------------------===//
999
1000/// getConstraintType - Given a constraint letter, return the type of
1001/// constraint it is for this target.
1002SparcTargetLowering::ConstraintType
1003SparcTargetLowering::getConstraintType(const std::string &Constraint) const {
1004 if (Constraint.size() == 1) {
1005 switch (Constraint[0]) {
1006 default: break;
1007 case 'r': return C_RegisterClass;
1008 }
1009 }
1010
1011 return TargetLowering::getConstraintType(Constraint);
1012}
1013
1014std::pair<unsigned, const TargetRegisterClass*>
1015SparcTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
1016 MVT VT) const {
1017 if (Constraint.size() == 1) {
1018 switch (Constraint[0]) {
1019 case 'r':
1020 return std::make_pair(0U, SP::IntRegsRegisterClass);
1021 }
1022 }
1023
1024 return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
1025}
1026
1027std::vector<unsigned> SparcTargetLowering::
1028getRegClassForInlineAsmConstraint(const std::string &Constraint,
1029 MVT VT) const {
1030 if (Constraint.size() != 1)
1031 return std::vector<unsigned>();
1032
1033 switch (Constraint[0]) {
1034 default: break;
1035 case 'r':
1036 return make_vector<unsigned>(SP::L0, SP::L1, SP::L2, SP::L3,
1037 SP::L4, SP::L5, SP::L6, SP::L7,
1038 SP::I0, SP::I1, SP::I2, SP::I3,
1039 SP::I4, SP::I5,
1040 SP::O0, SP::O1, SP::O2, SP::O3,
1041 SP::O4, SP::O5, SP::O7, 0);
1042 }
1043
1044 return std::vector<unsigned>();
1045}
Dan Gohman6520e202008-10-18 02:06:02 +00001046
1047bool
1048SparcTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
1049 // The Sparc target isn't yet aware of offsets.
1050 return false;
1051}
Bill Wendling20c568f2009-06-30 22:38:32 +00001052
Bill Wendlingb4202b82009-07-01 18:50:55 +00001053/// getFunctionAlignment - Return the Log2 alignment of this function.
Bill Wendling20c568f2009-06-30 22:38:32 +00001054unsigned SparcTargetLowering::getFunctionAlignment(const Function *) const {
1055 return 4;
1056}