[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelSimple.cpp X86InstrBuilder.h

Reid Spencer reid at x10sys.com
Sun Aug 29 17:13:36 PDT 2004



Changes in directory llvm/lib/Target/X86:

X86ISelSimple.cpp updated: 1.276 -> 1.277
X86InstrBuilder.h updated: 1.11 -> 1.12
---
Log message:

Reduce the number of arguments in the instruction builder and make some
improvements on instruction selection that account for register and frame
index bases.

Patch contributed by Jeff Cohen. Thanks Jeff!


---
Diffs of the changes:  (+137 -160)

Index: llvm/lib/Target/X86/X86ISelSimple.cpp
diff -u llvm/lib/Target/X86/X86ISelSimple.cpp:1.276 llvm/lib/Target/X86/X86ISelSimple.cpp:1.277
--- llvm/lib/Target/X86/X86ISelSimple.cpp:1.276	Mon Jul 26 13:45:48 2004
+++ llvm/lib/Target/X86/X86ISelSimple.cpp	Sun Aug 29 19:13:26 2004
@@ -237,23 +237,21 @@
 
     /// getAddressingMode - Get the addressing mode to use to address the
     /// specified value.  The returned value should be used with addFullAddress.
-    void getAddressingMode(Value *Addr, unsigned &BaseReg, unsigned &Scale,
-                           unsigned &IndexReg, unsigned &Disp);
+    void getAddressingMode(Value *Addr, X86AddressMode &AM);
 
 
     /// getGEPIndex - This is used to fold GEP instructions into X86 addressing
     /// expressions.
     void getGEPIndex(MachineBasicBlock *MBB, MachineBasicBlock::iterator IP,
                      std::vector<Value*> &GEPOps,
-                     std::vector<const Type*> &GEPTypes, unsigned &BaseReg,
-                     unsigned &Scale, unsigned &IndexReg, unsigned &Disp);
+                     std::vector<const Type*> &GEPTypes,
+                     X86AddressMode &AM);
 
     /// isGEPFoldable - Return true if the specified GEP can be completely
     /// folded into the addressing mode of a load/store or lea instruction.
     bool isGEPFoldable(MachineBasicBlock *MBB,
                        Value *Src, User::op_iterator IdxBegin,
-                       User::op_iterator IdxEnd, unsigned &BaseReg,
-                       unsigned &Scale, unsigned &IndexReg, unsigned &Disp);
+                       User::op_iterator IdxEnd, X86AddressMode &AM);
 
     /// emitGEPOperation - Common code shared between visitGetElementPtrInst and
     /// constant expression GEP support.
@@ -812,23 +810,28 @@
 }
 
 
-void ISel::getAddressingMode(Value *Addr, unsigned &BaseReg, unsigned &Scale,
-                             unsigned &IndexReg, unsigned &Disp) {
-  BaseReg = 0; Scale = 1; IndexReg = 0; Disp = 0;
+void ISel::getAddressingMode(Value *Addr, X86AddressMode &AM) {
+  AM.BaseType = X86AddressMode::RegBase;
+  AM.Base.Reg = 0; AM.Scale = 1; AM.IndexReg = 0; AM.Disp = 0;
   if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Addr)) {
     if (isGEPFoldable(BB, GEP->getOperand(0), GEP->op_begin()+1, GEP->op_end(),
-                       BaseReg, Scale, IndexReg, Disp))
+                       AM))
       return;
   } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Addr)) {
     if (CE->getOpcode() == Instruction::GetElementPtr)
       if (isGEPFoldable(BB, CE->getOperand(0), CE->op_begin()+1, CE->op_end(),
-                        BaseReg, Scale, IndexReg, Disp))
+                        AM))
         return;
+  } else if (AllocaInst *AI = dyn_castFixedAlloca(Addr)) {
+    AM.BaseType = X86AddressMode::FrameIndexBase;
+    AM.Base.FrameIndex = getFixedSizedAllocaFI(AI);
+    return;
   }
 
   // If it's not foldable, reset addr mode.
-  BaseReg = getReg(Addr);
-  Scale = 1; IndexReg = 0; Disp = 0;
+  AM.BaseType = X86AddressMode::RegBase;
+  AM.Base.Reg = getReg(Addr);
+  AM.Scale = 1; AM.IndexReg = 0; AM.Disp = 0;
 }
 
 // canFoldSetCCIntoBranchOrSelect - Return the setcc instruction if we can fold
