From owner-svn-src-all@FreeBSD.ORG Mon Aug 18 18:07:28 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id D0149F8A; Mon, 18 Aug 2014 18:07:28 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id BA0273375; Mon, 18 Aug 2014 18:07:28 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id s7II7SwI010674; Mon, 18 Aug 2014 18:07:28 GMT (envelope-from rdivacky@FreeBSD.org) Received: (from rdivacky@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id s7II7S7t010673; Mon, 18 Aug 2014 18:07:28 GMT (envelope-from rdivacky@FreeBSD.org) Message-Id: <201408181807.s7II7S7t010673@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: rdivacky set sender to rdivacky@FreeBSD.org using -f From: Roman Divacky Date: Mon, 18 Aug 2014 18:07:28 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r270148 - head/contrib/llvm/patches X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 18 Aug 2014 18:07:28 -0000 Author: rdivacky Date: Mon Aug 18 18:07:28 2014 New Revision: 270148 URL: http://svnweb.freebsd.org/changeset/base/270148 Log: Add the patch commited in r270147. Added: head/contrib/llvm/patches/patch-r270147-llvm-r197824-r213427-r213960.diff Added: head/contrib/llvm/patches/patch-r270147-llvm-r197824-r213427-r213960.diff ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/contrib/llvm/patches/patch-r270147-llvm-r197824-r213427-r213960.diff Mon Aug 18 18:07:28 2014 (r270148) @@ -0,0 +1,1303 @@ +Index: contrib/llvm/include/llvm/Support/ELF.h +=================================================================== +--- contrib/llvm/include/llvm/Support/ELF.h (revision 270019) ++++ contrib/llvm/include/llvm/Support/ELF.h (working copy) +@@ -437,6 +437,7 @@ + R_PPC_GOT16_LO = 15, + R_PPC_GOT16_HI = 16, + R_PPC_GOT16_HA = 17, ++ R_PPC_PLTREL24 = 18, + R_PPC_REL32 = 26, + R_PPC_TLS = 67, + R_PPC_DTPMOD32 = 68, +Index: contrib/llvm/lib/Object/ELF.cpp +=================================================================== +--- contrib/llvm/lib/Object/ELF.cpp (revision 270019) ++++ contrib/llvm/lib/Object/ELF.cpp (working copy) +@@ -507,6 +507,7 @@ + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT16_LO); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT16_HI); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT16_HA); ++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_PLTREL24); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_TLS); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_DTPMOD32); +Index: contrib/llvm/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp +=================================================================== +--- contrib/llvm/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp (revision 270019) ++++ contrib/llvm/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp (working copy) +@@ -18,6 +18,7 @@ + #include "llvm/MC/MCExpr.h" + #include "llvm/MC/MCInst.h" + #include "llvm/MC/MCInstrInfo.h" ++#include "llvm/MC/MCSymbol.h" + #include "llvm/Support/CommandLine.h" + #include "llvm/Support/raw_ostream.h" + #include "llvm/Target/TargetOpcodes.h" +@@ -294,10 +295,16 @@ + + void PPCInstPrinter::printTLSCall(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { +- printBranchOperand(MI, OpNo, O); ++ // On PPC64, VariantKind is VK_None, but on PPC32, it's VK_PLT, and it must ++ // come at the _end_ of the expression. ++ const MCOperand &Op = MI->getOperand(OpNo); ++ const MCSymbolRefExpr &refExp = cast(*Op.getExpr()); ++ O << refExp.getSymbol().getName(); + O << '('; + printOperand(MI, OpNo+1, O); + O << ')'; ++ if (refExp.getKind() != MCSymbolRefExpr::VK_None) ++ O << '@' << MCSymbolRefExpr::getVariantKindName(refExp.getKind()); + } + + +Index: contrib/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp +=================================================================== +--- contrib/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp (revision 270019) ++++ contrib/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp (working copy) +@@ -64,7 +64,15 @@ + llvm_unreachable("Unimplemented"); + case PPC::fixup_ppc_br24: + case PPC::fixup_ppc_br24abs: +- Type = ELF::R_PPC_REL24; ++ switch (Modifier) { ++ default: llvm_unreachable("Unsupported Modifier"); ++ case MCSymbolRefExpr::VK_None: ++ Type = ELF::R_PPC_REL24; ++ break; ++ case MCSymbolRefExpr::VK_PLT: ++ Type = ELF::R_PPC_PLTREL24; ++ break; ++ } + break; + case PPC::fixup_ppc_brcond14: + case PPC::fixup_ppc_brcond14abs: +@@ -205,7 +213,10 @@ + Type = ELF::R_PPC64_DTPREL16_HIGHESTA; + break; + case MCSymbolRefExpr::VK_PPC_GOT_TLSGD: +- Type = ELF::R_PPC64_GOT_TLSGD16; ++ if (is64Bit()) ++ Type = ELF::R_PPC64_GOT_TLSGD16; ++ else ++ Type = ELF::R_PPC_GOT_TLSGD16; + break; + case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO: + Type = ELF::R_PPC64_GOT_TLSGD16_LO; +@@ -217,7 +228,10 @@ + Type = ELF::R_PPC64_GOT_TLSGD16_HA; + break; + case MCSymbolRefExpr::VK_PPC_GOT_TLSLD: +- Type = ELF::R_PPC64_GOT_TLSLD16; ++ if (is64Bit()) ++ Type = ELF::R_PPC64_GOT_TLSLD16; ++ else ++ Type = ELF::R_PPC_GOT_TLSLD16; + break; + case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO: + Type = ELF::R_PPC64_GOT_TLSLD16_LO; +@@ -313,13 +327,22 @@ + switch (Modifier) { + default: llvm_unreachable("Unsupported Modifier"); + case MCSymbolRefExpr::VK_PPC_TLSGD: +- Type = ELF::R_PPC64_TLSGD; ++ if (is64Bit()) ++ Type = ELF::R_PPC64_TLSGD; ++ else ++ Type = ELF::R_PPC_TLSGD; + break; + case MCSymbolRefExpr::VK_PPC_TLSLD: +- Type = ELF::R_PPC64_TLSLD; ++ if (is64Bit()) ++ Type = ELF::R_PPC64_TLSLD; ++ else ++ Type = ELF::R_PPC_TLSLD; + break; + case MCSymbolRefExpr::VK_PPC_TLS: +- Type = ELF::R_PPC64_TLS; ++ if (is64Bit()) ++ Type = ELF::R_PPC64_TLS; ++ else ++ Type = ELF::R_PPC_TLS; + break; + } + break; +Index: contrib/llvm/lib/Target/PowerPC/PPC.h +=================================================================== +--- contrib/llvm/lib/Target/PowerPC/PPC.h (revision 270019) ++++ contrib/llvm/lib/Target/PowerPC/PPC.h (working copy) +@@ -53,10 +53,11 @@ + // PPC Specific MachineOperand flags. + MO_NO_FLAG, + +- /// MO_DARWIN_STUB - On a symbol operand "FOO", this indicates that the +- /// reference is actually to the "FOO$stub" symbol. This is used for calls +- /// and jumps to external functions on Tiger and earlier. +- MO_DARWIN_STUB = 1, ++ /// MO_PLT_OR_STUB - On a symbol operand "FOO", this indicates that the ++ /// reference is actually to the "FOO$stub" or "FOO@plt" symbol. This is ++ /// used for calls and jumps to external functions on Tiger and earlier, and ++ /// for PIC calls on Linux and ELF systems. ++ MO_PLT_OR_STUB = 1, + + /// MO_PIC_FLAG - If this bit is set, the symbol reference is relative to + /// the function's picbase, e.g. lo16(symbol-picbase). +Index: contrib/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp +=================================================================== +--- contrib/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp (revision 270019) ++++ contrib/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp (working copy) +@@ -19,6 +19,7 @@ + #define DEBUG_TYPE "asmprinter" + #include "PPC.h" + #include "InstPrinter/PPCInstPrinter.h" ++#include "PPCMachineFunctionInfo.h" + #include "MCTargetDesc/PPCPredicates.h" + #include "MCTargetDesc/PPCMCExpr.h" + #include "PPCSubtarget.h" +@@ -29,6 +30,7 @@ + #include "llvm/ADT/StringExtras.h" + #include "llvm/Assembly/Writer.h" + #include "llvm/CodeGen/AsmPrinter.h" ++#include "llvm/CodeGen/MachineConstantPool.h" + #include "llvm/CodeGen/MachineFunctionPass.h" + #include "llvm/CodeGen/MachineInstr.h" + #include "llvm/CodeGen/MachineInstrBuilder.h" +@@ -100,6 +102,7 @@ + } + + bool doFinalization(Module &M); ++ void EmitStartOfAsmFile(Module &M); + + virtual void EmitFunctionEntryLabel(); + +@@ -325,6 +328,7 @@ + /// + void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { + MCInst TmpInst; ++ bool isPPC64 = Subtarget.isPPC64(); + + // Lower multi-instruction pseudo operations. + switch (MI->getOpcode()) { +@@ -349,6 +353,66 @@ + OutStreamer.EmitLabel(PICBase); + return; + } ++ case PPC::GetGBRO: { ++ // Get the offset from the GOT Base Register to the GOT ++ LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); ++ MCSymbol *PICOffset = MF->getInfo()->getPICOffsetSymbol(); ++ TmpInst.setOpcode(PPC::LWZ); ++ const MCExpr *Exp = ++ MCSymbolRefExpr::Create(PICOffset, MCSymbolRefExpr::VK_None, OutContext); ++ const MCExpr *PB = ++ 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); ++ OutStreamer.EmitInstruction(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)); ++ OutStreamer.EmitInstruction(TmpInst); ++ return; ++ } ++ case PPC::LWZtoc: { ++ // Transform %X3 = LWZtoc , %X2 ++ LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); ++ ++ // Change the opcode to LWZ, and the global address operand to be a ++ // reference to the GOT entry we will synthesize later. ++ TmpInst.setOpcode(PPC::LWZ); ++ const MachineOperand &MO = MI->getOperand(1); ++ ++ // Map symbol -> label of TOC entry ++ assert(MO.isGlobal() || MO.isCPI() || MO.isJTI()); ++ MCSymbol *MOSymbol = NULL; ++ if (MO.isGlobal()) ++ MOSymbol = getSymbol(MO.getGlobal()); ++ else if (MO.isCPI()) ++ MOSymbol = GetCPISymbol(MO.getIndex()); ++ 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); ++ OutStreamer.EmitInstruction(TmpInst); ++ return; ++ } + case PPC::LDtocJTI: + case PPC::LDtocCPT: + case PPC::LDtoc: { +@@ -518,12 +582,13 @@ + .addExpr(SymGotTprel)); + return; + } +- case PPC::LDgotTprelL: { ++ case PPC::LDgotTprelL: ++ case PPC::LDgotTprelL32: { + // Transform %Xd = LDgotTprelL , %Xs + LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); + + // Change the opcode to LD. +- TmpInst.setOpcode(PPC::LD); ++ TmpInst.setOpcode(isPPC64 ? PPC::LD : PPC::LWZ); + const MachineOperand &MO = MI->getOperand(1); + const GlobalValue *GValue = MO.getGlobal(); + MCSymbol *MOSymbol = getSymbol(GValue); +@@ -534,6 +599,52 @@ + OutStreamer.EmitInstruction(TmpInst); + return; + } ++ ++ case PPC::PPC32PICGOT: { ++ MCSymbol *GOTSymbol = OutContext.GetOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_")); ++ MCSymbol *GOTRef = OutContext.CreateTempSymbol(); ++ MCSymbol *NextInstr = OutContext.CreateTempSymbol(); ++ ++ OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL) ++ // FIXME: We would like an efficient form for this, so we don't have to do ++ // a lot of extra uniquing. ++ .addExpr(MCSymbolRefExpr::Create(NextInstr, OutContext))); ++ const MCExpr *OffsExpr = ++ MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(GOTSymbol, OutContext), ++ MCSymbolRefExpr::Create(GOTRef, OutContext), ++ OutContext); ++ OutStreamer.EmitLabel(GOTRef); ++ OutStreamer.EmitValue(OffsExpr, 4); ++ OutStreamer.EmitLabel(NextInstr); ++ OutStreamer.EmitInstruction(MCInstBuilder(PPC::MFLR) ++ .addReg(MI->getOperand(0).getReg())); ++ OutStreamer.EmitInstruction(MCInstBuilder(PPC::LWZ) ++ .addReg(MI->getOperand(1).getReg()) ++ .addImm(0) ++ .addReg(MI->getOperand(0).getReg())); ++ OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADD4) ++ .addReg(MI->getOperand(0).getReg()) ++ .addReg(MI->getOperand(1).getReg()) ++ .addReg(MI->getOperand(0).getReg())); ++ return; ++ } ++ case PPC::PPC32GOT: { ++ MCSymbol *GOTSymbol = OutContext.GetOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_")); ++ const MCExpr *SymGotTlsL = ++ MCSymbolRefExpr::Create(GOTSymbol, MCSymbolRefExpr::VK_PPC_LO, ++ OutContext); ++ const MCExpr *SymGotTlsHA = ++ MCSymbolRefExpr::Create(GOTSymbol, MCSymbolRefExpr::VK_PPC_HA, ++ OutContext); ++ OutStreamer.EmitInstruction(MCInstBuilder(PPC::LI) ++ .addReg(MI->getOperand(0).getReg()) ++ .addExpr(SymGotTlsL)); ++ OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS) ++ .addReg(MI->getOperand(0).getReg()) ++ .addReg(MI->getOperand(0).getReg()) ++ .addExpr(SymGotTlsHA)); ++ return; ++ } + case PPC::ADDIStlsgdHA: { + // Transform: %Xd = ADDIStlsgdHA %X2, + // Into: %Xd = ADDIS8 %X2, sym@got@tlsgd@ha +@@ -550,31 +661,42 @@ + .addExpr(SymGotTlsGD)); + return; + } +- case PPC::ADDItlsgdL: { ++ case PPC::ADDItlsgdL: + // Transform: %Xd = ADDItlsgdL %Xs, + // Into: %Xd = ADDI8 %Xs, sym@got@tlsgd@l +- assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); ++ case PPC::ADDItlsgdL32: { ++ // Transform: %Rd = ADDItlsgdL32 %Rs, ++ // Into: %Rd = ADDI %Rs, sym@got@tlsgd + const MachineOperand &MO = MI->getOperand(2); + const GlobalValue *GValue = MO.getGlobal(); + MCSymbol *MOSymbol = getSymbol(GValue); + const MCExpr *SymGotTlsGD = +- MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO, ++ MCSymbolRefExpr::Create(MOSymbol, Subtarget.isPPC64() ? ++ MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO : ++ MCSymbolRefExpr::VK_PPC_GOT_TLSGD, + OutContext); +- OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDI8) +- .addReg(MI->getOperand(0).getReg()) +- .addReg(MI->getOperand(1).getReg()) +- .addExpr(SymGotTlsGD)); ++ OutStreamer.EmitInstruction(MCInstBuilder(Subtarget.isPPC64() ? PPC::ADDI8 : PPC::ADDI) ++ .addReg(MI->getOperand(0).getReg()) ++ .addReg(MI->getOperand(1).getReg()) ++ .addExpr(SymGotTlsGD)); + return; + } +- case PPC::GETtlsADDR: { ++ case PPC::GETtlsADDR: + // Transform: %X3 = GETtlsADDR %X3, + // Into: BL8_NOP_TLS __tls_get_addr(sym@tlsgd) +- assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); ++ case PPC::GETtlsADDR32: { ++ // Transform: %R3 = GETtlsADDR32 %R3, ++ // Into: BL_TLS __tls_get_addr(sym@tlsgd)@PLT + + StringRef Name = "__tls_get_addr"; + MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name); ++ MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None; ++ ++ if (!Subtarget.isPPC64() && !Subtarget.isDarwin() && ++ TM.getRelocationModel() == Reloc::PIC_) ++ Kind = MCSymbolRefExpr::VK_PLT; + const MCSymbolRefExpr *TlsRef = +- MCSymbolRefExpr::Create(TlsGetAddr, MCSymbolRefExpr::VK_None, OutContext); ++ MCSymbolRefExpr::Create(TlsGetAddr, Kind, OutContext); + const MachineOperand &MO = MI->getOperand(2); + const GlobalValue *GValue = MO.getGlobal(); + MCSymbol *MOSymbol = getSymbol(GValue); +@@ -581,7 +703,8 @@ + const MCExpr *SymVar = + MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSGD, + OutContext); +- OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_TLS) ++ OutStreamer.EmitInstruction(MCInstBuilder(Subtarget.isPPC64() ? ++ PPC::BL8_NOP_TLS : PPC::BL_TLS) + .addExpr(TlsRef) + .addExpr(SymVar)); + return; +@@ -602,31 +725,44 @@ + .addExpr(SymGotTlsLD)); + return; + } +- case PPC::ADDItlsldL: { ++ case PPC::ADDItlsldL: + // Transform: %Xd = ADDItlsldL %Xs, + // Into: %Xd = ADDI8 %Xs, sym@got@tlsld@l +- assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); ++ case PPC::ADDItlsldL32: { ++ // Transform: %Rd = ADDItlsldL32 %Rs, ++ // Into: %Rd = ADDI %Rs, sym@got@tlsld ++ + const MachineOperand &MO = MI->getOperand(2); + const GlobalValue *GValue = MO.getGlobal(); + MCSymbol *MOSymbol = getSymbol(GValue); + const MCExpr *SymGotTlsLD = +- MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO, ++ MCSymbolRefExpr::Create(MOSymbol, Subtarget.isPPC64() ? ++ MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO : ++ MCSymbolRefExpr::VK_PPC_GOT_TLSLD, + OutContext); +- OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDI8) ++ OutStreamer.EmitInstruction(MCInstBuilder(Subtarget.isPPC64() ? PPC::ADDI8 : PPC::ADDI) + .addReg(MI->getOperand(0).getReg()) + .addReg(MI->getOperand(1).getReg()) + .addExpr(SymGotTlsLD)); + return; + } +- case PPC::GETtlsldADDR: { ++ case PPC::GETtlsldADDR: + // Transform: %X3 = GETtlsldADDR %X3, + // Into: BL8_NOP_TLS __tls_get_addr(sym@tlsld) +- assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); ++ case PPC::GETtlsldADDR32: { ++ // Transform: %R3 = GETtlsldADDR32 %R3, ++ // Into: BL_TLS __tls_get_addr(sym@tlsld)@PLT + + StringRef Name = "__tls_get_addr"; + MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name); ++ MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None; ++ ++ if (!Subtarget.isPPC64() && !Subtarget.isDarwin() && ++ TM.getRelocationModel() == Reloc::PIC_) ++ Kind = MCSymbolRefExpr::VK_PLT; ++ + const MCSymbolRefExpr *TlsRef = +- MCSymbolRefExpr::Create(TlsGetAddr, MCSymbolRefExpr::VK_None, OutContext); ++ MCSymbolRefExpr::Create(TlsGetAddr, Kind, OutContext); + const MachineOperand &MO = MI->getOperand(2); + const GlobalValue *GValue = MO.getGlobal(); + MCSymbol *MOSymbol = getSymbol(GValue); +@@ -633,15 +769,19 @@ + const MCExpr *SymVar = + MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSLD, + OutContext); +- OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_TLS) ++ OutStreamer.EmitInstruction(MCInstBuilder(Subtarget.isPPC64() ? ++ PPC::BL8_NOP_TLS : PPC::BL_TLS) + .addExpr(TlsRef) + .addExpr(SymVar)); + return; + } +- case PPC::ADDISdtprelHA: { ++ case PPC::ADDISdtprelHA: + // Transform: %Xd = ADDISdtprelHA %X3, + // Into: %Xd = ADDIS8 %X3, sym@dtprel@ha +- assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); ++ case PPC::ADDISdtprelHA32: { ++ // Transform: %Rd = ADDISdtprelHA32 %R3, ++ // Into: %Rd = ADDIS %R3, sym@dtprel@ha ++ + const MachineOperand &MO = MI->getOperand(2); + const GlobalValue *GValue = MO.getGlobal(); + MCSymbol *MOSymbol = getSymbol(GValue); +@@ -648,16 +788,18 @@ + const MCExpr *SymDtprel = + MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_HA, + OutContext); +- OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8) ++ OutStreamer.EmitInstruction(MCInstBuilder(Subtarget.isPPC64() ? PPC::ADDIS8 : PPC::ADDIS) + .addReg(MI->getOperand(0).getReg()) + .addReg(PPC::X3) + .addExpr(SymDtprel)); + return; + } +- case PPC::ADDIdtprelL: { ++ case PPC::ADDIdtprelL: + // Transform: %Xd = ADDIdtprelL %Xs, + // Into: %Xd = ADDI8 %Xs, sym@dtprel@l +- assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); ++ case PPC::ADDIdtprelL32: { ++ // Transform: %Rd = ADDIdtprelL32 %Rs, ++ // Into: %Rd = ADDI %Rs, sym@dtprel@l + const MachineOperand &MO = MI->getOperand(2); + const GlobalValue *GValue = MO.getGlobal(); + MCSymbol *MOSymbol = getSymbol(GValue); +@@ -664,7 +806,7 @@ + const MCExpr *SymDtprel = + MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_LO, + OutContext); +- OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDI8) ++ OutStreamer.EmitInstruction(MCInstBuilder(Subtarget.isPPC64() ? PPC::ADDI8 : PPC::ADDI) + .addReg(MI->getOperand(0).getReg()) + .addReg(MI->getOperand(1).getReg()) + .addExpr(SymDtprel)); +@@ -726,9 +868,60 @@ + OutStreamer.EmitInstruction(TmpInst); + } + ++void PPCLinuxAsmPrinter::EmitStartOfAsmFile(Module &M) { ++ 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."); ++ OutStreamer.SwitchSection(OutContext.getELFSection(".got2", ++ ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC, ++ SectionKind::getReadOnly())); ++ ++ MCSymbol *TOCSym = OutContext.GetOrCreateSymbol(Twine(".L.TOC.")); ++ MCSymbol *CurrentPos = OutContext.CreateTempSymbol(); ++ ++ OutStreamer.EmitLabel(CurrentPos); ++ ++ // The GOT pointer points to the middle of the GOT, in order to reference the ++ // entire 64kB range. 0x8000 is the midpoint. ++ const MCExpr *tocExpr = ++ MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(CurrentPos, OutContext), ++ MCConstantExpr::Create(0x8000, OutContext), ++ OutContext); ++ ++ OutStreamer.EmitAssignment(TOCSym, tocExpr); ++ ++ OutStreamer.SwitchSection(getObjFileLowering().getTextSection()); ++} ++ + void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() { +- if (!Subtarget.isPPC64()) // linux/ppc32 - Normal entry label. ++ // linux/ppc32 - Normal entry label. ++ if (!Subtarget.isPPC64() && TM.getRelocationModel() != Reloc::PIC_) + return AsmPrinter::EmitFunctionEntryLabel(); ++ ++ if (!Subtarget.isPPC64()) { ++ const PPCFunctionInfo *PPCFI = MF->getInfo(); ++ if (PPCFI->usesPICBase()) { ++ MCSymbol *RelocSymbol = PPCFI->getPICOffsetSymbol(); ++ MCSymbol *PICBase = MF->getPICBaseSymbol(); ++ OutStreamer.EmitLabel(RelocSymbol); ++ ++ const MCExpr *OffsExpr = ++ MCBinaryExpr::CreateSub( ++ MCSymbolRefExpr::Create(OutContext.GetOrCreateSymbol(Twine(".L.TOC.")), ++ OutContext), ++ MCSymbolRefExpr::Create(PICBase, OutContext), ++ OutContext); ++ OutStreamer.EmitValue(OffsExpr, 4); ++ OutStreamer.EmitLabel(CurrentFnSym); ++ return; ++ } else ++ return AsmPrinter::EmitFunctionEntryLabel(); ++ } + + // Emit an official procedure descriptor. + MCSectionSubPair Current = OutStreamer.getCurrentSection(); +@@ -768,10 +961,17 @@ + PPCTargetStreamer &TS = + static_cast(OutStreamer.getTargetStreamer()); + +- if (isPPC64 && !TOC.empty()) { +- const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".toc", ++ if (!TOC.empty()) { ++ const MCSectionELF *Section; ++ ++ if (isPPC64) ++ Section = OutStreamer.getContext().getELFSection(".toc", + ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC, + SectionKind::getReadOnly()); ++ else ++ Section = OutStreamer.getContext().getELFSection(".got2", ++ ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC, ++ SectionKind::getReadOnly()); + OutStreamer.SwitchSection(Section); + + for (MapVector::iterator I = TOC.begin(), +@@ -778,7 +978,10 @@ + E = TOC.end(); I != E; ++I) { + OutStreamer.EmitLabel(I->second); + MCSymbol *S = OutContext.GetOrCreateSymbol(I->first->getName()); +- TS.emitTCEntry(*S); ++ if (isPPC64) ++ TS.emitTCEntry(*S); ++ else ++ OutStreamer.EmitSymbolValue(S, 4); + } + } + +Index: contrib/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp +=================================================================== +--- contrib/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp (revision 270019) ++++ contrib/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp (working copy) +@@ -299,7 +299,7 @@ + const PPCRegisterInfo *RegInfo = + static_cast(MF.getTarget().getRegisterInfo()); + bool HasBP = RegInfo->hasBasePointer(MF); +- unsigned BPReg = HasBP ? (unsigned) PPC::R30 : FPReg; ++ unsigned BPReg = HasBP ? (unsigned) RegInfo->getBaseRegister(MF): FPReg; + unsigned BP8Reg = HasBP ? (unsigned) PPC::X30 : FPReg; + + for (MachineFunction::iterator BI = MF.begin(), BE = MF.end(); +@@ -344,6 +344,7 @@ + DebugLoc dl; + bool needsFrameMoves = MMI.hasDebugInfo() || + MF.getFunction()->needsUnwindTableEntry(); ++ bool isPIC = MF.getTarget().getRelocationModel() == Reloc::PIC_; + + // Get processor type. + bool isPPC64 = Subtarget.isPPC64(); +@@ -387,7 +388,7 @@ + bool HasBP = RegInfo->hasBasePointer(MF); + + unsigned SPReg = isPPC64 ? PPC::X1 : PPC::R1; +- unsigned BPReg = isPPC64 ? PPC::X30 : PPC::R30; ++ unsigned BPReg = RegInfo->getBaseRegister(MF); + unsigned FPReg = isPPC64 ? PPC::X31 : PPC::R31; + unsigned LRReg = isPPC64 ? PPC::LR8 : PPC::LR; + unsigned ScratchReg = isPPC64 ? PPC::X0 : PPC::R0; +@@ -442,7 +443,9 @@ + BPOffset = FFI->getObjectOffset(BPIndex); + } else { + BPOffset = +- PPCFrameLowering::getBasePointerSaveOffset(isPPC64, isDarwinABI); ++ PPCFrameLowering::getBasePointerSaveOffset(isPPC64, ++ isDarwinABI, ++ isPIC); + } + } + +@@ -675,6 +678,7 @@ + // Get the ABI. + bool isDarwinABI = Subtarget.isDarwinABI(); + bool isSVR4ABI = Subtarget.isSVR4ABI(); ++ bool isPIC = MF.getTarget().getRelocationModel() == Reloc::PIC_; + + // Check if the link register (LR) has been saved. + PPCFunctionInfo *FI = MF.getInfo(); +@@ -685,7 +689,7 @@ + bool HasBP = RegInfo->hasBasePointer(MF); + + unsigned SPReg = isPPC64 ? PPC::X1 : PPC::R1; +- unsigned BPReg = isPPC64 ? PPC::X30 : PPC::R30; ++ unsigned BPReg = RegInfo->getBaseRegister(MF); + unsigned FPReg = isPPC64 ? PPC::X31 : PPC::R31; + unsigned ScratchReg = isPPC64 ? PPC::X0 : PPC::R0; + unsigned TempReg = isPPC64 ? PPC::X12 : PPC::R12; // another scratch reg +@@ -725,7 +729,9 @@ + BPOffset = FFI->getObjectOffset(BPIndex); + } else { + BPOffset = +- PPCFrameLowering::getBasePointerSaveOffset(isPPC64, isDarwinABI); ++ PPCFrameLowering::getBasePointerSaveOffset(isPPC64, ++ isDarwinABI, ++ isPIC); + } + } + +@@ -902,6 +908,7 @@ + int FPSI = FI->getFramePointerSaveIndex(); + bool isPPC64 = Subtarget.isPPC64(); + bool isDarwinABI = Subtarget.isDarwinABI(); ++ bool isPIC = MF.getTarget().getRelocationModel() == Reloc::PIC_; + MachineFrameInfo *MFI = MF.getFrameInfo(); + + // If the frame pointer save index hasn't been defined yet. +@@ -916,7 +923,7 @@ + + int BPSI = FI->getBasePointerSaveIndex(); + if (!BPSI && RegInfo->hasBasePointer(MF)) { +- int BPOffset = getBasePointerSaveOffset(isPPC64, isDarwinABI); ++ int BPOffset = getBasePointerSaveOffset(isPPC64, isDarwinABI, isPIC); + // Allocate the frame index for the base pointer save area. + BPSI = MFI->CreateFixedObject(isPPC64? 8 : 4, BPOffset, true); + // Save the result. +Index: contrib/llvm/lib/Target/PowerPC/PPCFrameLowering.h +=================================================================== +--- contrib/llvm/lib/Target/PowerPC/PPCFrameLowering.h (revision 270019) ++++ contrib/llvm/lib/Target/PowerPC/PPCFrameLowering.h (working copy) +@@ -96,12 +96,14 @@ + + /// getBasePointerSaveOffset - Return the previous frame offset to save the + /// base pointer. +- static unsigned getBasePointerSaveOffset(bool isPPC64, bool isDarwinABI) { ++ static unsigned getBasePointerSaveOffset(bool isPPC64, ++ bool isDarwinABI, ++ bool isPIC) { + if (isDarwinABI) + return isPPC64 ? -16U : -8U; + + // SVR4 ABI: First slot in the general register save area. +- return isPPC64 ? -16U : -8U; ++ return isPPC64 ? -16U : isPIC ? -12U : -8U; + } + + /// getLinkageSize - Return the size of the PowerPC ABI linkage area. +Index: contrib/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +=================================================================== +--- contrib/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp (revision 270019) ++++ contrib/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp (working copy) +@@ -15,6 +15,7 @@ + #define DEBUG_TYPE "ppc-codegen" + #include "PPC.h" + #include "MCTargetDesc/PPCPredicates.h" ++#include "PPCMachineFunctionInfo.h" + #include "PPCTargetMachine.h" + #include "llvm/CodeGen/MachineFunction.h" + #include "llvm/CodeGen/MachineInstrBuilder.h" +@@ -261,9 +262,21 @@ + DebugLoc dl; + + if (PPCLowering.getPointerTy() == MVT::i32) { +- GlobalBaseReg = RegInfo->createVirtualRegister(&PPC::GPRC_NOR0RegClass); ++ if (PPCSubTarget.isTargetELF()) ++ GlobalBaseReg = PPC::R30; ++ else ++ GlobalBaseReg = ++ RegInfo->createVirtualRegister(&PPC::GPRC_NOR0RegClass); + BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::MovePCtoLR)); + BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::MFLR), GlobalBaseReg); ++ if (PPCSubTarget.isTargetELF()) { ++ 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); ++ MF->getInfo()->setUsesPICBase(true); ++ } + } else { + GlobalBaseReg = RegInfo->createVirtualRegister(&PPC::G8RC_NOX0RegClass); + BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::MovePCtoLR8)); +@@ -1260,7 +1273,13 @@ + return CurDAG->SelectNodeTo(N, Reg, MVT::Other, Chain); + } + case PPCISD::TOC_ENTRY: { +- assert (PPCSubTarget.isPPC64() && "Only supported for 64-bit ABI"); ++ 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, +@@ -1306,6 +1325,12 @@ + return CurDAG->getMachineNode(PPC::ADDItocL, dl, MVT::i64, + SDValue(Tmp, 0), GA); + } ++ case PPCISD::PPC32_PICGOT: { ++ // Generate a PIC-safe GOT reference. ++ assert(!PPCSubTarget.isPPC64() && PPCSubTarget.isSVR4ABI() && ++ "PPCISD::PPC32_PICGOT is only supported for 32-bit SVR4"); ++ return CurDAG->SelectNodeTo(N, PPC::PPC32PICGOT, PPCLowering.getPointerTy(), MVT::i32); ++ } + case PPCISD::VADD_SPLAT: { + // This expands into one of three sequences, depending on whether + // the first operand is odd or even, positive or negative. +Index: contrib/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +=================================================================== +--- contrib/llvm/lib/Target/PowerPC/PPCISelLowering.cpp (revision 270019) ++++ contrib/llvm/lib/Target/PowerPC/PPCISelLowering.cpp (working copy) +@@ -670,6 +670,7 @@ + case PPCISD::ADDIS_TOC_HA: return "PPCISD::ADDIS_TOC_HA"; + case PPCISD::LD_TOC_L: return "PPCISD::LD_TOC_L"; + case PPCISD::ADDI_TOC_L: return "PPCISD::ADDI_TOC_L"; ++ case PPCISD::PPC32_GOT: return "PPCISD::PPC32_GOT"; + case PPCISD::ADDIS_GOT_TPREL_HA: return "PPCISD::ADDIS_GOT_TPREL_HA"; + case PPCISD::LD_GOT_TPREL_L: return "PPCISD::LD_GOT_TPREL_L"; + case PPCISD::ADD_TLS: return "PPCISD::ADD_TLS"; +@@ -1307,10 +1308,7 @@ + HiOpFlags = PPCII::MO_HA; + LoOpFlags = PPCII::MO_LO; + +- // Don't use the pic base if not in PIC relocation model. Or if we are on a +- // non-darwin platform. We don't support PIC on other platforms yet. +- bool isPIC = TM.getRelocationModel() == Reloc::PIC_ && +- TM.getSubtarget().isDarwin(); ++ bool isPIC = TM.getRelocationModel() == Reloc::PIC_; + if (isPIC) { + HiOpFlags |= PPCII::MO_PIC_FLAG; + LoOpFlags |= PPCII::MO_PIC_FLAG; +@@ -1366,6 +1364,15 @@ + + unsigned MOHiFlag, MOLoFlag; + bool isPIC = GetLabelAccessInfo(DAG.getTarget(), MOHiFlag, MOLoFlag); ++ ++ if (isPIC && PPCSubTarget.isSVR4ABI()) { ++ SDValue GA = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment(), ++ PPCII::MO_PIC_FLAG); ++ SDLoc DL(CP); ++ return DAG.getNode(PPCISD::TOC_ENTRY, SDLoc(CP), MVT::i32, GA, ++ DAG.getNode(PPCISD::GlobalBaseReg, DL, PtrVT)); ++ } ++ + SDValue CPIHi = + DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment(), 0, MOHiFlag); + SDValue CPILo = +@@ -1387,6 +1394,15 @@ + + unsigned MOHiFlag, MOLoFlag; + bool isPIC = GetLabelAccessInfo(DAG.getTarget(), MOHiFlag, MOLoFlag); ++ ++ if (isPIC && PPCSubTarget.isSVR4ABI()) { ++ SDValue GA = DAG.getTargetJumpTable(JT->getIndex(), PtrVT, ++ PPCII::MO_PIC_FLAG); ++ SDLoc DL(GA); ++ return DAG.getNode(PPCISD::TOC_ENTRY, SDLoc(JT), PtrVT, GA, ++ DAG.getNode(PPCISD::GlobalBaseReg, DL, PtrVT)); ++ } ++ + SDValue JTIHi = DAG.getTargetJumpTable(JT->getIndex(), PtrVT, MOHiFlag); + SDValue JTILo = DAG.getTargetJumpTable(JT->getIndex(), PtrVT, MOLoFlag); + return LowerLabelRef(JTIHi, JTILo, isPIC, DAG); +@@ -1400,6 +1416,7 @@ + + unsigned MOHiFlag, MOLoFlag; + bool isPIC = GetLabelAccessInfo(DAG.getTarget(), MOHiFlag, MOLoFlag); ++ + SDValue TgtBAHi = DAG.getTargetBlockAddress(BA, PtrVT, 0, MOHiFlag); + SDValue TgtBALo = DAG.getTargetBlockAddress(BA, PtrVT, 0, MOLoFlag); + return LowerLabelRef(TgtBAHi, TgtBALo, isPIC, DAG); +@@ -1431,64 +1448,79 @@ + return DAG.getNode(PPCISD::Lo, dl, PtrVT, TGALo, Hi); + } + +- if (!is64bit) +- llvm_unreachable("only local-exec is currently supported for ppc32"); +- + if (Model == TLSModel::InitialExec) { + SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, 0); + SDValue TGATLS = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, + PPCII::MO_TLS); +- SDValue GOTReg = DAG.getRegister(PPC::X2, MVT::i64); +- SDValue TPOffsetHi = DAG.getNode(PPCISD::ADDIS_GOT_TPREL_HA, dl, +- PtrVT, GOTReg, TGA); ++ SDValue GOTPtr; ++ if (is64bit) { ++ SDValue GOTReg = DAG.getRegister(PPC::X2, MVT::i64); ++ GOTPtr = DAG.getNode(PPCISD::ADDIS_GOT_TPREL_HA, dl, ++ PtrVT, GOTReg, TGA); ++ } else ++ GOTPtr = DAG.getNode(PPCISD::PPC32_GOT, dl, PtrVT); + SDValue TPOffset = DAG.getNode(PPCISD::LD_GOT_TPREL_L, dl, +- PtrVT, TGA, TPOffsetHi); ++ PtrVT, TGA, GOTPtr); + return DAG.getNode(PPCISD::ADD_TLS, dl, PtrVT, TPOffset, TGATLS); + } + + if (Model == TLSModel::GeneralDynamic) { + SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, 0); +- SDValue GOTReg = DAG.getRegister(PPC::X2, MVT::i64); +- SDValue GOTEntryHi = DAG.getNode(PPCISD::ADDIS_TLSGD_HA, dl, PtrVT, +- GOTReg, TGA); ++ SDValue GOTPtr; ++ if (is64bit) { ++ SDValue GOTReg = DAG.getRegister(PPC::X2, MVT::i64); ++ GOTPtr = DAG.getNode(PPCISD::ADDIS_TLSGD_HA, dl, PtrVT, ++ GOTReg, TGA); ++ } else { ++ GOTPtr = DAG.getNode(PPCISD::PPC32_PICGOT, dl, PtrVT); ++ } + SDValue GOTEntry = DAG.getNode(PPCISD::ADDI_TLSGD_L, dl, PtrVT, +- GOTEntryHi, TGA); ++ GOTPtr, TGA); + + // We need a chain node, and don't have one handy. The underlying + // call has no side effects, so using the function entry node + // suffices. + SDValue Chain = DAG.getEntryNode(); +- Chain = DAG.getCopyToReg(Chain, dl, PPC::X3, GOTEntry); +- SDValue ParmReg = DAG.getRegister(PPC::X3, MVT::i64); ++ Chain = DAG.getCopyToReg(Chain, dl, ++ is64bit ? PPC::X3 : PPC::R3, GOTEntry); ++ SDValue ParmReg = DAG.getRegister(is64bit ? PPC::X3 : PPC::R3, ++ is64bit ? MVT::i64 : MVT::i32); + SDValue TLSAddr = DAG.getNode(PPCISD::GET_TLS_ADDR, dl, + PtrVT, ParmReg, TGA); + // The return value from GET_TLS_ADDR really is in X3 already, but + // some hacks are needed here to tie everything together. The extra + // copies dissolve during subsequent transforms. +- Chain = DAG.getCopyToReg(Chain, dl, PPC::X3, TLSAddr); +- return DAG.getCopyFromReg(Chain, dl, PPC::X3, PtrVT); ++ Chain = DAG.getCopyToReg(Chain, dl, is64bit ? PPC::X3 : PPC::R3, TLSAddr); ++ return DAG.getCopyFromReg(Chain, dl, is64bit ? PPC::X3 : PPC::R3, PtrVT); + } + + if (Model == TLSModel::LocalDynamic) { + SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, 0); +- SDValue GOTReg = DAG.getRegister(PPC::X2, MVT::i64); +- SDValue GOTEntryHi = DAG.getNode(PPCISD::ADDIS_TLSLD_HA, dl, PtrVT, +- GOTReg, TGA); ++ SDValue GOTPtr; ++ if (is64bit) { ++ SDValue GOTReg = DAG.getRegister(PPC::X2, MVT::i64); ++ GOTPtr = DAG.getNode(PPCISD::ADDIS_TLSLD_HA, dl, PtrVT, ++ GOTReg, TGA); ++ } else { ++ GOTPtr = DAG.getNode(PPCISD::PPC32_PICGOT, dl, PtrVT); ++ } + SDValue GOTEntry = DAG.getNode(PPCISD::ADDI_TLSLD_L, dl, PtrVT, +- GOTEntryHi, TGA); ++ GOTPtr, TGA); + + // We need a chain node, and don't have one handy. The underlying + // call has no side effects, so using the function entry node + // suffices. + SDValue Chain = DAG.getEntryNode(); +- Chain = DAG.getCopyToReg(Chain, dl, PPC::X3, GOTEntry); +- SDValue ParmReg = DAG.getRegister(PPC::X3, MVT::i64); ++ Chain = DAG.getCopyToReg(Chain, dl, ++ is64bit ? PPC::X3 : PPC::R3, GOTEntry); ++ SDValue ParmReg = DAG.getRegister(is64bit ? PPC::X3 : PPC::R3, ++ is64bit ? MVT::i64 : MVT::i32); + SDValue TLSAddr = DAG.getNode(PPCISD::GET_TLSLD_ADDR, dl, + PtrVT, ParmReg, TGA); + // The return value from GET_TLSLD_ADDR really is in X3 already, but + // some hacks are needed here to tie everything together. The extra + // copies dissolve during subsequent transforms. +- Chain = DAG.getCopyToReg(Chain, dl, PPC::X3, TLSAddr); ++ Chain = DAG.getCopyToReg(Chain, dl, is64bit ? PPC::X3 : PPC::R3, TLSAddr); + SDValue DtvOffsetHi = DAG.getNode(PPCISD::ADDIS_DTPREL_HA, dl, PtrVT, + Chain, ParmReg, TGA); + return DAG.getNode(PPCISD::ADDI_DTPREL_L, dl, PtrVT, DtvOffsetHi, TGA); +@@ -1515,6 +1547,14 @@ + unsigned MOHiFlag, MOLoFlag; + bool isPIC = GetLabelAccessInfo(DAG.getTarget(), MOHiFlag, MOLoFlag, GV); + ++ if (isPIC && PPCSubTarget.isSVR4ABI()) { ++ SDValue GA = DAG.getTargetGlobalAddress(GV, DL, PtrVT, ++ GSDN->getOffset(), ++ PPCII::MO_PIC_FLAG); ++ return DAG.getNode(PPCISD::TOC_ENTRY, DL, MVT::i32, GA, ++ DAG.getNode(PPCISD::GlobalBaseReg, DL, MVT::i32)); ++ } ++ + SDValue GAHi = + DAG.getTargetGlobalAddress(GV, DL, PtrVT, GSDN->getOffset(), MOHiFlag); + SDValue GALo = +@@ -3214,15 +3254,18 @@ + // far-call stubs may be outside relocation limits for a BL instruction. + if (!DAG.getTarget().getSubtarget().isJITCodeModel()) { + unsigned OpFlags = 0; +- if (DAG.getTarget().getRelocationModel() != Reloc::Static && ++ if ((DAG.getTarget().getRelocationModel() != Reloc::Static && + (PPCSubTarget.getTargetTriple().isMacOSX() && + PPCSubTarget.getTargetTriple().isMacOSXVersionLT(10, 5)) && + (G->getGlobal()->isDeclaration() || +- G->getGlobal()->isWeakForLinker())) { ++ G->getGlobal()->isWeakForLinker())) || ++ (PPCSubTarget.isTargetELF() && !isPPC64 && ++ !G->getGlobal()->hasLocalLinkage() && ++ DAG.getTarget().getRelocationModel() == Reloc::PIC_)) { + // PC-relative references to external symbols should go through $stub, + // unless we're building with the leopard linker or later, which + // automatically synthesizes these stubs. +- OpFlags = PPCII::MO_DARWIN_STUB; ++ OpFlags = PPCII::MO_PLT_OR_STUB; + } + + // If the callee is a GlobalAddress/ExternalSymbol node (quite common, +@@ -3244,7 +3287,7 @@ + // PC-relative references to external symbols should go through $stub, + // unless we're building with the leopard linker or later, which + // automatically synthesizes these stubs. +- OpFlags = PPCII::MO_DARWIN_STUB; ++ OpFlags = PPCII::MO_PLT_OR_STUB; + } + + Callee = DAG.getTargetExternalSymbol(S->getSymbol(), Callee.getValueType(), +@@ -6255,7 +6298,10 @@ + // Since FP is only updated here but NOT referenced, it's treated as GPR. + unsigned FP = (PVT == MVT::i64) ? PPC::X31 : PPC::R31; + unsigned SP = (PVT == MVT::i64) ? PPC::X1 : PPC::R1; +- unsigned BP = (PVT == MVT::i64) ? PPC::X30 : PPC::R30; ++ unsigned BP = (PVT == MVT::i64) ? PPC::X30 : ++ (PPCSubTarget.isSVR4ABI() && ++ MF->getTarget().getRelocationModel() == Reloc::PIC_ ? ++ PPC::R29 : PPC::R30); + + MachineInstrBuilder MIB; + +Index: contrib/llvm/lib/Target/PowerPC/PPCISelLowering.h +=================================================================== +--- contrib/llvm/lib/Target/PowerPC/PPCISelLowering.h (revision 270019) ++++ contrib/llvm/lib/Target/PowerPC/PPCISelLowering.h (working copy) +@@ -177,6 +177,12 @@ + CR6SET, + CR6UNSET, + ++ PPC32_GOT, ++ ++ /// GPRC = address of _GLOBAL_OFFSET_TABLE_. Used by general dynamic and ++ /// local dynamic TLS on PPC32. ++ PPC32_PICGOT, ++ + /// G8RC = ADDIS_GOT_TPREL_HA %X2, Symbol - Used by the initial-exec + /// TLS model, produces an ADDIS8 instruction that adds the GOT + /// base to sym\@got\@tprel\@ha. +Index: contrib/llvm/lib/Target/PowerPC/PPCInstr64Bit.td +=================================================================== +--- contrib/llvm/lib/Target/PowerPC/PPCInstr64Bit.td (revision 270019) ++++ contrib/llvm/lib/Target/PowerPC/PPCInstr64Bit.td (working copy) +@@ -36,10 +36,6 @@ + def tocentry : Operand { *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***