[llvm-commits] [llvm] r119856 - /llvm/trunk/lib/Target/ARM/ARMFastISel.cpp

Eric Christopher echristo at apple.com
Fri Nov 19 14:30:02 PST 2010


Author: echristo
Date: Fri Nov 19 16:30:02 2010
New Revision: 119856

URL: http://llvm.org/viewvc/llvm-project?rev=119856&view=rev
Log:
Refactor address mode handling into a single struct (ala x86), this
should give allow a wider range of addressing modes.

No functional change.

Modified:
    llvm/trunk/lib/Target/ARM/ARMFastISel.cpp

Modified: llvm/trunk/lib/Target/ARM/ARMFastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFastISel.cpp?rev=119856&r1=119855&r2=119856&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMFastISel.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMFastISel.cpp Fri Nov 19 16:30:02 2010
@@ -53,6 +53,29 @@
                     cl::init(false), cl::Hidden);
 
 namespace {
+  
+  // All possible address modes, plus some.
+  typedef struct Address {
+    enum {
+      RegBase,
+      FrameIndexBase
+    } BaseType;
+    
+    union {
+      unsigned Reg;
+      int FI;
+    } Base;
+    
+    int Offset;
+    unsigned Scale;
+    unsigned PlusReg;
+    
+    // Innocuous defaults for our address.
+    Address()
+     : BaseType(RegBase), Offset(0), Scale(0), PlusReg(0) {
+       Base.Reg = 0;
+     }
+  } Address;
 
 class ARMFastISel : public FastISel {
 
@@ -138,10 +161,10 @@
   private:
     bool isTypeLegal(const Type *Ty, MVT &VT);
     bool isLoadTypeLegal(const Type *Ty, MVT &VT);
-    bool ARMEmitLoad(EVT VT, unsigned &ResultReg, unsigned Base, int Offset);
-    bool ARMEmitStore(EVT VT, unsigned SrcReg, unsigned Base, int Offset);
-    bool ARMComputeRegOffset(const Value *Obj, unsigned &Base, int &Offset);
-    void ARMSimplifyRegOffset(unsigned &Base, int &Offset, EVT VT);
+    bool ARMEmitLoad(EVT VT, unsigned &ResultReg, Address &Addr);
+    bool ARMEmitStore(EVT VT, unsigned SrcReg, Address &Addr);
+    bool ARMComputeAddress(const Value *Obj, Address &Addr);
+    void ARMSimplifyAddress(Address &Addr, EVT VT);
     unsigned ARMMaterializeFP(const ConstantFP *CFP, EVT VT);
     unsigned ARMMaterializeInt(const Constant *C, EVT VT);
     unsigned ARMMaterializeGV(const GlobalValue *GV, EVT VT);
@@ -581,8 +604,7 @@
 }
 
 // Computes the Reg+Offset to get to an object.
-bool ARMFastISel::ARMComputeRegOffset(const Value *Obj, unsigned &Base,
-                                      int &Offset) {
+bool ARMFastISel::ARMComputeAddress(const Value *Obj, Address &Addr) {
   // Some boilerplate from the X86 FastISel.
   const User *U = NULL;
   unsigned Opcode = Instruction::UserOp1;
@@ -611,24 +633,24 @@
     break;
     case Instruction::BitCast: {
       // Look through bitcasts.
-      return ARMComputeRegOffset(U->getOperand(0), Base, Offset);
+      return ARMComputeAddress(U->getOperand(0), Addr);
     }
     case Instruction::IntToPtr: {
       // Look past no-op inttoptrs.
       if (TLI.getValueType(U->getOperand(0)->getType()) == TLI.getPointerTy())
-        return ARMComputeRegOffset(U->getOperand(0), Base, Offset);
+        return ARMComputeAddress(U->getOperand(0), Addr);
       break;
     }
     case Instruction::PtrToInt: {
       // Look past no-op ptrtoints.
       if (TLI.getValueType(U->getType()) == TLI.getPointerTy())
-        return ARMComputeRegOffset(U->getOperand(0), Base, Offset);
+        return ARMComputeAddress(U->getOperand(0), Addr);
       break;
     }
     case Instruction::GetElementPtr: {
-      int SavedOffset = Offset;
-      unsigned SavedBase = Base;
-      int TmpOffset = Offset;
+      int SavedOffset = Addr.Offset;
+      unsigned SavedBase = Addr.Base.Reg;
+      int TmpOffset = Addr.Offset;
 
       // Iterate through the GEP folding the constants into offsets where
       // we can.
@@ -664,12 +686,12 @@
       }
 
       // Try to grab the base operand now.
-      Offset = TmpOffset;
-      if (ARMComputeRegOffset(U->getOperand(0), Base, Offset)) return true;
+      Addr.Offset = TmpOffset;
+      if (ARMComputeAddress(U->getOperand(0), Addr)) return true;
 
       // We failed, restore everything and try the other options.
-      Offset = SavedOffset;
-      Base = SavedBase;
+      Addr.Offset = SavedOffset;
+      Addr.Base.Reg = SavedBase;
 
       unsupported_gep:
       break;
@@ -680,7 +702,7 @@
 
       if (Reg == 0) return false;
 
-      Base = Reg;
+      Addr.Base.Reg = Reg;
       return true;
     }
   }
@@ -691,16 +713,16 @@
     unsigned Tmp = ARMMaterializeGV(GV, TLI.getValueType(Obj->getType()));
     if (Tmp == 0) return false;
 
-    Base = Tmp;
+    Addr.Base.Reg = Tmp;
     return true;
   }
 
   // Try to get this in a register if nothing else has worked.