@@ -1995,12 +1998,10 @@
       addFrameReference(BuildMI(BB, Opcode, 5, DestReg).addReg(Op0r), FI);
 
     } else {
-      unsigned BaseReg, Scale, IndexReg, Disp;
-      getAddressingMode(cast<LoadInst>(Op1)->getOperand(0), BaseReg,
-                        Scale, IndexReg, Disp);
+      X86AddressMode AM;
+      getAddressingMode(cast<LoadInst>(Op1)->getOperand(0), AM);
       
-      addFullAddress(BuildMI(BB, Opcode, 5, DestReg).addReg(Op0r),
-                     BaseReg, Scale, IndexReg, Disp);
+      addFullAddress(BuildMI(BB, Opcode, 5, DestReg).addReg(Op0r), AM);
     }
     return;
   }
@@ -2020,12 +2021,10 @@
       unsigned FI = getFixedSizedAllocaFI(AI);
       addFrameReference(BuildMI(BB, Opcode, 5, DestReg).addReg(Op1r), FI);
     } else {
-      unsigned BaseReg, Scale, IndexReg, Disp;
-      getAddressingMode(cast<LoadInst>(Op0)->getOperand(0), BaseReg,
-                        Scale, IndexReg, Disp);
+      X86AddressMode AM;
+      getAddressingMode(cast<LoadInst>(Op0)->getOperand(0), AM);
       
-      addFullAddress(BuildMI(BB, Opcode, 5, DestReg).addReg(Op1r),
-                     BaseReg, Scale, IndexReg, Disp);
+      addFullAddress(BuildMI(BB, Opcode, 5, DestReg).addReg(Op1r), AM);
     }
     return;
   }
@@ -2352,8 +2351,13 @@
   case 5:
   case 9:
     if (Class == cInt) {
-      addFullAddress(BuildMI(*MBB, IP, X86::LEA32r, 5, DestReg),
-                     op0Reg, ConstRHS-1, op0Reg, 0);
+      X86AddressMode AM;
+      AM.BaseType = X86AddressMode::RegBase;
+      AM.Base.Reg = op0Reg;
+      AM.Scale = ConstRHS-1;
+      AM.IndexReg = op0Reg;
+      AM.Disp = 0;
+      addFullAddress(BuildMI(*MBB, IP, X86::LEA32r, 5, DestReg), AM);
       return;
     }
   case -3:
@@ -2361,8 +2365,13 @@
   case -9:
     if (Class == cInt) {
       TmpReg = makeAnotherReg(DestTy);
-      addFullAddress(BuildMI(*MBB, IP, X86::LEA32r, 5, TmpReg),
-                     op0Reg, -ConstRHS-1, op0Reg, 0);
+      X86AddressMode AM;
+      AM.BaseType = X86AddressMode::RegBase;
+      AM.Base.Reg = op0Reg;
+      AM.Scale = -ConstRHS-1;
+      AM.IndexReg = op0Reg;
+      AM.Disp = 0;
+      addFullAddress(BuildMI(*MBB, IP, X86::LEA32r, 5, TmpReg), AM);
       BuildMI(*MBB, IP, NEGrTab[Class], 1, DestReg).addReg(TmpReg);
       return;
     }
@@ -2444,12 +2453,10 @@
           unsigned FI = getFixedSizedAllocaFI(AI);
           addFrameReference(BuildMI(BB, Opcode, 5, ResultReg).addReg(Op0r), FI);
         } else {
-          unsigned BaseReg, Scale, IndexReg, Disp;
-          getAddressingMode(LI->getOperand(0), BaseReg,
-                            Scale, IndexReg, Disp);
+          X86AddressMode AM;
+          getAddressingMode(LI->getOperand(0), AM);
           
-          addFullAddress(BuildMI(BB, Opcode, 5, ResultReg).addReg(Op0r),
-                         BaseReg, Scale, IndexReg, Disp);
+          addFullAddress(BuildMI(BB, Opcode, 5, ResultReg).addReg(Op0r), AM);
         }
         return;
       }
