blob: c121cf1fbda7bebbbb0a3daa959e001722ae20dc [file] [log] [blame]
Chris Lattner6c18b102005-12-17 07:47:01 +00001//===-- SparcV8ISelDAGToDAG.cpp - A dag to dag inst selector for SparcV8 --===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Chris Lattner and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines an instruction selector for the V8 target
11//
12//===----------------------------------------------------------------------===//
13
14#include "SparcV8.h"
15#include "SparcV8TargetMachine.h"
Chris Lattner384e5ef2005-12-18 13:33:06 +000016#include "llvm/DerivedTypes.h"
Chris Lattnera01b7572005-12-17 08:03:24 +000017#include "llvm/Function.h"
Chris Lattner8fa54dc2005-12-18 06:59:57 +000018#include "llvm/CodeGen/MachineFrameInfo.h"
Chris Lattnera01b7572005-12-17 08:03:24 +000019#include "llvm/CodeGen/MachineFunction.h"
Chris Lattner33084492005-12-18 08:13:54 +000020#include "llvm/CodeGen/MachineInstrBuilder.h"
Chris Lattner6c18b102005-12-17 07:47:01 +000021#include "llvm/CodeGen/SelectionDAG.h"
22#include "llvm/CodeGen/SelectionDAGISel.h"
Chris Lattnera01b7572005-12-17 08:03:24 +000023#include "llvm/CodeGen/SSARegMap.h"
Chris Lattner6c18b102005-12-17 07:47:01 +000024#include "llvm/Target/TargetLowering.h"
25#include "llvm/Support/Debug.h"
26#include <iostream>
27using namespace llvm;
28
29//===----------------------------------------------------------------------===//
30// TargetLowering Implementation
31//===----------------------------------------------------------------------===//
32
Chris Lattner4d55aca2005-12-18 01:20:35 +000033namespace V8ISD {
34 enum {
35 FIRST_NUMBER = ISD::BUILTIN_OP_END+V8::INSTRUCTION_LIST_END,
36 CMPICC, // Compare two GPR operands, set icc.
37 CMPFCC, // Compare two FP operands, set fcc.
38 BRICC, // Branch to dest on icc condition
39 BRFCC, // Branch to dest on fcc condition
Chris Lattnere3572462005-12-18 02:10:39 +000040
41 Hi, Lo, // Hi/Lo operations, typically on a global address.
Chris Lattner8fa54dc2005-12-18 06:59:57 +000042
43 FTOI, // FP to Int within a FP register.
44 ITOF, // Int to FP within a FP register.
Chris Lattner33084492005-12-18 08:13:54 +000045
46 SELECT_ICC, // Select between two values using the current ICC flags.
47 SELECT_FCC, // Select between two values using the current FCC flags.
Chris Lattner4d55aca2005-12-18 01:20:35 +000048 };
49}
50
Chris Lattner6c18b102005-12-17 07:47:01 +000051namespace {
52 class SparcV8TargetLowering : public TargetLowering {
Chris Lattner2db3ff62005-12-18 15:55:15 +000053 int VarArgsFrameOffset; // Frame offset to start of varargs area.
Chris Lattner6c18b102005-12-17 07:47:01 +000054 public:
55 SparcV8TargetLowering(TargetMachine &TM);
Chris Lattner4d55aca2005-12-18 01:20:35 +000056 virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
Chris Lattner6c18b102005-12-17 07:47:01 +000057 virtual std::vector<SDOperand>
58 LowerArguments(Function &F, SelectionDAG &DAG);
59 virtual std::pair<SDOperand, SDOperand>
60 LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg,
61 unsigned CC,
62 bool isTailCall, SDOperand Callee, ArgListTy &Args,
63 SelectionDAG &DAG);
64
65 virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op,
66 SelectionDAG &DAG);
67 virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP,
68 Value *VAListV, SelectionDAG &DAG);
69 virtual std::pair<SDOperand,SDOperand>
70 LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
71 const Type *ArgTy, SelectionDAG &DAG);
72 virtual std::pair<SDOperand, SDOperand>
73 LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
74 SelectionDAG &DAG);
Chris Lattner33084492005-12-18 08:13:54 +000075 virtual MachineBasicBlock *InsertAtEndOfBasicBlock(MachineInstr *MI,
76 MachineBasicBlock *MBB);
Chris Lattner6c18b102005-12-17 07:47:01 +000077 };
78}
79
80SparcV8TargetLowering::SparcV8TargetLowering(TargetMachine &TM)
81 : TargetLowering(TM) {
82
83 // Set up the register classes.
84 addRegisterClass(MVT::i32, V8::IntRegsRegisterClass);
85 addRegisterClass(MVT::f32, V8::FPRegsRegisterClass);
86 addRegisterClass(MVT::f64, V8::DFPRegsRegisterClass);
Chris Lattner9a60ff62005-12-17 20:50:42 +000087
Chris Lattnere3572462005-12-18 02:10:39 +000088 // Custom legalize GlobalAddress nodes into LO/HI parts.
89 setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
Chris Lattner76acc872005-12-18 02:37:35 +000090 setOperationAction(ISD::ConstantPool , MVT::i32, Custom);
Chris Lattnere3572462005-12-18 02:10:39 +000091
Chris Lattner9a60ff62005-12-17 20:50:42 +000092 // Sparc doesn't have sext_inreg, replace them with shl/sra
Chris Lattner33084492005-12-18 08:13:54 +000093 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand);
94 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8 , Expand);
95 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1 , Expand);
Chris Lattner7087e572005-12-17 22:39:19 +000096
97 // Sparc has no REM operation.
98 setOperationAction(ISD::UREM, MVT::i32, Expand);
99 setOperationAction(ISD::SREM, MVT::i32, Expand);
Chris Lattner8fa54dc2005-12-18 06:59:57 +0000100
101 // Custom expand fp<->sint
102 setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
103 setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
104
105 // Expand fp<->uint
106 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand);
107 setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand);
Chris Lattner6c18b102005-12-17 07:47:01 +0000108
Chris Lattner065c8962005-12-18 07:13:32 +0000109 setOperationAction(ISD::EXTLOAD, MVT::f32, Expand);
110
Chris Lattner4d55aca2005-12-18 01:20:35 +0000111 // Sparc has no select or setcc: expand to SELECT_CC.
112 setOperationAction(ISD::SELECT, MVT::i32, Expand);
113 setOperationAction(ISD::SELECT, MVT::f32, Expand);
114 setOperationAction(ISD::SELECT, MVT::f64, Expand);
115 setOperationAction(ISD::SETCC, MVT::i32, Expand);
116 setOperationAction(ISD::SETCC, MVT::f32, Expand);
117 setOperationAction(ISD::SETCC, MVT::f64, Expand);
118
119 // Sparc doesn't have BRCOND either, it has BR_CC.
120 setOperationAction(ISD::BRCOND, MVT::Other, Expand);
121 setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand);
122 setOperationAction(ISD::BRTWOWAY_CC, MVT::Other, Expand);
123 setOperationAction(ISD::BR_CC, MVT::i32, Custom);
124 setOperationAction(ISD::BR_CC, MVT::f32, Custom);
125 setOperationAction(ISD::BR_CC, MVT::f64, Custom);
126
Chris Lattner33084492005-12-18 08:13:54 +0000127 setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);
128 setOperationAction(ISD::SELECT_CC, MVT::f32, Custom);
129 setOperationAction(ISD::SELECT_CC, MVT::f64, Custom);
130
Chris Lattner6c18b102005-12-17 07:47:01 +0000131 computeRegisterProperties();
132}
133
Chris Lattner384e5ef2005-12-18 13:33:06 +0000134/// LowerArguments - V8 uses a very simple ABI, where all values are passed in
135/// either one or two GPRs, including FP values. TODO: we should pass FP values
136/// in FP registers for fastcc functions.
Chris Lattner6c18b102005-12-17 07:47:01 +0000137std::vector<SDOperand>
138SparcV8TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
Chris Lattnera01b7572005-12-17 08:03:24 +0000139 MachineFunction &MF = DAG.getMachineFunction();
140 SSARegMap *RegMap = MF.getSSARegMap();
141 std::vector<SDOperand> ArgValues;
142
Chris Lattner384e5ef2005-12-18 13:33:06 +0000143 static const unsigned ArgRegs[] = {
Chris Lattnera01b7572005-12-17 08:03:24 +0000144 V8::I0, V8::I1, V8::I2, V8::I3, V8::I4, V8::I5
145 };
Chris Lattner384e5ef2005-12-18 13:33:06 +0000146
147 const unsigned *CurArgReg = ArgRegs, *ArgRegEnd = ArgRegs+6;
148 unsigned ArgOffset = 68;
149
150 SDOperand Root = DAG.getRoot();
151 std::vector<SDOperand> OutChains;
152
Chris Lattnera01b7572005-12-17 08:03:24 +0000153 for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) {
154 MVT::ValueType ObjectVT = getValueType(I->getType());
Chris Lattnera01b7572005-12-17 08:03:24 +0000155
156 switch (ObjectVT) {
157 default: assert(0 && "Unhandled argument type!");
Chris Lattnera01b7572005-12-17 08:03:24 +0000158 case MVT::i1:
159 case MVT::i8:
160 case MVT::i16:
Chris Lattner384e5ef2005-12-18 13:33:06 +0000161 case MVT::i32:
162 if (I->use_empty()) { // Argument is dead.
163 if (CurArgReg < ArgRegEnd) ++CurArgReg;
164 ArgValues.push_back(DAG.getNode(ISD::UNDEF, ObjectVT));
165 } else if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR
166 unsigned VReg = RegMap->createVirtualRegister(&V8::IntRegsRegClass);
167 MF.addLiveIn(*CurArgReg++, VReg);
168 SDOperand Arg = DAG.getCopyFromReg(Root, VReg, MVT::i32);
169 if (ObjectVT != MVT::i32) {
170 unsigned AssertOp = I->getType()->isSigned() ? ISD::AssertSext
171 : ISD::AssertZext;
172 Arg = DAG.getNode(AssertOp, MVT::i32, Arg,
173 DAG.getValueType(ObjectVT));
174 Arg = DAG.getNode(ISD::TRUNCATE, ObjectVT, Arg);
175 }
176 ArgValues.push_back(Arg);
177 } else {
178 int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset);
179 SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
180 SDOperand Load;
181 if (ObjectVT == MVT::i32) {
182 Load = DAG.getLoad(MVT::i32, Root, FIPtr, DAG.getSrcValue(0));
183 } else {
184 unsigned LoadOp =
185 I->getType()->isSigned() ? ISD::SEXTLOAD : ISD::ZEXTLOAD;
186
187 Load = DAG.getExtLoad(LoadOp, MVT::i32, Root, FIPtr,
188 DAG.getSrcValue(0), ObjectVT);
189 }
190 ArgValues.push_back(Load);
Chris Lattnera01b7572005-12-17 08:03:24 +0000191 }
Chris Lattner384e5ef2005-12-18 13:33:06 +0000192
193 ArgOffset += 4;
Chris Lattner217aabf2005-12-17 20:59:06 +0000194 break;
Chris Lattner384e5ef2005-12-18 13:33:06 +0000195 case MVT::f32:
196 if (I->use_empty()) { // Argument is dead.
197 if (CurArgReg < ArgRegEnd) ++CurArgReg;
198 ArgValues.push_back(DAG.getNode(ISD::UNDEF, ObjectVT));
199 } else if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR
200 // FP value is passed in an integer register.
201 unsigned VReg = RegMap->createVirtualRegister(&V8::IntRegsRegClass);
202 MF.addLiveIn(*CurArgReg++, VReg);
203 SDOperand Arg = DAG.getCopyFromReg(Root, VReg, MVT::i32);
204
205 // We use the stack space that is already reserved for this reg.
206 int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset);
207 SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
208
209 SDOperand SV = DAG.getSrcValue(0);
210 SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Root,
211 Arg, FIPtr, SV);
212 ArgValues.push_back(DAG.getLoad(MVT::f32, Store, FIPtr, SV));
213 }
214 ArgOffset += 4;
Chris Lattner217aabf2005-12-17 20:59:06 +0000215 break;
Chris Lattner384e5ef2005-12-18 13:33:06 +0000216
217 case MVT::i64:
218 case MVT::f64:
219 if (I->use_empty()) { // Argument is dead.
220 if (CurArgReg < ArgRegEnd) ++CurArgReg;
221 if (CurArgReg < ArgRegEnd) ++CurArgReg;
222 ArgValues.push_back(DAG.getNode(ISD::UNDEF, ObjectVT));
223 } else if (CurArgReg == ArgRegEnd && ObjectVT == MVT::f64 &&
224 ((CurArgReg-ArgRegs) & 1) == 0) {
225 // If this is a double argument and the whole thing lives on the stack,
226 // and the argument is aligned, load the double straight from the stack.
227 // We can't do a load in cases like void foo([6ints], int,double),
228 // because the double wouldn't be aligned!
229 int FrameIdx = MF.getFrameInfo()->CreateFixedObject(8, ArgOffset);
230 SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
231 ArgValues.push_back(DAG.getLoad(MVT::f64, Root, FIPtr,
232 DAG.getSrcValue(0)));
233 } else {
234 SDOperand HiVal;
235 if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR
236 unsigned VRegHi = RegMap->createVirtualRegister(&V8::IntRegsRegClass);
237 MF.addLiveIn(*CurArgReg++, VRegHi);
238 HiVal = DAG.getCopyFromReg(Root, VRegHi, MVT::i32);
239 } else {
240 int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset);
241 SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
242 HiVal = DAG.getLoad(MVT::i32, Root, FIPtr, DAG.getSrcValue(0));
243 }
244
245 SDOperand LoVal;
246 if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR
247 unsigned VRegLo = RegMap->createVirtualRegister(&V8::IntRegsRegClass);
248 MF.addLiveIn(*CurArgReg++, VRegLo);
249 LoVal = DAG.getCopyFromReg(Root, VRegLo, MVT::i32);
250 } else {
251 int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset+4);
252 SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
253 LoVal = DAG.getLoad(MVT::i32, Root, FIPtr, DAG.getSrcValue(0));
254 }
255
256 // Compose the two halves together into an i64 unit.
257 SDOperand WholeValue =
258 DAG.getNode(ISD::BUILD_PAIR, MVT::i64, LoVal, HiVal);
259
260 if (ObjectVT == MVT::i64) {
261 // If we are emitting an i64, this is what we want.
262 ArgValues.push_back(WholeValue);
263 } else {
264 assert(ObjectVT == MVT::f64);
265 // Otherwise, emit a store to the stack and reload into FPR.
266 int FrameIdx = MF.getFrameInfo()->CreateStackObject(8, 8);
267 SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
268 SDOperand SV = DAG.getSrcValue(0);
269 SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Root,
270 WholeValue, FIPtr, SV);
271 ArgValues.push_back(DAG.getLoad(MVT::f64, Store, FIPtr, SV));
272 }
273 }
274 ArgOffset += 8;
275 break;
Chris Lattnera01b7572005-12-17 08:03:24 +0000276 }
277 }
278
Chris Lattner384e5ef2005-12-18 13:33:06 +0000279 // Store remaining ArgRegs to the stack if this is a varargs function.
280 if (F.getFunctionType()->isVarArg()) {
Chris Lattner2db3ff62005-12-18 15:55:15 +0000281 // Remember the vararg offset for the va_start implementation.
282 VarArgsFrameOffset = ArgOffset;
283
Chris Lattner384e5ef2005-12-18 13:33:06 +0000284 for (; CurArgReg != ArgRegEnd; ++CurArgReg) {
285 unsigned VReg = RegMap->createVirtualRegister(&V8::IntRegsRegClass);
286 MF.addLiveIn(*CurArgReg, VReg);
287 SDOperand Arg = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32);
288
289 int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset);
290 SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
291
292 OutChains.push_back(DAG.getNode(ISD::STORE, MVT::Other, DAG.getRoot(),
293 Arg, FIPtr, DAG.getSrcValue(0)));
294 ArgOffset += 4;
295 }
296 }
297
298 if (!OutChains.empty())
299 DAG.setRoot(DAG.getNode(ISD::TokenFactor, MVT::Other, OutChains));
Chris Lattnera01b7572005-12-17 08:03:24 +0000300
301 // Finally, inform the code generator which regs we return values in.
302 switch (getValueType(F.getReturnType())) {
303 default: assert(0 && "Unknown type!");
304 case MVT::isVoid: break;
305 case MVT::i1:
306 case MVT::i8:
307 case MVT::i16:
308 case MVT::i32:
309 MF.addLiveOut(V8::I0);
310 break;
311 case MVT::i64:
312 MF.addLiveOut(V8::I0);
313 MF.addLiveOut(V8::I1);
314 break;
315 case MVT::f32:
316 MF.addLiveOut(V8::F0);
317 break;
318 case MVT::f64:
319 MF.addLiveOut(V8::D0);
320 break;
321 }
322
323 return ArgValues;
Chris Lattner6c18b102005-12-17 07:47:01 +0000324}
325
326std::pair<SDOperand, SDOperand>
327SparcV8TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
328 bool isVarArg, unsigned CC,
329 bool isTailCall, SDOperand Callee,
330 ArgListTy &Args, SelectionDAG &DAG) {
Chris Lattner2db3ff62005-12-18 15:55:15 +0000331 MachineFunction &MF = DAG.getMachineFunction();
332 // Count the size of the outgoing arguments.
333 unsigned ArgsSize = 0;
334 for (unsigned i = 0, e = Args.size(); i != e; ++i) {
335 switch (getValueType(Args[i].second)) {
336 default: assert(0 && "Unknown value type!");
337 case MVT::i1:
338 case MVT::i8:
339 case MVT::i16:
340 case MVT::i32:
341 case MVT::f32:
342 ArgsSize += 4;
343 break;
344 case MVT::i64:
345 case MVT::f64:
346 ArgsSize += 8;
347 break;
348 }
349 }
350 if (ArgsSize > 4*6)
351 ArgsSize -= 4*6; // Space for first 6 arguments is prereserved.
352 else
353 ArgsSize = 0;
354
355 Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain,
356 DAG.getConstant(ArgsSize, getPointerTy()));
357
358 SDOperand StackPtr, NullSV;
359 std::vector<SDOperand> Stores;
360 std::vector<SDOperand> RegValuesToPass;
361 unsigned ArgOffset = 68;
362 for (unsigned i = 0, e = Args.size(); i != e; ++i) {
363 SDOperand Val = Args[i].first;
364 MVT::ValueType ObjectVT = Val.getValueType();
365 SDOperand ValToStore;
366 unsigned ObjSize;
367 switch (ObjectVT) {
368 default: assert(0 && "Unhandled argument type!");
369 case MVT::i1:
370 case MVT::i8:
371 case MVT::i16:
372 // Promote the integer to 32-bits. If the input type is signed, use a
373 // sign extend, otherwise use a zero extend.
374 if (Args[i].second->isSigned())
375 Val = DAG.getNode(ISD::SIGN_EXTEND, MVT::i32, Val);
376 else
377 Val = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Val);
378 // FALL THROUGH
379 case MVT::i32:
380 ObjSize = 4;
381
382 if (RegValuesToPass.size() >= 6) {
383 ValToStore = Val;
384 } else {
385 RegValuesToPass.push_back(Val);
386 }
387 break;
388 case MVT::f32:
389 ObjSize = 4;
390 if (RegValuesToPass.size() >= 6) {
391 ValToStore = Val;
392 } else {
393 // Convert this to a FP value in an int reg.
394 int FrameIdx = MF.getFrameInfo()->CreateStackObject(4, 4);
395 SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
396 SDOperand SV = DAG.getSrcValue(0);
397 SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Chain,
398 Val, FIPtr, SV);
399 Val = DAG.getLoad(MVT::i32, Store, FIPtr, SV);
400 RegValuesToPass.push_back(Val);
401 }
402 break;
403 case MVT::f64: {
404 ObjSize = 8;
405 // If we can store this directly into the outgoing slot, do so. We can
406 // do this when all ArgRegs are used and if the outgoing slot is aligned.
407 if (RegValuesToPass.size() >= 6 && ((ArgOffset-68) & 7) == 0) {
408 ValToStore = Val;
409 break;
410 }
411
412 // Otherwise, convert this to a FP value in int regs.
413 int FrameIdx = MF.getFrameInfo()->CreateStackObject(8, 8);
414 SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
415 SDOperand SV = DAG.getSrcValue(0);
416 SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Chain,
417 Val, FIPtr, SV);
418 Val = DAG.getLoad(MVT::i64, Store, FIPtr, SV);
419 }
420 // FALL THROUGH
421 case MVT::i64:
422 ObjSize = 8;
423 if (RegValuesToPass.size() >= 6) {
424 ValToStore = Val; // Whole thing is passed in memory.
425 break;
426 }
427
428 // Split the value into top and bottom part. Top part goes in a reg.
429 SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Val,
430 DAG.getConstant(1, MVT::i32));
431 SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Val,
432 DAG.getConstant(0, MVT::i32));
433 RegValuesToPass.push_back(Hi);
434
435 if (RegValuesToPass.size() >= 6) {
436 ValToStore = Lo;
437 } else {
438 RegValuesToPass.push_back(Lo);
439 }
440 break;
441 }
442
443 if (ValToStore.Val) {
444 if (!StackPtr.Val) {
445 StackPtr = DAG.getCopyFromReg(DAG.getEntryNode(), V8::SP, MVT::i32);
446 NullSV = DAG.getSrcValue(NULL);
447 }
448 SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
449 PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff);
450 Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
451 ValToStore, PtrOff, NullSV));
452 }
453 ArgOffset += ObjSize;
454 }
455
456 // Emit all stores, make sure the occur before any copies into physregs.
457 if (!Stores.empty())
458 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, Stores);
459
460 static const unsigned ArgRegs[] = {
461 V8::O0, V8::O1, V8::O2, V8::O3, V8::O4, V8::O5
462 };
463
464 // Build a sequence of copy-to-reg nodes chained together with token chain
465 // and flag operands which copy the outgoing args into O[0-5].
466 SDOperand InFlag;
467 for (unsigned i = 0, e = RegValuesToPass.size(); i != e; ++i) {
468 Chain = DAG.getCopyToReg(Chain, ArgRegs[i], RegValuesToPass[i], InFlag);
469 InFlag = Chain.getValue(1);
470 }
471
472 std::vector<MVT::ValueType> RetVals;
473 RetVals.push_back(MVT::Other);
474 RetVals.push_back(MVT::Flag);
475
476 // If the callee is a GlobalAddress node (quite common, every direct call is)
477 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
478 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
479 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), MVT::i32);
480
481 std::vector<MVT::ValueType> NodeTys;
482 NodeTys.push_back(MVT::Other); // Returns a chain
483 NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use.
484 Chain = SDOperand(DAG.getCall(NodeTys, Chain, Callee, InFlag), 0);
485 InFlag = Chain.getValue(1);
486
487 MVT::ValueType RetTyVT = getValueType(RetTy);
488 SDOperand RetVal;
489 if (RetTyVT != MVT::isVoid) {
490 switch (RetTyVT) {
491 default: assert(0 && "Unknown value type to return!");
492 case MVT::i1:
493 case MVT::i8:
494 case MVT::i16:
495 RetVal = DAG.getCopyFromReg(Chain, V8::O0, MVT::i32, InFlag);
496 Chain = RetVal.getValue(1);
497
498 // Add a note to keep track of whether it is sign or zero extended.
499 RetVal = DAG.getNode(RetTy->isSigned() ? ISD::AssertSext :ISD::AssertZext,
500 MVT::i32, RetVal, DAG.getValueType(RetTyVT));
501 RetVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, RetVal);
502 break;
503 case MVT::i32:
504 RetVal = DAG.getCopyFromReg(Chain, V8::O0, MVT::i32, InFlag);
505 Chain = RetVal.getValue(1);
506 break;
507 case MVT::f32:
508 RetVal = DAG.getCopyFromReg(Chain, V8::F0, MVT::f32, InFlag);
509 Chain = RetVal.getValue(1);
510 break;
511 case MVT::f64:
512 RetVal = DAG.getCopyFromReg(Chain, V8::D0, MVT::f64, InFlag);
513 Chain = RetVal.getValue(1);
514 break;
515 case MVT::i64:
516 SDOperand Lo = DAG.getCopyFromReg(Chain, V8::O0, MVT::i32, InFlag);
517 SDOperand Hi = DAG.getCopyFromReg(Lo.getValue(1), V8::O0, MVT::i32,
518 Lo.getValue(2));
519 RetVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Lo, Hi);
520 Chain = Hi.getValue(1);
521 break;
522 }
523 }
524
525 Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, Chain,
526 DAG.getConstant(ArgsSize, getPointerTy()));
527
528 MVT::ValueType ActualRetTyVT = RetTyVT;
529 if (RetTyVT >= MVT::i1 && RetTyVT <= MVT::i16)
530 ActualRetTyVT = MVT::i32; // Promote result to i32.
531
532 return std::make_pair(RetVal, Chain);
Chris Lattner6c18b102005-12-17 07:47:01 +0000533}
534
535SDOperand SparcV8TargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op,
536 SelectionDAG &DAG) {
Chris Lattner4b486312005-12-17 08:15:09 +0000537 if (Op.getValueType() == MVT::i64) {
538 SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op,
539 DAG.getConstant(1, MVT::i32));
540 SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op,
541 DAG.getConstant(0, MVT::i32));
542 return DAG.getNode(ISD::RET, MVT::Other, Chain, Lo, Hi);
543 } else {
544 return DAG.getNode(ISD::RET, MVT::Other, Chain, Op);
545 }
Chris Lattner6c18b102005-12-17 07:47:01 +0000546}
547
Chris Lattner4d55aca2005-12-18 01:20:35 +0000548SDOperand SparcV8TargetLowering::
549LowerVAStart(SDOperand Chain, SDOperand VAListP, Value *VAListV,
550 SelectionDAG &DAG) {
551
Chris Lattner6c18b102005-12-17 07:47:01 +0000552 assert(0 && "Unimp");
553 abort();
554}
555
Chris Lattner4d55aca2005-12-18 01:20:35 +0000556std::pair<SDOperand,SDOperand> SparcV8TargetLowering::
557LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
558 const Type *ArgTy, SelectionDAG &DAG) {
Chris Lattner6c18b102005-12-17 07:47:01 +0000559 assert(0 && "Unimp");
560 abort();
561}
562
Chris Lattner4d55aca2005-12-18 01:20:35 +0000563std::pair<SDOperand, SDOperand> SparcV8TargetLowering::
564LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
565 SelectionDAG &DAG) {
Chris Lattner6c18b102005-12-17 07:47:01 +0000566 assert(0 && "Unimp");
567 abort();
568}
569
Chris Lattner4d55aca2005-12-18 01:20:35 +0000570SDOperand SparcV8TargetLowering::
571LowerOperation(SDOperand Op, SelectionDAG &DAG) {
572 switch (Op.getOpcode()) {
573 default: assert(0 && "Should not custom lower this!");
Chris Lattnere3572462005-12-18 02:10:39 +0000574 case ISD::GlobalAddress: {
575 GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
576 SDOperand GA = DAG.getTargetGlobalAddress(GV, MVT::i32);
577 SDOperand Hi = DAG.getNode(V8ISD::Hi, MVT::i32, GA);
578 SDOperand Lo = DAG.getNode(V8ISD::Lo, MVT::i32, GA);
579 return DAG.getNode(ISD::ADD, MVT::i32, Lo, Hi);
580 }
Chris Lattner76acc872005-12-18 02:37:35 +0000581 case ISD::ConstantPool: {
582 Constant *C = cast<ConstantPoolSDNode>(Op)->get();
583 SDOperand CP = DAG.getTargetConstantPool(C, MVT::i32);
584 SDOperand Hi = DAG.getNode(V8ISD::Hi, MVT::i32, CP);
585 SDOperand Lo = DAG.getNode(V8ISD::Lo, MVT::i32, CP);
586 return DAG.getNode(ISD::ADD, MVT::i32, Lo, Hi);
587 }
Chris Lattner8fa54dc2005-12-18 06:59:57 +0000588 case ISD::FP_TO_SINT: {
589 // Convert the fp value to integer in an FP register.
590 Op = DAG.getNode(V8ISD::FTOI, Op.getOperand(0).getValueType(),
591 Op.getOperand(0));
592 int Size = Op.getOperand(0).getValueType() == MVT::f32 ? 4 : 8;
593 int FrameIdx =
594 DAG.getMachineFunction().getFrameInfo()->CreateStackObject(Size, Size);
595 SDOperand FI = DAG.getFrameIndex(FrameIdx, MVT::i32);
596 SDOperand ST = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(),
597 Op, FI, DAG.getSrcValue(0));
598 return DAG.getLoad(MVT::i32, ST, FI, DAG.getSrcValue(0));
599 }
600 case ISD::SINT_TO_FP: {
601 int Size = Op.getOperand(0).getValueType() == MVT::f32 ? 4 : 8;
602 int FrameIdx =
603 DAG.getMachineFunction().getFrameInfo()->CreateStackObject(Size, Size);
604 SDOperand FI = DAG.getFrameIndex(FrameIdx, MVT::i32);
605 SDOperand ST = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(),
606 Op.getOperand(0), FI, DAG.getSrcValue(0));
607
608 Op = DAG.getLoad(Op.getValueType(), ST, FI, DAG.getSrcValue(0));
609
610 // Convert the int value to FP in an FP register.
611 return DAG.getNode(V8ISD::ITOF, Op.getValueType(), Op);
612 }
Chris Lattner33084492005-12-18 08:13:54 +0000613 case ISD::BR_CC: {
614 SDOperand Chain = Op.getOperand(0);
615 SDOperand CC = Op.getOperand(1);
616 SDOperand LHS = Op.getOperand(2);
617 SDOperand RHS = Op.getOperand(3);
618 SDOperand Dest = Op.getOperand(4);
619
620 // Get the condition flag.
621 if (LHS.getValueType() == MVT::i32) {
622 SDOperand Cond = DAG.getNode(V8ISD::CMPICC, MVT::Flag, LHS, RHS);
623 return DAG.getNode(V8ISD::BRICC, MVT::Other, Chain, Dest, CC, Cond);
624 } else {
625 SDOperand Cond = DAG.getNode(V8ISD::CMPFCC, MVT::Flag, LHS, RHS);
626 return DAG.getNode(V8ISD::BRFCC, MVT::Other, Chain, Dest, CC, Cond);
627 }
628 }
629 case ISD::SELECT_CC: {
630 SDOperand LHS = Op.getOperand(0);
631 SDOperand RHS = Op.getOperand(1);
632 unsigned CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
633 SDOperand TrueVal = Op.getOperand(2);
634 SDOperand FalseVal = Op.getOperand(3);
635
636 unsigned Opc;
637 Opc = LHS.getValueType() == MVT::i32 ? V8ISD::CMPICC : V8ISD::CMPFCC;
638 SDOperand CompareFlag = DAG.getNode(Opc, MVT::Flag, LHS, RHS);
639
640 Opc = LHS.getValueType() == MVT::i32 ?
641 V8ISD::SELECT_ICC : V8ISD::SELECT_FCC;
642 return DAG.getNode(Opc, TrueVal.getValueType(), TrueVal, FalseVal,
643 DAG.getConstant(CC, MVT::i32), CompareFlag);
644 }
Chris Lattner4d55aca2005-12-18 01:20:35 +0000645 }
646}
647
Chris Lattner33084492005-12-18 08:13:54 +0000648MachineBasicBlock *
649SparcV8TargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI,
650 MachineBasicBlock *BB) {
651 unsigned BROpcode;
652 // Figure out the conditional branch opcode to use for this select_cc.
653 switch (MI->getOpcode()) {
654 default: assert(0 && "Unknown SELECT_CC!");
655 case V8::SELECT_CC_Int_ICC:
656 case V8::SELECT_CC_FP_ICC:
657 case V8::SELECT_CC_DFP_ICC:
658 // Integer compare.
659 switch ((ISD::CondCode)MI->getOperand(3).getImmedValue()) {
660 default: assert(0 && "Unknown integer condition code!");
661 case ISD::SETEQ: BROpcode = V8::BE; break;
662 case ISD::SETNE: BROpcode = V8::BNE; break;
663 case ISD::SETLT: BROpcode = V8::BL; break;
664 case ISD::SETGT: BROpcode = V8::BG; break;
665 case ISD::SETLE: BROpcode = V8::BLE; break;
666 case ISD::SETGE: BROpcode = V8::BGE; break;
667 case ISD::SETULT: BROpcode = V8::BCS; break;
668 case ISD::SETULE: BROpcode = V8::BLEU; break;
669 case ISD::SETUGT: BROpcode = V8::BGU; break;
670 case ISD::SETUGE: BROpcode = V8::BCC; break;
671 }
672 break;
673 case V8::SELECT_CC_Int_FCC:
674 case V8::SELECT_CC_FP_FCC:
675 case V8::SELECT_CC_DFP_FCC:
676 // FP compare.
677 switch ((ISD::CondCode)MI->getOperand(3).getImmedValue()) {
678 default: assert(0 && "Unknown fp condition code!");
679 case ISD::SETEQ: BROpcode = V8::FBE; break;
680 case ISD::SETNE: BROpcode = V8::FBNE; break;
681 case ISD::SETLT: BROpcode = V8::FBL; break;
682 case ISD::SETGT: BROpcode = V8::FBG; break;
683 case ISD::SETLE: BROpcode = V8::FBLE; break;
684 case ISD::SETGE: BROpcode = V8::FBGE; break;
685 case ISD::SETULT: BROpcode = V8::FBUL; break;
686 case ISD::SETULE: BROpcode = V8::FBULE; break;
687 case ISD::SETUGT: BROpcode = V8::FBUG; break;
688 case ISD::SETUGE: BROpcode = V8::FBUGE; break;
689 case ISD::SETUO: BROpcode = V8::FBU; break;
690 case ISD::SETO: BROpcode = V8::FBO; break;
691 case ISD::SETONE: BROpcode = V8::FBLG; break;
692 case ISD::SETUEQ: BROpcode = V8::FBUE; break;
693 }
694 break;
695 }
696
697 // To "insert" a SELECT_CC instruction, we actually have to insert the diamond
698 // control-flow pattern. The incoming instruction knows the destination vreg
699 // to set, the condition code register to branch on, the true/false values to
700 // select between, and a branch opcode to use.
701 const BasicBlock *LLVM_BB = BB->getBasicBlock();
702 ilist<MachineBasicBlock>::iterator It = BB;
703 ++It;
704
705 // thisMBB:
706 // ...
707 // TrueVal = ...
708 // [f]bCC copy1MBB
709 // fallthrough --> copy0MBB
710 MachineBasicBlock *thisMBB = BB;
711 MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB);
712 MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB);
713 BuildMI(BB, BROpcode, 1).addMBB(sinkMBB);
714 MachineFunction *F = BB->getParent();
715 F->getBasicBlockList().insert(It, copy0MBB);
716 F->getBasicBlockList().insert(It, sinkMBB);
717 // Update machine-CFG edges
718 BB->addSuccessor(copy0MBB);
719 BB->addSuccessor(sinkMBB);
720
721 // copy0MBB:
722 // %FalseValue = ...
723 // # fallthrough to sinkMBB
724 BB = copy0MBB;
725
726 // Update machine-CFG edges
727 BB->addSuccessor(sinkMBB);
728
729 // sinkMBB:
730 // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
731 // ...
732 BB = sinkMBB;
733 BuildMI(BB, V8::PHI, 4, MI->getOperand(0).getReg())
734 .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB)
735 .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB);
736
737 delete MI; // The pseudo instruction is gone now.
738 return BB;
739}
740
Chris Lattner6c18b102005-12-17 07:47:01 +0000741//===----------------------------------------------------------------------===//
742// Instruction Selector Implementation
743//===----------------------------------------------------------------------===//
744
745//===--------------------------------------------------------------------===//
746/// SparcV8DAGToDAGISel - PPC specific code to select Sparc V8 machine
747/// instructions for SelectionDAG operations.
748///
749namespace {
750class SparcV8DAGToDAGISel : public SelectionDAGISel {
751 SparcV8TargetLowering V8Lowering;
752public:
753 SparcV8DAGToDAGISel(TargetMachine &TM)
754 : SelectionDAGISel(V8Lowering), V8Lowering(TM) {}
755
756 SDOperand Select(SDOperand Op);
757
Chris Lattnerbc83fd92005-12-17 20:04:49 +0000758 // Complex Pattern Selectors.
759 bool SelectADDRrr(SDOperand N, SDOperand &R1, SDOperand &R2);
760 bool SelectADDRri(SDOperand N, SDOperand &Base, SDOperand &Offset);
761
Chris Lattner6c18b102005-12-17 07:47:01 +0000762 /// InstructionSelectBasicBlock - This callback is invoked by
763 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
764 virtual void InstructionSelectBasicBlock(SelectionDAG &DAG);
765
766 virtual const char *getPassName() const {
767 return "PowerPC DAG->DAG Pattern Instruction Selection";
768 }
769
770 // Include the pieces autogenerated from the target description.
771#include "SparcV8GenDAGISel.inc"
772};
773} // end anonymous namespace
774
775/// InstructionSelectBasicBlock - This callback is invoked by
776/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
777void SparcV8DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
778 DEBUG(BB->dump());
779
780 // Select target instructions for the DAG.
781 DAG.setRoot(Select(DAG.getRoot()));
782 CodeGenMap.clear();
783 DAG.RemoveDeadNodes();
784
785 // Emit machine code to BB.
786 ScheduleAndEmitDAG(DAG);
787}
788
Chris Lattner8fa54dc2005-12-18 06:59:57 +0000789bool SparcV8DAGToDAGISel::SelectADDRri(SDOperand Addr, SDOperand &Base,
790 SDOperand &Offset) {
Chris Lattnerd5aae052005-12-18 07:09:06 +0000791 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
792 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
Chris Lattner8fa54dc2005-12-18 06:59:57 +0000793 Offset = CurDAG->getTargetConstant(0, MVT::i32);
794 return true;
795 }
796
797 if (Addr.getOpcode() == ISD::ADD) {
798 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
799 if (Predicate_simm13(CN)) {
Chris Lattnerd5aae052005-12-18 07:09:06 +0000800 if (FrameIndexSDNode *FIN =
801 dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) {
Chris Lattner8fa54dc2005-12-18 06:59:57 +0000802 // Constant offset from frame ref.
Chris Lattnerd5aae052005-12-18 07:09:06 +0000803 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
Chris Lattner8fa54dc2005-12-18 06:59:57 +0000804 } else {
805 Base = Select(Addr.getOperand(0));
806 }
807 Offset = CurDAG->getTargetConstant(CN->getValue(), MVT::i32);
808 return true;
809 }
810 }
811 if (Addr.getOperand(0).getOpcode() == V8ISD::Lo) {
812 Base = Select(Addr.getOperand(1));
813 Offset = Addr.getOperand(0).getOperand(0);
814 return true;
815 }
816 if (Addr.getOperand(1).getOpcode() == V8ISD::Lo) {
817 Base = Select(Addr.getOperand(0));
818 Offset = Addr.getOperand(1).getOperand(0);
819 return true;
820 }
821 }
822 Base = Select(Addr);
823 Offset = CurDAG->getTargetConstant(0, MVT::i32);
824 return true;
825}
826
Chris Lattner9034b882005-12-17 21:25:27 +0000827bool SparcV8DAGToDAGISel::SelectADDRrr(SDOperand Addr, SDOperand &R1,
Chris Lattnerbc83fd92005-12-17 20:04:49 +0000828 SDOperand &R2) {
Chris Lattner8fa54dc2005-12-18 06:59:57 +0000829 if (Addr.getOpcode() == ISD::FrameIndex) return false;
Chris Lattner9034b882005-12-17 21:25:27 +0000830 if (Addr.getOpcode() == ISD::ADD) {
831 if (isa<ConstantSDNode>(Addr.getOperand(1)) &&
832 Predicate_simm13(Addr.getOperand(1).Val))
833 return false; // Let the reg+imm pattern catch this!
Chris Lattnere1389ad2005-12-18 02:27:00 +0000834 if (Addr.getOperand(0).getOpcode() == V8ISD::Lo ||
835 Addr.getOperand(1).getOpcode() == V8ISD::Lo)
836 return false; // Let the reg+imm pattern catch this!
Chris Lattnere3572462005-12-18 02:10:39 +0000837 R1 = Select(Addr.getOperand(0));
838 R2 = Select(Addr.getOperand(1));
Chris Lattner9034b882005-12-17 21:25:27 +0000839 return true;
840 }
841
842 R1 = Select(Addr);
Chris Lattnerbc83fd92005-12-17 20:04:49 +0000843 R2 = CurDAG->getRegister(V8::G0, MVT::i32);
844 return true;
845}
846
Chris Lattner6c18b102005-12-17 07:47:01 +0000847SDOperand SparcV8DAGToDAGISel::Select(SDOperand Op) {
848 SDNode *N = Op.Val;
Chris Lattner4d55aca2005-12-18 01:20:35 +0000849 if (N->getOpcode() >= ISD::BUILTIN_OP_END &&
850 N->getOpcode() < V8ISD::FIRST_NUMBER)
Chris Lattner6c18b102005-12-17 07:47:01 +0000851 return Op; // Already selected.
852 // If this has already been converted, use it.
853 std::map<SDOperand, SDOperand>::iterator CGMI = CodeGenMap.find(Op);
854 if (CGMI != CodeGenMap.end()) return CGMI->second;
855
856 switch (N->getOpcode()) {
857 default: break;
Chris Lattner4d55aca2005-12-18 01:20:35 +0000858 case ISD::BasicBlock: return CodeGenMap[Op] = Op;
Chris Lattner8fa54dc2005-12-18 06:59:57 +0000859 case ISD::FrameIndex: {
860 int FI = cast<FrameIndexSDNode>(N)->getIndex();
861 if (N->hasOneUse())
862 return CurDAG->SelectNodeTo(N, V8::ADDri, MVT::i32,
863 CurDAG->getTargetFrameIndex(FI, MVT::i32),
864 CurDAG->getTargetConstant(0, MVT::i32));
865 return CodeGenMap[Op] =
866 CurDAG->getTargetNode(V8::ADDri, MVT::i32,
867 CurDAG->getTargetFrameIndex(FI, MVT::i32),
868 CurDAG->getTargetConstant(0, MVT::i32));
869 }
Chris Lattner4d55aca2005-12-18 01:20:35 +0000870 case V8ISD::CMPICC: {
871 // FIXME: Handle compare with immediate.
872 SDOperand LHS = Select(N->getOperand(0));
873 SDOperand RHS = Select(N->getOperand(1));
874 SDOperand Result = CurDAG->getTargetNode(V8::SUBCCrr, MVT::i32, MVT::Flag,
875 LHS, RHS);
876 return CodeGenMap[Op] = Result.getValue(1);
877 }
Chris Lattnerd19fc652005-12-17 22:55:57 +0000878 case ISD::ADD_PARTS: {
879 SDOperand LHSL = Select(N->getOperand(0));
880 SDOperand LHSH = Select(N->getOperand(1));
881 SDOperand RHSL = Select(N->getOperand(2));
882 SDOperand RHSH = Select(N->getOperand(3));
883 // FIXME, handle immediate RHS.
884 SDOperand Low = CurDAG->getTargetNode(V8::ADDCCrr, MVT::i32, MVT::Flag,
885 LHSL, RHSL);
886 SDOperand Hi = CurDAG->getTargetNode(V8::ADDXrr, MVT::i32, LHSH, RHSH,
887 Low.getValue(1));
888 CodeGenMap[SDOperand(N, 0)] = Low;
889 CodeGenMap[SDOperand(N, 1)] = Hi;
890 return Op.ResNo ? Hi : Low;
891 }
892 case ISD::SUB_PARTS: {
893 SDOperand LHSL = Select(N->getOperand(0));
894 SDOperand LHSH = Select(N->getOperand(1));
895 SDOperand RHSL = Select(N->getOperand(2));
896 SDOperand RHSH = Select(N->getOperand(3));
897 // FIXME, handle immediate RHS.
898 SDOperand Low = CurDAG->getTargetNode(V8::SUBCCrr, MVT::i32, MVT::Flag,
899 LHSL, RHSL);
900 SDOperand Hi = CurDAG->getTargetNode(V8::SUBXrr, MVT::i32, LHSH, RHSH,
901 Low.getValue(1));
902 CodeGenMap[SDOperand(N, 0)] = Low;
903 CodeGenMap[SDOperand(N, 1)] = Hi;
904 return Op.ResNo ? Hi : Low;
905 }
Chris Lattner7087e572005-12-17 22:39:19 +0000906 case ISD::SDIV:
907 case ISD::UDIV: {
908 // FIXME: should use a custom expander to expose the SRA to the dag.
909 SDOperand DivLHS = Select(N->getOperand(0));
910 SDOperand DivRHS = Select(N->getOperand(1));
911
912 // Set the Y register to the high-part.
913 SDOperand TopPart;
914 if (N->getOpcode() == ISD::SDIV) {
915 TopPart = CurDAG->getTargetNode(V8::SRAri, MVT::i32, DivLHS,
916 CurDAG->getTargetConstant(31, MVT::i32));
917 } else {
918 TopPart = CurDAG->getRegister(V8::G0, MVT::i32);
919 }
920 TopPart = CurDAG->getTargetNode(V8::WRYrr, MVT::Flag, TopPart,
921 CurDAG->getRegister(V8::G0, MVT::i32));
922
923 // FIXME: Handle div by immediate.
924 unsigned Opcode = N->getOpcode() == ISD::SDIV ? V8::SDIVrr : V8::UDIVrr;
925 return CurDAG->SelectNodeTo(N, Opcode, MVT::i32, DivLHS, DivRHS, TopPart);
926 }
Chris Lattneree3d5fb2005-12-17 22:30:00 +0000927 case ISD::MULHU:
928 case ISD::MULHS: {
Chris Lattner7087e572005-12-17 22:39:19 +0000929 // FIXME: Handle mul by immediate.
Chris Lattneree3d5fb2005-12-17 22:30:00 +0000930 SDOperand MulLHS = Select(N->getOperand(0));
931 SDOperand MulRHS = Select(N->getOperand(1));
932 unsigned Opcode = N->getOpcode() == ISD::MULHU ? V8::UMULrr : V8::SMULrr;
933 SDOperand Mul = CurDAG->getTargetNode(Opcode, MVT::i32, MVT::Flag,
934 MulLHS, MulRHS);
935 // The high part is in the Y register.
936 return CurDAG->SelectNodeTo(N, V8::RDY, MVT::i32, Mul.getValue(1));
937 }
938
Chris Lattner4b486312005-12-17 08:15:09 +0000939 case ISD::RET: {
Chris Lattner2db3ff62005-12-18 15:55:15 +0000940 // FIXME: change this to use flag operands to allow autogen of ret.
Chris Lattner4b486312005-12-17 08:15:09 +0000941 if (N->getNumOperands() == 2) {
942 SDOperand Chain = Select(N->getOperand(0)); // Token chain.
943 SDOperand Val = Select(N->getOperand(1));
944 if (N->getOperand(1).getValueType() == MVT::i32) {
945 Chain = CurDAG->getCopyToReg(Chain, V8::I0, Val);
946 } else if (N->getOperand(1).getValueType() == MVT::f32) {
947 Chain = CurDAG->getCopyToReg(Chain, V8::F0, Val);
948 } else {
949 assert(N->getOperand(1).getValueType() == MVT::f64);
950 Chain = CurDAG->getCopyToReg(Chain, V8::D0, Val);
951 }
952 return CurDAG->SelectNodeTo(N, V8::RETL, MVT::Other, Chain);
953 } else if (N->getNumOperands() > 1) {
954 SDOperand Chain = Select(N->getOperand(0)); // Token chain.
955 assert(N->getOperand(1).getValueType() == MVT::i32 &&
956 N->getOperand(2).getValueType() == MVT::i32 &&
957 N->getNumOperands() == 3 && "Unknown two-register ret value!");
Chris Lattnerd19fc652005-12-17 22:55:57 +0000958 Chain = CurDAG->getCopyToReg(Chain, V8::I1, Select(N->getOperand(1)));
959 Chain = CurDAG->getCopyToReg(Chain, V8::I0, Select(N->getOperand(2)));
Chris Lattner4b486312005-12-17 08:15:09 +0000960 return CurDAG->SelectNodeTo(N, V8::RETL, MVT::Other, Chain);
961 }
962 break; // Generated code handles the void case.
963 }
Chris Lattner2db3ff62005-12-18 15:55:15 +0000964 case ISD::CALL:
965 // FIXME: This is a workaround for a bug in tblgen.
966 { // Pattern #47: (call:Flag (tglobaladdr:i32):$dst, ICC:Flag)
967 // Emits: (CALL:void (tglobaladdr:i32):$dst)
968 // Pattern complexity = 2 cost = 1
969 SDOperand N1 = N->getOperand(1);
970 if (N1.getOpcode() != ISD::TargetGlobalAddress) goto P47Fail;
971 SDOperand N2 = N->getOperand(2);
972 SDOperand InFlag = SDOperand(0,0);
973 SDOperand Chain = N->getOperand(0);
974 SDOperand Tmp0 = N1;
975 Chain = Select(Chain);
976 InFlag = Select(N2);
977 SDOperand Result = CurDAG->getTargetNode(V8::CALL, MVT::Other, MVT::Flag, Tmp0, Chain, InFlag);
978 Chain = CodeGenMap[SDOperand(N, 0)] = Result.getValue(0);
979 CodeGenMap[SDOperand(N, 1)] = Result.getValue(1);
980 return Result.getValue(Op.ResNo);
981 }
982 P47Fail:;
983
Chris Lattner6c18b102005-12-17 07:47:01 +0000984 }
985
986 return SelectCode(Op);
987}
988
989
990/// createPPCISelDag - This pass converts a legalized DAG into a
991/// PowerPC-specific DAG, ready for instruction scheduling.
992///
993FunctionPass *llvm::createSparcV8ISelDag(TargetMachine &TM) {
994 return new SparcV8DAGToDAGISel(TM);
995}