add initial support for converting select_cc -> fsel in the legalizer
[oota-llvm.git] / lib / Target / PowerPC / PPCISelLowering.cpp
1 //===-- PPC32ISelLowering.cpp - PPC32 DAG Lowering Implementation ---------===//
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 implements the PPC32ISelLowering class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "PPC32ISelLowering.h"
15 #include "PPC32TargetMachine.h"
16 #include "llvm/CodeGen/MachineFrameInfo.h"
17 #include "llvm/CodeGen/MachineFunction.h"
18 #include "llvm/CodeGen/SelectionDAG.h"
19 #include "llvm/Function.h"
20 #include "llvm/Support/CommandLine.h"
21 using namespace llvm;
22
23 namespace llvm {
24   cl::opt<bool> FSELTMP("ppc-fsel-custom-legalizer", cl::Hidden,
25                              cl::desc("Use a custom expander for fsel on ppc"));
26 }
27
28
29 PPC32TargetLowering::PPC32TargetLowering(TargetMachine &TM)
30   : TargetLowering(TM) {
31     
32   // Fold away setcc operations if possible.
33   setSetCCIsExpensive();
34   
35   // Set up the register classes.
36   addRegisterClass(MVT::i32, PPC32::GPRCRegisterClass);
37   addRegisterClass(MVT::f32, PPC32::FPRCRegisterClass);
38   addRegisterClass(MVT::f64, PPC32::FPRCRegisterClass);
39   
40   // PowerPC has no intrinsics for these particular operations
41   setOperationAction(ISD::MEMMOVE, MVT::Other, Expand);
42   setOperationAction(ISD::MEMSET, MVT::Other, Expand);
43   setOperationAction(ISD::MEMCPY, MVT::Other, Expand);
44   
45   // PowerPC has an i16 but no i8 (or i1) SEXTLOAD
46   setOperationAction(ISD::SEXTLOAD, MVT::i1, Expand);
47   setOperationAction(ISD::SEXTLOAD, MVT::i8, Expand);
48   
49   // PowerPC has no SREM/UREM instructions
50   setOperationAction(ISD::SREM, MVT::i32, Expand);
51   setOperationAction(ISD::UREM, MVT::i32, Expand);
52   
53   // We don't support sin/cos/sqrt/fmod
54   setOperationAction(ISD::FSIN , MVT::f64, Expand);
55   setOperationAction(ISD::FCOS , MVT::f64, Expand);
56   setOperationAction(ISD::SREM , MVT::f64, Expand);
57   setOperationAction(ISD::FSIN , MVT::f32, Expand);
58   setOperationAction(ISD::FCOS , MVT::f32, Expand);
59   setOperationAction(ISD::SREM , MVT::f32, Expand);
60   
61   // If we're enabling GP optimizations, use hardware square root
62   if (!TM.getSubtarget<PPCSubtarget>().isGigaProcessor()) {
63     setOperationAction(ISD::FSQRT, MVT::f64, Expand);
64     setOperationAction(ISD::FSQRT, MVT::f32, Expand);
65   }
66   
67   // PowerPC does not have CTPOP or CTTZ
68   setOperationAction(ISD::CTPOP, MVT::i32  , Expand);
69   setOperationAction(ISD::CTTZ , MVT::i32  , Expand);
70   
71   // PowerPC does not have Select
72   setOperationAction(ISD::SELECT, MVT::i32, Expand);
73   setOperationAction(ISD::SELECT, MVT::f32, Expand);
74   setOperationAction(ISD::SELECT, MVT::f64, Expand);
75   
76   // PowerPC wants to turn select_cc of FP into fsel.
77   if (FSELTMP) {
78     setOperationAction(ISD::SELECT_CC, MVT::f32, Custom);
79     setOperationAction(ISD::SELECT_CC, MVT::f64, Custom);
80   }
81
82   // PowerPC does not have BRCOND* which requires SetCC
83   setOperationAction(ISD::BRCOND,       MVT::Other, Expand);
84   setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand);
85   
86   // PowerPC does not have FP_TO_UINT
87   setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand);
88   
89   // PowerPC does not have [U|S]INT_TO_FP
90   setOperationAction(ISD::SINT_TO_FP, MVT::i32, Expand);
91   setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand);
92
93   setSetCCResultContents(ZeroOrOneSetCCResult);
94   if (!FSELTMP) {
95     addLegalFPImmediate(+0.0); // Necessary for FSEL
96     addLegalFPImmediate(-0.0); //
97   }
98   
99   computeRegisterProperties();
100 }
101
102 /// LowerOperation - Provide custom lowering hooks for some operations.
103 ///
104 SDOperand PPC32TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
105   switch (Op.getOpcode()) {
106   default: assert(0 && "Wasn't expecting to be able to lower this!"); 
107   case ISD::SELECT_CC:
108     // Turn FP only select_cc's into fsel instructions.
109     if (MVT::isFloatingPoint(Op.getOperand(0).getValueType()) &&
110         MVT::isFloatingPoint(Op.getOperand(2).getValueType())) {
111       ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
112       MVT::ValueType ResVT = Op.getValueType();
113       MVT::ValueType CmpVT = Op.getOperand(0).getValueType();
114       SDOperand LHS = Op.getOperand(0), RHS = Op.getOperand(1);
115       SDOperand TV  = Op.getOperand(2), FV  = Op.getOperand(3);
116
117       switch (CC) {
118       default: assert(0 && "Invalid FSEL condition"); abort();
119       case ISD::SETULT:
120       case ISD::SETLT:
121         return DAG.getTargetNode(PPC::FSEL, ResVT,
122                                  DAG.getNode(ISD::SUB, CmpVT, LHS, RHS), FV,TV);
123       case ISD::SETUGE:
124       case ISD::SETGE:
125         return DAG.getTargetNode(PPC::FSEL, ResVT,
126                                  DAG.getNode(ISD::SUB, CmpVT, LHS, RHS), TV,FV);
127       case ISD::SETUGT:
128       case ISD::SETGT:
129         return DAG.getTargetNode(PPC::FSEL, ResVT,
130                                  DAG.getNode(ISD::SUB, CmpVT, RHS, LHS), FV,TV);
131       case ISD::SETULE:
132       case ISD::SETLE:
133         return DAG.getTargetNode(PPC::FSEL, ResVT,
134                                  DAG.getNode(ISD::SUB, CmpVT, RHS, LHS), TV,FV);
135       }
136     }
137     break;    
138   }
139   return SDOperand();
140 }
141
142 std::vector<SDOperand>
143 PPC32TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
144   //
145   // add beautiful description of PPC stack frame format, or at least some docs
146   //
147   MachineFunction &MF = DAG.getMachineFunction();
148   MachineFrameInfo *MFI = MF.getFrameInfo();
149   MachineBasicBlock& BB = MF.front();
150   std::vector<SDOperand> ArgValues;
151   
152   // Due to the rather complicated nature of the PowerPC ABI, rather than a
153   // fixed size array of physical args, for the sake of simplicity let the STL
154   // handle tracking them for us.
155   std::vector<unsigned> argVR, argPR, argOp;
156   unsigned ArgOffset = 24;
157   unsigned GPR_remaining = 8;
158   unsigned FPR_remaining = 13;
159   unsigned GPR_idx = 0, FPR_idx = 0;
160   static const unsigned GPR[] = {
161     PPC::R3, PPC::R4, PPC::R5, PPC::R6,
162     PPC::R7, PPC::R8, PPC::R9, PPC::R10,
163   };
164   static const unsigned FPR[] = {
165     PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
166     PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13
167   };
168   
169   // Add DAG nodes to load the arguments...  On entry to a function on PPC,
170   // the arguments start at offset 24, although they are likely to be passed
171   // in registers.
172   for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) {
173     SDOperand newroot, argt;
174     unsigned ObjSize;
175     bool needsLoad = false;
176     bool ArgLive = !I->use_empty();
177     MVT::ValueType ObjectVT = getValueType(I->getType());
178     
179     switch (ObjectVT) {
180       default: assert(0 && "Unhandled argument type!");
181       case MVT::i1:
182       case MVT::i8:
183       case MVT::i16:
184       case MVT::i32:
185         ObjSize = 4;
186         if (!ArgLive) break;
187           if (GPR_remaining > 0) {
188             MF.addLiveIn(GPR[GPR_idx]);
189             argt = newroot = DAG.getCopyFromReg(DAG.getRoot(),
190                                                 GPR[GPR_idx], MVT::i32);
191             if (ObjectVT != MVT::i32)
192               argt = DAG.getNode(ISD::TRUNCATE, ObjectVT, newroot);
193           } else {
194             needsLoad = true;
195           }
196             break;
197       case MVT::i64: ObjSize = 8;
198         if (!ArgLive) break;
199           if (GPR_remaining > 0) {
200             SDOperand argHi, argLo;
201             MF.addLiveIn(GPR[GPR_idx]);
202             argHi = DAG.getCopyFromReg(DAG.getRoot(), GPR[GPR_idx], MVT::i32);
203             // If we have two or more remaining argument registers, then both halves
204             // of the i64 can be sourced from there.  Otherwise, the lower half will
205             // have to come off the stack.  This can happen when an i64 is preceded
206             // by 28 bytes of arguments.
207             if (GPR_remaining > 1) {
208               MF.addLiveIn(GPR[GPR_idx+1]);
209               argLo = DAG.getCopyFromReg(argHi, GPR[GPR_idx+1], MVT::i32);
210             } else {
211               int FI = MFI->CreateFixedObject(4, ArgOffset+4);
212               SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32);
213               argLo = DAG.getLoad(MVT::i32, DAG.getEntryNode(), FIN,
214                                   DAG.getSrcValue(NULL));
215             }
216             // Build the outgoing arg thingy
217             argt = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, argLo, argHi);
218             newroot = argLo;
219           } else {
220             needsLoad = true;
221           }
222             break;
223       case MVT::f32:
224       case MVT::f64:
225         ObjSize = (ObjectVT == MVT::f64) ? 8 : 4;
226         if (!ArgLive) break;
227           if (FPR_remaining > 0) {
228             MF.addLiveIn(FPR[FPR_idx]);
229             argt = newroot = DAG.getCopyFromReg(DAG.getRoot(), 
230                                                 FPR[FPR_idx], ObjectVT);
231             --FPR_remaining;
232             ++FPR_idx;
233           } else {
234             needsLoad = true;
235           }
236             break;
237     }
238     
239     // We need to load the argument to a virtual register if we determined above
240     // that we ran out of physical registers of the appropriate type
241     if (needsLoad) {
242       unsigned SubregOffset = 0;
243       if (ObjectVT == MVT::i8 || ObjectVT == MVT::i1) SubregOffset = 3;
244       if (ObjectVT == MVT::i16) SubregOffset = 2;
245       int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
246       SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32);
247       FIN = DAG.getNode(ISD::ADD, MVT::i32, FIN,
248                         DAG.getConstant(SubregOffset, MVT::i32));
249       argt = newroot = DAG.getLoad(ObjectVT, DAG.getEntryNode(), FIN,
250                                    DAG.getSrcValue(NULL));
251     }
252     
253     // Every 4 bytes of argument space consumes one of the GPRs available for
254     // argument passing.
255     if (GPR_remaining > 0) {
256       unsigned delta = (GPR_remaining > 1 && ObjSize == 8) ? 2 : 1;
257       GPR_remaining -= delta;
258       GPR_idx += delta;
259     }
260     ArgOffset += ObjSize;
261     if (newroot.Val)
262       DAG.setRoot(newroot.getValue(1));
263     
264     ArgValues.push_back(argt);
265   }
266   
267   // If the function takes variable number of arguments, make a frame index for
268   // the start of the first vararg value... for expansion of llvm.va_start.
269   if (F.isVarArg()) {
270     VarArgsFrameIndex = MFI->CreateFixedObject(4, ArgOffset);
271     SDOperand FIN = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32);
272     // If this function is vararg, store any remaining integer argument regs
273     // to their spots on the stack so that they may be loaded by deferencing the
274     // result of va_next.
275     std::vector<SDOperand> MemOps;
276     for (; GPR_remaining > 0; --GPR_remaining, ++GPR_idx) {
277       MF.addLiveIn(GPR[GPR_idx]);
278       SDOperand Val = DAG.getCopyFromReg(DAG.getRoot(), GPR[GPR_idx], MVT::i32);
279       SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1),
280                                     Val, FIN, DAG.getSrcValue(NULL));
281       MemOps.push_back(Store);
282       // Increment the address by four for the next argument to store
283       SDOperand PtrOff = DAG.getConstant(4, getPointerTy());
284       FIN = DAG.getNode(ISD::ADD, MVT::i32, FIN, PtrOff);
285     }
286     DAG.setRoot(DAG.getNode(ISD::TokenFactor, MVT::Other, MemOps));
287   }
288   
289   // Finally, inform the code generator which regs we return values in.
290   switch (getValueType(F.getReturnType())) {
291     default: assert(0 && "Unknown type!");
292     case MVT::isVoid: break;
293     case MVT::i1:
294     case MVT::i8:
295     case MVT::i16:
296     case MVT::i32:
297       MF.addLiveOut(PPC::R3);
298       break;
299     case MVT::i64:
300       MF.addLiveOut(PPC::R3);
301       MF.addLiveOut(PPC::R4);
302       break;
303     case MVT::f32:
304     case MVT::f64:
305       MF.addLiveOut(PPC::F1);
306       break;
307   }
308   
309   return ArgValues;
310 }
311
312 std::pair<SDOperand, SDOperand>
313 PPC32TargetLowering::LowerCallTo(SDOperand Chain,
314                                  const Type *RetTy, bool isVarArg,
315                                  unsigned CallingConv, bool isTailCall,
316                                  SDOperand Callee, ArgListTy &Args,
317                                  SelectionDAG &DAG) {
318   // args_to_use will accumulate outgoing args for the ISD::CALL case in
319   // SelectExpr to use to put the arguments in the appropriate registers.
320   std::vector<SDOperand> args_to_use;
321   
322   // Count how many bytes are to be pushed on the stack, including the linkage
323   // area, and parameter passing area.
324   unsigned NumBytes = 24;
325   
326   if (Args.empty()) {
327     Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain,
328                         DAG.getConstant(NumBytes, getPointerTy()));
329   } else {
330     for (unsigned i = 0, e = Args.size(); i != e; ++i)
331       switch (getValueType(Args[i].second)) {
332         default: assert(0 && "Unknown value type!");
333         case MVT::i1:
334         case MVT::i8:
335         case MVT::i16:
336         case MVT::i32:
337         case MVT::f32:
338           NumBytes += 4;
339           break;
340         case MVT::i64:
341         case MVT::f64:
342           NumBytes += 8;
343           break;
344       }
345         
346         // Just to be safe, we'll always reserve the full 24 bytes of linkage area
347         // plus 32 bytes of argument space in case any called code gets funky on us.
348         // (Required by ABI to support var arg)
349         if (NumBytes < 56) NumBytes = 56;
350     
351     // Adjust the stack pointer for the new arguments...
352     // These operations are automatically eliminated by the prolog/epilog pass
353     Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain,
354                         DAG.getConstant(NumBytes, getPointerTy()));
355     
356     // Set up a copy of the stack pointer for use loading and storing any
357     // arguments that may not fit in the registers available for argument
358     // passing.
359     SDOperand StackPtr = DAG.getCopyFromReg(DAG.getEntryNode(),
360                                             PPC::R1, MVT::i32);
361     
362     // Figure out which arguments are going to go in registers, and which in
363     // memory.  Also, if this is a vararg function, floating point operations
364     // must be stored to our stack, and loaded into integer regs as well, if
365     // any integer regs are available for argument passing.
366     unsigned ArgOffset = 24;
367     unsigned GPR_remaining = 8;
368     unsigned FPR_remaining = 13;
369     
370     std::vector<SDOperand> MemOps;
371     for (unsigned i = 0, e = Args.size(); i != e; ++i) {
372       // PtrOff will be used to store the current argument to the stack if a
373       // register cannot be found for it.
374       SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
375       PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff);
376       MVT::ValueType ArgVT = getValueType(Args[i].second);
377       
378       switch (ArgVT) {
379         default: assert(0 && "Unexpected ValueType for argument!");
380         case MVT::i1:
381         case MVT::i8:
382         case MVT::i16:
383           // Promote the integer to 32 bits.  If the input type is signed use a
384           // sign extend, otherwise use a zero extend.
385           if (Args[i].second->isSigned())
386             Args[i].first =DAG.getNode(ISD::SIGN_EXTEND, MVT::i32, Args[i].first);
387           else
388             Args[i].first =DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Args[i].first);
389           // FALL THROUGH
390         case MVT::i32:
391           if (GPR_remaining > 0) {
392             args_to_use.push_back(Args[i].first);
393             --GPR_remaining;
394           } else {
395             MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
396                                          Args[i].first, PtrOff,
397                                          DAG.getSrcValue(NULL)));
398           }
399           ArgOffset += 4;
400           break;
401         case MVT::i64:
402           // If we have one free GPR left, we can place the upper half of the i64
403           // in it, and store the other half to the stack.  If we have two or more
404           // free GPRs, then we can pass both halves of the i64 in registers.
405           if (GPR_remaining > 0) {
406             SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32,
407                                        Args[i].first, DAG.getConstant(1, MVT::i32));
408             SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32,
409                                        Args[i].first, DAG.getConstant(0, MVT::i32));
410             args_to_use.push_back(Hi);
411             --GPR_remaining;
412             if (GPR_remaining > 0) {
413               args_to_use.push_back(Lo);
414               --GPR_remaining;
415             } else {
416               SDOperand ConstFour = DAG.getConstant(4, getPointerTy());
417               PtrOff = DAG.getNode(ISD::ADD, MVT::i32, PtrOff, ConstFour);
418               MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
419                                            Lo, PtrOff, DAG.getSrcValue(NULL)));
420             }
421           } else {
422             MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
423                                          Args[i].first, PtrOff,
424                                          DAG.getSrcValue(NULL)));
425           }
426           ArgOffset += 8;
427           break;
428         case MVT::f32:
429         case MVT::f64:
430           if (FPR_remaining > 0) {
431             args_to_use.push_back(Args[i].first);
432             --FPR_remaining;
433             if (isVarArg) {
434               SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Chain,
435                                             Args[i].first, PtrOff,
436                                             DAG.getSrcValue(NULL));
437               MemOps.push_back(Store);
438               // Float varargs are always shadowed in available integer registers
439               if (GPR_remaining > 0) {
440                 SDOperand Load = DAG.getLoad(MVT::i32, Store, PtrOff,
441                                              DAG.getSrcValue(NULL));
442                 MemOps.push_back(Load);
443                 args_to_use.push_back(Load);
444                 --GPR_remaining;
445               }
446               if (GPR_remaining > 0 && MVT::f64 == ArgVT) {
447                 SDOperand ConstFour = DAG.getConstant(4, getPointerTy());
448                 PtrOff = DAG.getNode(ISD::ADD, MVT::i32, PtrOff, ConstFour);
449                 SDOperand Load = DAG.getLoad(MVT::i32, Store, PtrOff,
450                                              DAG.getSrcValue(NULL));
451                 MemOps.push_back(Load);
452                 args_to_use.push_back(Load);
453                 --GPR_remaining;
454               }
455             } else {
456               // If we have any FPRs remaining, we may also have GPRs remaining.
457               // Args passed in FPRs consume either 1 (f32) or 2 (f64) available
458               // GPRs.
459               if (GPR_remaining > 0) {
460                 args_to_use.push_back(DAG.getNode(ISD::UNDEF, MVT::i32));
461                 --GPR_remaining;
462               }
463               if (GPR_remaining > 0 && MVT::f64 == ArgVT) {
464                 args_to_use.push_back(DAG.getNode(ISD::UNDEF, MVT::i32));
465                 --GPR_remaining;
466               }
467             }
468           } else {
469             MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
470                                          Args[i].first, PtrOff,
471                                          DAG.getSrcValue(NULL)));
472           }
473           ArgOffset += (ArgVT == MVT::f32) ? 4 : 8;
474           break;
475       }
476     }
477     if (!MemOps.empty())
478       Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, MemOps);
479   }
480   
481   std::vector<MVT::ValueType> RetVals;
482   MVT::ValueType RetTyVT = getValueType(RetTy);
483   if (RetTyVT != MVT::isVoid)
484     RetVals.push_back(RetTyVT);
485   RetVals.push_back(MVT::Other);
486   
487   SDOperand TheCall = SDOperand(DAG.getCall(RetVals,
488                                             Chain, Callee, args_to_use), 0);
489   Chain = TheCall.getValue(RetTyVT != MVT::isVoid);
490   Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, Chain,
491                       DAG.getConstant(NumBytes, getPointerTy()));
492   return std::make_pair(TheCall, Chain);
493 }
494
495 SDOperand PPC32TargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP,
496                                             Value *VAListV, SelectionDAG &DAG) {
497   // vastart just stores the address of the VarArgsFrameIndex slot into the
498   // memory location argument.
499   SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32);
500   return DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, VAListP,
501                      DAG.getSrcValue(VAListV));
502 }
503
504 std::pair<SDOperand,SDOperand>
505 PPC32TargetLowering::LowerVAArg(SDOperand Chain,
506                                 SDOperand VAListP, Value *VAListV,
507                                 const Type *ArgTy, SelectionDAG &DAG) {
508   MVT::ValueType ArgVT = getValueType(ArgTy);
509   
510   SDOperand VAList =
511     DAG.getLoad(MVT::i32, Chain, VAListP, DAG.getSrcValue(VAListV));
512   SDOperand Result = DAG.getLoad(ArgVT, Chain, VAList, DAG.getSrcValue(NULL));
513   unsigned Amt;
514   if (ArgVT == MVT::i32 || ArgVT == MVT::f32)
515     Amt = 4;
516   else {
517     assert((ArgVT == MVT::i64 || ArgVT == MVT::f64) &&
518            "Other types should have been promoted for varargs!");
519     Amt = 8;
520   }
521   VAList = DAG.getNode(ISD::ADD, VAList.getValueType(), VAList,
522                        DAG.getConstant(Amt, VAList.getValueType()));
523   Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain,
524                       VAList, VAListP, DAG.getSrcValue(VAListV));
525   return std::make_pair(Result, Chain);
526 }
527
528
529 std::pair<SDOperand, SDOperand> PPC32TargetLowering::
530 LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
531                         SelectionDAG &DAG) {
532   assert(0 && "LowerFrameReturnAddress unimplemented");
533   abort();
534 }