@@ -2588,12 +2595,10 @@
           unsigned FI = getFixedSizedAllocaFI(AI);
           addFrameReference(BuildMI(BB, Opcode, 5, ResultReg).addReg(Op0r), FI);
         } else {
-          unsigned BaseReg, Scale, IndexReg, Disp;
-          getAddressingMode(LI->getOperand(0), BaseReg,
-                            Scale, IndexReg, Disp);
+          X86AddressMode AM;
+          getAddressingMode(LI->getOperand(0), AM);
           
-          addFullAddress(BuildMI(BB, Opcode, 5, ResultReg).addReg(Op0r),
-                         BaseReg, Scale, IndexReg, Disp);
+          addFullAddress(BuildMI(BB, Opcode, 5, ResultReg).addReg(Op0r), AM);
         }
         return;
       }
@@ -2609,10 +2614,9 @@
           unsigned FI = getFixedSizedAllocaFI(AI);
           addFrameReference(BuildMI(BB, Opcode, 5, ResultReg).addReg(Op1r), FI);
         } else {
-          unsigned BaseReg, Scale, IndexReg, Disp;
-          getAddressingMode(LI->getOperand(0), BaseReg, Scale, IndexReg, Disp);
-          addFullAddress(BuildMI(BB, Opcode, 5, ResultReg).addReg(Op1r),
-                         BaseReg, Scale, IndexReg, Disp);
+          X86AddressMode AM;
+          getAddressingMode(LI->getOperand(0), AM);
+          addFullAddress(BuildMI(BB, Opcode, 5, ResultReg).addReg(Op1r), AM);
         }
         return;
       }
@@ -2938,10 +2942,9 @@
           unsigned FI = getFixedSizedAllocaFI(AI);
           addFrameReference(BuildMI(BB, Opcode[Class], 4, DestReg), FI);
         } else {
-          unsigned BaseReg = 0, Scale = 1, IndexReg = 0, Disp = 0;
-          getAddressingMode(I.getOperand(0), BaseReg, Scale, IndexReg, Disp);
-          addFullAddress(BuildMI(BB, Opcode[Class], 4, DestReg),
-                         BaseReg, Scale, IndexReg, Disp);
+          X86AddressMode AM;
+          getAddressingMode(I.getOperand(0), AM);
+          addFullAddress(BuildMI(BB, Opcode[Class], 4, DestReg), AM);
         }
         return;
       } else {
@@ -3011,17 +3014,15 @@
       addFrameReference(BuildMI(BB, Opcode, 4, DestReg), FI);
     }
   } else {
-    unsigned BaseReg = 0, Scale = 1, IndexReg = 0, Disp = 0;
-    getAddressingMode(I.getOperand(0), BaseReg, Scale, IndexReg, Disp);
+    X86AddressMode AM;
+    getAddressingMode(I.getOperand(0), AM);
     
     if (Class == cLong) {
-      addFullAddress(BuildMI(BB, X86::MOV32rm, 4, DestReg),
-                     BaseReg, Scale, IndexReg, Disp);
-      addFullAddress(BuildMI(BB, X86::MOV32rm, 4, DestReg+1),
-                     BaseReg, Scale, IndexReg, Disp+4);
+      addFullAddress(BuildMI(BB, X86::MOV32rm, 4, DestReg), AM);
+      AM.Disp += 4;
+      addFullAddress(BuildMI(BB, X86::MOV32rm, 4, DestReg+1), AM);
     } else {
-      addFullAddress(BuildMI(BB, Opcode, 4, DestReg),
-                     BaseReg, Scale, IndexReg, Disp);
+      addFullAddress(BuildMI(BB, Opcode, 4, DestReg), AM);
     }
   }
 }