-  if (Base == 0) Base = getRegForValue(Obj);
-  return Base != 0;
+  if (Addr.Base.Reg == 0) Addr.Base.Reg = getRegForValue(Obj);
+  return Addr.Base.Reg != 0;
 }
 
-void ARMFastISel::ARMSimplifyRegOffset(unsigned &Base, int &Offset, EVT VT) {
+void ARMFastISel::ARMSimplifyAddress(Address &Addr, EVT VT) {
 
   assert(VT.isSimple() && "Non-simple types are invalid here!");
 
@@ -713,12 +735,12 @@
     case MVT::i16:
     case MVT::i32:
       // Integer loads/stores handle 12-bit offsets.
-      needsLowering = ((Offset & 0xfff) != Offset);
+      needsLowering = ((Addr.Offset & 0xfff) != Addr.Offset);
       break;
     case MVT::f32:
     case MVT::f64:
       // Floating point operands handle 8-bit offsets.
-      needsLowering = ((Offset & 0xff) != Offset);
+      needsLowering = ((Addr.Offset & 0xff) != Addr.Offset);
       break;
   }
 
@@ -734,21 +756,21 @@
 
     if (!isThumb)
       emitARMRegPlusImmediate(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
-                              BaseReg, Base, Offset, Pred, PredReg,
+                              BaseReg, Addr.Base.Reg, Addr.Offset,
+                              Pred, PredReg,
                               static_cast<const ARMBaseInstrInfo&>(TII));
     else {
       assert(AFI->isThumb2Function());
       emitT2RegPlusImmediate(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
-                             BaseReg, Base, Offset, Pred, PredReg,
+                             BaseReg, Addr.Base.Reg, Addr.Offset, Pred, PredReg,
                              static_cast<const ARMBaseInstrInfo&>(TII));
     }
-    Offset = 0;
-    Base = BaseReg;
+    Addr.Offset = 0;
+    Addr.Base.Reg = BaseReg;
   }
 }
 
-bool ARMFastISel::ARMEmitLoad(EVT VT, unsigned &ResultReg,
-                              unsigned Base, int Offset) {
+bool ARMFastISel::ARMEmitLoad(EVT VT, unsigned &ResultReg, Address &Addr) {
 
   assert(VT.isSimple() && "Non-simple types are invalid here!");
   unsigned Opc;
@@ -784,22 +806,22 @@
 
   ResultReg = createResultReg(RC);
 
-  ARMSimplifyRegOffset(Base, Offset, VT);
+  ARMSimplifyAddress(Addr, VT);
 
   // addrmode5 output depends on the selection dag addressing dividing the
   // offset by 4 that it then later multiplies. Do this here as well.
   if (isFloat)
-    Offset /= 4;
+    Addr.Offset /= 4;
 
   // LDRH needs an additional operand.
   if (!isThumb && VT.getSimpleVT().SimpleTy == MVT::i16)
     AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
                             TII.get(Opc), ResultReg)
-                    .addReg(Base).addReg(0).addImm(Offset));
+                    .addReg(Addr.Base.Reg).addReg(0).addImm(Addr.Offset));
   else
     AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
                             TII.get(Opc), ResultReg)
