diff options
author | Anton Korobeynikov <asl@math.spbu.ru> | 2007-01-12 19:20:47 +0000 |
---|---|---|
committer | Anton Korobeynikov <asl@math.spbu.ru> | 2007-01-12 19:20:47 +0000 |
commit | 7f70559bc47877bafc6dfa92b7df6b64650445fb (patch) | |
tree | 35e2a9f532175fdf23d0253f970ff2132448e5d9 /lib/Target/X86 | |
parent | ab7752c1496c2913793305ba4b989a551c5617e1 (diff) | |
download | external_llvm-7f70559bc47877bafc6dfa92b7df6b64650445fb.zip external_llvm-7f70559bc47877bafc6dfa92b7df6b64650445fb.tar.gz external_llvm-7f70559bc47877bafc6dfa92b7df6b64650445fb.tar.bz2 |
* PIC codegen for X86/Linux has been implemented
* PIC-aware internal structures in X86 Codegen have been refactored
* Visibility (default/weak) has been added
* Docs fixes (external weak linkage, visibility, formatting)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33136 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/X86')
-rw-r--r-- | lib/Target/X86/README.txt | 4 | ||||
-rwxr-xr-x | lib/Target/X86/X86ATTAsmPrinter.cpp | 109 | ||||
-rw-r--r-- | lib/Target/X86/X86AsmPrinter.cpp | 13 | ||||
-rwxr-xr-x | lib/Target/X86/X86AsmPrinter.h | 11 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelDAGToDAG.cpp | 17 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelLowering.cpp | 79 | ||||
-rw-r--r-- | lib/Target/X86/X86RegisterInfo.cpp | 4 | ||||
-rw-r--r-- | lib/Target/X86/X86Subtarget.cpp | 15 | ||||
-rw-r--r-- | lib/Target/X86/X86Subtarget.h | 25 | ||||
-rw-r--r-- | lib/Target/X86/X86TargetMachine.cpp | 21 |
10 files changed, 201 insertions, 97 deletions
diff --git a/lib/Target/X86/README.txt b/lib/Target/X86/README.txt index c871a76..7e36520 100644 --- a/lib/Target/X86/README.txt +++ b/lib/Target/X86/README.txt @@ -534,10 +534,6 @@ do not make use of. //===---------------------------------------------------------------------===// -We should handle __attribute__ ((__visibility__ ("hidden"))). - -//===---------------------------------------------------------------------===// - int %foo(int* %a, int %t) { entry: br label %cond_true diff --git a/lib/Target/X86/X86ATTAsmPrinter.cpp b/lib/Target/X86/X86ATTAsmPrinter.cpp index ccc2965..7edea6f 100755 --- a/lib/Target/X86/X86ATTAsmPrinter.cpp +++ b/lib/Target/X86/X86ATTAsmPrinter.cpp @@ -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" @@ -29,6 +30,21 @@ 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 = ".Lllvm$" + 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. std::string X86ATTAsmPrinter::getSectionForFunction(const Function &F) const { @@ -109,12 +125,15 @@ bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) { } break; } + if (F->hasHiddenVisibility()) + O << "\t.hidden " << CurrentFnName << "\n"; + O << CurrentFnName << ":\n"; // Add some workaround for linkonce linkage on Cygwin\MinGW if (Subtarget->isTargetCygMing() && (F->getLinkage() == Function::LinkOnceLinkage || F->getLinkage() == Function::WeakLinkage)) - O << "_llvm$workaround$fake$stub_" << CurrentFnName << ":\n"; + O << "Lllvm$workaround$fake$stub$" << CurrentFnName << ":\n"; if (Subtarget->isTargetDarwin() || Subtarget->isTargetELF() || @@ -193,9 +212,14 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, 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 +229,14 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, 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; @@ -228,11 +257,11 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, bool isExt = (GV->isExternal() || GV->hasWeakLinkage() || GV->hasLinkOnceLinkage()); + bool isHidden = GV->hasHiddenVisibility(); 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 +287,12 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, O << "__imp_"; } O << Name; + + if (Subtarget->isPICStyleGOT() && isCallOp && isa<Function>(GV)) { + // Assemble call via PLT for non-local symbols + if (!isHidden || isExt) + O << "@PLT"; + } } if (GV->hasExternalWeakLinkage()) @@ -269,31 +304,55 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, else if (Offset < 0) O << Offset; - if (isMemOp && Subtarget->is64Bit()) { - if (isExt && TM.getRelocationModel() != Reloc::Static) - O << "@GOTPCREL(%rip)"; - else if (!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)"; + if (isMemOp) { + if (isExt) { + if (Subtarget->isPICStyleGOT()) { + O << "@GOT"; + } else if (Subtarget->isPICStyleRIPRel()) { + O << "@GOTPCREL(%rip)"; + } 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)"; + } else { + if (Subtarget->is64Bit() && !NotRIPRel) + 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 +425,8 @@ void X86ATTAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op, } 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 --git a/lib/Target/X86/X86AsmPrinter.cpp b/lib/Target/X86/X86AsmPrinter.cpp index 4f55f42a..a896068 100644 --- a/lib/Target/X86/X86AsmPrinter.cpp +++ b/lib/Target/X86/X86AsmPrinter.cpp @@ -105,13 +105,9 @@ void X86SharedAsmPrinter::decorateName(std::string &Name, /// 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); } @@ -241,7 +237,6 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) { << "\n"; if (TAI->hasDotTypeDotSizeDirective()) O << "\t.size " << name << ", " << Size << "\n"; - // If the initializer is a extern weak symbol, remember to emit the weak // reference! if (const GlobalValue *GV = dyn_cast<GlobalValue>(C)) @@ -251,6 +246,8 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) { EmitGlobalConstant(C); O << '\n'; } + if (I->hasHiddenVisibility()) + O << "\t.hidden " << name << "\n"; } // Output linker support code for dllexported globals diff --git a/lib/Target/X86/X86AsmPrinter.h b/lib/Target/X86/X86AsmPrinter.h index ab885fd..87f1852 100755 --- a/lib/Target/X86/X86AsmPrinter.h +++ b/lib/Target/X86/X86AsmPrinter.h @@ -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 X86SharedAsmPrinter : public AsmPrinter { MachineFunctionPass::getAnalysisUsage(AU); } - PICStyle::X86AsmPICStyle X86PICStyle; - const X86Subtarget *Subtarget; // Necessary for Darwin to print out the apprioriate types of linker stubs diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp index 5c80f23..f36456e 100644 --- a/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -938,10 +938,23 @@ SDNode *X86DAGToDAGISel::getGlobalBaseReg() { 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 --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 44d094a..350f575 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -664,6 +664,13 @@ SDOperand X86TargetLowering::LowerCCCCallTo(SDOperand Op, SelectionDAG &DAG) { 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)) { @@ -687,7 +694,7 @@ SDOperand X86TargetLowering::LowerCCCCallTo(SDOperand Op, SelectionDAG &DAG) { for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) Ops.push_back(DAG.getRegister(RegsToPass[i].first, RegsToPass[i].second.getValueType())); - + if (InFlag.Val) Ops.push_back(InFlag); @@ -3856,12 +3863,12 @@ X86TargetLowering::LowerConstantPool(SDOperand Op, SelectionDAG &DAG) { 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->isPICStyleRIPRel()) { + Result = DAG.getNode(ISD::ADD, getPointerTy(), + DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()), + Result); } return Result; @@ -3872,19 +3879,19 @@ X86TargetLowering::LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG) { 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->isPICStyleRIPRel()) { + 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(SDOperand Op, SelectionDAG &DAG) { 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->isPICStyleRIPRel()) { + 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->isPICStyleRIPRel()) { + Result = DAG.getNode(ISD::ADD, getPointerTy(), + DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()), + Result); } return Result; @@ -4334,22 +4355,6 @@ SDOperand X86TargetLowering::LowerBRCOND(SDOperand Op, SelectionDAG &DAG) { 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) { unsigned CallingConv= cast<ConstantSDNode>(Op.getOperand(1))->getValue(); diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp index eff7972..6f9f3b6 100644 --- a/lib/Target/X86/X86RegisterInfo.cpp +++ b/lib/Target/X86/X86RegisterInfo.cpp @@ -178,6 +178,8 @@ static MachineInstr *FuseTwoAddrInst(unsigned Opcode, unsigned FrameIndex, 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 Opcode, unsigned OpNo, 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 --git a/lib/Target/X86/X86Subtarget.cpp b/lib/Target/X86/X86Subtarget.cpp index 6feb0af..5f2342f 100644 --- a/lib/Target/X86/X86Subtarget.cpp +++ b/lib/Target/X86/X86Subtarget.cpp @@ -19,11 +19,11 @@ 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(const GlobalValue* GV, 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 &M, const std::string &FS, bool is64Bit) // 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 --git a/lib/Target/X86/X86Subtarget.h b/lib/Target/X86/X86Subtarget.h index 863e1af..43e8508 100644 --- a/lib/Target/X86/X86Subtarget.h +++ b/lib/Target/X86/X86Subtarget.h @@ -22,13 +22,18 @@ namespace llvm { class Module; class GlobalValue; class TargetMachine; + +namespace PICStyle { +enum Style { + Stub, GOT, RIPRel, 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 isPICStyleRIPRel() const { return PICStyle == PICStyle::RIPRel; } + 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 --git a/lib/Target/X86/X86TargetMachine.cpp b/lib/Target/X86/X86TargetMachine.cpp index d92ae49..8bcda9a 100644 --- a/lib/Target/X86/X86TargetMachine.cpp +++ b/lib/Target/X86/X86TargetMachine.cpp @@ -127,6 +127,25 @@ X86TargetMachine::X86TargetMachine(const Module &M, const std::string &FS, bool if (getCodeModel() == CodeModel::Default) setCodeModel(CodeModel::Small); } + + if (getRelocationModel() == Reloc::PIC_) { + if (Subtarget.isTargetDarwin()) { + if (Subtarget.is64Bit()) + Subtarget.setPICStyle(PICStyle::RIPRel); + 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!"); + } } //===----------------------------------------------------------------------===// @@ -163,6 +182,8 @@ bool X86TargetMachine::addCodeEmitter(FunctionPassManager &PM, bool Fast, MachineCodeEmitter &MCE) { // FIXME: Move this to TargetJITInfo! setRelocationModel(Reloc::Static); + Subtarget.setPICStyle(PICStyle::None); + // JIT cannot ensure globals are placed in the lower 4G of address. if (Subtarget.is64Bit()) setCodeModel(CodeModel::Large); |