@@ -3030,13 +3031,8 @@
 /// instruction.
 ///
 void ISel::visitStoreInst(StoreInst &I) {
-  unsigned BaseReg = ~0U, Scale = ~0U, IndexReg = ~0U, Disp = ~0U;
-  unsigned AllocaFrameIdx = ~0U;
-
-  if (AllocaInst *AI = dyn_castFixedAlloca(I.getOperand(1)))
-    AllocaFrameIdx = getFixedSizedAllocaFI(AI);
-  else
-    getAddressingMode(I.getOperand(1), BaseReg, Scale, IndexReg, Disp);
+  X86AddressMode AM;
+  getAddressingMode(I.getOperand(1), AM);
 
   const Type *ValTy = I.getOperand(0)->getType();
   unsigned Class = getClassB(ValTy);
@@ -3044,42 +3040,20 @@
   if (ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(0))) {
     uint64_t Val = CI->getRawValue();
     if (Class == cLong) {
-      if (AllocaFrameIdx != ~0U) {
-        addFrameReference(BuildMI(BB, X86::MOV32mi, 5),
-                          AllocaFrameIdx).addImm(Val & ~0U);
-        addFrameReference(BuildMI(BB, X86::MOV32mi, 5),
-                          AllocaFrameIdx, 4).addImm(Val>>32);
-      } else {
-        addFullAddress(BuildMI(BB, X86::MOV32mi, 5),
-                       BaseReg, Scale, IndexReg, Disp).addImm(Val & ~0U);
-        addFullAddress(BuildMI(BB, X86::MOV32mi, 5),
-                       BaseReg, Scale, IndexReg, Disp+4).addImm(Val>>32);
-      }
+      addFullAddress(BuildMI(BB, X86::MOV32mi, 5), AM).addImm(Val & ~0U);
+      AM.Disp += 4;
+      addFullAddress(BuildMI(BB, X86::MOV32mi, 5), AM).addImm(Val>>32);
     } else {
       static const unsigned Opcodes[] = {
         X86::MOV8mi, X86::MOV16mi, X86::MOV32mi
       };
       unsigned Opcode = Opcodes[Class];
-      if (AllocaFrameIdx != ~0U)
-        addFrameReference(BuildMI(BB, Opcode, 5), AllocaFrameIdx).addImm(Val);
-      else
-        addFullAddress(BuildMI(BB, Opcode, 5),
-                       BaseReg, Scale, IndexReg, Disp).addImm(Val);
+      addFullAddress(BuildMI(BB, Opcode, 5), AM).addImm(Val);
     }
   } else if (isa<ConstantPointerNull>(I.getOperand(0))) {
-    if (AllocaFrameIdx != ~0U)
-      addFrameReference(BuildMI(BB, X86::MOV32mi, 5), AllocaFrameIdx).addImm(0);
-    else
-      addFullAddress(BuildMI(BB, X86::MOV32mi, 5),
-                     BaseReg, Scale, IndexReg, Disp).addImm(0);
-    
+     addFullAddress(BuildMI(BB, X86::MOV32mi, 5), AM).addImm(0);
   } else if (ConstantBool *CB = dyn_cast<ConstantBool>(I.getOperand(0))) {
-    if (AllocaFrameIdx != ~0U)
-      addFrameReference(BuildMI(BB, X86::MOV8mi, 5),
-                        AllocaFrameIdx).addImm(CB->getValue());
-    else
-      addFullAddress(BuildMI(BB, X86::MOV8mi, 5),
-                     BaseReg, Scale, IndexReg, Disp).addImm(CB->getValue());
+    addFullAddress(BuildMI(BB, X86::MOV8mi, 5), AM).addImm(CB->getValue());
   } else if (ConstantFP *CFP = dyn_cast<ConstantFP>(I.getOperand(0))) {
     // Store constant FP values with integer instructions to avoid having to
     // load the constants from the constant pool then do a store.
@@ -3089,45 +3063,24 @@
         float    F;
       } V;
       V.F = CFP->getValue();