-                    .addReg(Base).addImm(Offset));
+                    .addReg(Addr.Base.Reg).addImm(Addr.Offset));
   return true;
 }
 
@@ -810,22 +832,20 @@
     return false;
 
   // Our register and offset with innocuous defaults.
-  unsigned Base = 0;
-  int Offset = 0;
+  Address Addr;
 
   // See if we can handle this as Reg + Offset
-  if (!ARMComputeRegOffset(I->getOperand(0), Base, Offset))
+  if (!ARMComputeAddress(I->getOperand(0), Addr))
     return false;
 
   unsigned ResultReg;
-  if (!ARMEmitLoad(VT, ResultReg, Base, Offset)) return false;
+  if (!ARMEmitLoad(VT, ResultReg, Addr)) return false;
 
   UpdateValueMap(I, ResultReg);
   return true;
 }
 
-bool ARMFastISel::ARMEmitStore(EVT VT, unsigned SrcReg,
-                               unsigned Base, int Offset) {
+bool ARMFastISel::ARMEmitStore(EVT VT, unsigned SrcReg, Address &Addr) {
   unsigned StrOpc;
   bool isFloat = false;
   bool needReg0Op = false;
@@ -862,23 +882,24 @@
       break;
   }
 
-  ARMSimplifyRegOffset(Base, Offset, VT);
+  ARMSimplifyAddress(Addr, VT);
 
   // addrmode5 output depends on the selection dag addressing dividing the
   // offset by 4 that it then later multiplies. Do this here as well.
   if (isFloat)
-    Offset /= 4;
+    Addr.Offset /= 4;
 
   // FIXME: The 'needReg0Op' bit goes away once STRH is converted to
   // not use the mega-addrmode stuff.
   if (!needReg0Op)
     AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
                             TII.get(StrOpc))
-                    .addReg(SrcReg).addReg(Base).addImm(Offset));
+                    .addReg(SrcReg).addReg(Addr.Base.Reg).addImm(Addr.Offset));
   else
     AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
                             TII.get(StrOpc))
-                    .addReg(SrcReg).addReg(Base).addReg(0).addImm(Offset));
+                    .addReg(SrcReg).addReg(Addr.Base.Reg)
+                    .addReg(0).addImm(Addr.Offset));
 
   return true;
 }
@@ -898,14 +919,13 @@
     return false;
 
   // Our register and offset with innocuous defaults.
-  unsigned Base = 0;
-  int Offset = 0;
+  Address Addr;
 
   // See if we can handle this as Reg + Offset
-  if (!ARMComputeRegOffset(I->getOperand(1), Base, Offset))
+  if (!ARMComputeAddress(I->getOperand(1), Addr))
     return false;
 
-  if (!ARMEmitStore(VT, SrcReg, Base, Offset)) return false;
+  if (!ARMEmitStore(VT, SrcReg, Addr)) return false;
 
   return true;
 }
@@ -1475,10 +1495,12 @@
     } else {
       assert(VA.isMemLoc());
       // Need to store on the stack.
-      unsigned Base = ARM::SP;
-      int Offset = VA.getLocMemOffset();
+      Address Addr;
+      Addr.BaseType = Address::RegBase;
+      Addr.Base.Reg = ARM::SP;
+      Addr.Offset = VA.getLocMemOffset();
 
-      if (!ARMEmitStore(ArgVT, Arg, Base, Offset)) return false;
+      if (!ARMEmitStore(ArgVT, Arg, Addr)) return false;
     }
   }
   return true;





More information about the llvm-commits mailing list