+/// visitGetElementPtrInst - I don't know, most programs don't have
+/// getelementptr instructions, right? That means we can put off
+/// implementing this, right? Right. This method emits machine
+/// instructions to perform type-safe pointer arithmetic. I am
+/// guessing this could be cleaned up somewhat to use fewer temporary
+/// registers.
+void
+ISel::visitGetElementPtrInst (GetElementPtrInst &I)
+{
+ Value *basePtr = I.getPointerOperand ();
+ const TargetData &TD = TM.DataLayout;
+ unsigned basePtrReg = getReg (basePtr);
+ unsigned resultReg = getReg (I);
+ const Type *Ty = basePtr->getType();
+ // GEPs have zero or more indices; we must perform a struct access
+ // or array access for each one.
+ for (GetElementPtrInst::op_iterator oi = I.idx_begin (),
+ oe = I.idx_end (); oi != oe; ++oi) {
+ Value *idx = *oi;
+ unsigned nextBasePtrReg = makeAnotherReg ();
+ 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 memberOffset =
+ TD.getStructLayout (StTy)->MemberOffsets[idxValue];
+ // Emit an ADD to add memberOffset to the basePtr.
+ BuildMI (BB, X86::ADDri32, 2,
+ nextBasePtrReg).addReg (basePtrReg).addZImm (memberOffset);
+ // 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].
+ // The documentation does not seem to match the code on the type
+ // of array indices. The code seems to use long, and the docs
+ // (and the comments) say uint. If it is long, I don't know what
+ // we are going to do, because the X86 loves 64-bit types.
+ const Type *typeOfSequentialTypeIndex = SqTy->getIndexType ();
+ // 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 () == typeOfSequentialTypeIndex
+ && "Funny-looking array index in GEP");
+ // We want to add basePtrReg 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);
+ unsigned elementSizeReg = makeAnotherReg ();
+ copyConstantToRegister (ConstantInt::get (typeOfSequentialTypeIndex,
+ elementSize),
+ elementSizeReg);
+ unsigned idxReg = getReg (idx);
+ // Emit a MUL to multiply the register holding the index by
+ // elementSize, putting the result in memberOffsetReg.
+ unsigned memberOffsetReg = makeAnotherReg ();
+ doMultiply (memberOffsetReg, typeOfSequentialTypeIndex,
+ elementSizeReg, idxReg);
+ // Emit an ADD to add memberOffsetReg to the basePtr.
+ BuildMI (BB, X86::ADDrr32, 2,
+ nextBasePtrReg).addReg (basePtrReg).addReg (memberOffsetReg);
+ }
+ // Now that we are here, further indices refer to subtypes of this
+ // one, so we don't need to worry about basePtrReg itself, anymore.
+ basePtrReg = nextBasePtrReg;