Hello, Everyone.

Please find patch, which will enable PIC codegen for x86/Linux target (I
think it can be easily adopted to any target, which uses GOT-style
relocations).

It was tested on some small applications from llvm-test and was running
fine. I hope to test it on huge apps soon.

-- 
With best regards, Anton Korobeynikov.

Faculty of Mathematics & Mechanics, Saint Petersburg State University.

diff -r 744250c38a89 lib/Target/X86/X86ATTAsmPrinter.cpp
--- a/lib/Target/X86/X86ATTAsmPrinter.cpp	Sat Jan 06 00:23:53 2007 +0000
+++ b/lib/Target/X86/X86ATTAsmPrinter.cpp	Thu Jan 04 16:06:56 2007 +0300
@@ -19,6 +19,7 @@
 #include "X86MachineFunctionInfo.h"
 #include "X86TargetMachine.h"
 #include "X86TargetAsmInfo.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/CallingConv.h"
 #include "llvm/Module.h"
 #include "llvm/Support/Mangler.h"
@@ -28,6 +29,21 @@ using namespace llvm;
 using namespace llvm;
 
 STATISTIC(EmittedInsts, "Number of machine instrs printed");
+
+static std::string computePICLabel(unsigned fnNumber,
+                                   const X86Subtarget* Subtarget) 
+{
+  std::string label;
+
+  if (Subtarget->isTargetDarwin()) {
+    label =  "\"L" + utostr_32(fnNumber) + "$pb\"";
+  } else if (Subtarget->isTargetELF()) {
+    label = "llvm$" + utostr_32(fnNumber) + "$piclabel";
+  } else
+    assert(0 && "Don't know how to print PIC label!\n");
+
+  return label;
+}
 
 /// getSectionForFunction - Return the section that we should emit the
 /// specified function body into.
