[llvm-commits] [llvm] r42780 - in /llvm/trunk/lib/Target/Mips: MipsISelLowering.cpp MipsISelLowering.h MipsRegisterInfo.cpp

Bruno Cardoso Lopes bruno.cardoso at gmail.com
Mon Oct 8 20:15:13 PDT 2007


Author: bruno
Date: Mon Oct  8 22:15:11 2007
New Revision: 42780

URL: http://llvm.org/viewvc/llvm-project?rev=42780&view=rev
Log:
Position Independent Code (PIC) support [3]

Modified:
    llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp
    llvm/trunk/lib/Target/Mips/MipsISelLowering.h
    llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp

Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp?rev=42780&r1=42779&r2=42780&view=diff

==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Mon Oct  8 22:15:11 2007
@@ -44,6 +44,7 @@
     case MipsISD::Lo        : return "MipsISD::Lo";
     case MipsISD::Ret       : return "MipsISD::Ret";
     case MipsISD::Add       : return "MipsISD::Add";
+    case MipsISD::LoadAddr  : return "MipsISD::LoadAddr";
     default                 : return NULL;
   }
 }
@@ -146,18 +147,25 @@
 SDOperand MipsTargetLowering::
 LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG) 
 {
+  SDOperand ResNode;
   GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
 
   SDOperand GA = DAG.getTargetGlobalAddress(GV, MVT::i32);
 
-  const MVT::ValueType *VTs = DAG.getNodeValueTypes(MVT::i32, MVT::Flag);
-  SDOperand Ops[] = { GA };
+  // On PIC code global addresses are loaded with "la" instruction
+  if (!(getTargetMachine().getRelocationModel() == Reloc::PIC_)) {
+    const MVT::ValueType *VTs = DAG.getNodeValueTypes(MVT::i32, MVT::Flag);
+    SDOperand Ops[] = { GA };
+
+    SDOperand Hi = DAG.getNode(MipsISD::Hi, VTs, 2, Ops, 1);
+    SDOperand Lo = DAG.getNode(MipsISD::Lo, MVT::i32, GA);
+
+    SDOperand InFlag = Hi.getValue(1);
+    ResNode = DAG.getNode(MipsISD::Add, MVT::i32, Lo, Hi, InFlag);
+  } else
+    ResNode = DAG.getNode(MipsISD::LoadAddr, MVT::i32, GA);
 
-  SDOperand Hi = DAG.getNode(MipsISD::Hi, VTs, 2, Ops, 1);
-  SDOperand Lo = DAG.getNode(MipsISD::Lo, MVT::i32, GA);
-
-  SDOperand InFlag = Hi.getValue(1);
-  return DAG.getNode(MipsISD::Add, MVT::i32, Lo, Hi, InFlag);
+  return ResNode;
 }
 
 SDOperand MipsTargetLowering::
@@ -236,6 +244,7 @@
   SmallVector<SDOperand, 8> MemOpChains;
 
   SDOperand StackPtr;
+  unsigned LastStackLoc=0;
 
   // Walk the register/memloc assignments, inserting copies/loads.
   for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
@@ -273,8 +282,9 @@
       // Create the frame index object for this incoming parameter
       // This guarantees that when allocating Local Area the firsts
       // 16 bytes which are alwayes reserved won't be overwritten.
+      LastStackLoc = (16 + VA.getLocMemOffset());
       int FI = MFI->CreateFixedObject(MVT::getSizeInBits(VA.getValVT())/8,
-                                      (16 + VA.getLocMemOffset()));
+                                      LastStackLoc);
 
       SDOperand PtrOff = DAG.getFrameIndex(FI,getPointerTy());
 
@@ -284,6 +294,14 @@
     }
   }
 
+  // Create a stack location to hold GP when PIC is used 
+  if (getTargetMachine().getRelocationModel() == Reloc::PIC_) {
+      LastStackLoc = (!LastStackLoc) ? (16) : (LastStackLoc+4);
+      MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
+      MFI->CreateFixedObject(4, LastStackLoc);
+      MipsFI->setGPStackOffset(LastStackLoc);
+  }
+
   // Transform all store nodes into one single node because
   // all store nodes are independent of each other.
   if (!MemOpChains.empty())     