-      if (AllocaFrameIdx != ~0U)
-        addFrameReference(BuildMI(BB, X86::MOV32mi, 5),
-                          AllocaFrameIdx).addImm(V.I);
-      else
-        addFullAddress(BuildMI(BB, X86::MOV32mi, 5),
-                       BaseReg, Scale, IndexReg, Disp).addImm(V.I);
+      addFullAddress(BuildMI(BB, X86::MOV32mi, 5), AM).addImm(V.I);
     } else {
       union {
         uint64_t I;
         double   F;
       } V;
       V.F = CFP->getValue();
-      if (AllocaFrameIdx != ~0U) {
-        addFrameReference(BuildMI(BB, X86::MOV32mi, 5),
-                          AllocaFrameIdx).addImm((unsigned)V.I);
-        addFrameReference(BuildMI(BB, X86::MOV32mi, 5),
-                          AllocaFrameIdx, 4).addImm(unsigned(V.I >> 32));
-      } else {
-        addFullAddress(BuildMI(BB, X86::MOV32mi, 5),
-                       BaseReg, Scale, IndexReg, Disp).addImm((unsigned)V.I);
-        addFullAddress(BuildMI(BB, X86::MOV32mi, 5),
-                       BaseReg, Scale, IndexReg, Disp+4).addImm(
+      addFullAddress(BuildMI(BB, X86::MOV32mi, 5), AM).addImm((unsigned)V.I);
+      AM.Disp += 4;
+      addFullAddress(BuildMI(BB, X86::MOV32mi, 5), AM).addImm(
                                                           unsigned(V.I >> 32));
-      }
     }
     
   } else if (Class == cLong) {
     unsigned ValReg = getReg(I.getOperand(0));
-    if (AllocaFrameIdx != ~0U) {
-      addFrameReference(BuildMI(BB, X86::MOV32mr, 5),
-                        AllocaFrameIdx).addReg(ValReg);
-      addFrameReference(BuildMI(BB, X86::MOV32mr, 5),
-                        AllocaFrameIdx, 4).addReg(ValReg+1);
-    } else {
-      addFullAddress(BuildMI(BB, X86::MOV32mr, 5),
-                     BaseReg, Scale, IndexReg, Disp).addReg(ValReg);
-      addFullAddress(BuildMI(BB, X86::MOV32mr, 5),
-                     BaseReg, Scale, IndexReg, Disp+4).addReg(ValReg+1);
-    }
+    addFullAddress(BuildMI(BB, X86::MOV32mr, 5), AM).addReg(ValReg);
+    AM.Disp += 4;
+    addFullAddress(BuildMI(BB, X86::MOV32mr, 5), AM).addReg(ValReg+1);
   } else {
     unsigned ValReg = getReg(I.getOperand(0));
     static const unsigned Opcodes[] = {
@@ -3136,11 +3089,7 @@
     unsigned Opcode = Opcodes[Class];
     if (ValTy == Type::DoubleTy) Opcode = X86::FST64m;
 
-    if (AllocaFrameIdx != ~0U)
-      addFrameReference(BuildMI(BB, Opcode, 5), AllocaFrameIdx).addReg(ValReg);
-    else
-      addFullAddress(BuildMI(BB, Opcode, 1+4),
-                     BaseReg, Scale, IndexReg, Disp).addReg(ValReg);
+    addFullAddress(BuildMI(BB, Opcode, 1+4), AM).addReg(ValReg);
   }
 }
 