@@ -193,9 +209,14 @@ void X86ATTAsmPrinter::printOperand(cons
     if (!isMemOp) O << '$';
     O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << "_"
       << MO.getJumpTableIndex();
-    if (X86PICStyle == PICStyle::Stub &&
-        TM.getRelocationModel() == Reloc::PIC_)
-      O << "-\"L" << getFunctionNumber() << "$pb\"";
+
+    if (TM.getRelocationModel() == Reloc::PIC_) {
+      if (Subtarget->isPICStyleStub())
+        O << "-\"L" << getFunctionNumber() << "$pb\"";
+      else if (Subtarget->isPICStyleGOT())
+        O << "@GOTOFF";
+    }
+    
     if (isMemOp && Subtarget->is64Bit() && !NotRIPRel)
       O << "(%rip)";
     return;
@@ -205,9 +226,14 @@ void X86ATTAsmPrinter::printOperand(cons
     if (!isMemOp) O << '$';
     O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_"
       << MO.getConstantPoolIndex();
-    if (X86PICStyle == PICStyle::Stub &&
-        TM.getRelocationModel() == Reloc::PIC_)
-      O << "-\"L" << getFunctionNumber() << "$pb\"";
+
+    if (TM.getRelocationModel() == Reloc::PIC_) {
+      if (Subtarget->isPICStyleStub())
+        O << "-\"L" << getFunctionNumber() << "$pb\"";
+      if (Subtarget->isPICStyleGOT())
+        O << "@GOTOFF";
+    }
+    
     int Offset = MO.getOffset();
     if (Offset > 0)
       O << "+" << Offset;
@@ -231,8 +257,7 @@ void X86ATTAsmPrinter::printOperand(cons
     
     X86SharedAsmPrinter::decorateName(Name, GV);
     
-    if (X86PICStyle == PICStyle::Stub &&
-        TM.getRelocationModel() != Reloc::Static) {
+    if (Subtarget->isPICStyleStub()) {
       // Link-once, External, or Weakly-linked global variables need
       // non-lazily-resolved stubs
       if (isExt) {
@@ -258,6 +283,9 @@ void X86ATTAsmPrinter::printOperand(cons
         O << "__imp_";          
       }       
       O << Name;
+
+      if (Subtarget->isPICStyleGOT() && isCallOp && isa<Function>(GV))
+        O << "@PLT";
     }
 
     if (GV->hasExternalWeakLinkage())
@@ -268,32 +296,53 @@ void X86ATTAsmPrinter::printOperand(cons
       O << "+" << Offset;
     else if (Offset < 0)
       O << Offset;
-
-    if (isMemOp && Subtarget->is64Bit()) {
-      if (isExt && TM.getRelocationModel() != Reloc::Static)
-        O << "@GOTPCREL(%rip)";
-      else if (!NotRIPRel)
+    
+    if (isMemOp) {
+      if (isExt) {
+        if (Subtarget->isPICStyleGOT()) {
+          O << "@GOT";
+        } else if (Subtarget->is64Bit() && Subtarget->isPICStyleGOTPCRel()) {
+          O << "@GOTPCREL(%rip)";
+        }
+      } else if (Subtarget->is64Bit() && !NotRIPRel)
         // Use rip when possible to reduce code size, except when index or
         // base register are also part of the address. e.g.
         // foo(%rip)(%rcx,%rax,4) is not legal
-        O << "(%rip)";        
+        O << "(%rip)";
+      else if (Subtarget->isPICStyleGOT())
+        O << "@GOTOFF";
     }
 
     return;
   }
   case MachineOperand::MO_ExternalSymbol: {
     bool isCallOp = Modifier && !strcmp(Modifier, "call");
-    if (isCallOp && 
-        X86PICStyle == PICStyle::Stub &&
-        TM.getRelocationModel() != Reloc::Static) {
-      std::string Name(TAI->getGlobalPrefix());
-      Name += MO.getSymbolName();
+    std::string Name(TAI->getGlobalPrefix());
+    Name += MO.getSymbolName();
+    if (isCallOp && Subtarget->isPICStyleStub()) {
       FnStubs.insert(Name);
       O << "L" << Name << "$stub";
       return;
     }
     if (!isCallOp) O << '$';
-    O << TAI->getGlobalPrefix() << MO.getSymbolName();
+    O << Name;
+
+    if (Subtarget->isPICStyleGOT()) {
+      std::string GOTName(TAI->getGlobalPrefix());
+      GOTName+="_GLOBAL_OFFSET_TABLE_";
+      if (Name == GOTName)
+        // Really hack! Emit extra offset to PC during printing GOT offset to
+        // compensate size of popl instruction. The resulting code should look
+        // like:
+        //   call .piclabel
+        // piclabel:
+        //   popl %some_register
+        //   addl $_GLOBAL_ADDRESS_TABLE_ + [.-piclabel], %some_register
+        O << " + [.-" << computePICLabel(getFunctionNumber(), Subtarget) << "]";
+    }
+
+    if (isCallOp && Subtarget->isPICStyleGOT())
+      O << "@PLT";
 
     if (!isCallOp && Subtarget->is64Bit())
       O << "(%rip)";
@@ -366,8 +415,9 @@ void X86ATTAsmPrinter::printMemReference
 }
 
 void X86ATTAsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op) {
-  O << "\"L" << getFunctionNumber() << "$pb\"\n";
-  O << "\"L" << getFunctionNumber() << "$pb\":";
+  std::string label = computePICLabel(getFunctionNumber(), Subtarget);
+  
+  O << label << "\n" << label << ":";
 }
 
 
diff -r 744250c38a89 lib/Target/X86/X86AsmPrinter.cpp
--- a/lib/Target/X86/X86AsmPrinter.cpp	Sat Jan 06 00:23:53 2007 +0000
+++ b/lib/Target/X86/X86AsmPrinter.cpp	Wed Jan 03 22:32:49 2007 +0300
@@ -105,13 +105,9 @@ void X86SharedAsmPrinter::decorateName(s
 
 /// doInitialization
 bool X86SharedAsmPrinter::doInitialization(Module &M) {
-  if (Subtarget->isTargetDarwin()) {
-    if (!Subtarget->is64Bit())
-      X86PICStyle = PICStyle::Stub;
-
-    // Emit initial debug information.
-    DW.BeginModule(&M);
-  } else if (Subtarget->isTargetELF() || Subtarget->isTargetCygMing()) {
+  if (Subtarget->isTargetELF() ||
+      Subtarget->isTargetCygMing() ||
+      Subtarget->isTargetDarwin()) {
     // Emit initial debug information.
     DW.BeginModule(&M);
   }
diff -r 744250c38a89 lib/Target/X86/X86AsmPrinter.h
--- a/lib/Target/X86/X86AsmPrinter.h	Sat Jan 06 00:23:53 2007 +0000
+++ b/lib/Target/X86/X86AsmPrinter.h	Wed Jan 03 15:34:27 2007 +0300
@@ -28,19 +28,12 @@
 
 namespace llvm {
 
-// FIXME: Move this to CodeGen/AsmPrinter.h
-namespace PICStyle {
-  enum X86AsmPICStyle {
-    Stub, GOT
-  };
-}
-
 struct VISIBILITY_HIDDEN X86SharedAsmPrinter : public AsmPrinter {
   DwarfWriter DW;
 
   X86SharedAsmPrinter(std::ostream &O, X86TargetMachine &TM,
                       const TargetAsmInfo *T)
-    : AsmPrinter(O, TM, T), DW(O, this, T), X86PICStyle(PICStyle::GOT) {
+    : AsmPrinter(O, TM, T), DW(O, this, T) {
     Subtarget = &TM.getSubtarget<X86Subtarget>();
   }
 
@@ -73,8 +66,6 @@ struct VISIBILITY_HIDDEN X86SharedAsmPri
     MachineFunctionPass::getAnalysisUsage(AU);
   }
 
-  PICStyle::X86AsmPICStyle X86PICStyle;
-  
   const X86Subtarget *Subtarget;
 
   // Necessary for Darwin to print out the apprioriate types of linker stubs
diff -r 744250c38a89 lib/Target/X86/X86ISelDAGToDAG.cpp
--- a/lib/Target/X86/X86ISelDAGToDAG.cpp	Sat Jan 06 00:23:53 2007 +0000
+++ b/lib/Target/X86/X86ISelDAGToDAG.cpp	Thu Jan 04 15:35:06 2007 +0300
@@ -938,10 +938,23 @@ SDNode *X86DAGToDAGISel::getGlobalBaseRe
     MachineBasicBlock &FirstMBB = BB->getParent()->front();
     MachineBasicBlock::iterator MBBI = FirstMBB.begin();
     SSARegMap *RegMap = BB->getParent()->getSSARegMap();
-    GlobalBaseReg = RegMap->createVirtualRegister(X86::GR32RegisterClass);
+    unsigned PC = RegMap->createVirtualRegister(X86::GR32RegisterClass);
+    
     const TargetInstrInfo *TII = TM.getInstrInfo();
     BuildMI(FirstMBB, MBBI, TII->get(X86::MovePCtoStack));
-    BuildMI(FirstMBB, MBBI, TII->get(X86::POP32r), GlobalBaseReg);
+    BuildMI(FirstMBB, MBBI, TII->get(X86::POP32r), PC);
+    
+    // If we're using vanilla 'GOT' PIC style, we should use relative addressing
+    // not to pc, but to _GLOBAL_ADDRESS_TABLE_ external
+    if (Subtarget->isPICStyleGOT()) {
+      GlobalBaseReg = RegMap->createVirtualRegister(X86::GR32RegisterClass);
+      BuildMI(FirstMBB, MBBI, TII->get(X86::ADD32ri), GlobalBaseReg).
+        addReg(PC).
+        addExternalSymbol("_GLOBAL_OFFSET_TABLE_");
+    } else {
+      GlobalBaseReg = PC;
+    }
+    
   }
   return CurDAG->getRegister(GlobalBaseReg, TLI.getPointerTy()).Val;
 }
diff -r 744250c38a89 lib/Target/X86/X86ISelLowering.cpp
--- a/lib/Target/X86/X86ISelLowering.cpp	Sat Jan 06 00:23:53 2007 +0000
+++ b/lib/Target/X86/X86ISelLowering.cpp	Sat Jan 06 01:08:25 2007 +0300
@@ -664,6 +664,13 @@ SDOperand X86TargetLowering::LowerCCCCal
     InFlag = Chain.getValue(1);
   }
 
+  if (Subtarget->isPICStyleGOT()) {
+    Chain = DAG.getCopyToReg(Chain, X86::EBX,
+                             DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()),
+                             InFlag);
+    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)) {
@@ -3856,12 +3863,12 @@ X86TargetLowering::LowerConstantPool(SDO
                                                getPointerTy(),
                                                CP->getAlignment());
   Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result);
-  if (Subtarget->isTargetDarwin()) {
-    // With PIC, the address is actually $g + Offset.
-    if (!Subtarget->is64Bit() &&
-        getTargetMachine().getRelocationModel() == Reloc::PIC_)
-      Result = DAG.getNode(ISD::ADD, getPointerTy(),
-                    DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()), Result);
+  // With PIC, the address is actually $g + Offset.
+  if (getTargetMachine().getRelocationModel() == Reloc::PIC_ &&
+      !Subtarget->isPICStyleGOTPCRel()) {
+    Result = DAG.getNode(ISD::ADD, getPointerTy(),
+                         DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()),
+                         Result);
   }
 
   return Result;
@@ -3872,19 +3879,19 @@ X86TargetLowering::LowerGlobalAddress(SD
   GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
   SDOperand Result = DAG.getTargetGlobalAddress(GV, getPointerTy());
   Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result);
-  if (Subtarget->isTargetDarwin()) {
-    // With PIC, the address is actually $g + Offset.
-    if (!Subtarget->is64Bit() &&
-        getTargetMachine().getRelocationModel() == Reloc::PIC_)
-      Result = DAG.getNode(ISD::ADD, getPointerTy(),
-                           DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()),
-                           Result);
+  // With PIC, the address is actually $g + Offset.
+  if (getTargetMachine().getRelocationModel() == Reloc::PIC_ &&
+      !Subtarget->isPICStyleGOTPCRel()) {
+    Result = DAG.getNode(ISD::ADD, getPointerTy(),
+                         DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()),
+                         Result);
   }
   
   // For Darwin & Mingw32, external and weak symbols are indirect, so we want to
   // load the value at address GV, not the value of GV itself. This means that
   // the GlobalAddress must be in the base or index register of the address, not
   // the GV offset field. Platform check is inside GVRequiresExtraLoad() call
+  // The same applies for external symbols during PIC codegen
   if (Subtarget->GVRequiresExtraLoad(GV, getTargetMachine(), false))
     Result = DAG.getLoad(getPointerTy(), DAG.getEntryNode(), Result, NULL, 0);
 
@@ -3896,13 +3903,27 @@ X86TargetLowering::LowerExternalSymbol(S
   const char *Sym = cast<ExternalSymbolSDNode>(Op)->getSymbol();
   SDOperand Result = DAG.getTargetExternalSymbol(Sym, getPointerTy());
   Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result);
-  if (Subtarget->isTargetDarwin()) {
-    // With PIC, the address is actually $g + Offset.
-    if (!Subtarget->is64Bit() &&
-        getTargetMachine().getRelocationModel() == Reloc::PIC_)
-      Result = DAG.getNode(ISD::ADD, getPointerTy(),
-                           DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()),
-                           Result);
+  // With PIC, the address is actually $g + Offset.
+  if (getTargetMachine().getRelocationModel() == Reloc::PIC_ &&
+      !Subtarget->isPICStyleGOTPCRel()) {
+    Result = DAG.getNode(ISD::ADD, getPointerTy(),
+                         DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()),
+                         Result);
+  }
+
+  return Result;
+}
+
+SDOperand X86TargetLowering::LowerJumpTable(SDOperand Op, SelectionDAG &DAG) {
+  JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
+  SDOperand Result = DAG.getTargetJumpTable(JT->getIndex(), getPointerTy());
+  Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result);
+  // With PIC, the address is actually $g + Offset.
+  if (getTargetMachine().getRelocationModel() == Reloc::PIC_ &&
+      !Subtarget->isPICStyleGOTPCRel()) {
+    Result = DAG.getNode(ISD::ADD, getPointerTy(),
+                         DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()),
+                         Result);
   }
 
   return Result;
@@ -4332,22 +4353,6 @@ SDOperand X86TargetLowering::LowerBRCOND
   }
   return DAG.getNode(X86ISD::BRCOND, Op.getValueType(),
                      Cond, Op.getOperand(2), CC, Cond.getValue(1));
