Index: include/llvm/CodeGen/CommandFlags.h =================================================================== --- include/llvm/CodeGen/CommandFlags.h +++ include/llvm/CodeGen/CommandFlags.h @@ -54,6 +54,19 @@ "Relocatable external references, non-relocatable code"), clEnumValEnd)); +cl::opt +PLevel("pic-level", + cl::desc("Choose PIC level (small or large)"), + cl::init(PICLevel::Default), + cl::values( + clEnumValN(PICLevel::Default, "default", + "Target default PIC level"), + clEnumValN(PICLevel::Small, "small", + "Small PIC model (-fpic)"), + clEnumValN(PICLevel::Large, "large", + "Large PIC model (-fPIC)"), + clEnumValEnd)); + cl::opt TMModel("thread-model", cl::desc("Choose threading model"), Index: include/llvm/ExecutionEngine/ExecutionEngine.h =================================================================== --- include/llvm/ExecutionEngine/ExecutionEngine.h +++ include/llvm/ExecutionEngine/ExecutionEngine.h @@ -498,6 +498,7 @@ TargetOptions Options; Reloc::Model RelocModel; CodeModel::Model CMModel; + PICLevel::Level PLevel; std::string MArch; std::string MCPU; SmallVector MAttrs; @@ -581,6 +582,13 @@ return *this; } + /// setPICLevel - Set the PICLevel that the ExecutionEngine target is using. + /// Defaults to the target specific default "PICLevel::Default" + EngineBuilder &setPICLevel(PICLevel::Level PL) { + PLevel = PL; + return *this; + } + /// setMArch - Override the architecture set by the Module's triple. EngineBuilder &setMArch(StringRef march) { MArch.assign(march.begin(), march.end()); Index: include/llvm/MC/MCCodeGenInfo.h =================================================================== --- include/llvm/MC/MCCodeGenInfo.h +++ include/llvm/MC/MCCodeGenInfo.h @@ -24,6 +24,8 @@ /// Reloc::Model RelocationModel; + PICLevel::Level PLevel; + /// CMModel - Code model. /// CodeModel::Model CMModel; @@ -35,7 +37,8 @@ public: void InitMCCodeGenInfo(Reloc::Model RM = Reloc::Default, CodeModel::Model CM = CodeModel::Default, - CodeGenOpt::Level OL = CodeGenOpt::Default); + CodeGenOpt::Level OL = CodeGenOpt::Default, + PICLevel::Level PL = PICLevel::Default ); Reloc::Model getRelocationModel() const { return RelocationModel; } @@ -43,6 +46,8 @@ CodeGenOpt::Level getOptLevel() const { return OptLevel; } + PICLevel::Level getPICLevel() const { return PLevel; } + // Allow overriding OptLevel on a per-function basis. void setOptLevel(CodeGenOpt::Level Level) { OptLevel = Level; } }; Index: include/llvm/MC/MCExpr.h =================================================================== --- include/llvm/MC/MCExpr.h +++ include/llvm/MC/MCExpr.h @@ -250,6 +250,7 @@ VK_PPC_GOT_TLSLD_HI, // symbol@got@tlsld@h VK_PPC_GOT_TLSLD_HA, // symbol@got@tlsld@ha VK_PPC_TLSLD, // symbol@tlsld + VK_PPC_LOCAL, // symbol@local VK_Mips_GPREL, VK_Mips_GOT_CALL, Index: include/llvm/MC/MCObjectFileInfo.h =================================================================== --- include/llvm/MC/MCObjectFileInfo.h +++ include/llvm/MC/MCObjectFileInfo.h @@ -194,7 +194,7 @@ public: void InitMCObjectFileInfo(StringRef TT, Reloc::Model RM, CodeModel::Model CM, - MCContext &ctx); + PICLevel::Level PL, MCContext &ctx); bool getSupportsWeakOmittedEHFrame() const { return SupportsWeakOmittedEHFrame; Index: include/llvm/Support/CodeGen.h =================================================================== --- include/llvm/Support/CodeGen.h +++ include/llvm/Support/CodeGen.h @@ -25,6 +25,10 @@ enum Model { Default, Static, PIC_, DynamicNoPIC }; } + namespace PICLevel { + enum Level { Default, Small, Large }; + }; + // Code model types. namespace CodeModel { enum Model { Default, JITDefault, Small, Kernel, Medium, Large }; Index: include/llvm/Support/ELF.h =================================================================== --- include/llvm/Support/ELF.h +++ include/llvm/Support/ELF.h @@ -460,6 +460,7 @@ R_PPC_GOT16_HA = 17, R_PPC_PLTREL24 = 18, R_PPC_JMP_SLOT = 21, + R_PPC_LOCAL24PC = 23, R_PPC_REL32 = 26, R_PPC_TLS = 67, R_PPC_DTPMOD32 = 68, Index: include/llvm/Support/TargetRegistry.h =================================================================== --- include/llvm/Support/TargetRegistry.h +++ include/llvm/Support/TargetRegistry.h @@ -84,7 +84,8 @@ typedef MCCodeGenInfo *(*MCCodeGenInfoCtorFnTy)(StringRef TT, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL); + CodeGenOpt::Level OL, + PICLevel::Level PL); typedef MCInstrInfo *(*MCInstrInfoCtorFnTy)(void); typedef MCInstrAnalysis *(*MCInstrAnalysisCtorFnTy)(const MCInstrInfo*Info); typedef MCRegisterInfo *(*MCRegInfoCtorFnTy)(StringRef TT); @@ -98,7 +99,8 @@ const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL); + CodeGenOpt::Level OL, + PICLevel::Level PL); typedef AsmPrinter *(*AsmPrinterCtorTy)(TargetMachine &TM, MCStreamer &Streamer); typedef MCAsmBackend *(*MCAsmBackendCtorTy)(const Target &T, @@ -291,10 +293,11 @@ /// MCCodeGenInfo *createMCCodeGenInfo(StringRef Triple, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) const { + CodeGenOpt::Level OL, + PICLevel::Level PL) const { if (!MCCodeGenInfoCtorFn) return nullptr; - return MCCodeGenInfoCtorFn(Triple, RM, CM, OL); + return MCCodeGenInfoCtorFn(Triple, RM, CM, OL, PL); } /// createMCInstrInfo - Create a MCInstrInfo implementation. @@ -348,11 +351,12 @@ StringRef Features, const TargetOptions &Options, Reloc::Model RM = Reloc::Default, CodeModel::Model CM = CodeModel::Default, - CodeGenOpt::Level OL = CodeGenOpt::Default) const { + CodeGenOpt::Level OL = CodeGenOpt::Default, + PICLevel::Level PL = PICLevel::Default) const { if (!TargetMachineCtorFn) return nullptr; return TargetMachineCtorFn(*this, Triple, CPU, Features, Options, - RM, CM, OL); + RM, CM, OL, PL); } /// createMCAsmBackend - Create a target specific assembly parser. @@ -894,7 +898,8 @@ private: static MCCodeGenInfo *Allocator(StringRef /*TT*/, Reloc::Model /*RM*/, CodeModel::Model /*CM*/, - CodeGenOpt::Level /*OL*/) { + CodeGenOpt::Level /*OL*/, + PICLevel::Level /*PL*/) { return new MCCodeGenInfoImpl(); } }; @@ -1066,8 +1071,9 @@ const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) { - return new TargetMachineImpl(T, TT, CPU, FS, Options, RM, CM, OL); + CodeGenOpt::Level OL, + PICLevel::Level PL) { + return new TargetMachineImpl(T, TT, CPU, FS, Options, RM, CM, OL, PL); } }; Index: include/llvm/Target/TargetMachine.h =================================================================== --- include/llvm/Target/TargetMachine.h +++ include/llvm/Target/TargetMachine.h @@ -128,6 +128,10 @@ /// choices are static, PIC, and dynamic-no-pic, and target default. Reloc::Model getRelocationModel() const; + /// getPICLevel - Returns the PIC level (-fpic vs -fPIC) + /// choices are small, large, and target default. + PICLevel::Level getPICLevel() const; + /// getCodeModel - Returns the code model. The choices are small, kernel, /// medium, large, and target default. CodeModel::Model getCodeModel() const; @@ -220,7 +224,7 @@ LLVMTargetMachine(const Target &T, StringRef TargetTriple, StringRef CPU, StringRef FS, TargetOptions Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL); + CodeGenOpt::Level OL, PICLevel::Level PL); void initAsmInfo(); public: Index: lib/CodeGen/LLVMTargetMachine.cpp =================================================================== --- lib/CodeGen/LLVMTargetMachine.cpp +++ lib/CodeGen/LLVMTargetMachine.cpp @@ -71,9 +71,9 @@ StringRef CPU, StringRef FS, TargetOptions Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) + CodeGenOpt::Level OL, PICLevel::Level PL) : TargetMachine(T, Triple, CPU, FS, Options) { - CodeGenInfo = T.createMCCodeGenInfo(Triple, RM, CM, OL); + CodeGenInfo = T.createMCCodeGenInfo(Triple, RM, CM, OL, PL); } void LLVMTargetMachine::addAnalysisPasses(PassManagerBase &PM) { Index: lib/MC/MCCodeGenInfo.cpp =================================================================== --- lib/MC/MCCodeGenInfo.cpp +++ lib/MC/MCCodeGenInfo.cpp @@ -16,8 +16,9 @@ using namespace llvm; void MCCodeGenInfo::InitMCCodeGenInfo(Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) { + CodeGenOpt::Level OL, PICLevel::Level PL) { RelocationModel = RM; CMModel = CM; OptLevel = OL; + PLevel = PL; } Index: lib/MC/MCExpr.cpp =================================================================== --- lib/MC/MCExpr.cpp +++ lib/MC/MCExpr.cpp @@ -247,6 +247,7 @@ case VK_PPC_GOT_TLSLD_HI: return "got@tlsld@h"; case VK_PPC_GOT_TLSLD_HA: return "got@tlsld@ha"; case VK_PPC_TLSLD: return "tlsld"; + case VK_PPC_LOCAL: return "local"; case VK_Mips_GPREL: return "GPREL"; case VK_Mips_GOT_CALL: return "GOT_CALL"; case VK_Mips_GOT16: return "GOT16"; Index: lib/MC/MCObjectFileInfo.cpp =================================================================== --- lib/MC/MCObjectFileInfo.cpp +++ lib/MC/MCObjectFileInfo.cpp @@ -809,6 +809,7 @@ void MCObjectFileInfo::InitMCObjectFileInfo(StringRef T, Reloc::Model relocm, CodeModel::Model cm, + PICLevel::Level pl, MCContext &ctx) { RelocM = relocm; CMModel = cm; Index: lib/Object/IRObjectFile.cpp =================================================================== --- lib/Object/IRObjectFile.cpp +++ lib/Object/IRObjectFile.cpp @@ -70,7 +70,7 @@ MCObjectFileInfo MOFI; MCContext MCCtx(MAI.get(), MRI.get(), &MOFI); - MOFI.InitMCObjectFileInfo(Triple, Reloc::Default, CodeModel::Default, MCCtx); + MOFI.InitMCObjectFileInfo(Triple, Reloc::Default, CodeModel::Default, PICLevel::Default, MCCtx); std::unique_ptr Streamer(new RecordStreamer(MCCtx)); std::unique_ptr Buffer(MemoryBuffer::getMemBuffer(InlineAsm)); Index: lib/Target/AArch64/AArch64TargetMachine.h =================================================================== --- lib/Target/AArch64/AArch64TargetMachine.h +++ lib/Target/AArch64/AArch64TargetMachine.h @@ -29,7 +29,8 @@ AArch64TargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL, bool IsLittleEndian); + CodeGenOpt::Level OL, PICLevel::Level PL, + bool IsLittleEndian); const AArch64Subtarget *getSubtargetImpl() const override { return &Subtarget; @@ -56,7 +57,7 @@ AArch64leTargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL); + CodeGenOpt::Level OL, PICLevel::Level PL); }; // AArch64beTargetMachine - AArch64 big endian target machine. @@ -67,7 +68,7 @@ AArch64beTargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL); + CodeGenOpt::Level OL, PICLevel::Level PL); }; } // end namespace llvm Index: lib/Target/AArch64/AArch64TargetMachine.cpp =================================================================== --- lib/Target/AArch64/AArch64TargetMachine.cpp +++ lib/Target/AArch64/AArch64TargetMachine.cpp @@ -93,8 +93,9 @@ const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, CodeGenOpt::Level OL, + PICLevel::Level PL, bool LittleEndian) - : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), + : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, PL), Subtarget(TT, CPU, FS, *this, LittleEndian), usingPBQP(false) { initAsmInfo(); @@ -111,8 +112,9 @@ AArch64leTargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) - : AArch64TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {} + CodeGenOpt::Level OL, + PICLevel::Level PL) + : AArch64TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, PL, true) {} void AArch64beTargetMachine::anchor() { } @@ -120,8 +122,9 @@ AArch64beTargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) - : AArch64TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {} + CodeGenOpt::Level OL, + PICLevel::Level PL) + : AArch64TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, PL, false) {} namespace { /// AArch64 Code Generator Pass Configuration Options. Index: lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp =================================================================== --- lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp +++ lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp @@ -79,7 +79,8 @@ static MCCodeGenInfo *createAArch64MCCodeGenInfo(StringRef TT, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) { + CodeGenOpt::Level OL, + PICLevel::Level PL) { Triple TheTriple(TT); assert((TheTriple.isOSBinFormatELF() || TheTriple.isOSBinFormatMachO()) && "Only expect Darwin and ELF targets"); @@ -105,7 +106,7 @@ RM = Reloc::Static; MCCodeGenInfo *X = new MCCodeGenInfo(); - X->InitMCCodeGenInfo(RM, CM, OL); + X->InitMCCodeGenInfo(RM, CM, OL, PL); return X; } Index: lib/Target/ARM/ARMTargetMachine.h =================================================================== --- lib/Target/ARM/ARMTargetMachine.h +++ lib/Target/ARM/ARMTargetMachine.h @@ -30,6 +30,7 @@ const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, CodeGenOpt::Level OL, + PICLevel::Level PL, bool isLittle); const ARMSubtarget *getSubtargetImpl() const override { return &Subtarget; } @@ -48,7 +49,8 @@ public: ARMTargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, - CodeModel::Model CM, CodeGenOpt::Level OL, bool isLittle); + CodeModel::Model CM, CodeGenOpt::Level OL, + PICLevel::Level PL, bool isLittle); }; /// ARMLETargetMachine - ARM little endian target machine. @@ -59,7 +61,7 @@ ARMLETargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL); + CodeGenOpt::Level OL, PICLevel::Level PL); }; /// ARMBETargetMachine - ARM big endian target machine. @@ -69,7 +71,7 @@ public: ARMBETargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, - CodeModel::Model CM, CodeGenOpt::Level OL); + CodeModel::Model CM, CodeGenOpt::Level OL, PICLevel::Level PL); }; /// ThumbTargetMachine - Thumb target machine. @@ -81,7 +83,8 @@ public: ThumbTargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, - CodeModel::Model CM, CodeGenOpt::Level OL, bool isLittle); + CodeModel::Model CM, CodeGenOpt::Level OL, + PICLevel::Level PL, bool isLittle); }; /// ThumbLETargetMachine - Thumb little endian target machine. @@ -92,7 +95,7 @@ ThumbLETargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL); + CodeGenOpt::Level OL, PICLevel::Level PL); }; /// ThumbBETargetMachine - Thumb big endian target machine. @@ -103,7 +106,7 @@ ThumbBETargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL); + CodeGenOpt::Level OL, PICLevel::Level PL); }; } // end namespace llvm Index: lib/Target/ARM/ARMTargetMachine.cpp =================================================================== --- lib/Target/ARM/ARMTargetMachine.cpp +++ lib/Target/ARM/ARMTargetMachine.cpp @@ -49,8 +49,9 @@ StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL, bool isLittle) - : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), + CodeGenOpt::Level OL, PICLevel::Level PL, + bool isLittle) + : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, PL), Subtarget(TT, CPU, FS, *this, isLittle, Options) { // Default to triple-appropriate float ABI @@ -73,8 +74,9 @@ ARMTargetMachine::ARMTargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL, bool isLittle) - : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, isLittle) { + CodeGenOpt::Level OL, PICLevel::Level PL, + bool isLittle) + : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, PL, isLittle) { initAsmInfo(); if (!Subtarget.hasARMOps()) report_fatal_error("CPU: '" + Subtarget.getCPUString() + "' does not " @@ -87,8 +89,8 @@ StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) - : ARMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {} + CodeGenOpt::Level OL, PICLevel::Level PL) + : ARMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, PL, true) {} void ARMBETargetMachine::anchor() { } @@ -96,8 +98,8 @@ StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) - : ARMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {} + CodeGenOpt::Level OL, PICLevel::Level PL) + : ARMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, PL, false) {} void ThumbTargetMachine::anchor() { } @@ -105,8 +107,9 @@ StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL, bool isLittle) - : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, + CodeGenOpt::Level OL, PICLevel::Level PL, + bool isLittle) + : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, PL, isLittle) { initAsmInfo(); } @@ -117,8 +120,8 @@ StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) - : ThumbTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {} + CodeGenOpt::Level OL, PICLevel::Level PL) + : ThumbTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, PL, true) {} void ThumbBETargetMachine::anchor() { } @@ -126,8 +129,8 @@ StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) - : ThumbTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {} + CodeGenOpt::Level OL, PICLevel::Level PL) + : ThumbTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, PL, false) {} namespace { /// ARM Code Generator Pass Configuration Options. Index: lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp =================================================================== --- lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp +++ lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp @@ -251,14 +251,15 @@ static MCCodeGenInfo *createARMMCCodeGenInfo(StringRef TT, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) { + CodeGenOpt::Level OL, + PICLevel::Level PL) { MCCodeGenInfo *X = new MCCodeGenInfo(); if (RM == Reloc::Default) { Triple TheTriple(TT); // Default relocation model on Darwin is PIC, not DynamicNoPIC. RM = TheTriple.isOSDarwin() ? Reloc::PIC_ : Reloc::DynamicNoPIC; } - X->InitMCCodeGenInfo(RM, CM, OL); + X->InitMCCodeGenInfo(RM, CM, OL, PL); return X; } Index: lib/Target/CppBackend/CPPTargetMachine.h =================================================================== --- lib/Target/CppBackend/CPPTargetMachine.h +++ lib/Target/CppBackend/CPPTargetMachine.h @@ -29,7 +29,7 @@ CPPTargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) + CodeGenOpt::Level OL, PICLevel::Level PL) : TargetMachine(T, TT, CPU, FS, Options), Subtarget() {} private: CPPSubtarget Subtarget; Index: lib/Target/Hexagon/HexagonTargetMachine.h =================================================================== --- lib/Target/Hexagon/HexagonTargetMachine.h +++ lib/Target/Hexagon/HexagonTargetMachine.h @@ -29,7 +29,7 @@ HexagonTargetMachine(const Target &T, StringRef TT,StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL); + CodeGenOpt::Level OL, PICLevel::Level PL); const HexagonSubtarget *getSubtargetImpl() const override { return &Subtarget; Index: lib/Target/Hexagon/HexagonTargetMachine.cpp =================================================================== --- lib/Target/Hexagon/HexagonTargetMachine.cpp +++ lib/Target/Hexagon/HexagonTargetMachine.cpp @@ -68,8 +68,9 @@ StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) - : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), + CodeGenOpt::Level OL, + PICLevel::Level PL) + : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, PL), Subtarget(TT, CPU, FS, *this) { initAsmInfo(); } Index: lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp =================================================================== --- lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp +++ lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp @@ -68,11 +68,12 @@ static MCCodeGenInfo *createHexagonMCCodeGenInfo(StringRef TT, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) { + CodeGenOpt::Level OL, + PICLevel::Level PL) { MCCodeGenInfo *X = new MCCodeGenInfo(); // For the time being, use static relocations, since there's really no // support for PIC yet. - X->InitMCCodeGenInfo(Reloc::Static, CM, OL); + X->InitMCCodeGenInfo(Reloc::Static, CM, OL, PL); return X; } Index: lib/Target/MSP430/MCTargetDesc/MSP430MCTargetDesc.cpp =================================================================== --- lib/Target/MSP430/MCTargetDesc/MSP430MCTargetDesc.cpp +++ lib/Target/MSP430/MCTargetDesc/MSP430MCTargetDesc.cpp @@ -52,9 +52,10 @@ static MCCodeGenInfo *createMSP430MCCodeGenInfo(StringRef TT, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) { + CodeGenOpt::Level OL, + PICLevel::Level PL) { MCCodeGenInfo *X = new MCCodeGenInfo(); - X->InitMCCodeGenInfo(RM, CM, OL); + X->InitMCCodeGenInfo(RM, CM, OL, PL); return X; } Index: lib/Target/MSP430/MSP430TargetMachine.h =================================================================== --- lib/Target/MSP430/MSP430TargetMachine.h +++ lib/Target/MSP430/MSP430TargetMachine.h @@ -30,7 +30,7 @@ MSP430TargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL); + CodeGenOpt::Level OL, PICLevel::Level PL); const MSP430Subtarget *getSubtargetImpl() const override { return &Subtarget; Index: lib/Target/MSP430/MSP430TargetMachine.cpp =================================================================== --- lib/Target/MSP430/MSP430TargetMachine.cpp +++ lib/Target/MSP430/MSP430TargetMachine.cpp @@ -28,8 +28,9 @@ StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) - : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), + CodeGenOpt::Level OL, + PICLevel::Level PL) + : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, PL), Subtarget(TT, CPU, FS, *this) { initAsmInfo(); } Index: lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp +++ lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp @@ -87,13 +87,14 @@ static MCCodeGenInfo *createMipsMCCodeGenInfo(StringRef TT, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) { + CodeGenOpt::Level OL, + PICLevel::Level PL) { MCCodeGenInfo *X = new MCCodeGenInfo(); if (CM == CodeModel::JITDefault) RM = Reloc::Static; else if (RM == Reloc::Default) RM = Reloc::PIC_; - X->InitMCCodeGenInfo(RM, CM, OL); + X->InitMCCodeGenInfo(RM, CM, OL, PL); return X; } Index: lib/Target/Mips/MipsTargetMachine.h =================================================================== --- lib/Target/Mips/MipsTargetMachine.h +++ lib/Target/Mips/MipsTargetMachine.h @@ -33,7 +33,8 @@ public: MipsTargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, - CodeModel::Model CM, CodeGenOpt::Level OL, bool isLittle); + CodeModel::Model CM, CodeGenOpt::Level OL, + PICLevel::Level PL, bool isLittle); virtual ~MipsTargetMachine() {} @@ -60,7 +61,7 @@ MipsebTargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL); + CodeGenOpt::Level OL, PICLevel::Level PL); }; /// MipselTargetMachine - Mips32/64 little endian target machine. @@ -71,7 +72,7 @@ MipselTargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL); + CodeGenOpt::Level OL, PICLevel::Level PL); }; } // End llvm namespace Index: lib/Target/Mips/MipsTargetMachine.cpp =================================================================== --- lib/Target/Mips/MipsTargetMachine.cpp +++ lib/Target/Mips/MipsTargetMachine.cpp @@ -54,8 +54,10 @@ StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL, bool isLittle) - : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), + CodeGenOpt::Level OL, + PICLevel::Level PL, + bool isLittle) + : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, PL), Subtarget(nullptr), DefaultSubtarget(TT, CPU, FS, isLittle, this), NoMips16Subtarget(TT, CPU, FS.empty() ? "-mips16" : FS.str() + ",-mips16", isLittle, this), @@ -71,8 +73,8 @@ MipsebTargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) - : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {} + CodeGenOpt::Level OL, PICLevel::Level PL) + : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, PL, false) {} void MipselTargetMachine::anchor() { } @@ -80,8 +82,8 @@ MipselTargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) - : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {} + CodeGenOpt::Level OL, PICLevel::Level PL) + : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, PL, true) {} void MipsTargetMachine::resetSubtarget(MachineFunction *MF) { DEBUG(dbgs() << "resetSubtarget\n"); Index: lib/Target/NVPTX/MCTargetDesc/NVPTXMCTargetDesc.cpp =================================================================== --- lib/Target/NVPTX/MCTargetDesc/NVPTXMCTargetDesc.cpp +++ lib/Target/NVPTX/MCTargetDesc/NVPTXMCTargetDesc.cpp @@ -52,9 +52,10 @@ } static MCCodeGenInfo *createNVPTXMCCodeGenInfo( - StringRef TT, Reloc::Model RM, CodeModel::Model CM, CodeGenOpt::Level OL) { + StringRef TT, Reloc::Model RM, CodeModel::Model CM, CodeGenOpt::Level OL, + PICLevel::Level PL) { MCCodeGenInfo *X = new MCCodeGenInfo(); - X->InitMCCodeGenInfo(RM, CM, OL); + X->InitMCCodeGenInfo(RM, CM, OL, PL); return X; } Index: lib/Target/NVPTX/NVPTXTargetMachine.h =================================================================== --- lib/Target/NVPTX/NVPTXTargetMachine.h +++ lib/Target/NVPTX/NVPTXTargetMachine.h @@ -33,7 +33,8 @@ public: NVPTXTargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, - CodeModel::Model CM, CodeGenOpt::Level OP, bool is64bit); + CodeModel::Model CM, CodeGenOpt::Level OP, + PICLevel::Level PL, bool is64bit); const NVPTXSubtarget *getSubtargetImpl() const override { return &Subtarget; } @@ -57,7 +58,7 @@ NVPTXTargetMachine32(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL); + CodeGenOpt::Level OL, PICLevel::Level PL); }; class NVPTXTargetMachine64 : public NVPTXTargetMachine { @@ -66,7 +67,7 @@ NVPTXTargetMachine64(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL); + CodeGenOpt::Level OL, PICLevel::Level PL); }; } // end namespace llvm Index: lib/Target/NVPTX/NVPTXTargetMachine.cpp =================================================================== --- lib/Target/NVPTX/NVPTXTargetMachine.cpp +++ lib/Target/NVPTX/NVPTXTargetMachine.cpp @@ -70,8 +70,10 @@ StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL, bool is64bit) - : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), + CodeGenOpt::Level OL, + PICLevel::Level PL, + bool is64bit) + : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, PL), Subtarget(TT, CPU, FS, *this, is64bit) { initAsmInfo(); } @@ -81,16 +83,16 @@ NVPTXTargetMachine32::NVPTXTargetMachine32( const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) - : NVPTXTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {} + CodeGenOpt::Level OL, PICLevel::Level PL) + : NVPTXTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, PL, false) {} void NVPTXTargetMachine64::anchor() {} NVPTXTargetMachine64::NVPTXTargetMachine64( const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) - : NVPTXTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {} + CodeGenOpt::Level OL, PICLevel::Level PL) + : NVPTXTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, PL, true) {} namespace { class NVPTXPassConfig : public TargetPassConfig { Index: lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp =================================================================== --- lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp +++ lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp @@ -87,6 +87,9 @@ case MCSymbolRefExpr::VK_PLT: Type = ELF::R_PPC_PLTREL24; break; + case MCSymbolRefExpr::VK_PPC_LOCAL: + Type = ELF::R_PPC_LOCAL24PC; + break; } break; case PPC::fixup_ppc_brcond14: Index: lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp =================================================================== --- lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp +++ lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp @@ -92,7 +92,8 @@ static MCCodeGenInfo *createPPCMCCodeGenInfo(StringRef TT, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) { + CodeGenOpt::Level OL, + PICLevel::Level PL) { MCCodeGenInfo *X = new MCCodeGenInfo(); if (RM == Reloc::Default) { @@ -108,7 +109,10 @@ (T.getArch() == Triple::ppc64 || T.getArch() == Triple::ppc64le)) CM = CodeModel::Medium; } - X->InitMCCodeGenInfo(RM, CM, OL); + if (PL == PICLevel::Default) { + PL = PICLevel::Large; + } + X->InitMCCodeGenInfo(RM, CM, OL, PL); return X; } Index: lib/Target/PowerPC/PPCAsmPrinter.cpp =================================================================== --- lib/Target/PowerPC/PPCAsmPrinter.cpp +++ lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -311,12 +311,31 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { MCInst TmpInst; bool isPPC64 = Subtarget.isPPC64(); + bool isDarwin = Subtarget.isDarwin(); // Lower multi-instruction pseudo operations. switch (MI->getOpcode()) { default: break; case TargetOpcode::DBG_VALUE: llvm_unreachable("Should be handled target independently"); + case PPC::MoveGOTtoLR: { + // Transform %LR = MoveGOTtoLR + // Into this: bl _GLOBAL_OFFSET_TABLE_@local-4 + // _GLOBAL_OFFSET_TABLE_@local-4 (instruction preceding + // _GLOBAL_OFFSET_TABLE_) has exactly one instruction: + // blrl + // This will return the pointer to _GLOBAL_OFFSET_TABLE_@local + MCSymbol *GOTSymbol = OutContext.GetOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_")); + const MCExpr *OffsExpr = + MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(GOTSymbol, MCSymbolRefExpr::VK_PPC_LOCAL, + OutContext), + MCConstantExpr::Create(4, OutContext), + OutContext); + + // Emit the 'bl'. + EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BL).addExpr(OffsExpr)); + return; + } case PPC::MovePCtoLR: case PPC::MovePCtoLR8: { // Transform %LR = MovePCtoLR @@ -335,10 +354,14 @@ OutStreamer.EmitLabel(PICBase); return; } - case PPC::GetGBRO: { + case PPC::UpdateGBR: { + // Transform %Rd = UpdateGBR(%Rt, %Ri) + // Into: lwz %Rt, .L0$poff - .L0$pb(%Ri) + // add %Rd, %Rt, %Ri // Get the offset from the GOT Base Register to the GOT - LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); - MCSymbol *PICOffset = MF->getInfo()->getPICOffsetSymbol(); + LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin); + MCSymbol *PICOffset = + MF->getInfo()->getPICOffsetSymbol(); TmpInst.setOpcode(PPC::LWZ); const MCExpr *Exp = MCSymbolRefExpr::Create(PICOffset, MCSymbolRefExpr::VK_None, OutContext); @@ -346,26 +369,30 @@ MCSymbolRefExpr::Create(MF->getPICBaseSymbol(), MCSymbolRefExpr::VK_None, OutContext); - const MCOperand MO = TmpInst.getOperand(1); - TmpInst.getOperand(1) = MCOperand::CreateExpr(MCBinaryExpr::CreateSub(Exp, - PB, - OutContext)); - TmpInst.addOperand(MO); + const MCOperand TR = TmpInst.getOperand(1); + const MCOperand PICR = TmpInst.getOperand(0); + + // Step 1: lwz %Rt, .L$poff - .L$pb(%Ri) + TmpInst.getOperand(1) = + MCOperand::CreateExpr(MCBinaryExpr::CreateSub(Exp, + PB, + OutContext)); + TmpInst.getOperand(0) = TR; + TmpInst.getOperand(2) = PICR; EmitToStreamer(OutStreamer, TmpInst); - return; - } - case PPC::UpdateGBR: { + // Update the GOT Base Register to point to the GOT. It may be possible to // merge this with the PPC::GetGBRO, doing it all in one step. - LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); TmpInst.setOpcode(PPC::ADD4); - TmpInst.addOperand(TmpInst.getOperand(0)); + TmpInst.getOperand(0) = PICR; + TmpInst.getOperand(1) = TR; + TmpInst.getOperand(2) = PICR; EmitToStreamer(OutStreamer, TmpInst); return; } case PPC::LWZtoc: { - // Transform %X3 = LWZtoc , %X2 - LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); + // Transform %R3 = LWZtoc , %R2 + LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin); // Change the opcode to LWZ, and the global address operand to be a // reference to the GOT entry we will synthesize later. @@ -382,16 +409,23 @@ else if (MO.isJTI()) MOSymbol = GetJTISymbol(MO.getIndex()); - MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol); - - const MCExpr *Exp = - MCSymbolRefExpr::Create(TOCEntry, MCSymbolRefExpr::VK_None, - OutContext); - const MCExpr *PB = - MCSymbolRefExpr::Create(OutContext.GetOrCreateSymbol(Twine(".L.TOC.")), - OutContext); - Exp = MCBinaryExpr::CreateSub(Exp, PB, OutContext); - TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp); + if (TM.getPICLevel() == PICLevel::Large) { + MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol); + + const MCExpr *Exp = + MCSymbolRefExpr::Create(TOCEntry, MCSymbolRefExpr::VK_None, + OutContext); + const MCExpr *PB = + MCSymbolRefExpr::Create(OutContext.GetOrCreateSymbol(Twine(".LTOC.")), + OutContext); + Exp = MCBinaryExpr::CreateSub(Exp, PB, OutContext); + TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp); + } else { + const MCExpr *Exp = + MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_GOT, + OutContext); + TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp); + } EmitToStreamer(OutStreamer, TmpInst); return; } @@ -399,7 +433,7 @@ case PPC::LDtocCPT: case PPC::LDtoc: { // Transform %X3 = LDtoc , %X2 - LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); + LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin); // Change the opcode to LD, and the global address operand to be a // reference to the TOC entry we will synthesize later. @@ -428,7 +462,7 @@ case PPC::ADDIStocHA: { // Transform %Xd = ADDIStocHA %X2, - LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); + LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin); // Change the opcode to ADDIS8. If the global address is external, has // common linkage, is a non-local function address, or is a jump table @@ -470,7 +504,7 @@ } case PPC::LDtocL: { // Transform %Xd = LDtocL , %Xs - LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); + LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin); // Change the opcode to LD. If the global address is external, has // common linkage, or is a jump table address, then reference the @@ -507,7 +541,7 @@ } case PPC::ADDItocL: { // Transform %Xd = ADDItocL %Xs, - LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); + LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin); // Change the opcode to ADDI8. If the global address is external, then // generate a TOC entry and reference that. Otherwise reference the @@ -558,7 +592,7 @@ case PPC::LDgotTprelL: case PPC::LDgotTprelL32: { // Transform %Xd = LDgotTprelL , %Xs - LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); + LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin); // Change the opcode to LD. TmpInst.setOpcode(isPPC64 ? PPC::LD : PPC::LWZ); @@ -841,7 +875,7 @@ } } - LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); + LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin); EmitToStreamer(OutStreamer, TmpInst); } @@ -857,16 +891,14 @@ if (Subtarget.isPPC64() || TM.getRelocationModel() != Reloc::PIC_) return AsmPrinter::EmitStartOfAsmFile(M); - // FIXME: The use of .got2 assumes large GOT model (-fPIC), which is not - // optimal for some cases. We should consider supporting small model (-fpic) - // as well in the future. - assert(TM.getCodeModel() != CodeModel::Small && - "Small code model PIC is currently unsupported."); + if (TM.getPICLevel() != PICLevel::Large) + return AsmPrinter::EmitStartOfAsmFile(M); + OutStreamer.SwitchSection(OutContext.getELFSection(".got2", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC, SectionKind::getReadOnly())); - MCSymbol *TOCSym = OutContext.GetOrCreateSymbol(Twine(".L.TOC.")); + MCSymbol *TOCSym = OutContext.GetOrCreateSymbol(Twine(".LTOC.")); MCSymbol *CurrentPos = OutContext.CreateTempSymbol(); OutStreamer.EmitLabel(CurrentPos); @@ -885,10 +917,13 @@ void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() { // linux/ppc32 - Normal entry label. - if (!Subtarget.isPPC64() && TM.getRelocationModel() != Reloc::PIC_) + if (!Subtarget.isPPC64() && + (TM.getRelocationModel() != Reloc::PIC_ || + TM.getPICLevel() != PICLevel::Large)) return AsmPrinter::EmitFunctionEntryLabel(); - if (!Subtarget.isPPC64()) { + if (!Subtarget.isPPC64() && TM.getRelocationModel() == Reloc::PIC_ + && TM.getPICLevel() == PICLevel::Large) { const PPCFunctionInfo *PPCFI = MF->getInfo(); if (PPCFI->usesPICBase()) { MCSymbol *RelocSymbol = PPCFI->getPICOffsetSymbol(); @@ -897,7 +932,7 @@ const MCExpr *OffsExpr = MCBinaryExpr::CreateSub( - MCSymbolRefExpr::Create(OutContext.GetOrCreateSymbol(Twine(".L.TOC.")), + MCSymbolRefExpr::Create(OutContext.GetOrCreateSymbol(Twine(".LTOC.")), OutContext), MCSymbolRefExpr::Create(PICBase, OutContext), OutContext); Index: lib/Target/PowerPC/PPCISelDAGToDAG.cpp =================================================================== --- lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -281,14 +281,17 @@ else GlobalBaseReg = RegInfo->createVirtualRegister(&PPC::GPRC_NOR0RegClass); - BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::MovePCtoLR)); + if (PPCSubTarget->isTargetELF() && + TM.getPICLevel() == PICLevel::Small) + BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::MoveGOTtoLR)); + else + BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::MovePCtoLR)); BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::MFLR), GlobalBaseReg); - if (PPCSubTarget->isTargetELF()) { + if (PPCSubTarget->isTargetELF() && TM.getPICLevel() == PICLevel::Large) { unsigned TempReg = RegInfo->createVirtualRegister(&PPC::GPRCRegClass); BuildMI(FirstMBB, MBBI, dl, - TII.get(PPC::GetGBRO), TempReg).addReg(GlobalBaseReg); - BuildMI(FirstMBB, MBBI, dl, - TII.get(PPC::UpdateGBR)).addReg(GlobalBaseReg).addReg(TempReg); + TII.get(PPC::UpdateGBR)).addReg(GlobalBaseReg) + .addReg(TempReg, RegState::Define).addReg(GlobalBaseReg); MF->getInfo()->setUsesPICBase(true); } } else { @@ -1436,13 +1439,13 @@ return CurDAG->SelectNodeTo(N, Reg, MVT::Other, Chain); } case PPCISD::TOC_ENTRY: { + assert ((PPCSubTarget->isPPC64() || PPCSubTarget->isSVR4ABI()) && + "Only supported for 64-bit ABI and 32-bit SVR4"); if (PPCSubTarget->isSVR4ABI() && !PPCSubTarget->isPPC64()) { SDValue GA = N->getOperand(0); return CurDAG->getMachineNode(PPC::LWZtoc, dl, MVT::i32, GA, N->getOperand(1)); } - assert (PPCSubTarget->isPPC64() && - "Only supported for 64-bit ABI and 32-bit SVR4"); // For medium and large code model, we generate two instructions as // described below. Otherwise we allow SelectCodeCommon to handle this, Index: lib/Target/PowerPC/PPCISelLowering.cpp =================================================================== --- lib/Target/PowerPC/PPCISelLowering.cpp +++ lib/Target/PowerPC/PPCISelLowering.cpp @@ -1655,6 +1655,7 @@ const GlobalValue *GV = GA->getGlobal(); EVT PtrVT = getPointerTy(); bool is64bit = Subtarget.isPPC64(); + PICLevel::Level picLevel = getTargetMachine().getPICLevel(); TLSModel::Model Model = getTargetMachine().getTLSModel(GV); @@ -1693,7 +1694,10 @@ GOTPtr = DAG.getNode(PPCISD::ADDIS_TLSGD_HA, dl, PtrVT, GOTReg, TGA); } else { - GOTPtr = DAG.getNode(PPCISD::PPC32_PICGOT, dl, PtrVT); + if (picLevel == PICLevel::Large) + GOTPtr = DAG.getNode(PPCISD::PPC32_PICGOT, dl, PtrVT); + else + GOTPtr = DAG.getNode(PPCISD::GlobalBaseReg, dl, PtrVT); } SDValue GOTEntry = DAG.getNode(PPCISD::ADDI_TLSGD_L, dl, PtrVT, GOTPtr, TGA); @@ -1723,7 +1727,10 @@ GOTPtr = DAG.getNode(PPCISD::ADDIS_TLSLD_HA, dl, PtrVT, GOTReg, TGA); } else { - GOTPtr = DAG.getNode(PPCISD::PPC32_PICGOT, dl, PtrVT); + if (picLevel == PICLevel::Large) + GOTPtr = DAG.getNode(PPCISD::PPC32_PICGOT, dl, PtrVT); + else + GOTPtr = DAG.getNode(PPCISD::GlobalBaseReg, dl, PtrVT); } SDValue GOTEntry = DAG.getNode(PPCISD::ADDI_TLSLD_L, dl, PtrVT, GOTPtr, TGA); Index: lib/Target/PowerPC/PPCInstrInfo.td =================================================================== --- lib/Target/PowerPC/PPCInstrInfo.td +++ lib/Target/PowerPC/PPCInstrInfo.td @@ -1025,6 +1025,9 @@ let Defs = [LR] in def MovePCtoLR : Pseudo<(outs), (ins), "#MovePCtoLR", []>, PPC970_Unit_BRU; +let Defs = [LR] in + def MoveGOTtoLR : Pseudo<(outs), (ins), "#MoveGOTtoLR", []>, + PPC970_Unit_BRU; let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, PPC970_Unit = 7 in { let isBarrier = 1 in { @@ -2500,15 +2503,13 @@ tglobaltlsaddr:$disp))]>; // Support for Position-independent code -def LWZtoc: Pseudo<(outs gprc:$rD), (ins tocentry32:$disp, gprc:$reg), - "#LWZtoc", - [(set i32:$rD, - (PPCtoc_entry tglobaladdr:$disp, i32:$reg))]>; +def LWZtoc : Pseudo<(outs gprc:$rD), (ins tocentry32:$disp, gprc:$reg), + "#LWZtoc", + [(set i32:$rD, + (PPCtoc_entry tglobaladdr:$disp, i32:$reg))]>; // Get Global (GOT) Base Register offset, from the word immediately preceding // the function label. -def GetGBRO: Pseudo<(outs gprc:$rT), (ins gprc:$rI), "#GetGBRO", []>; -// Update the Global(GOT) Base Register with the above offset. -def UpdateGBR: Pseudo<(outs gprc:$rT), (ins gprc:$rI), "#UpdateGBR", []>; +def UpdateGBR : Pseudo<(outs gprc:$rD, gprc:$rT), (ins gprc:$rI), "#UpdateGBR", []>; // Standard shifts. These are represented separately from the real shifts above Index: lib/Target/PowerPC/PPCTargetMachine.h =================================================================== --- lib/Target/PowerPC/PPCTargetMachine.h +++ lib/Target/PowerPC/PPCTargetMachine.h @@ -30,7 +30,8 @@ PPCTargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL); + CodeGenOpt::Level OL, + PICLevel::Level PL); const PPCSubtarget *getSubtargetImpl() const override { return &Subtarget; } @@ -49,7 +50,8 @@ PPC32TargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL); + CodeGenOpt::Level OL, + PICLevel::Level PL); }; /// PPC64TargetMachine - PowerPC 64-bit target machine. @@ -60,7 +62,8 @@ PPC64TargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL); + CodeGenOpt::Level OL, + PICLevel::Level PL); }; } // end namespace llvm Index: lib/Target/PowerPC/PPCTargetMachine.cpp =================================================================== --- lib/Target/PowerPC/PPCTargetMachine.cpp +++ lib/Target/PowerPC/PPCTargetMachine.cpp @@ -40,8 +40,9 @@ PPCTargetMachine::PPCTargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) - : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), + CodeGenOpt::Level OL, + PICLevel::Level PL) + : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, PL), Subtarget(TT, CPU, FS, *this, OL) { initAsmInfo(); } @@ -52,8 +53,9 @@ StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) - : PPCTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL) { + CodeGenOpt::Level OL, + PICLevel::Level PL) + : PPCTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, PL) { } void PPC64TargetMachine::anchor() { } @@ -62,8 +64,9 @@ StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) - : PPCTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL) { + CodeGenOpt::Level OL, + PICLevel::Level PL) + : PPCTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, PL) { } Index: lib/Target/R600/AMDGPUTargetMachine.h =================================================================== --- lib/Target/R600/AMDGPUTargetMachine.h +++ lib/Target/R600/AMDGPUTargetMachine.h @@ -31,7 +31,8 @@ public: AMDGPUTargetMachine(const Target &T, StringRef TT, StringRef FS, StringRef CPU, TargetOptions Options, Reloc::Model RM, - CodeModel::Model CM, CodeGenOpt::Level OL); + CodeModel::Model CM, CodeGenOpt::Level OL, + PICLevel::Level PL); ~AMDGPUTargetMachine(); const AMDGPUSubtarget *getSubtargetImpl() const override { return &Subtarget; Index: lib/Target/R600/AMDGPUTargetMachine.cpp =================================================================== --- lib/Target/R600/AMDGPUTargetMachine.cpp +++ lib/Target/R600/AMDGPUTargetMachine.cpp @@ -52,8 +52,9 @@ StringRef CPU, StringRef FS, TargetOptions Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OptLevel) - : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OptLevel), + CodeGenOpt::Level OptLevel, + PICLevel::Level PL) + : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OptLevel, PL), Subtarget(TT, CPU, FS, *this), IntrinsicInfo() { setRequiresStructuredCFG(true); initAsmInfo(); Index: lib/Target/R600/MCTargetDesc/AMDGPUMCTargetDesc.cpp =================================================================== --- lib/Target/R600/MCTargetDesc/AMDGPUMCTargetDesc.cpp +++ lib/Target/R600/MCTargetDesc/AMDGPUMCTargetDesc.cpp @@ -56,9 +56,10 @@ static MCCodeGenInfo *createAMDGPUMCCodeGenInfo(StringRef TT, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) { + CodeGenOpt::Level OL, + PICLevel::Level PL) { MCCodeGenInfo *X = new MCCodeGenInfo(); - X->InitMCCodeGenInfo(RM, CM, OL); + X->InitMCCodeGenInfo(RM, CM, OL, PL); return X; } Index: lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp =================================================================== --- lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp +++ lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp @@ -86,7 +86,8 @@ static MCCodeGenInfo *createSparcMCCodeGenInfo(StringRef TT, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) { + CodeGenOpt::Level OL, + PICLevel::Level PL) { MCCodeGenInfo *X = new MCCodeGenInfo(); // The default 32-bit code model is abs32/pic32 and the default 32-bit @@ -97,13 +98,14 @@ case CodeModel::JITDefault: CM = CodeModel::Small; break; } - X->InitMCCodeGenInfo(RM, CM, OL); + X->InitMCCodeGenInfo(RM, CM, OL, PL); return X; } static MCCodeGenInfo *createSparcV9MCCodeGenInfo(StringRef TT, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) { + CodeGenOpt::Level OL, + PICLevel::Level PL) { MCCodeGenInfo *X = new MCCodeGenInfo(); // The default 64-bit code model is abs44/pic32 and the default 64-bit @@ -118,7 +120,7 @@ break; } - X->InitMCCodeGenInfo(RM, CM, OL); + X->InitMCCodeGenInfo(RM, CM, OL, PL); return X; } Index: lib/Target/Sparc/SparcTargetMachine.h =================================================================== --- lib/Target/Sparc/SparcTargetMachine.h +++ lib/Target/Sparc/SparcTargetMachine.h @@ -26,7 +26,7 @@ SparcTargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL, bool is64bit); + CodeGenOpt::Level OL, PICLevel::Level PL, bool is64bit); const SparcSubtarget *getSubtargetImpl() const override { return &Subtarget; } @@ -43,7 +43,8 @@ StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL); + CodeGenOpt::Level OL, + PICLevel::Level PL); }; /// SparcV9TargetMachine - Sparc 64-bit target machine @@ -55,7 +56,8 @@ StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL); + CodeGenOpt::Level OL, + PICLevel::Level PL); }; } // end namespace llvm Index: lib/Target/Sparc/SparcTargetMachine.cpp =================================================================== --- lib/Target/Sparc/SparcTargetMachine.cpp +++ lib/Target/Sparc/SparcTargetMachine.cpp @@ -30,8 +30,9 @@ const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, CodeGenOpt::Level OL, + PICLevel::Level PL, bool is64bit) - : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), + : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, PL), Subtarget(TT, CPU, FS, *this, is64bit) { initAsmInfo(); } @@ -77,8 +78,9 @@ const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) - : SparcTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) { + CodeGenOpt::Level OL, + PICLevel::Level PL) + : SparcTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, PL, false) { } void SparcV9TargetMachine::anchor() { } @@ -89,6 +91,7 @@ const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) - : SparcTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) { + CodeGenOpt::Level OL, + PICLevel::Level PL) + : SparcTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, PL, true) { } Index: lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.cpp =================================================================== --- lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.cpp +++ lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.cpp @@ -127,7 +127,8 @@ static MCCodeGenInfo *createSystemZMCCodeGenInfo(StringRef TT, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) { + CodeGenOpt::Level OL, + PICLevel::Level PL) { MCCodeGenInfo *X = new MCCodeGenInfo(); // Static code is suitable for use in a dynamic executable; there is no @@ -168,7 +169,7 @@ CM = CodeModel::Small; else if (CM == CodeModel::JITDefault) CM = RM == Reloc::PIC_ ? CodeModel::Small : CodeModel::Medium; - X->InitMCCodeGenInfo(RM, CM, OL); + X->InitMCCodeGenInfo(RM, CM, OL, PL); return X; } Index: lib/Target/SystemZ/SystemZTargetMachine.h =================================================================== --- lib/Target/SystemZ/SystemZTargetMachine.h +++ lib/Target/SystemZ/SystemZTargetMachine.h @@ -29,7 +29,7 @@ SystemZTargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL); + CodeGenOpt::Level OL, PICLevel::Level); // Override TargetMachine. const SystemZSubtarget *getSubtargetImpl() const override { Index: lib/Target/SystemZ/SystemZTargetMachine.cpp =================================================================== --- lib/Target/SystemZ/SystemZTargetMachine.cpp +++ lib/Target/SystemZ/SystemZTargetMachine.cpp @@ -23,8 +23,9 @@ StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) - : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), + CodeGenOpt::Level OL, + PICLevel::Level PL) + : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, PL), Subtarget(TT, CPU, FS, *this) { initAsmInfo(); } Index: lib/Target/TargetLoweringObjectFile.cpp =================================================================== --- lib/Target/TargetLoweringObjectFile.cpp +++ lib/Target/TargetLoweringObjectFile.cpp @@ -45,7 +45,7 @@ Ctx = &ctx; DL = TM.getSubtargetImpl()->getDataLayout(); InitMCObjectFileInfo(TM.getTargetTriple(), - TM.getRelocationModel(), TM.getCodeModel(), *Ctx); + TM.getRelocationModel(), TM.getCodeModel(), TM.getPICLevel(), *Ctx); } TargetLoweringObjectFile::~TargetLoweringObjectFile() { Index: lib/Target/TargetMachine.cpp =================================================================== --- lib/Target/TargetMachine.cpp +++ lib/Target/TargetMachine.cpp @@ -173,6 +173,14 @@ Options.DataSections = V; } +/// getPICLevel - Returns the code generation PIC level. The choices are +/// small, large, and target default. +PICLevel::Level TargetMachine::getPICLevel() const { + if (!CodeGenInfo) + return PICLevel::Default; + return CodeGenInfo->getPICLevel(); +} + void TargetMachine::getNameWithPrefix(SmallVectorImpl &Name, const GlobalValue *GV, Mangler &Mang, bool MayAlwaysUsePrivate) const { Index: lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp =================================================================== --- lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp +++ lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp @@ -301,7 +301,8 @@ static MCCodeGenInfo *createX86MCCodeGenInfo(StringRef TT, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) { + CodeGenOpt::Level OL, + PICLevel::Level PL) { MCCodeGenInfo *X = new MCCodeGenInfo(); Triple T(TT); @@ -345,7 +346,7 @@ // 64-bit JIT places everything in the same buffer except external funcs. CM = is64Bit ? CodeModel::Large : CodeModel::Small; - X->InitMCCodeGenInfo(RM, CM, OL); + X->InitMCCodeGenInfo(RM, CM, OL, PL); return X; } Index: lib/Target/X86/X86TargetMachine.h =================================================================== --- lib/Target/X86/X86TargetMachine.h +++ lib/Target/X86/X86TargetMachine.h @@ -30,7 +30,7 @@ X86TargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL); + CodeGenOpt::Level OL, PICLevel::Level PL); const X86Subtarget *getSubtargetImpl() const override { return &Subtarget; } /// \brief Register X86 analysis passes with a pass manager. Index: lib/Target/X86/X86TargetMachine.cpp =================================================================== --- lib/Target/X86/X86TargetMachine.cpp +++ lib/Target/X86/X86TargetMachine.cpp @@ -34,8 +34,8 @@ X86TargetMachine::X86TargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) - : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), + CodeGenOpt::Level OL, PICLevel::Level PL) + : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, PL), Subtarget(TT, CPU, FS, *this, Options.StackAlignmentOverride) { // default to hard float ABI if (Options.FloatABIType == FloatABI::Default) Index: lib/Target/XCore/MCTargetDesc/XCoreMCTargetDesc.cpp =================================================================== --- lib/Target/XCore/MCTargetDesc/XCoreMCTargetDesc.cpp +++ lib/Target/XCore/MCTargetDesc/XCoreMCTargetDesc.cpp @@ -66,7 +66,8 @@ static MCCodeGenInfo *createXCoreMCCodeGenInfo(StringRef TT, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) { + CodeGenOpt::Level OL, + PICLevel::Level PL) { MCCodeGenInfo *X = new MCCodeGenInfo(); if (RM == Reloc::Default) { RM = Reloc::Static; @@ -77,7 +78,7 @@ if (CM != CodeModel::Small && CM != CodeModel::Large) report_fatal_error("Target only supports CodeModel Small or Large"); - X->InitMCCodeGenInfo(RM, CM, OL); + X->InitMCCodeGenInfo(RM, CM, OL, PL); return X; } Index: lib/Target/XCore/XCoreTargetMachine.h =================================================================== --- lib/Target/XCore/XCoreTargetMachine.h +++ lib/Target/XCore/XCoreTargetMachine.h @@ -25,7 +25,7 @@ XCoreTargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL); + CodeGenOpt::Level OL, PICLevel::Level PL); const XCoreSubtarget *getSubtargetImpl() const override { return &Subtarget; } Index: lib/Target/XCore/XCoreTargetMachine.cpp =================================================================== --- lib/Target/XCore/XCoreTargetMachine.cpp +++ lib/Target/XCore/XCoreTargetMachine.cpp @@ -24,8 +24,9 @@ StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) - : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), + CodeGenOpt::Level OL, + PICLevel::Level PL) + : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, PL), Subtarget(TT, CPU, FS, *this) { initAsmInfo(); } Index: test/CodeGen/PowerPC/ppc32-pic.ll =================================================================== --- test/CodeGen/PowerPC/ppc32-pic.ll +++ test/CodeGen/PowerPC/ppc32-pic.ll @@ -1,21 +1,27 @@ -; RUN: llc < %s -mtriple=powerpc-unknown-linux-gnu -relocation-model=pic | FileCheck %s -@foobar = common global i32 0, align 4 +; RUN: llc < %s -mtriple=powerpc-unknown-linux-gnu -relocation-model=pic -pic-level=small | FileCheck -check-prefix=SMALL-BSS %s +; RUN: llc < %s -mtriple=powerpc-unknown-linux-gnu -relocation-model=pic -pic-level=large | FileCheck -check-prefix=LARGE-BSS %s +@bar = common global i32 0, align 4 define i32 @foo() { entry: - %0 = load i32* @foobar, align 4 + %0 = load i32* @bar, align 4 ret i32 %0 } -; CHECK: [[POFF:\.L[0-9]+\$poff]]: -; CHECK-NEXT: .long .L.TOC.-[[PB:\.L[0-9]+\$pb]] -; CHECK-NEXT: foo: -; CHECK: bl [[PB]] -; CHECK-NEXT: [[PB]]: -; CHECK: mflr 30 -; CHECK: lwz [[REG:[0-9]+]], [[POFF]]-[[PB]](30) -; CHECK-NEXT: add 30, [[REG]], 30 -; CHECK: lwz [[VREG:[0-9]+]], [[VREF:\.LC[0-9]+]]-.L.TOC.(30) -; CHECK: lwz {{[0-9]+}}, 0([[VREG]]) -; CHECK: [[VREF]]: -; CHECK-NEXT: .long foobar +; SMALL-BSS-LABEL:foo: +; SMALL-BSS: bl _GLOBAL_OFFSET_TABLE_@local-4 +; SMALL-BSS: mflr 30 +; SMALL-BSS: lwz [[VREG:[0-9]+]], bar@GOT(30) +; SMALL-BSS: lwz {{[0-9]+}}, 0([[VREG]]) +; LARGE-BSS: [[POFF:\.L[0-9]+\$poff]]: +; LARGE-BSS-NEXT: .long .LTOC.-[[PB:\.L[0-9]+\$pb]] +; LARGE-BSS-NEXT: foo: +; LARGE-BSS: bl [[PB]] +; LARGE-BSS-NEXT: [[PB]]: +; LARGE-BSS: mflr 30 +; LARGE-BSS: lwz [[REG:[0-9]+]], [[POFF]]-[[PB]](30) +; LARGE-BSS-NEXT: add 30, [[REG]], 30 +; LARGE-BSS: lwz [[VREG:[0-9]+]], [[VREF:\.LC[0-9]+]]-.LTOC.(30) +; LARGE-BSS: lwz {{[0-9]+}}, 0([[VREG]]) +; LARGE-BSS: [[VREF]]: +; LARGE-BSS-NEXT: .long bar Index: test/CodeGen/PowerPC/sections.ll =================================================================== --- test/CodeGen/PowerPC/sections.ll +++ test/CodeGen/PowerPC/sections.ll @@ -1,12 +1,14 @@ ; Test to make sure that bss sections are printed with '.section' directive. ; RUN: llc < %s -mtriple=powerpc-unknown-linux-gnu | FileCheck %s ; RUN: llc < %s -mtriple=powerpc-unknown-linux-gnu -relocation-model=pic | FileCheck %s -check-prefix=PIC +; RUN: llc < %s -mtriple=powerpc-unknown-linux-gnu -relocation-model=pic -pic-level=large| FileCheck %s -check-prefix=LARGE-PIC @A = global i32 0 ; CHECK: .section .bss,"aw",@nobits ; CHECK: .globl A - -; PIC: .section .got2,"aw",@progbits ; PIC: .section .bss,"aw",@nobits ; PIC: .globl A +; LARGE-PIC: .section .got2,"aw",@progbits +; LARGE-PIC: .section .bss,"aw",@nobits +; LARGE-PIC: .globl A Index: test/CodeGen/PowerPC/tls-pic.ll =================================================================== --- test/CodeGen/PowerPC/tls-pic.ll +++ test/CodeGen/PowerPC/tls-pic.ll @@ -25,7 +25,7 @@ ; OPT0: addis [[REG2:[0-9]+]], 3, a@dtprel@ha ; OPT0-NEXT: addi {{[0-9]+}}, [[REG2]], a@dtprel@l ; OPT0-32-LABEL: main -; OPT0-32: addi {{[0-9]+}}, {{[0-9]+}}, a@got@tlsld +; OPT0-32: addi 3, {{[0-9]+}}, a@got@tlsld ; OPT0-32: bl __tls_get_addr(a@tlsld)@PLT ; OPT0-32: addis [[REG:[0-9]+]], 3, a@dtprel@ha ; OPT0-32-NEXT: addi {{[0-9]+}}, [[REG]], a@dtprel@l Index: tools/llc/llc.cpp =================================================================== --- tools/llc/llc.cpp +++ tools/llc/llc.cpp @@ -275,7 +275,8 @@ std::unique_ptr target( TheTarget->createTargetMachine(TheTriple.getTriple(), MCPU, FeaturesStr, - Options, RelocModel, CMModel, OLvl)); + Options, RelocModel, CMModel, + OLvl, PLevel)); assert(target.get() && "Could not allocate target machine!"); // If we don't have a module then just exit now. We do this down Index: tools/llvm-mc/llvm-mc.cpp =================================================================== --- tools/llvm-mc/llvm-mc.cpp +++ tools/llvm-mc/llvm-mc.cpp @@ -126,6 +126,19 @@ "Relocatable external references, non-relocatable code"), clEnumValEnd)); +static cl::opt +PLevel("pic-level", + cl::desc("Choose the PIC level (small or large)"), + cl::init(PICLevel::Default), + cl::values( + clEnumValN(PICLevel::Default, "default", + "Target default PIC level"), + clEnumValN(PICLevel::Small, "small", + "Small-model PIC (-fpic)"), + clEnumValN(PICLevel::Large, "large", + "Large-model PIC (-fPIC)"), + clEnumValEnd)); + static cl::opt CMModel("code-model", cl::desc("Choose code model"), @@ -403,7 +416,7 @@ // MCObjectFileInfo needs a MCContext reference in order to initialize itself. MCObjectFileInfo MOFI; MCContext Ctx(MAI.get(), MRI.get(), &MOFI, &SrcMgr); - MOFI.InitMCObjectFileInfo(TripleName, RelocModel, CMModel, Ctx); + MOFI.InitMCObjectFileInfo(TripleName, RelocModel, CMModel, PLevel, Ctx); if (SaveTempLabels) Ctx.setAllowTemporaryLabels(false);