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