-}
-
-SDOperand X86TargetLowering::LowerJumpTable(SDOperand Op, SelectionDAG &DAG) {
-  JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
-  SDOperand Result = DAG.getTargetJumpTable(JT->getIndex(), getPointerTy());
-  Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result);
-  if (Subtarget->isTargetDarwin()) {
-    // With PIC, the address is actually $g + Offset.
-    if (!Subtarget->is64Bit() &&
-        getTargetMachine().getRelocationModel() == Reloc::PIC_)
-      Result = DAG.getNode(ISD::ADD, getPointerTy(),
-                           DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()),
-                           Result);
-  }
-
-  return Result;
 }
 
 SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
diff -r 744250c38a89 lib/Target/X86/X86RegisterInfo.cpp
--- a/lib/Target/X86/X86RegisterInfo.cpp	Sat Jan 06 00:23:53 2007 +0000
+++ b/lib/Target/X86/X86RegisterInfo.cpp	Sat Jan 06 02:41:23 2007 +0300
@@ -178,6 +178,8 @@ static MachineInstr *FuseTwoAddrInst(uns
       MIB = MIB.addGlobalAddress(MO.getGlobal(), MO.getOffset());
     else if (MO.isJumpTableIndex())
       MIB = MIB.addJumpTableIndex(MO.getJumpTableIndex());
+    else if (MO.isExternalSymbol())
+      MIB = MIB.addExternalSymbol(MO.getSymbolName());
     else
       assert(0 && "Unknown operand type!");
   }