@@ -301,13 +319,13 @@
     InFlag = Chain.getValue(1);
   }
 
-  // If the callee is a GlobalAddress node (quite common, every direct 
-  // call is) turn it into a TargetGlobalAddress node so that legalize 
-  // doesn't hack it.
-  if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
+  // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
+  // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol 
+  // node so that legalize doesn't hack it. Otherwise we have an indirect call,
+  // if PIC is used, the call must use register GP
+  if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
     Callee = DAG.getTargetGlobalAddress(G->getGlobal(), getPointerTy());
-  } else 
-  if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
+  else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
     Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy());
 
   // MipsJmpLink = #chain, #target_address, #opt_in_flags...
@@ -543,8 +561,7 @@
 
     // ISD::RET => ret chain, (regnum1,val1), ...
     // So i*2+1 index only the regnums
-    Chain = DAG.getCopyToReg(Chain, VA.getLocReg(), 
-                                 Op.getOperand(i*2+1), Flag);
+    Chain = DAG.getCopyToReg(Chain, VA.getLocReg(), Op.getOperand(i*2+1), Flag);
 
     // guarantee that all emitted copies are
     // stuck together, avoiding something bad
@@ -554,10 +571,10 @@
   // Return on Mips is always a "jr $ra"
   if (Flag.Val)
     return DAG.getNode(MipsISD::Ret, MVT::Other, 
-                           Chain, DAG.getRegister(Mips::RA, MVT::i32), Flag);
+                       Chain, DAG.getRegister(Mips::RA, MVT::i32), Flag);
   else // Return Void
     return DAG.getNode(MipsISD::Ret, MVT::Other, 
-                           Chain, DAG.getRegister(Mips::RA, MVT::i32));
+                       Chain, DAG.getRegister(Mips::RA, MVT::i32));
 }
 
 //===----------------------------------------------------------------------===//

Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.h?rev=42780&r1=42779&r2=42780&view=diff

==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsISelLowering.h (original)
+++ llvm/trunk/lib/Target/Mips/MipsISelLowering.h Mon Oct  8 22:15:11 2007
@@ -41,7 +41,10 @@
       Ret,
 
       // Need to support addition with a input flag
-      Add
+      Add,
+
+      // Used on PIC Code to load global addresses
+      LoadAddr
     };
   }
 

Modified: llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp?rev=42780&r1=42779&r2=42780&view=diff

==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp Mon Oct  8 22:15:11 2007
@@ -369,9 +369,10 @@
   MachineFrameInfo *MFI    = MF.getFrameInfo();
   MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
   MachineBasicBlock::iterator MBBI = MBB.begin();
+  bool isPIC = (MF.getTarget().getRelocationModel() == Reloc::PIC_);
 
-  // Replace the dummy '0' SPOffset by the negative offsets, as 
-  // explained on LowerFORMAL_ARGUMENTS
+  // Replace the dummy '0' SPOffset by the negative 
+  // offsets, as explained on LowerFORMAL_ARGUMENTS
   MipsFI->adjustLoadArgsFI(MFI);
   MipsFI->adjustStoreVarArgsFI(MFI); 
 
@@ -421,6 +422,10 @@
   // Update frame info
   MFI->setStackSize(NumBytes);
 
+  // PIC speficic function prologue
+  if (isPIC)
+    BuildMI(MBB, MBBI, TII.get(Mips::CPLOAD)).addReg(Mips::T9);
+
   // Adjust stack : addi sp, sp, (-imm)
   BuildMI(MBB, MBBI, TII.get(Mips::ADDiu), Mips::SP)
       .addReg(Mips::SP).addImm(-NumBytes);
@@ -443,6 +448,12 @@
     BuildMI(MBB, MBBI, TII.get(Mips::ADDu), Mips::FP)
       .addReg(Mips::SP).addReg(Mips::ZERO);
   }
+
+  // PIC speficic function prologue
+  if ((isPIC) && (MFI->hasCalls()))
+    BuildMI(MBB, MBBI, TII.get(Mips::CPRESTORE))
+      .addImm(MipsFI->getGPStackOffset());
+
 }
 
 void MipsRegisterInfo::





More information about the llvm-commits mailing list