Add frameindex support
[oota-llvm.git] / lib / Target / Sparc / SparcISelDAGToDAG.cpp
1 //===-- 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"
16 #include "llvm/Function.h"
17 #include "llvm/CodeGen/MachineFrameInfo.h"
18 #include "llvm/CodeGen/MachineFunction.h"
19 #include "llvm/CodeGen/SelectionDAG.h"
20 #include "llvm/CodeGen/SelectionDAGISel.h"
21 #include "llvm/CodeGen/SSARegMap.h"
22 #include "llvm/Target/TargetLowering.h"
23 #include "llvm/Support/Debug.h"
24 #include <iostream>
25 using namespace llvm;
26
27 //===----------------------------------------------------------------------===//
28 // TargetLowering Implementation
29 //===----------------------------------------------------------------------===//
30
31 namespace V8ISD {
32   enum {
33     FIRST_NUMBER = ISD::BUILTIN_OP_END+V8::INSTRUCTION_LIST_END,
34     CMPICC,   // Compare two GPR operands, set icc.
35     CMPFCC,   // Compare two FP operands, set fcc.
36     BRICC,    // Branch to dest on icc condition
37     BRFCC,    // Branch to dest on fcc condition
38     
39     Hi, Lo,   // Hi/Lo operations, typically on a global address.
40     
41     FTOI,     // FP to Int within a FP register.
42     ITOF,     // Int to FP within a FP register.
43   };
44 }
45
46 namespace {
47   class SparcV8TargetLowering : public TargetLowering {
48   public:
49     SparcV8TargetLowering(TargetMachine &TM);
50     virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
51     virtual std::vector<SDOperand>
52       LowerArguments(Function &F, SelectionDAG &DAG);
53     virtual std::pair<SDOperand, SDOperand>
54       LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg,
55                   unsigned CC,
56                   bool isTailCall, SDOperand Callee, ArgListTy &Args,
57                   SelectionDAG &DAG);
58     
59     virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op,
60                                     SelectionDAG &DAG);
61     virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP,
62                                    Value *VAListV, SelectionDAG &DAG);
63     virtual std::pair<SDOperand,SDOperand>
64       LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
65                  const Type *ArgTy, SelectionDAG &DAG);
66     virtual std::pair<SDOperand, SDOperand>
67       LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
68                               SelectionDAG &DAG);
69   };
70 }
71
72 SparcV8TargetLowering::SparcV8TargetLowering(TargetMachine &TM)
73   : TargetLowering(TM) {
74   
75   // Set up the register classes.
76   addRegisterClass(MVT::i32, V8::IntRegsRegisterClass);
77   addRegisterClass(MVT::f32, V8::FPRegsRegisterClass);
78   addRegisterClass(MVT::f64, V8::DFPRegsRegisterClass);
79
80   // Custom legalize GlobalAddress nodes into LO/HI parts.
81   setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
82   setOperationAction(ISD::ConstantPool , MVT::i32, Custom);
83   
84   // Sparc doesn't have sext_inreg, replace them with shl/sra
85   setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16  , Expand);
86   setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8   , Expand);
87   setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1   , Expand);
88
89   // Sparc has no REM operation.
90   setOperationAction(ISD::UREM, MVT::i32, Expand);
91   setOperationAction(ISD::SREM, MVT::i32, Expand);
92
93   // Custom expand fp<->sint
94   setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
95   setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
96
97   // Expand fp<->uint
98   setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand);
99   setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand);
100   
101   // Sparc has no select or setcc: expand to SELECT_CC.
102   setOperationAction(ISD::SELECT, MVT::i32, Expand);
103   setOperationAction(ISD::SELECT, MVT::f32, Expand);
104   setOperationAction(ISD::SELECT, MVT::f64, Expand);
105   setOperationAction(ISD::SETCC, MVT::i32, Expand);
106   setOperationAction(ISD::SETCC, MVT::f32, Expand);
107   setOperationAction(ISD::SETCC, MVT::f64, Expand);
108   
109   // Sparc doesn't have BRCOND either, it has BR_CC.
110   setOperationAction(ISD::BRCOND, MVT::Other, Expand);
111   setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand);
112   setOperationAction(ISD::BRTWOWAY_CC, MVT::Other, Expand);
113   setOperationAction(ISD::BR_CC, MVT::i32, Custom);
114   setOperationAction(ISD::BR_CC, MVT::f32, Custom);
115   setOperationAction(ISD::BR_CC, MVT::f64, Custom);
116   
117   computeRegisterProperties();
118 }
119
120 std::vector<SDOperand>
121 SparcV8TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
122   MachineFunction &MF = DAG.getMachineFunction();
123   SSARegMap *RegMap = MF.getSSARegMap();
124   std::vector<SDOperand> ArgValues;
125   
126   static const unsigned GPR[] = {
127     V8::I0, V8::I1, V8::I2, V8::I3, V8::I4, V8::I5
128   };
129   unsigned ArgNo = 0;
130   for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) {
131     MVT::ValueType ObjectVT = getValueType(I->getType());
132     assert(ArgNo < 6 && "Only args in regs for now");
133     
134     switch (ObjectVT) {
135     default: assert(0 && "Unhandled argument type!");
136     // TODO: MVT::i64 & FP
137     case MVT::i1:
138     case MVT::i8:
139     case MVT::i16:
140     case MVT::i32: {
141       unsigned VReg = RegMap->createVirtualRegister(&V8::IntRegsRegClass);
142       MF.addLiveIn(GPR[ArgNo++], VReg);
143       SDOperand Arg = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32);
144       DAG.setRoot(Arg.getValue(1));
145       if (ObjectVT != MVT::i32) {
146         unsigned AssertOp = I->getType()->isSigned() ? ISD::AssertSext 
147                                                      : ISD::AssertZext;
148         Arg = DAG.getNode(AssertOp, MVT::i32, Arg, 
149                           DAG.getValueType(ObjectVT));
150         Arg = DAG.getNode(ISD::TRUNCATE, ObjectVT, Arg);
151       }
152       ArgValues.push_back(Arg);
153       break;
154     }
155     case MVT::i64: {
156       unsigned VRegHi = RegMap->createVirtualRegister(&V8::IntRegsRegClass);
157       MF.addLiveIn(GPR[ArgNo++], VRegHi);
158       unsigned VRegLo = RegMap->createVirtualRegister(&V8::IntRegsRegClass);
159       MF.addLiveIn(GPR[ArgNo++], VRegLo);
160       SDOperand ArgLo = DAG.getCopyFromReg(DAG.getRoot(), VRegLo, MVT::i32);
161       SDOperand ArgHi = DAG.getCopyFromReg(ArgLo.getValue(1), VRegHi, MVT::i32);
162       DAG.setRoot(ArgHi.getValue(1));
163       ArgValues.push_back(DAG.getNode(ISD::BUILD_PAIR, MVT::i64, ArgLo, ArgHi));
164       break;
165     }
166     }
167   }
168   
169   assert(!F.isVarArg() && "Unimp");
170   
171   // Finally, inform the code generator which regs we return values in.
172   switch (getValueType(F.getReturnType())) {
173   default: assert(0 && "Unknown type!");
174   case MVT::isVoid: break;
175   case MVT::i1:
176   case MVT::i8:
177   case MVT::i16:
178   case MVT::i32:
179     MF.addLiveOut(V8::I0);
180     break;
181   case MVT::i64:
182     MF.addLiveOut(V8::I0);
183     MF.addLiveOut(V8::I1);
184     break;
185   case MVT::f32:
186     MF.addLiveOut(V8::F0);
187     break;
188   case MVT::f64:
189     MF.addLiveOut(V8::D0);
190     break;
191   }
192   
193   return ArgValues;
194 }
195
196 std::pair<SDOperand, SDOperand>
197 SparcV8TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
198                                    bool isVarArg, unsigned CC,
199                                    bool isTailCall, SDOperand Callee, 
200                                    ArgListTy &Args, SelectionDAG &DAG) {
201   assert(0 && "Unimp");
202   abort();
203 }
204
205 SDOperand SparcV8TargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op,
206                                                SelectionDAG &DAG) {
207   if (Op.getValueType() == MVT::i64) {
208     SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op, 
209                                DAG.getConstant(1, MVT::i32));
210     SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op,
211                                DAG.getConstant(0, MVT::i32));
212     return DAG.getNode(ISD::RET, MVT::Other, Chain, Lo, Hi);
213   } else {
214     return DAG.getNode(ISD::RET, MVT::Other, Chain, Op);
215   }
216 }
217
218 SDOperand SparcV8TargetLowering::
219 LowerVAStart(SDOperand Chain, SDOperand VAListP, Value *VAListV, 
220              SelectionDAG &DAG) {
221              
222   assert(0 && "Unimp");
223   abort();
224 }
225
226 std::pair<SDOperand,SDOperand> SparcV8TargetLowering::
227 LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
228            const Type *ArgTy, SelectionDAG &DAG) {
229   assert(0 && "Unimp");
230   abort();
231 }
232
233 std::pair<SDOperand, SDOperand> SparcV8TargetLowering::
234 LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
235                         SelectionDAG &DAG) {
236   assert(0 && "Unimp");
237   abort();
238 }
239
240 SDOperand SparcV8TargetLowering::
241 LowerOperation(SDOperand Op, SelectionDAG &DAG) {
242   switch (Op.getOpcode()) {
243   default: assert(0 && "Should not custom lower this!");
244   case ISD::BR_CC: {
245     SDOperand Chain = Op.getOperand(0);
246     SDOperand CC = Op.getOperand(1);
247     SDOperand LHS = Op.getOperand(2);
248     SDOperand RHS = Op.getOperand(3);
249     SDOperand Dest = Op.getOperand(4);
250     
251     // Get the condition flag.
252     if (LHS.getValueType() == MVT::i32) {
253       SDOperand Cond = DAG.getNode(V8ISD::CMPICC, MVT::Flag, LHS, RHS);
254       return DAG.getNode(V8ISD::BRICC, MVT::Other, Chain, Dest, CC, Cond);
255     } else {
256       SDOperand Cond = DAG.getNode(V8ISD::CMPFCC, MVT::Flag, LHS, RHS);
257       return DAG.getNode(V8ISD::BRFCC, MVT::Other, Chain, Dest, CC, Cond);
258     }
259   }
260   case ISD::GlobalAddress: {
261     GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
262     SDOperand GA = DAG.getTargetGlobalAddress(GV, MVT::i32);
263     SDOperand Hi = DAG.getNode(V8ISD::Hi, MVT::i32, GA);
264     SDOperand Lo = DAG.getNode(V8ISD::Lo, MVT::i32, GA);
265     return DAG.getNode(ISD::ADD, MVT::i32, Lo, Hi);
266   }
267   case ISD::ConstantPool: {
268     Constant *C = cast<ConstantPoolSDNode>(Op)->get();
269     SDOperand CP = DAG.getTargetConstantPool(C, MVT::i32);
270     SDOperand Hi = DAG.getNode(V8ISD::Hi, MVT::i32, CP);
271     SDOperand Lo = DAG.getNode(V8ISD::Lo, MVT::i32, CP);
272     return DAG.getNode(ISD::ADD, MVT::i32, Lo, Hi);
273   }
274   case ISD::FP_TO_SINT: {
275     // Convert the fp value to integer in an FP register.
276     Op = DAG.getNode(V8ISD::FTOI, Op.getOperand(0).getValueType(),
277                      Op.getOperand(0));
278     int Size = Op.getOperand(0).getValueType() == MVT::f32 ? 4 : 8;
279     int FrameIdx =
280       DAG.getMachineFunction().getFrameInfo()->CreateStackObject(Size, Size);
281     SDOperand FI = DAG.getFrameIndex(FrameIdx, MVT::i32);
282     SDOperand ST = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(),
283                                Op, FI, DAG.getSrcValue(0));
284     return DAG.getLoad(MVT::i32, ST, FI, DAG.getSrcValue(0));
285   }
286   case ISD::SINT_TO_FP: {
287     int Size = Op.getOperand(0).getValueType() == MVT::f32 ? 4 : 8;
288     int FrameIdx =
289       DAG.getMachineFunction().getFrameInfo()->CreateStackObject(Size, Size);
290     SDOperand FI = DAG.getFrameIndex(FrameIdx, MVT::i32);
291     SDOperand ST = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(),
292                                Op.getOperand(0), FI, DAG.getSrcValue(0));
293     
294     Op = DAG.getLoad(Op.getValueType(), ST, FI, DAG.getSrcValue(0));
295     
296     // Convert the int value to FP in an FP register.
297     return DAG.getNode(V8ISD::ITOF, Op.getValueType(), Op);
298   }
299   }  
300 }
301
302
303 //===----------------------------------------------------------------------===//
304 // Instruction Selector Implementation
305 //===----------------------------------------------------------------------===//
306
307 //===--------------------------------------------------------------------===//
308 /// SparcV8DAGToDAGISel - PPC specific code to select Sparc V8 machine
309 /// instructions for SelectionDAG operations.
310 ///
311 namespace {
312 class SparcV8DAGToDAGISel : public SelectionDAGISel {
313   SparcV8TargetLowering V8Lowering;
314 public:
315   SparcV8DAGToDAGISel(TargetMachine &TM)
316     : SelectionDAGISel(V8Lowering), V8Lowering(TM) {}
317
318   SDOperand Select(SDOperand Op);
319
320   // Complex Pattern Selectors.
321   bool SelectADDRrr(SDOperand N, SDOperand &R1, SDOperand &R2);
322   bool SelectADDRri(SDOperand N, SDOperand &Base, SDOperand &Offset);
323   
324   /// InstructionSelectBasicBlock - This callback is invoked by
325   /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
326   virtual void InstructionSelectBasicBlock(SelectionDAG &DAG);
327   
328   virtual const char *getPassName() const {
329     return "PowerPC DAG->DAG Pattern Instruction Selection";
330   } 
331   
332   // Include the pieces autogenerated from the target description.
333 #include "SparcV8GenDAGISel.inc"
334 };
335 }  // end anonymous namespace
336
337 /// InstructionSelectBasicBlock - This callback is invoked by
338 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
339 void SparcV8DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
340   DEBUG(BB->dump());
341   
342   // Select target instructions for the DAG.
343   DAG.setRoot(Select(DAG.getRoot()));
344   CodeGenMap.clear();
345   DAG.RemoveDeadNodes();
346   
347   // Emit machine code to BB. 
348   ScheduleAndEmitDAG(DAG);
349 }
350
351 bool SparcV8DAGToDAGISel::SelectADDRri(SDOperand Addr, SDOperand &Base,
352                                        SDOperand &Offset) {
353   if (Addr.getOpcode() == ISD::FrameIndex) {
354     int FI = cast<FrameIndexSDNode>(Addr)->getIndex();
355     Base = CurDAG->getTargetFrameIndex(FI, MVT::i32);
356     Offset = CurDAG->getTargetConstant(0, MVT::i32);
357     return true;
358   }
359   
360   if (Addr.getOpcode() == ISD::ADD) {
361     if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
362       if (Predicate_simm13(CN)) {
363         if (Addr.getOperand(0).getOpcode() == ISD::FrameIndex) {
364           // Constant offset from frame ref.
365           int FI = cast<FrameIndexSDNode>(Addr)->getIndex();
366           Base = CurDAG->getTargetFrameIndex(FI, MVT::i32);
367         } else {
368           Base = Select(Addr.getOperand(0));
369         }
370         Offset = CurDAG->getTargetConstant(CN->getValue(), MVT::i32);
371         return true;
372       }
373     }
374     if (Addr.getOperand(0).getOpcode() == V8ISD::Lo) {
375       Base = Select(Addr.getOperand(1));
376       Offset = Addr.getOperand(0).getOperand(0);
377       return true;
378     }
379     if (Addr.getOperand(1).getOpcode() == V8ISD::Lo) {
380       Base = Select(Addr.getOperand(0));
381       Offset = Addr.getOperand(1).getOperand(0);
382       return true;
383     }
384   }
385   Base = Select(Addr);
386   Offset = CurDAG->getTargetConstant(0, MVT::i32);
387   return true;
388 }
389
390 bool SparcV8DAGToDAGISel::SelectADDRrr(SDOperand Addr, SDOperand &R1, 
391                                        SDOperand &R2) {
392   if (Addr.getOpcode() == ISD::FrameIndex) return false; 
393   if (Addr.getOpcode() == ISD::ADD) {
394     if (isa<ConstantSDNode>(Addr.getOperand(1)) &&
395         Predicate_simm13(Addr.getOperand(1).Val))
396       return false;  // Let the reg+imm pattern catch this!
397     if (Addr.getOperand(0).getOpcode() == V8ISD::Lo ||
398         Addr.getOperand(1).getOpcode() == V8ISD::Lo)
399       return false;  // Let the reg+imm pattern catch this!
400     R1 = Select(Addr.getOperand(0));
401     R2 = Select(Addr.getOperand(1));
402     return true;
403   }
404
405   R1 = Select(Addr);
406   R2 = CurDAG->getRegister(V8::G0, MVT::i32);
407   return true;
408 }
409
410 SDOperand SparcV8DAGToDAGISel::Select(SDOperand Op) {
411   SDNode *N = Op.Val;
412   if (N->getOpcode() >= ISD::BUILTIN_OP_END &&
413       N->getOpcode() < V8ISD::FIRST_NUMBER)
414     return Op;   // Already selected.
415                  // If this has already been converted, use it.
416   std::map<SDOperand, SDOperand>::iterator CGMI = CodeGenMap.find(Op);
417   if (CGMI != CodeGenMap.end()) return CGMI->second;
418   
419   switch (N->getOpcode()) {
420   default: break;
421   case ISD::BasicBlock:         return CodeGenMap[Op] = Op;
422   case ISD::FrameIndex: {
423     int FI = cast<FrameIndexSDNode>(N)->getIndex();
424     if (N->hasOneUse())
425       return CurDAG->SelectNodeTo(N, V8::ADDri, MVT::i32,
426                                   CurDAG->getTargetFrameIndex(FI, MVT::i32),
427                                   CurDAG->getTargetConstant(0, MVT::i32));
428     return CodeGenMap[Op] = 
429       CurDAG->getTargetNode(V8::ADDri, MVT::i32,
430                             CurDAG->getTargetFrameIndex(FI, MVT::i32),
431                             CurDAG->getTargetConstant(0, MVT::i32));
432   }
433   case V8ISD::CMPICC: {
434     // FIXME: Handle compare with immediate.
435     SDOperand LHS = Select(N->getOperand(0));
436     SDOperand RHS = Select(N->getOperand(1));
437     SDOperand Result = CurDAG->getTargetNode(V8::SUBCCrr, MVT::i32, MVT::Flag,
438                                              LHS, RHS);
439     return CodeGenMap[Op] = Result.getValue(1);
440   }
441   case ISD::ADD_PARTS: {
442     SDOperand LHSL = Select(N->getOperand(0));
443     SDOperand LHSH = Select(N->getOperand(1));
444     SDOperand RHSL = Select(N->getOperand(2));
445     SDOperand RHSH = Select(N->getOperand(3));
446     // FIXME, handle immediate RHS.
447     SDOperand Low = CurDAG->getTargetNode(V8::ADDCCrr, MVT::i32, MVT::Flag,
448                                           LHSL, RHSL);
449     SDOperand Hi  = CurDAG->getTargetNode(V8::ADDXrr, MVT::i32, LHSH, RHSH, 
450                                           Low.getValue(1));
451     CodeGenMap[SDOperand(N, 0)] = Low;
452     CodeGenMap[SDOperand(N, 1)] = Hi;
453     return Op.ResNo ? Hi : Low;
454   }
455   case ISD::SUB_PARTS: {
456     SDOperand LHSL = Select(N->getOperand(0));
457     SDOperand LHSH = Select(N->getOperand(1));
458     SDOperand RHSL = Select(N->getOperand(2));
459     SDOperand RHSH = Select(N->getOperand(3));
460     // FIXME, handle immediate RHS.
461     SDOperand Low = CurDAG->getTargetNode(V8::SUBCCrr, MVT::i32, MVT::Flag,
462                                           LHSL, RHSL);
463     SDOperand Hi  = CurDAG->getTargetNode(V8::SUBXrr, MVT::i32, LHSH, RHSH, 
464                                           Low.getValue(1));
465     CodeGenMap[SDOperand(N, 0)] = Low;
466     CodeGenMap[SDOperand(N, 1)] = Hi;
467     return Op.ResNo ? Hi : Low;
468   }
469   case ISD::SDIV:
470   case ISD::UDIV: {
471     // FIXME: should use a custom expander to expose the SRA to the dag.
472     SDOperand DivLHS = Select(N->getOperand(0));
473     SDOperand DivRHS = Select(N->getOperand(1));
474     
475     // Set the Y register to the high-part.
476     SDOperand TopPart;
477     if (N->getOpcode() == ISD::SDIV) {
478       TopPart = CurDAG->getTargetNode(V8::SRAri, MVT::i32, DivLHS,
479                                       CurDAG->getTargetConstant(31, MVT::i32));
480     } else {
481       TopPart = CurDAG->getRegister(V8::G0, MVT::i32);
482     }
483     TopPart = CurDAG->getTargetNode(V8::WRYrr, MVT::Flag, TopPart,
484                                     CurDAG->getRegister(V8::G0, MVT::i32));
485
486     // FIXME: Handle div by immediate.
487     unsigned Opcode = N->getOpcode() == ISD::SDIV ? V8::SDIVrr : V8::UDIVrr;
488     return CurDAG->SelectNodeTo(N, Opcode, MVT::i32, DivLHS, DivRHS, TopPart);
489   }    
490   case ISD::MULHU:
491   case ISD::MULHS: {
492     // FIXME: Handle mul by immediate.
493     SDOperand MulLHS = Select(N->getOperand(0));
494     SDOperand MulRHS = Select(N->getOperand(1));
495     unsigned Opcode = N->getOpcode() == ISD::MULHU ? V8::UMULrr : V8::SMULrr;
496     SDOperand Mul = CurDAG->getTargetNode(Opcode, MVT::i32, MVT::Flag,
497                                           MulLHS, MulRHS);
498     // The high part is in the Y register.
499     return CurDAG->SelectNodeTo(N, V8::RDY, MVT::i32, Mul.getValue(1));
500   }
501     
502   case ISD::RET: {
503     if (N->getNumOperands() == 2) {
504       SDOperand Chain = Select(N->getOperand(0));     // Token chain.
505       SDOperand Val = Select(N->getOperand(1));
506       if (N->getOperand(1).getValueType() == MVT::i32) {
507         Chain = CurDAG->getCopyToReg(Chain, V8::I0, Val);
508       } else if (N->getOperand(1).getValueType() == MVT::f32) {
509         Chain = CurDAG->getCopyToReg(Chain, V8::F0, Val);
510       } else {
511         assert(N->getOperand(1).getValueType() == MVT::f64);
512         Chain = CurDAG->getCopyToReg(Chain, V8::D0, Val);
513       }
514       return CurDAG->SelectNodeTo(N, V8::RETL, MVT::Other, Chain);
515     } else if (N->getNumOperands() > 1) {
516       SDOperand Chain = Select(N->getOperand(0));     // Token chain.
517       assert(N->getOperand(1).getValueType() == MVT::i32 &&
518              N->getOperand(2).getValueType() == MVT::i32 &&
519              N->getNumOperands() == 3 && "Unknown two-register ret value!");
520       Chain = CurDAG->getCopyToReg(Chain, V8::I1, Select(N->getOperand(1)));
521       Chain = CurDAG->getCopyToReg(Chain, V8::I0, Select(N->getOperand(2)));
522       return CurDAG->SelectNodeTo(N, V8::RETL, MVT::Other, Chain);
523     }
524     break;  // Generated code handles the void case.
525   }
526   }
527   
528   return SelectCode(Op);
529 }
530
531
532 /// createPPCISelDag - This pass converts a legalized DAG into a 
533 /// PowerPC-specific DAG, ready for instruction scheduling.
534 ///
535 FunctionPass *llvm::createSparcV8ISelDag(TargetMachine &TM) {
536   return new SparcV8DAGToDAGISel(TM);
537 }