@@ -202,6 +204,8 @@ static MachineInstr *FuseInst(unsigned O
       MIB = MIB.addGlobalAddress(MO.getGlobal(), MO.getOffset());
     else if (MO.isJumpTableIndex())
       MIB = MIB.addJumpTableIndex(MO.getJumpTableIndex());
+    else if (MO.isExternalSymbol())
+      MIB = MIB.addExternalSymbol(MO.getSymbolName());
     else
       assert(0 && "Unknown operand for FuseInst!");
   }
diff -r 744250c38a89 lib/Target/X86/X86Subtarget.cpp
--- a/lib/Target/X86/X86Subtarget.cpp	Sat Jan 06 00:23:53 2007 +0000
+++ b/lib/Target/X86/X86Subtarget.cpp	Sat Jan 06 03:37:01 2007 +0300
@@ -19,11 +19,11 @@ using namespace llvm;
 using namespace llvm;
 
 cl::opt<X86Subtarget::AsmWriterFlavorTy>
-AsmWriterFlavor("x86-asm-syntax", cl::init(X86Subtarget::unset),
+AsmWriterFlavor("x86-asm-syntax", cl::init(X86Subtarget::Unset),
   cl::desc("Choose style of code to emit from X86 backend:"),
   cl::values(
-    clEnumValN(X86Subtarget::att,   "att",   "  Emit AT&T-style assembly"),
-    clEnumValN(X86Subtarget::intel, "intel", "  Emit Intel-style assembly"),
+    clEnumValN(X86Subtarget::ATT,   "att",   "  Emit AT&T-style assembly"),
+    clEnumValN(X86Subtarget::Intel, "intel", "  Emit Intel-style assembly"),
     clEnumValEnd));
 
 
@@ -36,7 +36,7 @@ bool X86Subtarget::GVRequiresExtraLoad(c
                                        bool isDirectCall) const
 {
   if (TM.getRelocationModel() != Reloc::Static)
-    if (isTargetDarwin()) {
+    if (isTargetDarwin() || isPICStyleGOT()) {
       return (!isDirectCall &&
               (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() ||
                (GV->isExternal() && !GV->hasNotBeenReadFromBytecode())));
@@ -212,6 +212,7 @@ static const char *GetCurrentX86CPU() {
 
 X86Subtarget::X86Subtarget(const Module &M, const std::string &FS, bool is64Bit)
   : AsmFlavor(AsmWriterFlavor)
+  , PICStyle(PICStyle::None)
   , X86SSELevel(NoMMXSSE)
   , HasX86_64(false)
   , stackAlignment(8)
@@ -270,11 +271,11 @@ X86Subtarget::X86Subtarget(const Module 
 
   // If the asm syntax hasn't been overridden on the command line, use whatever
   // the target wants.
-  if (AsmFlavor == X86Subtarget::unset) {
+  if (AsmFlavor == X86Subtarget::Unset) {
     if (TargetType == isWindows) {
-      AsmFlavor = X86Subtarget::intel;
+      AsmFlavor = X86Subtarget::Intel;
     } else {
-      AsmFlavor = X86Subtarget::att;
+      AsmFlavor = X86Subtarget::ATT;
     }
   }
 
diff -r 744250c38a89 lib/Target/X86/X86Subtarget.h
--- a/lib/Target/X86/X86Subtarget.h	Sat Jan 06 00:23:53 2007 +0000
+++ b/lib/Target/X86/X86Subtarget.h	Sat Jan 06 03:37:43 2007 +0300
@@ -22,13 +22,18 @@ class Module;
 class Module;
 class GlobalValue;
 class TargetMachine;
+  
+namespace PICStyle {
+enum Style {
+  Stub, GOT, GOTPCRel, WinPIC, None
+};
+}
 
 class X86Subtarget : public TargetSubtarget {
 public:
   enum AsmWriterFlavorTy {
-    att, intel, unset
+    ATT, Intel, Unset
   };
-
 protected:
   enum X86SSEEnum {
     NoMMXSSE, MMX, SSE1, SSE2, SSE3
@@ -41,6 +46,9 @@ protected:
   /// AsmFlavor - Which x86 asm dialect to use.
   AsmWriterFlavorTy AsmFlavor;
 
+  /// PICStyle - Which PIC style to use
+  PICStyle::Style PICStyle;
+  
   /// X86SSELevel - MMX, SSE1, SSE2, SSE3, or none supported.
   X86SSEEnum X86SSELevel;
 
@@ -93,6 +101,9 @@ public:
 
   bool is64Bit() const { return Is64Bit; }
 
+  PICStyle::Style getPICStyle() const { return PICStyle; }
+  void setPICStyle(PICStyle::Style Style)  { PICStyle = Style; }
+
   bool hasMMX() const { return X86SSELevel >= MMX; }
   bool hasSSE1() const { return X86SSELevel >= SSE1; }
   bool hasSSE2() const { return X86SSELevel >= SSE2; }
@@ -100,8 +111,8 @@ public:
   bool has3DNow() const { return X863DNowLevel >= ThreeDNow; }
   bool has3DNowA() const { return X863DNowLevel >= ThreeDNowA; }
 
-  bool isFlavorAtt() const { return AsmFlavor == att; }
-  bool isFlavorIntel() const { return AsmFlavor == intel; }
+  bool isFlavorAtt() const { return AsmFlavor == ATT; }
+  bool isFlavorIntel() const { return AsmFlavor == Intel; }
 
   bool isTargetDarwin() const { return TargetType == isDarwin; }
   bool isTargetELF() const { return TargetType == isELF; }
@@ -111,6 +122,12 @@ public:
                                          TargetType == isCygwin); }
   bool isTargetCygwin() const { return TargetType == isCygwin; }
 
+  bool isPICStyleSet() const { return PICStyle != PICStyle::None; }
+  bool isPICStyleGOT() const { return PICStyle == PICStyle::GOT; }
+  bool isPICStyleStub() const { return PICStyle == PICStyle::Stub; }
+  bool isPICStyleGOTPCRel() const { return PICStyle == PICStyle::GOTPCRel; }
+  bool isPICStyleWinPIC() const { return PICStyle == PICStyle:: WinPIC; }
+    
   /// True if accessing the GV requires an extra load. For Windows, dllimported
   /// symbols are indirect, loading the value at address GV rather then the
   /// value of GV itself. This means that the GlobalAddress must be in the base
diff -r 744250c38a89 lib/Target/X86/X86TargetMachine.cpp
--- a/lib/Target/X86/X86TargetMachine.cpp	Sat Jan 06 00:23:53 2007 +0000
+++ b/lib/Target/X86/X86TargetMachine.cpp	Sat Jan 06 03:31:45 2007 +0300
@@ -127,6 +127,26 @@ X86TargetMachine::X86TargetMachine(const
     if (getCodeModel() == CodeModel::Default)
       setCodeModel(CodeModel::Small);
   }
+
+  if (getRelocationModel() == Reloc::PIC_) {
+    if (Subtarget.isTargetDarwin()) {
+      if (Subtarget.is64Bit())
+        Subtarget.setPICStyle(PICStyle::GOTPCRel);
+      else
+        Subtarget.setPICStyle(PICStyle::Stub);
+    } else if (Subtarget.isTargetELF())
+      Subtarget.setPICStyle(PICStyle::GOT);
+    else
+      assert(0 && "Don't know how to generate PIC code for this target!");
+  } else if (getRelocationModel() == Reloc::DynamicNoPIC) {
+    if (Subtarget.isTargetDarwin())
+      Subtarget.setPICStyle(PICStyle::Stub);
+    else if (Subtarget.isTargetCygMing())
+      Subtarget.setPICStyle(PICStyle::WinPIC);
+    else
+      assert(0 && "Don't know how to generate PIC code for this target!");
+  }
+  
 }
 
 //===----------------------------------------------------------------------===//
_______________________________________________
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits

Reply via email to