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/X86ATTAsmPrinter.cpp | |
parent | ab7752c1496c2913793305ba4b989a551c5617e1 (diff) | |
download | llvm-7f70559bc47877bafc6dfa92b7df6b64650445fb.tar.gz llvm-7f70559bc47877bafc6dfa92b7df6b64650445fb.tar.bz2 llvm-7f70559bc47877bafc6dfa92b7df6b64650445fb.tar.xz |
* 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/X86ATTAsmPrinter.cpp')
-rwxr-xr-x | lib/Target/X86/X86ATTAsmPrinter.cpp | 109 |
1 files changed, 84 insertions, 25 deletions
diff --git a/lib/Target/X86/X86ATTAsmPrinter.cpp b/lib/Target/X86/X86ATTAsmPrinter.cpp index ccc2965064..7edea6f074 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 << ":"; } |