Add all the rest of the ADD and SUB variants, some of which are important for
[oota-llvm.git] / lib / Target / SparcV8 / SparcV8ISelSimple.cpp
1 //===-- InstSelectSimple.cpp - A simple instruction selector for SparcV8 --===//
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 // 
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines a simple peephole instruction selector for the V8 target
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "SparcV8.h"
15 #include "SparcV8InstrInfo.h"
16 #include "llvm/Support/Debug.h"
17 #include "llvm/Instructions.h"
18 #include "llvm/Pass.h"
19 #include "llvm/Constants.h"
20 #include "llvm/CodeGen/IntrinsicLowering.h"
21 #include "llvm/CodeGen/MachineInstrBuilder.h"
22 #include "llvm/CodeGen/MachineFrameInfo.h"
23 #include "llvm/CodeGen/MachineConstantPool.h"
24 #include "llvm/CodeGen/MachineFunction.h"
25 #include "llvm/CodeGen/SSARegMap.h"
26 #include "llvm/Target/TargetMachine.h"
27 #include "llvm/Support/GetElementPtrTypeIterator.h"
28 #include "llvm/Support/InstVisitor.h"
29 #include "llvm/Support/CFG.h"
30 using namespace llvm;
31
32 namespace {
33   struct V8ISel : public FunctionPass, public InstVisitor<V8ISel> {
34     TargetMachine &TM;
35     MachineFunction *F;                 // The function we are compiling into
36     MachineBasicBlock *BB;              // The current MBB we are compiling
37     int VarArgsOffset;                  // Offset from fp for start of varargs area
38
39     std::map<Value*, unsigned> RegMap;  // Mapping between Val's and SSA Regs
40
41     // MBBMap - Mapping between LLVM BB -> Machine BB
42     std::map<const BasicBlock*, MachineBasicBlock*> MBBMap;
43
44     V8ISel(TargetMachine &tm) : TM(tm), F(0), BB(0) {}
45
46     /// runOnFunction - Top level implementation of instruction selection for
47     /// the entire function.
48     ///
49     bool runOnFunction(Function &Fn);
50
51     virtual const char *getPassName() const {
52       return "SparcV8 Simple Instruction Selection";
53     }
54
55     /// emitGEPOperation - Common code shared between visitGetElementPtrInst and
56     /// constant expression GEP support.
57     ///
58     void emitGEPOperation(MachineBasicBlock *BB, MachineBasicBlock::iterator IP,
59                           Value *Src, User::op_iterator IdxBegin,
60                           User::op_iterator IdxEnd, unsigned TargetReg);
61
62     /// emitCastOperation - Common code shared between visitCastInst and
63     /// constant expression cast support.
64     ///
65     void emitCastOperation(MachineBasicBlock *BB,MachineBasicBlock::iterator IP,
66                            Value *Src, const Type *DestTy, unsigned TargetReg);
67
68     /// emitIntegerCast, emitFPToIntegerCast - Helper methods for
69     /// emitCastOperation.
70     ///
71     unsigned emitIntegerCast (MachineBasicBlock *BB,
72                               MachineBasicBlock::iterator IP,
73                               const Type *oldTy, unsigned SrcReg,
74                               const Type *newTy, unsigned DestReg);
75     void emitFPToIntegerCast (MachineBasicBlock *BB,
76                               MachineBasicBlock::iterator IP, const Type *oldTy,
77                               unsigned SrcReg, const Type *newTy,
78                               unsigned DestReg);
79
80     /// visitBasicBlock - This method is called when we are visiting a new basic
81     /// block.  This simply creates a new MachineBasicBlock to emit code into
82     /// and adds it to the current MachineFunction.  Subsequent visit* for
83     /// instructions will be invoked for all instructions in the basic block.
84     ///
85     void visitBasicBlock(BasicBlock &LLVM_BB) {
86       BB = MBBMap[&LLVM_BB];
87     }
88
89     void emitOp64LibraryCall (MachineBasicBlock *MBB,
90                               MachineBasicBlock::iterator IP,
91                               unsigned DestReg, const char *FuncName,
92                               unsigned Op0Reg, unsigned Op1Reg);
93     void visitBinaryOperator(Instruction &I);
94     void visitShiftInst (ShiftInst &SI) { visitBinaryOperator (SI); }
95     void visitSetCondInst(SetCondInst &I);
96     void visitCallInst(CallInst &I);
97     void visitReturnInst(ReturnInst &I);
98     void visitBranchInst(BranchInst &I);
99     void visitUnreachableInst(UnreachableInst &I) {}
100     void visitCastInst(CastInst &I);
101     void visitVANextInst(VANextInst &I);
102     void visitVAArgInst(VAArgInst &I);
103     void visitLoadInst(LoadInst &I);
104     void visitStoreInst(StoreInst &I);
105     void visitPHINode(PHINode &I) {}      // PHI nodes handled by second pass
106     void visitGetElementPtrInst(GetElementPtrInst &I);
107     void visitAllocaInst(AllocaInst &I);
108
109     void visitInstruction(Instruction &I) {
110       std::cerr << "Unhandled instruction: " << I;
111       abort();
112     }
113
114     /// LowerUnknownIntrinsicFunctionCalls - This performs a prepass over the
115     /// function, lowering any calls to unknown intrinsic functions into the
116     /// equivalent LLVM code.
117     void LowerUnknownIntrinsicFunctionCalls(Function &F);
118     void visitIntrinsicCall(Intrinsic::ID ID, CallInst &CI);
119
120     void LoadArgumentsToVirtualRegs(Function *F);
121
122     /// SelectPHINodes - Insert machine code to generate phis.  This is tricky
123     /// because we have to generate our sources into the source basic blocks,
124     /// not the current one.
125     ///
126     void SelectPHINodes();
127
128     /// copyConstantToRegister - Output the instructions required to put the
129     /// specified constant into the specified register.
130     ///
131     void copyConstantToRegister(MachineBasicBlock *MBB,
132                                 MachineBasicBlock::iterator IP,
133                                 Constant *C, unsigned R);
134
135     /// makeAnotherReg - This method returns the next register number we haven't
136     /// yet used.
137     ///
138     /// Long values are handled somewhat specially.  They are always allocated
139     /// as pairs of 32 bit integer values.  The register number returned is the
140     /// lower 32 bits of the long value, and the regNum+1 is the upper 32 bits
141     /// of the long value.
142     ///
143     unsigned makeAnotherReg(const Type *Ty) {
144       assert(dynamic_cast<const SparcV8RegisterInfo*>(TM.getRegisterInfo()) &&
145              "Current target doesn't have SparcV8 reg info??");
146       const SparcV8RegisterInfo *MRI =
147         static_cast<const SparcV8RegisterInfo*>(TM.getRegisterInfo());
148       if (Ty == Type::LongTy || Ty == Type::ULongTy) {
149         const TargetRegisterClass *RC = MRI->getRegClassForType(Type::IntTy);
150         // Create the lower part
151         F->getSSARegMap()->createVirtualRegister(RC);
152         // Create the upper part.
153         return F->getSSARegMap()->createVirtualRegister(RC)-1;
154       }
155
156       // Add the mapping of regnumber => reg class to MachineFunction
157       const TargetRegisterClass *RC = MRI->getRegClassForType(Ty);
158       return F->getSSARegMap()->createVirtualRegister(RC);
159     }
160
161     unsigned getReg(Value &V) { return getReg (&V); } // allow refs.
162     unsigned getReg(Value *V) {
163       // Just append to the end of the current bb.
164       MachineBasicBlock::iterator It = BB->end();
165       return getReg(V, BB, It);
166     }
167     unsigned getReg(Value *V, MachineBasicBlock *MBB,
168                     MachineBasicBlock::iterator IPt) {
169       unsigned &Reg = RegMap[V];
170       if (Reg == 0) {
171         Reg = makeAnotherReg(V->getType());
172         RegMap[V] = Reg;
173       }
174       // If this operand is a constant, emit the code to copy the constant into
175       // the register here...
176       //
177       if (Constant *C = dyn_cast<Constant>(V)) {
178         copyConstantToRegister(MBB, IPt, C, Reg);
179         RegMap.erase(V);  // Assign a new name to this constant if ref'd again
180       } else if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
181         // Move the address of the global into the register
182         unsigned TmpReg = makeAnotherReg(V->getType());
183         BuildMI (*MBB, IPt, V8::SETHIi, 1, TmpReg).addGlobalAddress (GV);
184         BuildMI (*MBB, IPt, V8::ORri, 2, Reg).addReg (TmpReg)
185           .addGlobalAddress (GV);
186         RegMap.erase(V);  // Assign a new name to this address if ref'd again
187       }
188
189       return Reg;
190     }
191
192   };
193 }
194
195 FunctionPass *llvm::createSparcV8SimpleInstructionSelector(TargetMachine &TM) {
196   return new V8ISel(TM);
197 }
198
199 enum TypeClass {
200   cByte, cShort, cInt, cLong, cFloat, cDouble
201 };
202
203 static TypeClass getClass (const Type *T) {
204   switch (T->getTypeID()) {
205     case Type::UByteTyID:  case Type::SByteTyID:  return cByte;
206     case Type::UShortTyID: case Type::ShortTyID:  return cShort;
207     case Type::PointerTyID:
208     case Type::UIntTyID:   case Type::IntTyID:    return cInt;
209     case Type::ULongTyID:  case Type::LongTyID:   return cLong;
210     case Type::FloatTyID:                         return cFloat;
211     case Type::DoubleTyID:                        return cDouble;
212     default:
213       assert (0 && "Type of unknown class passed to getClass?");
214       return cByte;
215   }
216 }
217
218 static TypeClass getClassB(const Type *T) {
219   if (T == Type::BoolTy) return cByte;
220   return getClass(T);
221 }
222
223 /// copyConstantToRegister - Output the instructions required to put the
224 /// specified constant into the specified register.
225 ///
226 void V8ISel::copyConstantToRegister(MachineBasicBlock *MBB,
227                                     MachineBasicBlock::iterator IP,
228                                     Constant *C, unsigned R) {
229   if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
230     switch (CE->getOpcode()) {
231     case Instruction::GetElementPtr:
232       emitGEPOperation(MBB, IP, CE->getOperand(0),
233                        CE->op_begin()+1, CE->op_end(), R);
234       return;
235     case Instruction::Cast:
236       emitCastOperation(MBB, IP, CE->getOperand(0), CE->getType(), R);
237       return;
238     default:
239       std::cerr << "Copying this constant expr not yet handled: " << *CE;
240       abort();
241     }
242   } else if (isa<UndefValue>(C)) {
243     BuildMI(*MBB, IP, V8::IMPLICIT_DEF, 0, R);
244     if (getClassB (C->getType ()) == cLong)
245       BuildMI(*MBB, IP, V8::IMPLICIT_DEF, 0, R+1);
246     return;
247   }
248
249   if (C->getType()->isIntegral ()) {
250     uint64_t Val;
251     unsigned Class = getClassB (C->getType ());
252     if (Class == cLong) {
253       unsigned TmpReg = makeAnotherReg (Type::IntTy);
254       unsigned TmpReg2 = makeAnotherReg (Type::IntTy);
255       // Copy the value into the register pair.
256       // R = top(more-significant) half, R+1 = bottom(less-significant) half
257       uint64_t Val = cast<ConstantInt>(C)->getRawValue();
258       copyConstantToRegister(MBB, IP, ConstantUInt::get(Type::UIntTy,
259                              Val >> 32), R);
260       copyConstantToRegister(MBB, IP, ConstantUInt::get(Type::UIntTy,
261                              Val & 0xffffffffU), R+1);
262       return;
263     }
264
265     assert(Class <= cInt && "Type not handled yet!");
266
267     if (C->getType() == Type::BoolTy) {
268       Val = (C == ConstantBool::True);
269     } else {
270       ConstantInt *CI = cast<ConstantInt> (C);
271       Val = CI->getRawValue ();
272     }
273     switch (Class) {
274       case cByte:  Val =  (int8_t) Val; break;
275       case cShort: Val = (int16_t) Val; break;
276       case cInt:   Val = (int32_t) Val; break;
277       default:
278         std::cerr << "Offending constant: " << *C << "\n";
279         assert (0 && "Can't copy this kind of constant into register yet");
280         return;
281     }
282     if (Val == 0) {
283       BuildMI (*MBB, IP, V8::ORrr, 2, R).addReg (V8::G0).addReg(V8::G0);
284     } else if (((int64_t)Val >= -4096) && ((int64_t)Val <= 4095)) {
285       BuildMI (*MBB, IP, V8::ORri, 2, R).addReg (V8::G0).addSImm(Val);
286     } else {
287       unsigned TmpReg = makeAnotherReg (C->getType ());
288       BuildMI (*MBB, IP, V8::SETHIi, 1, TmpReg)
289         .addSImm (((uint32_t) Val) >> 10);
290       BuildMI (*MBB, IP, V8::ORri, 2, R).addReg (TmpReg)
291         .addSImm (((uint32_t) Val) & 0x03ff);
292       return;
293     }
294   } else if (ConstantFP *CFP = dyn_cast<ConstantFP>(C)) {
295     // We need to spill the constant to memory...
296     MachineConstantPool *CP = F->getConstantPool();
297     unsigned CPI = CP->getConstantPoolIndex(CFP);
298     const Type *Ty = CFP->getType();
299     unsigned TmpReg = makeAnotherReg (Type::UIntTy);
300     unsigned AddrReg = makeAnotherReg (Type::UIntTy);
301
302     assert(Ty == Type::FloatTy || Ty == Type::DoubleTy && "Unknown FP type!");
303     unsigned LoadOpcode = Ty == Type::FloatTy ? V8::LDFri : V8::LDDFri;
304     BuildMI (*MBB, IP, V8::SETHIi, 1, TmpReg).addConstantPoolIndex (CPI);
305     BuildMI (*MBB, IP, V8::ORri, 2, AddrReg).addReg (TmpReg)
306       .addConstantPoolIndex (CPI);
307     BuildMI (*MBB, IP, LoadOpcode, 2, R).addReg (AddrReg).addSImm (0);
308   } else if (isa<ConstantPointerNull>(C)) {
309     // Copy zero (null pointer) to the register.
310     BuildMI (*MBB, IP, V8::ORri, 2, R).addReg (V8::G0).addSImm (0);
311   } else if (GlobalValue *GV = dyn_cast<GlobalValue>(C)) {
312     // Copy it with a SETHI/OR pair; the JIT + asmwriter should recognize
313     // that SETHI %reg,global == SETHI %reg,%hi(global) and 
314     // OR %reg,global,%reg == OR %reg,%lo(global),%reg.
315     unsigned TmpReg = makeAnotherReg (C->getType ());
316     BuildMI (*MBB, IP, V8::SETHIi, 1, TmpReg).addGlobalAddress(GV);
317     BuildMI (*MBB, IP, V8::ORri, 2, R).addReg(TmpReg).addGlobalAddress(GV);
318   } else {
319     std::cerr << "Offending constant: " << *C << "\n";
320     assert (0 && "Can't copy this kind of constant into register yet");
321   }
322 }
323
324 void V8ISel::LoadArgumentsToVirtualRegs (Function *LF) {
325   static const unsigned IncomingArgRegs[] = { V8::I0, V8::I1, V8::I2,
326     V8::I3, V8::I4, V8::I5 };
327
328   // Add IMPLICIT_DEFs of input regs.
329   unsigned ArgNo = 0;
330   for (Function::aiterator I = LF->abegin(), E = LF->aend();
331        I != E && ArgNo < 6; ++I, ++ArgNo) {
332     switch (getClassB(I->getType())) {
333     case cByte:
334     case cShort:
335     case cInt:
336     case cFloat:
337       BuildMI(BB, V8::IMPLICIT_DEF, 0, IncomingArgRegs[ArgNo]);
338       break;
339     case cDouble:
340     case cLong:
341       // Double and Long use register pairs.
342       BuildMI(BB, V8::IMPLICIT_DEF, 0, IncomingArgRegs[ArgNo]);
343       ++ArgNo;
344       if (ArgNo < 6)
345         BuildMI(BB, V8::IMPLICIT_DEF, 0, IncomingArgRegs[ArgNo]);
346       break;
347     default:
348       assert (0 && "type not handled");
349       return;
350     }
351   }
352
353   const unsigned *IAREnd = &IncomingArgRegs[6];
354   const unsigned *IAR = &IncomingArgRegs[0];
355   unsigned ArgOffset = 68;
356
357   // Store registers onto stack if this is a varargs function. 
358   // FIXME: This doesn't really pertain to "loading arguments into
359   // virtual registers", so it's not clear that it really belongs here.
360   // FIXME: We could avoid storing any args onto the stack that don't 
361   // need to be in memory, because they come before the ellipsis in the
362   // parameter list (and thus could never be accessed through va_arg).
363   if (LF->getFunctionType ()->isVarArg ()) {
364     for (unsigned i = 0; i < 6; ++i) {
365       int FI = F->getFrameInfo()->CreateFixedObject(4, ArgOffset);
366       assert (IAR != IAREnd
367               && "About to dereference past end of IncomingArgRegs");
368       BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (0).addReg (*IAR++);
369       ArgOffset += 4;
370     }
371     // Reset the pointers now that we're done.
372     ArgOffset = 68;
373     IAR = &IncomingArgRegs[0];
374   }
375
376   // Copy args out of their incoming hard regs or stack slots into virtual regs.
377   for (Function::aiterator I = LF->abegin(), E = LF->aend(); I != E; ++I) {
378     Argument &A = *I;
379     unsigned ArgReg = getReg (A);
380     if (getClassB (A.getType ()) < cLong) {
381       // Get it out of the incoming arg register
382       if (ArgOffset < 92) {
383         assert (IAR != IAREnd
384                 && "About to dereference past end of IncomingArgRegs");
385         BuildMI (BB, V8::ORrr, 2, ArgReg).addReg (V8::G0).addReg (*IAR++);
386       } else {
387         int FI = F->getFrameInfo()->CreateFixedObject(4, ArgOffset);
388         BuildMI (BB, V8::LD, 3, ArgReg).addFrameIndex (FI).addSImm (0);
389       }
390       ArgOffset += 4;
391     } else if (getClassB (A.getType ()) == cFloat) {
392       if (ArgOffset < 92) {
393         // Single-fp args are passed in integer registers; go through
394         // memory to get them out of integer registers and back into fp. (Bleh!)
395         unsigned FltAlign = TM.getTargetData().getFloatAlignment();
396         int FI = F->getFrameInfo()->CreateStackObject(4, FltAlign);
397         assert (IAR != IAREnd
398                 && "About to dereference past end of IncomingArgRegs");
399         BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (0).addReg (*IAR++);
400         BuildMI (BB, V8::LDFri, 2, ArgReg).addFrameIndex (FI).addSImm (0);
401       } else {
402         int FI = F->getFrameInfo()->CreateFixedObject(4, ArgOffset);
403         BuildMI (BB, V8::LDFri, 3, ArgReg).addFrameIndex (FI).addSImm (0);
404       }
405       ArgOffset += 4;
406     } else if (getClassB (A.getType ()) == cDouble) {
407       // Double-fp args are passed in pairs of integer registers; go through
408       // memory to get them out of integer registers and back into fp. (Bleh!)
409       // We'd like to 'ldd' these right out of the incoming-args area,
410       // but it might not be 8-byte aligned (e.g., call x(int x, double d)).
411       unsigned DblAlign = TM.getTargetData().getDoubleAlignment();
412       int FI = F->getFrameInfo()->CreateStackObject(8, DblAlign);
413       if (ArgOffset < 92 && IAR != IAREnd) {
414         BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (0).addReg (*IAR++);
415       } else {
416         unsigned TempReg = makeAnotherReg (Type::IntTy);
417         BuildMI (BB, V8::LD, 2, TempReg).addFrameIndex (FI).addSImm (0);
418         BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (0).addReg (TempReg);
419       }
420       ArgOffset += 4;
421       if (ArgOffset < 92 && IAR != IAREnd) {
422         BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (4).addReg (*IAR++);
423       } else {
424         unsigned TempReg = makeAnotherReg (Type::IntTy);
425         BuildMI (BB, V8::LD, 2, TempReg).addFrameIndex (FI).addSImm (4);
426         BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (4).addReg (TempReg);
427       }
428       ArgOffset += 4;
429       BuildMI (BB, V8::LDDFri, 2, ArgReg).addFrameIndex (FI).addSImm (0);
430     } else if (getClassB (A.getType ()) == cLong) {
431       // do the first half...
432       if (ArgOffset < 92) {
433         assert (IAR != IAREnd
434                 && "About to dereference past end of IncomingArgRegs");
435         BuildMI (BB, V8::ORrr, 2, ArgReg).addReg (V8::G0).addReg (*IAR++);
436       } else {
437         int FI = F->getFrameInfo()->CreateFixedObject(4, ArgOffset);
438         BuildMI (BB, V8::LD, 2, ArgReg).addFrameIndex (FI).addSImm (0);
439       }
440       ArgOffset += 4;
441       // ...then do the second half
442       if (ArgOffset < 92) {
443         assert (IAR != IAREnd
444                 && "About to dereference past end of IncomingArgRegs");
445         BuildMI (BB, V8::ORrr, 2, ArgReg+1).addReg (V8::G0).addReg (*IAR++);
446       } else {
447         int FI = F->getFrameInfo()->CreateFixedObject(4, ArgOffset);
448         BuildMI (BB, V8::LD, 2, ArgReg+1).addFrameIndex (FI).addSImm (0);
449       }
450       ArgOffset += 4;
451     } else {
452       assert (0 && "Unknown class?!");
453     }
454   }
455
456   // If the function takes variable number of arguments, remember the fp
457   // offset for the start of the first vararg value... this is used to expand
458   // llvm.va_start.
459   if (LF->getFunctionType ()->isVarArg ())
460     VarArgsOffset = ArgOffset;
461 }
462
463 void V8ISel::SelectPHINodes() {
464   const TargetInstrInfo &TII = *TM.getInstrInfo();
465   const Function &LF = *F->getFunction();  // The LLVM function...
466   for (Function::const_iterator I = LF.begin(), E = LF.end(); I != E; ++I) {
467     const BasicBlock *BB = I;
468     MachineBasicBlock &MBB = *MBBMap[I];
469
470     // Loop over all of the PHI nodes in the LLVM basic block...
471     MachineBasicBlock::iterator PHIInsertPoint = MBB.begin();
472     for (BasicBlock::const_iterator I = BB->begin();
473          PHINode *PN = const_cast<PHINode*>(dyn_cast<PHINode>(I)); ++I) {
474
475       // Create a new machine instr PHI node, and insert it.
476       unsigned PHIReg = getReg(*PN);
477       MachineInstr *PhiMI = BuildMI(MBB, PHIInsertPoint,
478                                     V8::PHI, PN->getNumOperands(), PHIReg);
479
480       MachineInstr *LongPhiMI = 0;
481       if (PN->getType() == Type::LongTy || PN->getType() == Type::ULongTy)
482         LongPhiMI = BuildMI(MBB, PHIInsertPoint,
483                             V8::PHI, PN->getNumOperands(), PHIReg+1);
484
485       // PHIValues - Map of blocks to incoming virtual registers.  We use this
486       // so that we only initialize one incoming value for a particular block,
487       // even if the block has multiple entries in the PHI node.
488       //
489       std::map<MachineBasicBlock*, unsigned> PHIValues;
490
491       for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
492         MachineBasicBlock *PredMBB = 0;
493         for (MachineBasicBlock::pred_iterator PI = MBB.pred_begin (),
494              PE = MBB.pred_end (); PI != PE; ++PI)
495           if (PN->getIncomingBlock(i) == (*PI)->getBasicBlock()) {
496             PredMBB = *PI;
497             break;
498           }
499         assert (PredMBB && "Couldn't find incoming machine-cfg edge for phi");
500         
501         unsigned ValReg;
502         std::map<MachineBasicBlock*, unsigned>::iterator EntryIt =
503           PHIValues.lower_bound(PredMBB);
504
505         if (EntryIt != PHIValues.end() && EntryIt->first == PredMBB) {
506           // We already inserted an initialization of the register for this
507           // predecessor.  Recycle it.
508           ValReg = EntryIt->second;
509
510         } else {        
511           // Get the incoming value into a virtual register.
512           //
513           Value *Val = PN->getIncomingValue(i);
514
515           // If this is a constant or GlobalValue, we may have to insert code
516           // into the basic block to compute it into a virtual register.
517           if ((isa<Constant>(Val) && !isa<ConstantExpr>(Val)) ||
518               isa<GlobalValue>(Val)) {
519             // Simple constants get emitted at the end of the basic block,
520             // before any terminator instructions.  We "know" that the code to
521             // move a constant into a register will never clobber any flags.
522             ValReg = getReg(Val, PredMBB, PredMBB->getFirstTerminator());
523           } else {
524             // Because we don't want to clobber any values which might be in
525             // physical registers with the computation of this constant (which
526             // might be arbitrarily complex if it is a constant expression),
527             // just insert the computation at the top of the basic block.
528             MachineBasicBlock::iterator PI = PredMBB->begin();
529             
530             // Skip over any PHI nodes though!
531             while (PI != PredMBB->end() && PI->getOpcode() == V8::PHI)
532               ++PI;
533             
534             ValReg = getReg(Val, PredMBB, PI);
535           }
536
537           // Remember that we inserted a value for this PHI for this predecessor
538           PHIValues.insert(EntryIt, std::make_pair(PredMBB, ValReg));
539         }
540
541         PhiMI->addRegOperand(ValReg);
542         PhiMI->addMachineBasicBlockOperand(PredMBB);
543         if (LongPhiMI) {
544           LongPhiMI->addRegOperand(ValReg+1);
545           LongPhiMI->addMachineBasicBlockOperand(PredMBB);
546         }
547       }
548
549       // Now that we emitted all of the incoming values for the PHI node, make
550       // sure to reposition the InsertPoint after the PHI that we just added.
551       // This is needed because we might have inserted a constant into this
552       // block, right after the PHI's which is before the old insert point!
553       PHIInsertPoint = LongPhiMI ? LongPhiMI : PhiMI;
554       ++PHIInsertPoint;
555     }
556   }
557 }
558
559 bool V8ISel::runOnFunction(Function &Fn) {
560   // First pass over the function, lower any unknown intrinsic functions
561   // with the IntrinsicLowering class.
562   LowerUnknownIntrinsicFunctionCalls(Fn);
563   
564   F = &MachineFunction::construct(&Fn, TM);
565   
566   // Create all of the machine basic blocks for the function...
567   for (Function::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I)
568     F->getBasicBlockList().push_back(MBBMap[I] = new MachineBasicBlock(I));
569   
570   BB = &F->front();
571   
572   // Set up a frame object for the return address.  This is used by the
573   // llvm.returnaddress & llvm.frameaddress intrinisics.
574   //ReturnAddressIndex = F->getFrameInfo()->CreateFixedObject(4, -4);
575   
576   // Copy incoming arguments off of the stack and out of fixed registers.
577   LoadArgumentsToVirtualRegs(&Fn);
578   
579   // Instruction select everything except PHI nodes
580   visit(Fn);
581   
582   // Select the PHI nodes
583   SelectPHINodes();
584   
585   RegMap.clear();
586   MBBMap.clear();
587   F = 0;
588   // We always build a machine code representation for the function
589   return true;
590 }
591
592 void V8ISel::visitCastInst(CastInst &I) {
593   Value *Op = I.getOperand(0);
594   unsigned DestReg = getReg(I);
595   MachineBasicBlock::iterator MI = BB->end();
596   emitCastOperation(BB, MI, Op, I.getType(), DestReg);
597 }
598
599 unsigned V8ISel::emitIntegerCast (MachineBasicBlock *BB,
600                               MachineBasicBlock::iterator IP, const Type *oldTy,
601                               unsigned SrcReg, const Type *newTy,
602                               unsigned DestReg) {
603   if (oldTy == newTy) {
604     // No-op cast - just emit a copy; assume the reg. allocator will zap it.
605     BuildMI (*BB, IP, V8::ORrr, 2, DestReg).addReg (V8::G0).addReg(SrcReg);
606     return SrcReg;
607   }
608   // Emit left-shift, then right-shift to sign- or zero-extend.
609   unsigned TmpReg = makeAnotherReg (newTy);
610   unsigned shiftWidth = 32 - (8 * TM.getTargetData ().getTypeSize (newTy));
611   BuildMI (*BB, IP, V8::SLLri, 2, TmpReg).addZImm (shiftWidth).addReg(SrcReg);
612   if (newTy->isSigned ()) { // sign-extend with SRA
613     BuildMI(*BB, IP, V8::SRAri, 2, DestReg).addZImm (shiftWidth).addReg(TmpReg);
614   } else { // zero-extend with SRL
615     BuildMI(*BB, IP, V8::SRLri, 2, DestReg).addZImm (shiftWidth).addReg(TmpReg);
616   }
617   // Return the temp reg. in case this is one half of a cast to long.
618   return TmpReg;
619 }
620
621 void V8ISel::emitFPToIntegerCast (MachineBasicBlock *BB,
622                                   MachineBasicBlock::iterator IP,
623                                   const Type *oldTy, unsigned SrcReg,
624                                   const Type *newTy, unsigned DestReg) {
625   unsigned FPCastOpcode, FPStoreOpcode, FPSize, FPAlign;
626   unsigned oldTyClass = getClassB(oldTy);
627   if (oldTyClass == cFloat) { 
628     FPCastOpcode = V8::FSTOI; FPStoreOpcode = V8::STFri; FPSize = 4; 
629     FPAlign = TM.getTargetData().getFloatAlignment();
630   } else { // it's a double
631     FPCastOpcode = V8::FDTOI; FPStoreOpcode = V8::STDFri; FPSize = 8; 
632     FPAlign = TM.getTargetData().getDoubleAlignment();
633   }
634   unsigned TempReg = makeAnotherReg (oldTy);
635   BuildMI (*BB, IP, FPCastOpcode, 1, TempReg).addReg (SrcReg);
636   int FI = F->getFrameInfo()->CreateStackObject(FPSize, FPAlign);
637   BuildMI (*BB, IP, FPStoreOpcode, 3).addFrameIndex (FI).addSImm (0)
638     .addReg (TempReg);
639   unsigned TempReg2 = makeAnotherReg (newTy);
640   BuildMI (*BB, IP, V8::LD, 3, TempReg2).addFrameIndex (FI).addSImm (0);
641   emitIntegerCast (BB, IP, Type::IntTy, TempReg2, newTy, DestReg);
642 }
643
644 /// emitCastOperation - Common code shared between visitCastInst and constant
645 /// expression cast support.
646 ///
647 void V8ISel::emitCastOperation(MachineBasicBlock *BB,
648                                MachineBasicBlock::iterator IP, Value *Src,
649                                const Type *DestTy, unsigned DestReg) {
650   const Type *SrcTy = Src->getType();
651   unsigned SrcClass = getClassB(SrcTy);
652   unsigned DestClass = getClassB(DestTy);
653   unsigned SrcReg = getReg(Src, BB, IP);
654
655   const Type *oldTy = SrcTy;
656   const Type *newTy = DestTy;
657   unsigned oldTyClass = SrcClass;
658   unsigned newTyClass = DestClass;
659
660   if (oldTyClass < cLong && newTyClass < cLong) {
661     emitIntegerCast (BB, IP, oldTy, SrcReg, newTy, DestReg);
662   } else switch (newTyClass) {
663     case cByte:
664     case cShort:
665     case cInt:
666       switch (oldTyClass) {
667       case cLong: 
668         // Treat it like a cast from the lower half of the value.
669         emitIntegerCast (BB, IP, Type::IntTy, SrcReg+1, newTy, DestReg);
670         break;
671       case cFloat: 
672       case cDouble:
673         emitFPToIntegerCast (BB, IP, oldTy, SrcReg, newTy, DestReg);
674         break;
675       default: goto not_yet;
676       }
677       return;
678
679     case cFloat:
680       switch (oldTyClass) {
681       case cLong: goto not_yet;
682       case cFloat:
683         BuildMI (*BB, IP, V8::FMOVS, 1, DestReg).addReg (SrcReg);
684         break;
685       case cDouble:
686         BuildMI (*BB, IP, V8::FDTOS, 1, DestReg).addReg (SrcReg);
687         break;
688       default: {
689         unsigned FltAlign = TM.getTargetData().getFloatAlignment();
690         // cast integer type to float.  Store it to a stack slot and then load
691         // it using ldf into a floating point register. then do fitos.
692         unsigned TmpReg = makeAnotherReg (newTy);
693         int FI = F->getFrameInfo()->CreateStackObject(4, FltAlign);
694         BuildMI (*BB, IP, V8::ST, 3).addFrameIndex (FI).addSImm (0)
695           .addReg (SrcReg);
696         BuildMI (*BB, IP, V8::LDFri, 2, TmpReg).addFrameIndex (FI).addSImm (0);
697         BuildMI (*BB, IP, V8::FITOS, 1, DestReg).addReg(TmpReg);
698         break;
699       }
700       }
701       return;
702
703     case cDouble:
704       switch (oldTyClass) {
705       case cLong: goto not_yet;
706       case cFloat:
707         BuildMI (*BB, IP, V8::FSTOD, 1, DestReg).addReg (SrcReg);
708         break;
709       case cDouble: // use double move pseudo-instr
710         BuildMI (*BB, IP, V8::FpMOVD, 1, DestReg).addReg (SrcReg);
711         break;
712       default: {
713         unsigned DoubleAlignment = TM.getTargetData().getDoubleAlignment();
714         unsigned TmpReg = makeAnotherReg (newTy);
715         int FI = F->getFrameInfo()->CreateStackObject(8, DoubleAlignment);
716         BuildMI (*BB, IP, V8::ST, 3).addFrameIndex (FI).addSImm (0)
717           .addReg (SrcReg);
718         BuildMI (*BB, IP, V8::LDDFri, 2, TmpReg).addFrameIndex (FI).addSImm (0);
719         BuildMI (*BB, IP, V8::FITOD, 1, DestReg).addReg(TmpReg);
720         break;
721       }
722       }
723       return;
724
725     case cLong:
726       switch (oldTyClass) {
727       case cByte:
728       case cShort:
729       case cInt: {
730         // Cast to (u)int in the bottom half, and sign(zero) extend in the top
731         // half.
732         const Type *OldHalfTy = oldTy->isSigned() ? Type::IntTy : Type::UIntTy;
733         const Type *NewHalfTy = newTy->isSigned() ? Type::IntTy : Type::UIntTy;
734         unsigned TempReg = emitIntegerCast (BB, IP, OldHalfTy, SrcReg,
735                                             NewHalfTy, DestReg+1);
736         if (newTy->isSigned ()) {
737           BuildMI (*BB, IP, V8::SRAri, 2, DestReg).addReg (TempReg) 
738             .addZImm (31);
739         } else {
740           BuildMI (*BB, IP, V8::ORrr, 2, DestReg).addReg (V8::G0) 
741             .addReg (V8::G0);
742         }
743         break;
744       }
745       case cLong:
746         // Just copy both halves.
747         BuildMI (*BB, IP, V8::ORrr, 2, DestReg).addReg (V8::G0).addReg (SrcReg);
748         BuildMI (*BB, IP, V8::ORrr, 2, DestReg+1).addReg (V8::G0)
749           .addReg (SrcReg+1);
750         break;
751       default: goto not_yet;
752       }
753       return;
754
755     default: goto not_yet;
756   }
757   return;
758 not_yet:
759   std::cerr << "Sorry, cast still unsupported: SrcTy = " << *SrcTy
760             << ", DestTy = " << *DestTy << "\n";
761   abort ();
762 }
763
764 void V8ISel::visitLoadInst(LoadInst &I) {
765   unsigned DestReg = getReg (I);
766   unsigned PtrReg = getReg (I.getOperand (0));
767   switch (getClassB (I.getType ())) {
768    case cByte:
769     if (I.getType ()->isSigned ())
770       BuildMI (BB, V8::LDSB, 2, DestReg).addReg (PtrReg).addSImm(0);
771     else
772       BuildMI (BB, V8::LDUB, 2, DestReg).addReg (PtrReg).addSImm(0);
773     return;
774    case cShort:
775     if (I.getType ()->isSigned ())
776       BuildMI (BB, V8::LDSH, 2, DestReg).addReg (PtrReg).addSImm(0);
777     else
778       BuildMI (BB, V8::LDUH, 2, DestReg).addReg (PtrReg).addSImm(0);
779     return;
780    case cInt:
781     BuildMI (BB, V8::LD, 2, DestReg).addReg (PtrReg).addSImm(0);
782     return;
783    case cLong:
784     BuildMI (BB, V8::LD, 2, DestReg).addReg (PtrReg).addSImm(0);
785     BuildMI (BB, V8::LD, 2, DestReg+1).addReg (PtrReg).addSImm(4);
786     return;
787    case cFloat:
788     BuildMI (BB, V8::LDFri, 2, DestReg).addReg (PtrReg).addSImm(0);
789     return;
790    case cDouble:
791     BuildMI (BB, V8::LDDFri, 2, DestReg).addReg (PtrReg).addSImm(0);
792     return;
793    default:
794     std::cerr << "Load instruction not handled: " << I;
795     abort ();
796     return;
797   }
798 }
799
800 void V8ISel::visitStoreInst(StoreInst &I) {
801   Value *SrcVal = I.getOperand (0);
802   unsigned SrcReg = getReg (SrcVal);
803   unsigned PtrReg = getReg (I.getOperand (1));
804   switch (getClassB (SrcVal->getType ())) {
805    case cByte:
806     BuildMI (BB, V8::STB, 3).addReg (PtrReg).addSImm (0).addReg (SrcReg);
807     return;
808    case cShort:
809     BuildMI (BB, V8::STH, 3).addReg (PtrReg).addSImm (0).addReg (SrcReg);
810     return;
811    case cInt:
812     BuildMI (BB, V8::ST, 3).addReg (PtrReg).addSImm (0).addReg (SrcReg);
813     return;
814    case cLong:
815     BuildMI (BB, V8::ST, 3).addReg (PtrReg).addSImm (0).addReg (SrcReg);
816     BuildMI (BB, V8::ST, 3).addReg (PtrReg).addSImm (4).addReg (SrcReg+1);
817     return;
818    case cFloat:
819     BuildMI (BB, V8::STFri, 3).addReg (PtrReg).addSImm (0).addReg (SrcReg);
820     return;
821    case cDouble:
822     BuildMI (BB, V8::STDFri, 3).addReg (PtrReg).addSImm (0).addReg (SrcReg);
823     return;
824    default:
825     std::cerr << "Store instruction not handled: " << I;
826     abort ();
827     return;
828   }
829 }
830
831 void V8ISel::visitCallInst(CallInst &I) {
832   MachineInstr *TheCall;
833   // Is it an intrinsic function call?
834   if (Function *F = I.getCalledFunction()) {
835     if (Intrinsic::ID ID = (Intrinsic::ID)F->getIntrinsicID()) {
836       visitIntrinsicCall(ID, I);   // Special intrinsics are not handled here
837       return;
838     }
839   }
840
841   // How much extra call stack will we need?
842   int extraStack = 0;
843   for (unsigned i = 0; i < I.getNumOperands (); ++i) {
844     switch (getClassB (I.getOperand (i)->getType ())) {
845       case cLong: extraStack += 8; break;
846       case cFloat: extraStack += 4; break;
847       case cDouble: extraStack += 8; break;
848       default: extraStack += 4; break;
849     }
850   }
851   extraStack -= 24;
852   if (extraStack < 0) {
853     extraStack = 0;
854   } else {
855     // Round up extra stack size to the nearest doubleword.
856     extraStack = (extraStack + 7) & ~7;
857   }
858
859   // Deal with args
860   static const unsigned OutgoingArgRegs[] = { V8::O0, V8::O1, V8::O2, V8::O3,
861     V8::O4, V8::O5 };
862   const unsigned *OAREnd = &OutgoingArgRegs[6];
863   const unsigned *OAR = &OutgoingArgRegs[0];
864   unsigned ArgOffset = 68;
865   if (extraStack) BuildMI (BB, V8::ADJCALLSTACKDOWN, 1).addImm (extraStack);
866   for (unsigned i = 1; i < I.getNumOperands (); ++i) {
867     unsigned ArgReg = getReg (I.getOperand (i));
868     if (getClassB (I.getOperand (i)->getType ()) < cLong) {
869       // Schlep it over into the incoming arg register
870       if (ArgOffset < 92) {
871         assert (OAR != OAREnd && "About to dereference past end of OutgoingArgRegs");
872         BuildMI (BB, V8::ORrr, 2, *OAR++).addReg (V8::G0).addReg (ArgReg);
873       } else {
874         BuildMI (BB, V8::ST, 3).addReg (V8::SP).addSImm (ArgOffset).addReg (ArgReg);
875       }
876       ArgOffset += 4;
877     } else if (getClassB (I.getOperand (i)->getType ()) == cFloat) {
878       if (ArgOffset < 92) {
879         // Single-fp args are passed in integer registers; go through
880         // memory to get them out of FP registers. (Bleh!)
881         unsigned FltAlign = TM.getTargetData().getFloatAlignment();
882         int FI = F->getFrameInfo()->CreateStackObject(4, FltAlign);
883         BuildMI (BB, V8::STFri, 3).addFrameIndex (FI).addSImm (0).addReg (ArgReg);
884         assert (OAR != OAREnd && "About to dereference past end of OutgoingArgRegs");
885         BuildMI (BB, V8::LD, 2, *OAR++).addFrameIndex (FI).addSImm (0);
886       } else {
887         BuildMI (BB, V8::STFri, 3).addReg (V8::SP).addSImm (ArgOffset).addReg (ArgReg);
888       }
889       ArgOffset += 4;
890     } else if (getClassB (I.getOperand (i)->getType ()) == cDouble) {
891       // Double-fp args are passed in pairs of integer registers; go through
892       // memory to get them out of FP registers. (Bleh!)
893       // We'd like to 'std' these right onto the outgoing-args area, but it might
894       // not be 8-byte aligned (e.g., call x(int x, double d)). sigh.
895       unsigned DblAlign = TM.getTargetData().getDoubleAlignment();
896       int FI = F->getFrameInfo()->CreateStackObject(8, DblAlign);
897       BuildMI (BB, V8::STDFri, 3).addFrameIndex (FI).addSImm (0).addReg (ArgReg);
898       if (ArgOffset < 92 && OAR != OAREnd) {
899         assert (OAR != OAREnd && "About to dereference past end of OutgoingArgRegs");
900         BuildMI (BB, V8::LD, 2, *OAR++).addFrameIndex (FI).addSImm (0);
901       } else {
902         unsigned TempReg = makeAnotherReg (Type::IntTy);
903         BuildMI (BB, V8::LD, 2, TempReg).addFrameIndex (FI).addSImm (0);
904         BuildMI (BB, V8::ST, 3).addReg (V8::SP).addSImm (ArgOffset).addReg (TempReg);
905       }
906       ArgOffset += 4;
907       if (ArgOffset < 92 && OAR != OAREnd) {
908         assert (OAR != OAREnd && "About to dereference past end of OutgoingArgRegs");
909         BuildMI (BB, V8::LD, 2, *OAR++).addFrameIndex (FI).addSImm (4);
910       } else {
911         unsigned TempReg = makeAnotherReg (Type::IntTy);
912         BuildMI (BB, V8::LD, 2, TempReg).addFrameIndex (FI).addSImm (4);
913         BuildMI (BB, V8::ST, 3).addReg (V8::SP).addSImm (ArgOffset).addReg (TempReg);
914       }
915       ArgOffset += 4;
916     } else if (getClassB (I.getOperand (i)->getType ()) == cLong) {
917       // do the first half...
918       if (ArgOffset < 92) {
919         assert (OAR != OAREnd && "About to dereference past end of OutgoingArgRegs");
920         BuildMI (BB, V8::ORrr, 2, *OAR++).addReg (V8::G0).addReg (ArgReg);
921       } else {
922         BuildMI (BB, V8::ST, 3).addReg (V8::SP).addSImm (ArgOffset).addReg (ArgReg);
923       }
924       ArgOffset += 4;
925       // ...then do the second half
926       if (ArgOffset < 92) {
927         assert (OAR != OAREnd && "About to dereference past end of OutgoingArgRegs");
928         BuildMI (BB, V8::ORrr, 2, *OAR++).addReg (V8::G0).addReg (ArgReg+1);
929       } else {
930         BuildMI (BB, V8::ST, 3).addReg (V8::SP).addSImm (ArgOffset).addReg (ArgReg+1);
931       }
932       ArgOffset += 4;
933     } else {
934       assert (0 && "Unknown class?!");
935     }
936   }
937
938   // Emit call instruction
939   if (Function *F = I.getCalledFunction ()) {
940     BuildMI (BB, V8::CALL, 1).addGlobalAddress (F, true);
941   } else {  // Emit an indirect call...
942     unsigned Reg = getReg (I.getCalledValue ());
943     BuildMI (BB, V8::JMPLrr, 3, V8::O7).addReg (Reg).addReg (V8::G0);
944   }
945
946   if (extraStack) BuildMI (BB, V8::ADJCALLSTACKUP, 1).addImm (extraStack);
947
948   // Deal w/ return value: schlep it over into the destination register
949   if (I.getType () == Type::VoidTy)
950     return;
951   unsigned DestReg = getReg (I);
952   switch (getClassB (I.getType ())) {
953     case cByte:
954     case cShort:
955     case cInt:
956       BuildMI (BB, V8::ORrr, 2, DestReg).addReg(V8::G0).addReg(V8::O0);
957       break;
958     case cFloat:
959       BuildMI (BB, V8::FMOVS, 2, DestReg).addReg(V8::F0);
960       break;
961     case cDouble:
962       BuildMI (BB, V8::FpMOVD, 2, DestReg).addReg(V8::D0);
963       break;
964     case cLong:
965       BuildMI (BB, V8::ORrr, 2, DestReg).addReg(V8::G0).addReg(V8::O0);
966       BuildMI (BB, V8::ORrr, 2, DestReg+1).addReg(V8::G0).addReg(V8::O1);
967       break;
968     default:
969       std::cerr << "Return type of call instruction not handled: " << I;
970       abort ();
971   }
972 }
973
974 void V8ISel::visitReturnInst(ReturnInst &I) {
975   if (I.getNumOperands () == 1) {
976     unsigned RetValReg = getReg (I.getOperand (0));
977     switch (getClassB (I.getOperand (0)->getType ())) {
978       case cByte:
979       case cShort:
980       case cInt:
981         // Schlep it over into i0 (where it will become o0 after restore).
982         BuildMI (BB, V8::ORrr, 2, V8::I0).addReg(V8::G0).addReg(RetValReg);
983         break;
984       case cFloat:
985         BuildMI (BB, V8::FMOVS, 1, V8::F0).addReg(RetValReg);
986         break;
987       case cDouble:
988         BuildMI (BB, V8::FpMOVD, 1, V8::D0).addReg(RetValReg);
989         break;
990       case cLong:
991         BuildMI (BB, V8::ORrr, 2, V8::I0).addReg(V8::G0).addReg(RetValReg);
992         BuildMI (BB, V8::ORrr, 2, V8::I1).addReg(V8::G0).addReg(RetValReg+1);
993         break;
994       default:
995         std::cerr << "Return instruction of this type not handled: " << I;
996         abort ();
997     }
998   }
999
1000   // Just emit a 'retl' instruction to return.
1001   BuildMI(BB, V8::RETL, 0);
1002   return;
1003 }
1004
1005 static inline BasicBlock *getBlockAfter(BasicBlock *BB) {
1006   Function::iterator I = BB; ++I;  // Get iterator to next block
1007   return I != BB->getParent()->end() ? &*I : 0;
1008 }
1009
1010 /// visitBranchInst - Handles conditional and unconditional branches.
1011 ///
1012 void V8ISel::visitBranchInst(BranchInst &I) {
1013   BasicBlock *takenSucc = I.getSuccessor (0);
1014   MachineBasicBlock *takenSuccMBB = MBBMap[takenSucc];
1015   BB->addSuccessor (takenSuccMBB);
1016   if (I.isConditional()) {  // conditional branch
1017     BasicBlock *notTakenSucc = I.getSuccessor (1);
1018     MachineBasicBlock *notTakenSuccMBB = MBBMap[notTakenSucc];
1019     BB->addSuccessor (notTakenSuccMBB);
1020
1021     // CondReg=(<condition>);
1022     // If (CondReg==0) goto notTakenSuccMBB;
1023     unsigned CondReg = getReg (I.getCondition ());
1024     BuildMI (BB, V8::CMPri, 2).addSImm (0).addReg (CondReg);
1025     BuildMI (BB, V8::BE, 1).addMBB (notTakenSuccMBB);
1026   }
1027   // goto takenSuccMBB;
1028   BuildMI (BB, V8::BA, 1).addMBB (takenSuccMBB);
1029 }
1030
1031 /// emitGEPOperation - Common code shared between visitGetElementPtrInst and
1032 /// constant expression GEP support.
1033 ///
1034 void V8ISel::emitGEPOperation (MachineBasicBlock *MBB,
1035                                MachineBasicBlock::iterator IP,
1036                                Value *Src, User::op_iterator IdxBegin,
1037                                User::op_iterator IdxEnd, unsigned TargetReg) {
1038   const TargetData &TD = TM.getTargetData ();
1039   const Type *Ty = Src->getType ();
1040   unsigned basePtrReg = getReg (Src, MBB, IP);
1041
1042   // GEPs have zero or more indices; we must perform a struct access
1043   // or array access for each one.
1044   for (GetElementPtrInst::op_iterator oi = IdxBegin, oe = IdxEnd; oi != oe;
1045        ++oi) {
1046     Value *idx = *oi;
1047     unsigned nextBasePtrReg = makeAnotherReg (Type::UIntTy);
1048     if (const StructType *StTy = dyn_cast<StructType> (Ty)) {
1049       // It's a struct access.  idx is the index into the structure,
1050       // which names the field. Use the TargetData structure to
1051       // pick out what the layout of the structure is in memory.
1052       // Use the (constant) structure index's value to find the
1053       // right byte offset from the StructLayout class's list of
1054       // structure member offsets.
1055       unsigned fieldIndex = cast<ConstantUInt> (idx)->getValue ();
1056       unsigned memberOffset =
1057         TD.getStructLayout (StTy)->MemberOffsets[fieldIndex];
1058       // Emit an ADD to add memberOffset to the basePtr.
1059       BuildMI (*MBB, IP, V8::ADDri, 2,
1060                nextBasePtrReg).addReg (basePtrReg).addZImm (memberOffset);
1061       // The next type is the member of the structure selected by the
1062       // index.
1063       Ty = StTy->getElementType (fieldIndex);
1064     } else if (const SequentialType *SqTy = dyn_cast<SequentialType> (Ty)) {
1065       // It's an array or pointer access: [ArraySize x ElementType].
1066       // We want to add basePtrReg to (idxReg * sizeof ElementType). First, we
1067       // must find the size of the pointed-to type (Not coincidentally, the next
1068       // type is the type of the elements in the array).
1069       Ty = SqTy->getElementType ();
1070       unsigned elementSize = TD.getTypeSize (Ty);
1071       unsigned idxReg = getReg (idx, MBB, IP);
1072       unsigned OffsetReg = makeAnotherReg (Type::IntTy);
1073       unsigned elementSizeReg = makeAnotherReg (Type::UIntTy);
1074       copyConstantToRegister (MBB, IP,
1075         ConstantUInt::get(Type::UIntTy, elementSize), elementSizeReg);
1076       // Emit a SMUL to multiply the register holding the index by
1077       // elementSize, putting the result in OffsetReg.
1078       BuildMI (*MBB, IP, V8::SMULrr, 2,
1079                OffsetReg).addReg (elementSizeReg).addReg (idxReg);
1080       // Emit an ADD to add OffsetReg to the basePtr.
1081       BuildMI (*MBB, IP, V8::ADDrr, 2,
1082                nextBasePtrReg).addReg (basePtrReg).addReg (OffsetReg);
1083     }
1084     basePtrReg = nextBasePtrReg;
1085   }
1086   // After we have processed all the indices, the result is left in
1087   // basePtrReg.  Move it to the register where we were expected to
1088   // put the answer.
1089   BuildMI (BB, V8::ORrr, 1, TargetReg).addReg (V8::G0).addReg (basePtrReg);
1090 }
1091
1092 void V8ISel::visitGetElementPtrInst (GetElementPtrInst &I) {
1093   unsigned outputReg = getReg (I);
1094   emitGEPOperation (BB, BB->end (), I.getOperand (0),
1095                     I.op_begin ()+1, I.op_end (), outputReg);
1096 }
1097
1098 void V8ISel::emitOp64LibraryCall (MachineBasicBlock *MBB,
1099                                   MachineBasicBlock::iterator IP,
1100                                   unsigned DestReg,
1101                                   const char *FuncName,
1102                                   unsigned Op0Reg, unsigned Op1Reg) {
1103   BuildMI (*MBB, IP, V8::ORrr, 2, V8::O0).addReg (V8::G0).addReg (Op0Reg);
1104   BuildMI (*MBB, IP, V8::ORrr, 2, V8::O1).addReg (V8::G0).addReg (Op0Reg+1);
1105   BuildMI (*MBB, IP, V8::ORrr, 2, V8::O2).addReg (V8::G0).addReg (Op1Reg);
1106   BuildMI (*MBB, IP, V8::ORrr, 2, V8::O3).addReg (V8::G0).addReg (Op1Reg+1);
1107   BuildMI (*MBB, IP, V8::CALL, 1).addExternalSymbol (FuncName, true);
1108   BuildMI (*MBB, IP, V8::ORrr, 2, DestReg).addReg (V8::G0).addReg (V8::O0);
1109   BuildMI (*MBB, IP, V8::ORrr, 2, DestReg+1).addReg (V8::G0).addReg (V8::O1);
1110 }
1111
1112 void V8ISel::visitBinaryOperator (Instruction &I) {
1113   unsigned DestReg = getReg (I);
1114   unsigned Op0Reg = getReg (I.getOperand (0));
1115   unsigned Op1Reg = getReg (I.getOperand (1));
1116
1117   unsigned Class = getClassB (I.getType());
1118   unsigned OpCase = ~0;
1119
1120   if (Class > cLong) {
1121     switch (I.getOpcode ()) {
1122     case Instruction::Add: OpCase = 0; break;
1123     case Instruction::Sub: OpCase = 1; break;
1124     case Instruction::Mul: OpCase = 2; break;
1125     case Instruction::Div: OpCase = 3; break;
1126     default: visitInstruction (I); return;
1127     }
1128     static unsigned Opcodes[] = { V8::FADDS, V8::FADDD,
1129                                   V8::FSUBS, V8::FSUBD,
1130                                   V8::FMULS, V8::FMULD,
1131                                   V8::FDIVS, V8::FDIVD };
1132     BuildMI (BB, Opcodes[2*OpCase + (Class - cFloat)], 2, DestReg)
1133       .addReg (Op0Reg).addReg (Op1Reg);
1134     return;
1135   }
1136
1137   unsigned ResultReg = DestReg;
1138   if (Class != cInt && Class != cLong)
1139     ResultReg = makeAnotherReg (I.getType ());
1140
1141   if (Class == cLong) {
1142     const char *FuncName;
1143     DEBUG (std::cerr << "Class = cLong\n");
1144     DEBUG (std::cerr << "Op0Reg = " << Op0Reg << ", " << Op0Reg+1 << "\n");
1145     DEBUG (std::cerr << "Op1Reg = " << Op1Reg << ", " << Op1Reg+1 << "\n");
1146     DEBUG (std::cerr << "ResultReg = " << ResultReg << ", " << ResultReg+1 << "\n");
1147     DEBUG (std::cerr << "DestReg = " << DestReg << ", " << DestReg+1 <<  "\n");
1148     switch (I.getOpcode ()) {
1149     case Instruction::Add:
1150       BuildMI (BB, V8::ADDCCrr, 2, ResultReg+1).addReg (Op0Reg+1)
1151         .addReg (Op1Reg+1);
1152       BuildMI (BB, V8::ADDXrr, 2, ResultReg).addReg (Op0Reg).addReg (Op1Reg);
1153       return;
1154     case Instruction::Sub:
1155       BuildMI (BB, V8::SUBCCrr, 2, ResultReg+1).addReg (Op0Reg+1)
1156         .addReg (Op1Reg+1);
1157       BuildMI (BB, V8::SUBXrr, 2, ResultReg).addReg (Op0Reg).addReg (Op1Reg);
1158       return;
1159     case Instruction::Mul:
1160       FuncName = I.getType ()->isSigned () ? "__mul64" : "__umul64";
1161       emitOp64LibraryCall (BB, BB->end (), DestReg, FuncName, Op0Reg, Op1Reg);
1162       return;
1163     case Instruction::Div:
1164       FuncName = I.getType ()->isSigned () ? "__div64" : "__udiv64";
1165       emitOp64LibraryCall (BB, BB->end (), DestReg, FuncName, Op0Reg, Op1Reg);
1166       return;
1167     case Instruction::Rem:
1168       FuncName = I.getType ()->isSigned () ? "__rem64" : "__urem64";
1169       emitOp64LibraryCall (BB, BB->end (), DestReg, FuncName, Op0Reg, Op1Reg);
1170       return;
1171     }
1172   }
1173
1174   // FIXME: support long, ulong.
1175   switch (I.getOpcode ()) {
1176   case Instruction::Add: OpCase = 0; break;
1177   case Instruction::Sub: OpCase = 1; break;
1178   case Instruction::Mul: OpCase = 2; break;
1179   case Instruction::And: OpCase = 3; break;
1180   case Instruction::Or:  OpCase = 4; break;
1181   case Instruction::Xor: OpCase = 5; break;
1182   case Instruction::Shl: OpCase = 6; break;
1183   case Instruction::Shr: OpCase = 7+I.getType()->isSigned(); break;
1184
1185   case Instruction::Div:
1186   case Instruction::Rem: {
1187     unsigned Dest = ResultReg;
1188     if (I.getOpcode() == Instruction::Rem)
1189       Dest = makeAnotherReg(I.getType());
1190
1191     // FIXME: this is probably only right for 32 bit operands.
1192     if (I.getType ()->isSigned()) {
1193       unsigned Tmp = makeAnotherReg (I.getType ());
1194       // Sign extend into the Y register
1195       BuildMI (BB, V8::SRAri, 2, Tmp).addReg (Op0Reg).addZImm (31);
1196       BuildMI (BB, V8::WRrr, 2, V8::Y).addReg (Tmp).addReg (V8::G0);
1197       BuildMI (BB, V8::SDIVrr, 2, Dest).addReg (Op0Reg).addReg (Op1Reg);
1198     } else {
1199       // Zero extend into the Y register, ie, just set it to zero
1200       BuildMI (BB, V8::WRrr, 2, V8::Y).addReg (V8::G0).addReg (V8::G0);
1201       BuildMI (BB, V8::UDIVrr, 2, Dest).addReg (Op0Reg).addReg (Op1Reg);
1202     }
1203
1204     if (I.getOpcode() == Instruction::Rem) {
1205       unsigned Tmp = makeAnotherReg (I.getType ());
1206       BuildMI (BB, V8::SMULrr, 2, Tmp).addReg(Dest).addReg(Op1Reg);
1207       BuildMI (BB, V8::SUBrr, 2, ResultReg).addReg(Op0Reg).addReg(Tmp);
1208     }
1209     break;
1210   }
1211   default:
1212     visitInstruction (I);
1213     return;
1214   }
1215
1216   static const unsigned Opcodes[] = {
1217     V8::ADDrr, V8::SUBrr, V8::SMULrr, V8::ANDrr, V8::ORrr, V8::XORrr,
1218     V8::SLLrr, V8::SRLrr, V8::SRArr
1219   };
1220   if (OpCase != ~0U) {
1221     BuildMI (BB, Opcodes[OpCase], 2, ResultReg).addReg (Op0Reg).addReg (Op1Reg);
1222   }
1223
1224   switch (getClassB (I.getType ())) {
1225     case cByte: 
1226       if (I.getType ()->isSigned ()) { // add byte
1227         BuildMI (BB, V8::ANDri, 2, DestReg).addReg (ResultReg).addZImm (0xff);
1228       } else { // add ubyte
1229         unsigned TmpReg = makeAnotherReg (I.getType ());
1230         BuildMI (BB, V8::SLLri, 2, TmpReg).addReg (ResultReg).addZImm (24);
1231         BuildMI (BB, V8::SRAri, 2, DestReg).addReg (TmpReg).addZImm (24);
1232       }
1233       break;
1234     case cShort:
1235       if (I.getType ()->isSigned ()) { // add short
1236         unsigned TmpReg = makeAnotherReg (I.getType ());
1237         BuildMI (BB, V8::SLLri, 2, TmpReg).addReg (ResultReg).addZImm (16);
1238         BuildMI (BB, V8::SRAri, 2, DestReg).addReg (TmpReg).addZImm (16);
1239       } else { // add ushort
1240         unsigned TmpReg = makeAnotherReg (I.getType ());
1241         BuildMI (BB, V8::SLLri, 2, TmpReg).addReg (ResultReg).addZImm (16);
1242         BuildMI (BB, V8::SRLri, 2, DestReg).addReg (TmpReg).addZImm (16);
1243       }
1244       break;
1245     case cInt:
1246       // Nothing to do here.
1247       break;
1248     case cLong:
1249       // Only support and, or, xor here - others taken care of above.
1250       if (OpCase < 3 || OpCase > 5) {
1251         visitInstruction (I);
1252         return;
1253       }
1254       // Do the other half of the value:
1255       BuildMI (BB, Opcodes[OpCase], 2, ResultReg+1).addReg (Op0Reg+1)
1256         .addReg (Op1Reg+1);
1257       break;
1258     default:
1259       visitInstruction (I);
1260   }
1261 }
1262
1263 void V8ISel::visitSetCondInst(SetCondInst &I) {
1264   unsigned Op0Reg = getReg (I.getOperand (0));
1265   unsigned Op1Reg = getReg (I.getOperand (1));
1266   unsigned DestReg = getReg (I);
1267   const Type *Ty = I.getOperand (0)->getType ();
1268   
1269   // Compare the two values.
1270   if (getClass (Ty) < cLong) {
1271     BuildMI(BB, V8::SUBCCrr, 2, V8::G0).addReg(Op0Reg).addReg(Op1Reg);
1272   } else if (getClass (Ty) == cLong) {
1273     // Here is one way to open-code each of the setccs for SIGNED longs...
1274     // I haven't checked it yet, but you *should* be able to just switch
1275     // bl/bg/ble/bge with bcs/bgu/bleu/bcc to get the version for
1276     // unsigned longs.
1277     // setlt/setge subcc   %left_1, %right_1, %g0
1278     // ^^^^^^^^^^^ subxcc  %left_0, %right_0, %g0
1279     //             bl/bge (as with ordinary setcc)
1280     // setle/setgt subcc   %g0, 1, %g0
1281     // ^^^^^^^^^^^ subxcc  %left_1, %right_1, %g0
1282     //             subxcc  %left_0, %right_0, %g0
1283     //             ble/bg (as with ordinary setcc)
1284     // seteq/setne xor %left_1, %right_1, %temp_0
1285     // ^^^^^^^^^^^ xor %left_0, %right_0, %temp_1
1286     //             subcc   %g0, %temp_1, %g0
1287     //     seteq                           setne
1288     //     ^^^^^                           ^^^^^
1289     //     subx    %g0, -1, %temp_2        addx    %g0, 0, %temp_2
1290     //             subcc   %g0, %temp_0, %g0
1291     //     subx    %g0, -1, %temp_3        addx    %g0, 0, %temp_3
1292     //     and %temp_2, %temp_3, %result   or  %temp_2, %temp_3, %result
1293     assert (0 && "can't setcc on longs yet");
1294   } else if (getClass (Ty) == cFloat) {
1295     BuildMI(BB, V8::FCMPS, 2).addReg(Op0Reg).addReg(Op1Reg);
1296   } else if (getClass (Ty) == cDouble) {
1297     BuildMI(BB, V8::FCMPD, 2).addReg(Op0Reg).addReg(Op1Reg);
1298   }
1299
1300   unsigned BranchIdx;
1301   switch (I.getOpcode()) {
1302   default: assert(0 && "Unknown setcc instruction!");
1303   case Instruction::SetEQ: BranchIdx = 0; break;
1304   case Instruction::SetNE: BranchIdx = 1; break;
1305   case Instruction::SetLT: BranchIdx = 2; break;
1306   case Instruction::SetGT: BranchIdx = 3; break;
1307   case Instruction::SetLE: BranchIdx = 4; break;
1308   case Instruction::SetGE: BranchIdx = 5; break;
1309   }
1310   unsigned Column = 0;
1311   if (Ty->isSigned() && !Ty->isFloatingPoint()) Column = 1;
1312   if (Ty->isFloatingPoint()) Column = 2;
1313   static unsigned OpcodeTab[3*6] = {
1314                                  // LLVM            SparcV8
1315                                  //        unsigned signed  fp
1316     V8::BE,   V8::BE,  V8::FBE,  // seteq = be      be      fbe
1317     V8::BNE,  V8::BNE, V8::FBNE, // setne = bne     bne     fbne
1318     V8::BCS,  V8::BL,  V8::FBL,  // setlt = bcs     bl      fbl
1319     V8::BGU,  V8::BG,  V8::FBG,  // setgt = bgu     bg      fbg
1320     V8::BLEU, V8::BLE, V8::FBLE, // setle = bleu    ble     fble
1321     V8::BCC,  V8::BGE, V8::FBGE  // setge = bcc     bge     fbge
1322   };
1323   unsigned Opcode = OpcodeTab[3*BranchIdx + Column];
1324
1325   MachineBasicBlock *thisMBB = BB;
1326   const BasicBlock *LLVM_BB = BB->getBasicBlock ();
1327   //  thisMBB:
1328   //  ...
1329   //   subcc %reg0, %reg1, %g0
1330   //   bCC copy1MBB
1331   //   ba copy0MBB
1332
1333   // FIXME: we wouldn't need copy0MBB (we could fold it into thisMBB)
1334   // if we could insert other, non-terminator instructions after the
1335   // bCC. But MBB->getFirstTerminator() can't understand this.
1336   MachineBasicBlock *copy1MBB = new MachineBasicBlock (LLVM_BB);
1337   F->getBasicBlockList ().push_back (copy1MBB);
1338   BuildMI (BB, Opcode, 1).addMBB (copy1MBB);
1339   MachineBasicBlock *copy0MBB = new MachineBasicBlock (LLVM_BB);
1340   F->getBasicBlockList ().push_back (copy0MBB);
1341   BuildMI (BB, V8::BA, 1).addMBB (copy0MBB);
1342   // Update machine-CFG edges
1343   BB->addSuccessor (copy1MBB);
1344   BB->addSuccessor (copy0MBB);
1345
1346   //  copy0MBB:
1347   //   %FalseValue = or %G0, 0
1348   //   ba sinkMBB
1349   BB = copy0MBB;
1350   unsigned FalseValue = makeAnotherReg (I.getType ());
1351   BuildMI (BB, V8::ORri, 2, FalseValue).addReg (V8::G0).addZImm (0);
1352   MachineBasicBlock *sinkMBB = new MachineBasicBlock (LLVM_BB);
1353   F->getBasicBlockList ().push_back (sinkMBB);
1354   BuildMI (BB, V8::BA, 1).addMBB (sinkMBB);
1355   // Update machine-CFG edges
1356   BB->addSuccessor (sinkMBB);
1357
1358   DEBUG (std::cerr << "thisMBB is at " << (void*)thisMBB << "\n");
1359   DEBUG (std::cerr << "copy1MBB is at " << (void*)copy1MBB << "\n");
1360   DEBUG (std::cerr << "copy0MBB is at " << (void*)copy0MBB << "\n");
1361   DEBUG (std::cerr << "sinkMBB is at " << (void*)sinkMBB << "\n");
1362
1363   //  copy1MBB:
1364   //   %TrueValue = or %G0, 1
1365   //   ba sinkMBB
1366   BB = copy1MBB;
1367   unsigned TrueValue = makeAnotherReg (I.getType ());
1368   BuildMI (BB, V8::ORri, 2, TrueValue).addReg (V8::G0).addZImm (1);
1369   BuildMI (BB, V8::BA, 1).addMBB (sinkMBB);
1370   // Update machine-CFG edges
1371   BB->addSuccessor (sinkMBB);
1372
1373   //  sinkMBB:
1374   //   %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, copy1MBB ]
1375   //  ...
1376   BB = sinkMBB;
1377   BuildMI (BB, V8::PHI, 4, DestReg).addReg (FalseValue)
1378     .addMBB (copy0MBB).addReg (TrueValue).addMBB (copy1MBB);
1379 }
1380
1381 void V8ISel::visitAllocaInst(AllocaInst &I) {
1382   // Find the data size of the alloca inst's getAllocatedType.
1383   const Type *Ty = I.getAllocatedType();
1384   unsigned TySize = TM.getTargetData().getTypeSize(Ty);
1385
1386   unsigned ArraySizeReg = getReg (I.getArraySize ());
1387   unsigned TySizeReg = getReg (ConstantUInt::get (Type::UIntTy, TySize));
1388   unsigned TmpReg1 = makeAnotherReg (Type::UIntTy);
1389   unsigned TmpReg2 = makeAnotherReg (Type::UIntTy);
1390   unsigned StackAdjReg = makeAnotherReg (Type::UIntTy);
1391
1392   // StackAdjReg = (ArraySize * TySize) rounded up to nearest
1393   // doubleword boundary.
1394   BuildMI (BB, V8::UMULrr, 2, TmpReg1).addReg (ArraySizeReg).addReg (TySizeReg);
1395
1396   // Round up TmpReg1 to nearest doubleword boundary:
1397   BuildMI (BB, V8::ADDri, 2, TmpReg2).addReg (TmpReg1).addSImm (7);
1398   BuildMI (BB, V8::ANDri, 2, StackAdjReg).addReg (TmpReg2).addSImm (-8);
1399
1400   // Subtract size from stack pointer, thereby allocating some space.
1401   BuildMI (BB, V8::SUBrr, 2, V8::SP).addReg (V8::SP).addReg (StackAdjReg);
1402
1403   // Put a pointer to the space into the result register, by copying
1404   // the stack pointer.
1405   BuildMI (BB, V8::ADDri, 2, getReg(I)).addReg (V8::SP).addSImm (96);
1406
1407   // Inform the Frame Information that we have just allocated a variable-sized
1408   // object.
1409   F->getFrameInfo()->CreateVariableSizedObject();
1410 }
1411
1412 /// LowerUnknownIntrinsicFunctionCalls - This performs a prepass over the
1413 /// function, lowering any calls to unknown intrinsic functions into the
1414 /// equivalent LLVM code.
1415 void V8ISel::LowerUnknownIntrinsicFunctionCalls(Function &F) {
1416   for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
1417     for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; )
1418       if (CallInst *CI = dyn_cast<CallInst>(I++))
1419         if (Function *F = CI->getCalledFunction())
1420           switch (F->getIntrinsicID()) {
1421           case Intrinsic::vastart:
1422           case Intrinsic::vacopy:
1423           case Intrinsic::vaend:
1424             // We directly implement these intrinsics
1425           case Intrinsic::not_intrinsic: break;
1426           default:
1427             // All other intrinsic calls we must lower.
1428             Instruction *Before = CI->getPrev();
1429             TM.getIntrinsicLowering().LowerIntrinsicCall(CI);
1430             if (Before) {        // Move iterator to instruction after call
1431               I = Before;  ++I;
1432             } else {
1433               I = BB->begin();
1434             }
1435           }
1436 }
1437
1438
1439 void V8ISel::visitIntrinsicCall(Intrinsic::ID ID, CallInst &CI) {
1440   switch (ID) {
1441   default:
1442     std::cerr << "Sorry, unknown intrinsic function call:\n" << CI; abort ();
1443
1444   case Intrinsic::vastart: {
1445     // Add the VarArgsOffset to the frame pointer, and copy it to the result.
1446     unsigned DestReg = getReg (CI);
1447     BuildMI (BB, V8::ADDri, 2, DestReg).addReg (V8::FP).addSImm (VarArgsOffset);
1448     return;
1449   }
1450
1451   case Intrinsic::vaend:
1452     // va_end is a no-op on SparcV8.
1453     return;
1454
1455   case Intrinsic::vacopy: {
1456     // Copy the va_list ptr (arg1) to the result.
1457     unsigned DestReg = getReg (CI), SrcReg = getReg (CI.getOperand (1));
1458     BuildMI (BB, V8::ORrr, 2, DestReg).addReg (V8::G0).addReg (SrcReg);
1459     return;
1460   }
1461   }
1462 }
1463
1464 void V8ISel::visitVANextInst (VANextInst &I) {
1465   // Add the type size to the vararg pointer (arg0).
1466   unsigned DestReg = getReg (I);
1467   unsigned SrcReg = getReg (I.getOperand (0));
1468   unsigned TySize = TM.getTargetData ().getTypeSize (I.getArgType ());
1469   BuildMI (BB, V8::ADDri, 2, DestReg).addReg (SrcReg).addSImm (TySize);
1470 }
1471
1472 void V8ISel::visitVAArgInst (VAArgInst &I) {
1473   unsigned VAList = getReg (I.getOperand (0));
1474   unsigned DestReg = getReg (I);
1475
1476   switch (I.getType ()->getTypeID ()) {
1477   case Type::PointerTyID:
1478   case Type::UIntTyID:
1479   case Type::IntTyID:
1480         BuildMI (BB, V8::LD, 2, DestReg).addReg (VAList).addSImm (0);
1481     return;
1482
1483   case Type::ULongTyID:
1484   case Type::LongTyID:
1485         BuildMI (BB, V8::LD, 2, DestReg).addReg (VAList).addSImm (0);
1486         BuildMI (BB, V8::LD, 2, DestReg+1).addReg (VAList).addSImm (4);
1487     return;
1488
1489   case Type::DoubleTyID: {
1490     unsigned DblAlign = TM.getTargetData().getDoubleAlignment();
1491     unsigned TempReg = makeAnotherReg (Type::IntTy);
1492     unsigned TempReg2 = makeAnotherReg (Type::IntTy);
1493     int FI = F->getFrameInfo()->CreateStackObject(8, DblAlign);
1494     BuildMI (BB, V8::LD, 2, TempReg).addReg (VAList).addSImm (0);
1495     BuildMI (BB, V8::LD, 2, TempReg2).addReg (VAList).addSImm (4);
1496     BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (0).addReg (TempReg);
1497     BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (4).addReg (TempReg2);
1498     BuildMI (BB, V8::LDDFri, 2, DestReg).addFrameIndex (FI).addSImm (0);
1499     return;
1500   }
1501
1502   default:
1503     std::cerr << "Sorry, vaarg instruction of this type still unsupported:\n"
1504               << I;
1505     abort ();
1506     return;
1507   }
1508 }