+ case Type::PointerTyID:
+ case Type::UIntTyID:
+ case Type::IntTyID:
+ Size = 4;
+ break;
+ case Type::ULongTyID:
+ case Type::LongTyID:
+ case Type::DoubleTyID:
+ Size = 8;
+ break;
+ }
+
+ // Increment the VAList pointer...
+ BuildMI(BB, X86::ADDri32, 2, DestReg).addReg(VAList).addZImm(Size);
+}
+
+void ISel::visitVAArgInst(VAArgInst &I) {
+ unsigned VAList = getReg(I.getOperand(0));
+ unsigned DestReg = getReg(I);
+
+ switch (I.getType()->getPrimitiveID()) {
+ default:
+ std::cerr << I;
+ assert(0 && "Error: bad type for va_next instruction!");
+ return;
+ case Type::PointerTyID:
+ case Type::UIntTyID:
+ case Type::IntTyID:
+ addDirectMem(BuildMI(BB, X86::MOVmr32, 4, DestReg), VAList);
+ break;
+ case Type::ULongTyID:
+ case Type::LongTyID:
+ addDirectMem(BuildMI(BB, X86::MOVmr32, 4, DestReg), VAList);
+ addRegOffset(BuildMI(BB, X86::MOVmr32, 4, DestReg+1), VAList, 4);
+ break;
+ case Type::DoubleTyID:
+ addDirectMem(BuildMI(BB, X86::FLDr64, 4, DestReg), VAList);
+ break;
+ }
+}
+
+
+void ISel::visitGetElementPtrInst(GetElementPtrInst &I) {
+ unsigned outputReg = getReg(I);
+ MachineBasicBlock::iterator MI = BB->end();
+ emitGEPOperation(BB, MI, I.getOperand(0),
+ I.op_begin()+1, I.op_end(), outputReg);
+}
+
+void ISel::emitGEPOperation(MachineBasicBlock *MBB,
+ MachineBasicBlock::iterator &IP,
+ Value *Src, User::op_iterator IdxBegin,
+ User::op_iterator IdxEnd, unsigned TargetReg) {
+ const TargetData &TD = TM.getTargetData();
+ const Type *Ty = Src->getType();
+ unsigned BaseReg = getReg(Src, MBB, IP);
+
+ // GEPs have zero or more indices; we must perform a struct access
+ // or array access for each one.
+ for (GetElementPtrInst::op_iterator oi = IdxBegin,
+ oe = IdxEnd; oi != oe; ++oi) {
+ Value *idx = *oi;
+ unsigned NextReg = BaseReg;
+ if (const StructType *StTy = dyn_cast<StructType>(Ty)) {
+ // It's a struct access. idx is the index into the structure,
+ // which names the field. This index must have ubyte type.
+ const ConstantUInt *CUI = cast<ConstantUInt>(idx);
+ assert(CUI->getType() == Type::UByteTy
+ && "Funny-looking structure index in GEP");
+ // Use the TargetData structure to pick out what the layout of
+ // the structure is in memory. Since the structure index must
+ // be constant, we can get its value and use it to find the
+ // right byte offset from the StructLayout class's list of
+ // structure member offsets.
+ unsigned idxValue = CUI->getValue();
+ unsigned FieldOff = TD.getStructLayout(StTy)->MemberOffsets[idxValue];
+ if (FieldOff) {
+ NextReg = makeAnotherReg(Type::UIntTy);
+ // Emit an ADD to add FieldOff to the basePtr.
+ BMI(MBB, IP, X86::ADDri32, 2,NextReg).addReg(BaseReg).addZImm(FieldOff);
+ }
+ // The next type is the member of the structure selected by the
+ // index.
+ Ty = StTy->getElementTypes()[idxValue];
+ } else if (const SequentialType *SqTy = cast<SequentialType>(Ty)) {
+ // It's an array or pointer access: [ArraySize x ElementType].
+
+ // idx is the index into the array. Unlike with structure
+ // indices, we may not know its actual value at code-generation
+ // time.
+ assert(idx->getType() == Type::LongTy && "Bad GEP array index!");
+
+ // Most GEP instructions use a [cast (int/uint) to LongTy] as their
+ // operand on X86. Handle this case directly now...
+ if (CastInst *CI = dyn_cast<CastInst>(idx))
+ if (CI->getOperand(0)->getType() == Type::IntTy ||
+ CI->getOperand(0)->getType() == Type::UIntTy)
+ idx = CI->getOperand(0);
+
+ // We want to add BaseReg to(idxReg * sizeof ElementType). First, we
+ // must find the size of the pointed-to type (Not coincidentally, the next
+ // type is the type of the elements in the array).
+ Ty = SqTy->getElementType();
+ unsigned elementSize = TD.getTypeSize(Ty);
+
+ // If idxReg is a constant, we don't need to perform the multiply!
+ if (ConstantSInt *CSI = dyn_cast<ConstantSInt>(idx)) {
+ if (!CSI->isNullValue()) {
+ unsigned Offset = elementSize*CSI->getValue();
+ NextReg = makeAnotherReg(Type::UIntTy);
+ BMI(MBB, IP, X86::ADDri32, 2,NextReg).addReg(BaseReg).addZImm(Offset);
+ }
+ } else if (elementSize == 1) {
+ // If the element size is 1, we don't have to multiply, just add
+ unsigned idxReg = getReg(idx, MBB, IP);
+ NextReg = makeAnotherReg(Type::UIntTy);
+ BMI(MBB, IP, X86::ADDrr32, 2, NextReg).addReg(BaseReg).addReg(idxReg);
+ } else {
+ unsigned idxReg = getReg(idx, MBB, IP);
+ unsigned OffsetReg = makeAnotherReg(Type::UIntTy);
+
+ doMultiplyConst(MBB, IP, OffsetReg, Type::IntTy, idxReg, elementSize);
+
+ // Emit an ADD to add OffsetReg to the basePtr.
+ NextReg = makeAnotherReg(Type::UIntTy);
+ BMI(MBB, IP, X86::ADDrr32, 2,NextReg).addReg(BaseReg).addReg(OffsetReg);
+ }
+ }
+ // Now that we are here, further indices refer to subtypes of this
+ // one, so we don't need to worry about BaseReg itself, anymore.
+ BaseReg = NextReg;