@@ -3539,8 +3488,8 @@
 void ISel::visitGetElementPtrInst(GetElementPtrInst &I) {
   // If this GEP instruction will be folded into all of its users, we don't need
   // to explicitly calculate it!
-  unsigned A, B, C, D;
-  if (isGEPFoldable(0, I.getOperand(0), I.op_begin()+1, I.op_end(), A,B,C,D)) {
+  X86AddressMode AM;
+  if (isGEPFoldable(0, I.getOperand(0), I.op_begin()+1, I.op_end(), AM)) {
     // Check all of the users of the instruction to see if they are loads and
     // stores.
     bool AllWillFold = true;
@@ -3575,15 +3524,16 @@
 ///
 void ISel::getGEPIndex(MachineBasicBlock *MBB, MachineBasicBlock::iterator IP,
                        std::vector<Value*> &GEPOps,
-                       std::vector<const Type*> &GEPTypes, unsigned &BaseReg,
-                       unsigned &Scale, unsigned &IndexReg, unsigned &Disp) {
+                       std::vector<const Type*> &GEPTypes,
+                       X86AddressMode &AM) {
   const TargetData &TD = TM.getTargetData();
 
   // Clear out the state we are working with...
-  BaseReg = 0;    // No base register
-  Scale = 1;      // Unit scale
-  IndexReg = 0;   // No index register
-  Disp = 0;       // No displacement
+  AM.BaseType = X86AddressMode::RegBase;
+  AM.Base.Reg = 0;   // No base register
+  AM.Scale = 1;      // Unit scale
+  AM.IndexReg = 0;   // No index register
+  AM.Disp = 0;       // No displacement
 
   // While there are GEP indexes that can be folded into the current address,
   // keep processing them.
@@ -3597,7 +3547,7 @@
       // 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.
-      Disp += TD.getStructLayout(StTy)->MemberOffsets[CUI->getValue()];
+      AM.Disp += TD.getStructLayout(StTy)->MemberOffsets[CUI->getValue()];
       GEPOps.pop_back();        // Consume a GEP operand
       GEPTypes.pop_back();
     } else {
@@ -3612,18 +3562,18 @@
       // If idx is a constant, fold it into the offset.
       unsigned TypeSize = TD.getTypeSize(SqTy->getElementType());
       if (ConstantSInt *CSI = dyn_cast<ConstantSInt>(idx)) {
-        Disp += TypeSize*CSI->getValue();
+        AM.Disp += TypeSize*CSI->getValue();
       } else if (ConstantUInt *CUI = dyn_cast<ConstantUInt>(idx)) {
-        Disp += TypeSize*CUI->getValue();
+        AM.Disp += TypeSize*CUI->getValue();
       } else {
         // If the index reg is already taken, we can't handle this index.
-        if (IndexReg) return;
+        if (AM.IndexReg) return;
 
         // If this is a size that we can handle, then add the index as 
         switch (TypeSize) {
         case 1: case 2: case 4: case 8:
           // These are all acceptable scales on X86.
-          Scale = TypeSize;
+          AM.Scale = TypeSize;
           break;
         default:
           // Otherwise, we can't handle this scale
@@ -3635,7 +3585,7 @@
               CI->getOperand(0)->getType() == Type::UIntTy)
             idx = CI->getOperand(0);
 
-        IndexReg = MBB ? getReg(idx, MBB, IP) : 1;
+        AM.IndexReg = MBB ? getReg(idx, MBB, IP) : 1;
       }
 
       GEPOps.pop_back();        // Consume a GEP operand
@@ -3646,22 +3596,23 @@
   // GEPTypes is empty, which means we have a single operand left.  Set it as
   // the base register.
   //
-  assert(BaseReg == 0);
+  assert(AM.Base.Reg == 0);
 
-#if 0   // FIXME: TODO!
-  if (AllocaInst *AI = dyn_castFixedAlloca(V)) {
-    // FIXME: When we can add FrameIndex values as the first operand, we can
-    // make GEP's of allocas MUCH more efficient!
-    unsigned FI = getFixedSizedAllocaFI(AI);
+  if (AllocaInst *AI = dyn_castFixedAlloca(GEPOps.back())) {
+    AM.BaseType = X86AddressMode::FrameIndexBase;
+    AM.Base.FrameIndex = getFixedSizedAllocaFI(AI);
     GEPOps.pop_back();
     return;
-  } else if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
+  }
+
+#if 0   // FIXME: TODO!
+  if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
     // FIXME: When addressing modes are more powerful/correct, we could load
     // global addresses directly as 32-bit immediates.
   }
 #endif
 
-  BaseReg = MBB ? getReg(GEPOps[0], MBB, IP) : 1;
+  AM.Base.Reg = MBB ? getReg(GEPOps[0], MBB, IP) : 1;
   GEPOps.pop_back();        // Consume the last GEP operand
 }
 
@@ -3670,8 +3621,7 @@
 /// folded into the addressing mode of a load/store or lea instruction.
 bool ISel::isGEPFoldable(MachineBasicBlock *MBB,
                          Value *Src, User::op_iterator IdxBegin,
-                         User::op_iterator IdxEnd, unsigned &BaseReg,
-                         unsigned &Scale, unsigned &IndexReg, unsigned &Disp) {
+                         User::op_iterator IdxEnd, X86AddressMode &AM) {
 
   std::vector<Value*> GEPOps;
   GEPOps.resize(IdxEnd-IdxBegin+1);
@@ -3684,7 +3634,7 @@
 
   MachineBasicBlock::iterator IP;
   if (MBB) IP = MBB->end();
-  getGEPIndex(MBB, IP, GEPOps, GEPTypes, BaseReg, Scale, IndexReg, Disp);
+  getGEPIndex(MBB, IP, GEPOps, GEPTypes, AM);
 
   // We can fold it away iff the getGEPIndex call eliminated all operands.
   return GEPOps.empty();
@@ -3723,23 +3673,23 @@
   // Keep emitting instructions until we consume the entire GEP instruction.
   while (!GEPOps.empty()) {
     unsigned OldSize = GEPOps.size();
-    unsigned BaseReg, Scale, IndexReg, Disp;
-    getGEPIndex(MBB, IP, GEPOps, GEPTypes, BaseReg, Scale, IndexReg, Disp);
+    X86AddressMode AM;
+    getGEPIndex(MBB, IP, GEPOps, GEPTypes, AM);
     
     if (GEPOps.size() != OldSize) {
       // getGEPIndex consumed some of the input.  Build an LEA instruction here.
       unsigned NextTarget = 0;
       if (!GEPOps.empty()) {
-        assert(BaseReg == 0 &&
+        assert(AM.Base.Reg == 0 &&
            "getGEPIndex should have left the base register open for chaining!");
-        NextTarget = BaseReg = makeAnotherReg(Type::UIntTy);
+        NextTarget = AM.Base.Reg = makeAnotherReg(Type::UIntTy);
       }
 
-      if (IndexReg == 0 && Disp == 0)
-        BuildMI(*MBB, IP, X86::MOV32rr, 1, TargetReg).addReg(BaseReg);
+      if (AM.BaseType == X86AddressMode::RegBase &&
+              AM.IndexReg == 0 && AM.Disp == 0)
+        BuildMI(*MBB, IP, X86::MOV32rr, 1, TargetReg).addReg(AM.Base.Reg);
       else
-        addFullAddress(BuildMI(*MBB, IP, X86::LEA32r, 5, TargetReg),
-                       BaseReg, Scale, IndexReg, Disp);
+        addFullAddress(BuildMI(*MBB, IP, X86::LEA32r, 5, TargetReg), AM);
       --IP;
       TargetReg = NextTarget;
     } else if (GEPTypes.empty()) {


Index: llvm/lib/Target/X86/X86InstrBuilder.h
diff -u llvm/lib/Target/X86/X86InstrBuilder.h:1.11 llvm/lib/Target/X86/X86InstrBuilder.h:1.12
--- llvm/lib/Target/X86/X86InstrBuilder.h:1.11	Thu Mar  4 12:05:02 2004
+++ llvm/lib/Target/X86/X86InstrBuilder.h	Sun Aug 29 19:13:26 2004
@@ -28,6 +28,29 @@
 
 namespace llvm {
 
+/// X86AddressMode - This struct holds a generalized full x86 address mode.
+/// The base register can be a frame index, which will eventually be replaced
+/// with BP or SP and Disp being offsetted accordingly.
+/// FIXME: add support for globals as a new base type.
+struct X86AddressMode {
+    enum {
+      UnknownBase,
+      RegBase,
+      FrameIndexBase
+    } BaseType;
+
+    union {
+      unsigned Reg;
+      int FrameIndex;
+    } Base;
+
+    unsigned Scale;
+    unsigned IndexReg;
+    unsigned Disp;
+
+    X86AddressMode() : BaseType(UnknownBase) {}
+};
+
 /// addDirectMem - This function is used to add a direct memory reference to the
 /// current instruction -- that is, a dereference of an address in a register,
 /// with no scale, index or displacement. An example is: DWORD PTR [EAX].
@@ -50,12 +73,16 @@
 }
 
 inline const MachineInstrBuilder &addFullAddress(const MachineInstrBuilder &MIB,
-                                                 unsigned BaseReg,
-                                                 unsigned Scale,
-                                                 unsigned IndexReg,
-                                                 unsigned Disp) {
-  assert (Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8);
-  return MIB.addReg(BaseReg).addZImm(Scale).addReg(IndexReg).addSImm(Disp);
+                                                 const X86AddressMode &AM) {
+  assert (AM.Scale == 1 || AM.Scale == 2 || AM.Scale == 4 || AM.Scale == 8);
+
+  if (AM.BaseType == X86AddressMode::RegBase)
+    MIB.addReg(AM.Base.Reg);
+  else if (AM.BaseType == X86AddressMode::FrameIndexBase)
+    MIB.addFrameIndex(AM.Base.FrameIndex);
+  else
+    assert (0);
+  return MIB.addZImm(AM.Scale).addReg(AM.IndexReg).addSImm(AM.Disp);
 }
 
 /// addFrameReference - This function is used to add a reference to the base of






More information about the llvm-commits mailing list