Index: llvm/include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def =================================================================== --- llvm/include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def +++ llvm/include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def @@ -97,6 +97,7 @@ #undef R_PPC64_DTPREL16_HIGH #undef R_PPC64_DTPREL16_HIGHA #undef R_PPC64_REL24_NOTOC +#undef R_PPC64_PCREL_OPT #undef R_PPC64_PCREL34 #undef R_PPC64_GOT_PCREL34 #undef R_PPC64_IRELATIVE @@ -194,6 +195,7 @@ ELF_RELOC(R_PPC64_DTPREL16_HIGH, 114) ELF_RELOC(R_PPC64_DTPREL16_HIGHA, 115) ELF_RELOC(R_PPC64_REL24_NOTOC, 116) +ELF_RELOC(R_PPC64_PCREL_OPT, 123) ELF_RELOC(R_PPC64_PCREL34, 132) ELF_RELOC(R_PPC64_GOT_PCREL34, 133) ELF_RELOC(R_PPC64_IRELATIVE, 248) Index: llvm/include/llvm/MC/MCExpr.h =================================================================== --- llvm/include/llvm/MC/MCExpr.h +++ llvm/include/llvm/MC/MCExpr.h @@ -302,6 +302,7 @@ VK_PPC_TLSLD, // symbol@tlsld VK_PPC_LOCAL, // symbol@local VK_PPC_NOTOC, // symbol@notoc + VK_PPC_LINKER_OPT, // Not actually emitted as symbol@ppclinkeropt VK_COFF_IMGREL32, // symbol@imgrel (image-relative) Index: llvm/lib/MC/MCExpr.cpp =================================================================== --- llvm/lib/MC/MCExpr.cpp +++ llvm/lib/MC/MCExpr.cpp @@ -322,6 +322,7 @@ case VK_PPC_TLSLD: return "tlsld"; case VK_PPC_LOCAL: return "local"; case VK_PPC_NOTOC: return "notoc"; + case VK_PPC_LINKER_OPT: return "ppclinkeropt"; case VK_COFF_IMGREL32: return "IMGREL"; case VK_Hexagon_LO16: return "LO16"; case VK_Hexagon_HI16: return "HI16"; @@ -437,6 +438,7 @@ .Case("got@tlsld@ha", VK_PPC_GOT_TLSLD_HA) .Case("got@pcrel", VK_PPC_GOT_PCREL) .Case("notoc", VK_PPC_NOTOC) + .Case("ppclinkeropt", VK_PPC_LINKER_OPT) .Case("gdgot", VK_Hexagon_GD_GOT) .Case("gdplt", VK_Hexagon_GD_PLT) .Case("iegot", VK_Hexagon_IE_GOT) Index: llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp =================================================================== --- llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp +++ llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp @@ -126,6 +126,7 @@ bool ParseDarwinDirectiveMachine(SMLoc L); bool ParseDirectiveAbiVersion(SMLoc L); bool ParseDirectiveLocalEntry(SMLoc L); + bool ParseDirectiveReloc(SMLoc L); bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, @@ -1660,6 +1661,8 @@ ParseDirectiveAbiVersion(DirectiveID.getLoc()); else if (IDVal == ".localentry") ParseDirectiveLocalEntry(DirectiveID.getLoc()); + else if (IDVal == ".reloc") + ParseDirectiveReloc(DirectiveID.getLoc()); else return true; return false; @@ -1804,7 +1807,55 @@ return false; } +/// ParseDirectiveReloc +/// Very similar to the one in AsmParser::parseDirectiveReloc except that we +/// want to be able to parse MCExpr::Binary too. +/// Format: .reloc expression , identifier [ , expression ] +bool PPCAsmParser::ParseDirectiveReloc(SMLoc DirectiveLoc) { + const MCExpr *Offset; + const MCExpr *Expr = nullptr; + int64_t OffsetValue; + SMLoc OffsetLoc = getLexer().getTok().getLoc(); + + if (getParser().parseExpression(Offset)) + return true; + + if ((Offset->evaluateAsAbsolute(OffsetValue, + getStreamer().getAssemblerPtr()) && + check(OffsetValue < 0, OffsetLoc, "expression is negative")) || + (check(Offset->getKind() != llvm::MCExpr::Constant && + Offset->getKind() != llvm::MCExpr::SymbolRef && + Offset->getKind() != llvm::MCExpr::Binary, + OffsetLoc, "expected non-negative number, label or a binary " + "expression")) || + (parseToken(AsmToken::Comma, "expected comma") || + check(getTok().isNot(AsmToken::Identifier), "expected relocation name"))) + return true; + + SMLoc NameLoc = getLexer().getTok().getLoc(); + StringRef Name = getLexer().getTok().getIdentifier(); + getParser().Lex(); + + if (getLexer().is(AsmToken::Comma)) { + getParser().Lex(); + SMLoc ExprLoc = getLexer().getLoc(); + if (getParser().parseExpression(Expr)) + return true; + MCValue Value; + if (!Expr->evaluateAsRelocatable(Value, nullptr, nullptr)) + return Error(ExprLoc, "expression must be relocatable"); + } + + if (parseToken(AsmToken::EndOfStatement, + "unexpected token in .reloc directive")) + return true; + + if (getStreamer().emitRelocDirective(*Offset, Name, Expr, DirectiveLoc, getSTI())) + return Error(NameLoc, "unknown relocation name"); + + return false; +} /// Force static initialization. extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCAsmParser() { Index: llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp =================================================================== --- llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp +++ llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp @@ -47,6 +47,8 @@ return Value & 0xfffc; case PPC::fixup_ppc_pcrel34: return Value & 0x3ffffffff; + case PPC::fixup_ppc_linker_opt: + return Value; } } @@ -68,6 +70,7 @@ case PPC::fixup_ppc_br24_notoc: return 4; case PPC::fixup_ppc_pcrel34: + case PPC::fixup_ppc_linker_opt: case FK_Data_8: return 8; case PPC::fixup_ppc_nofixup: @@ -100,6 +103,7 @@ { "fixup_ppc_half16", 0, 16, 0 }, { "fixup_ppc_half16ds", 0, 14, 0 }, { "fixup_ppc_pcrel34", 0, 34, MCFixupKindInfo::FKF_IsPCRel }, + { "fixup_ppc_linker_opt", 0, 64, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_ppc_nofixup", 0, 0, 0 } }; const static MCFixupKindInfo InfosLE[PPC::NumTargetFixupKinds] = { @@ -112,6 +116,7 @@ { "fixup_ppc_half16", 0, 16, 0 }, { "fixup_ppc_half16ds", 2, 14, 0 }, { "fixup_ppc_pcrel34", 0, 34, MCFixupKindInfo::FKF_IsPCRel }, + { "fixup_ppc_linker_opt", 0, 64, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_ppc_nofixup", 0, 0, 0 } }; @@ -158,6 +163,9 @@ switch ((unsigned)Kind) { default: return Kind >= FirstLiteralRelocationKind; + case FK_NONE: + case PPC::fixup_ppc_linker_opt: + return true; case PPC::fixup_ppc_br24: case PPC::fixup_ppc_br24abs: case PPC::fixup_ppc_br24_notoc: Index: llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp =================================================================== --- llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp +++ llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp @@ -103,6 +103,9 @@ break; } break; + case PPC::fixup_ppc_linker_opt: + Type = ELF::R_PPC64_PCREL_OPT; + break; case PPC::fixup_ppc_brcond14: case PPC::fixup_ppc_brcond14abs: Type = ELF::R_PPC_REL14; Index: llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFStreamer.h =================================================================== --- llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFStreamer.h +++ llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFStreamer.h @@ -41,6 +41,11 @@ // EmitLabel updates LastLabel and LastLabelLoc when a new label is emitted. void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override; + + // Emit a .reloc label. + bool emitRelocDirective(const MCExpr &Offset, StringRef Name, + const MCExpr *Expr, SMLoc Loc, + const MCSubtargetInfo &STI) override; }; MCELFStreamer *createPPCELFStreamer(MCContext &Context, Index: llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFStreamer.cpp =================================================================== --- llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFStreamer.cpp +++ llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFStreamer.cpp @@ -22,6 +22,7 @@ #include "PPCELFStreamer.h" #include "PPCInstrInfo.h" #include "PPCMCCodeEmitter.h" +#include "PPCFixupKinds.h" #include "llvm/BinaryFormat/ELF.h" #include "llvm/MC/MCAsmBackend.h" #include "llvm/MC/MCAssembler.h" @@ -99,6 +100,102 @@ MCELFStreamer::emitLabel(Symbol); } + +static bool getOffsetFromBinaryExpr(const MCBinaryExpr& BinExpr, + uint64_t &Offset, + MCDataFragment** DF) { + const MCExpr *LHS = BinExpr.getLHS(); + const MCExpr *RHS = BinExpr.getRHS(); + if (LHS->getKind() != MCExpr::SymbolRef || + RHS->getKind() != MCExpr::Constant) + return false; + + // If we have reached this far the LHS is a symbol and the RHS is a + // constant. + const MCSymbolRefExpr *Symbol = static_cast(LHS); + const MCConstantExpr *ConstVal = static_cast(RHS); + + // Get the Data Fragment. + // If there is no data fragment for this symbol just return false. + MCFragment *Fragment = Symbol->getSymbol().getFragment(); + if (!Fragment || Fragment->getKind() != MCFragment::FT_Data) + return false; + + Offset = Symbol->getSymbol().getOffset(); + switch(BinExpr.getOpcode()) { + default: + // Other opcodes are not supported. + return false; + case MCBinaryExpr::Add: + Offset += ConstVal->getValue(); + break; + case MCBinaryExpr::Sub: + Offset -= ConstVal->getValue(); + break; + } + + *DF = static_cast(Fragment); + return true; +} + +bool PPCELFStreamer::emitRelocDirective(const MCExpr &Offset, StringRef Name, + const MCExpr *Expr, SMLoc Loc, + const MCSubtargetInfo &STI) { + // If there is no MCExpr let the parent class handle it. + if (!Expr) + return MCELFStreamer::emitRelocDirective(Offset, Name, Expr, Loc, STI); + + Optional MaybeKind = getAssembler().getBackend().getFixupKind(Name); + if (!MaybeKind.hasValue()) + return true; + + MCFixupKind Kind = *MaybeKind; + + switch(Offset.getKind()) { + case MCExpr::Binary: { + const MCBinaryExpr &BinExpr = cast(Offset); + uint64_t ComputedOffset; + MCDataFragment *DF = nullptr; + if (!getOffsetFromBinaryExpr(BinExpr, ComputedOffset, &DF)) + break; + + assert(DF && "Expected a valid data fragment."); + + DF->getFixups().push_back(MCFixup::create(ComputedOffset, + Expr, Kind, Loc)); + return false; + } + case MCExpr::SymbolRef: { + const MCSymbolRefExpr &SRE = cast(Offset); + const MCSymbol &Symbol = SRE.getSymbol(); + if (!Symbol.isDefined()) + break; + + if (Symbol.isVariable()) { + const MCExpr *SymbolExpr = Symbol.getVariableValue(); + if (SymbolExpr->getKind() != MCExpr::Binary) + break; + + const MCBinaryExpr &BinExpr = cast(*SymbolExpr); + uint64_t ComputedOffset; + MCDataFragment *DF = nullptr; + if (!getOffsetFromBinaryExpr(BinExpr, ComputedOffset, &DF)) + break; + assert(DF && "Expected a valid data fragment."); + DF->getFixups().push_back(MCFixup::create(ComputedOffset, + Expr, Kind, Loc)); + return false; + } + break; + } + default: + // Fall through to the parent class. + break; + } + // If the directive cannot be handled here pass it on to the parent class. + return MCELFStreamer::emitRelocDirective(Offset, Name, Expr, Loc, STI); +} + MCELFStreamer *llvm::createPPCELFStreamer( MCContext &Context, std::unique_ptr MAB, std::unique_ptr OW, Index: llvm/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h =================================================================== --- llvm/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h +++ llvm/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h @@ -43,6 +43,9 @@ // A 34-bit fixup corresponding to PC-relative paddi. fixup_ppc_pcrel34, + // A linker opt fixup + fixup_ppc_linker_opt, + /// Not a true fixup, but ties a symbol to a call to __tls_get_addr for the /// TLS general and local dynamic models, or inserts the thread-pointer /// register number. Index: llvm/test/MC/PowerPC/future-reloc-with-expr.s =================================================================== --- /dev/null +++ llvm/test/MC/PowerPC/future-reloc-with-expr.s @@ -0,0 +1,336 @@ +# RUN: llvm-mc -triple=powerpc64le-unknown-unknown -filetype=obj %s | \ +# RUN: llvm-objdump -dr --mcpu=future - | FileCheck %s + + +## +# This section of tests contains the MCBinaryExpr as the first paremter of the +# .reloc relocation. +## + .text + .abiversion 2 + .globl Minimal + .p2align 4 + .type Minimal,@function +Minimal: +.LMinimal$local: +# %bb.0: # %entry + pld 3, vec@got@pcrel(0), 1 +.Lpcrel1: + .reloc .Lpcrel1-8,R_PPC64_PCREL_OPT,.-(.Lpcrel1-8) + lwa 3, 4(3) + blr + .long 0 + .quad 0 +# CHECK-LABEL: Minimal +# CHECK: pld 3, 0(0), 1 +# CHECK-NEXT: R_PPC64_GOT_PCREL34 vec +# CHECK-NEXT: R_PPC64_PCREL_OPT *ABS*+0x8 +# CHECK-NEXT: lwa 3, 4(3) +# CHECK-NEXT: blr + + .globl SingleInsnBetween + .p2align 4 + .type SingleInsnBetween,@function +SingleInsnBetween: +.LSingleInsnBetween$local: +# %bb.0: # %entry + pld 3, vec@got@pcrel(0), 1 +.Lpcrel2: + addi 3, 3, 42 + .reloc .Lpcrel2-8,R_PPC64_PCREL_OPT,.-(.Lpcrel2-8) + lwa 3, 4(3) + blr + .long 0 + .quad 0 +# CHECK_LABEL: SingleInsnBetween +# CHECK: pld 3, 0(0), 1 +# CHECK-NEXT: R_PPC64_GOT_PCREL34 vec +# CHECK-NEXT: R_PPC64_PCREL_OPT *ABS*+0xc +# CHECK-NEXT: addi 3, 3, 42 +# CHECK-NEXT: lwa 3, 4(3) +# CHECK-NEXT: blr + + + .globl MultiInsnBetween # -- Begin function + .p2align 4 + .type MultiInsnBetween,@function +MultiInsnBetween: +.LMultiInsnBetween$local: +# %bb.0: # %entry + pld 3, vec@got@pcrel(0), 1 +.Lpcrel3: + addi 3, 3, 42 + addi 3, 3, 42 + addi 3, 3, 42 + addi 3, 3, 42 + addi 3, 3, 42 + .reloc .Lpcrel3-8,R_PPC64_PCREL_OPT,.-(.Lpcrel3-8) + lwa 3, 4(3) + blr + .long 0 + .quad 0 +# CHECK_LABEL: MultiInsnBetween +# CHECK: pld 3, 0(0), 1 +# CHECK-NEXT: R_PPC64_GOT_PCREL34 vec +# CHECK-NEXT: R_PPC64_PCREL_OPT *ABS*+0x1c +# CHECK-NEXT: addi 3, 3, 42 +# CHECK-NEXT: addi 3, 3, 42 +# CHECK-NEXT: addi 3, 3, 42 +# CHECK-NEXT: addi 3, 3, 42 +# CHECK-NEXT: addi 3, 3, 42 +# CHECK-NEXT: lwa 3, 4(3) +# CHECK-NEXT: blr + + .globl PrefixInsnBetween # -- Begin function + .p2align 4 + .type PrefixInsnBetween,@function +PrefixInsnBetween: +.LPrefixInsnBetween$local: +# %bb.0: # %entry + pld 3, vec@got@pcrel(0), 1 +.Lpcrel4: + addi 3, 3, 42 + paddi 3, 3, 42, 0 + addi 3, 3, 42 + paddi 3, 3, 42, 0 + addi 3, 3, 42 + .reloc .Lpcrel4-8,R_PPC64_PCREL_OPT,.-(.Lpcrel4-8) + lwa 3, 4(3) + blr + .long 0 + .quad 0 +# CHECK_LABEL: PrefixInsnBetween +# CHECK: pld 3, 0(0), 1 +# CHECK-NEXT: R_PPC64_GOT_PCREL34 vec +# CHECK-NEXT: R_PPC64_PCREL_OPT *ABS*+0x28 +# CHECK-NEXT: addi 3, 3, 42 +# CHECK-NEXT: nop +# CHECK-NEXT: paddi 3, 3, 42, 0 +# CHECK-NEXT: addi 3, 3, 42 +# CHECK-NEXT: paddi 3, 3, 42, 0 +# CHECK-NEXT: addi 3, 3, 42 +# CHECK-NEXT: lwa 3, 4(3) +# CHECK-NEXT: blr + + + .globl SpaceBetween # -- Begin function + .p2align 4 + .type SpaceBetween,@function +SpaceBetween: +.LSpaceBetween$local: +# %bb.0: # %entry + pld 3, vec@got@pcrel(0), 1 +.Lpcrel5: + addi 3, 3, 42 + paddi 3, 3, 42, 0 + addi 3, 3, 42 + .space 40, 0 + paddi 3, 3, 42, 0 + addi 3, 3, 42 + .reloc .Lpcrel5-8,R_PPC64_PCREL_OPT,.-(.Lpcrel5-8) + lwa 3, 4(3) + blr + .long 0 + .quad 0 +# CHECK_LABEL: SpaceBetween +# CHECK: pld 3, 0(0), 1 +# CHECK-NEXT: R_PPC64_GOT_PCREL34 vec +# CHECK-NEXT: R_PPC64_PCREL_OPT *ABS*+0x50 +# CHECK-NEXT: addi 3, 3, 42 +# CHECK-NEXT: nop +# CHECK-NEXT: paddi 3, 3, 42, 0 +# CHECK-NEXT: addi 3, 3, 42 +# CHECK: paddi 3, 3, 42, 0 +# CHECK-NEXT: addi 3, 3, 42 +# CHECK-NEXT: lwa 3, 4(3) +# CHECK-NEXT: blr + + + .globl Plus + .p2align 4 + .type Plus,@function +Plus: +.LPlus$local: +# %bb.0: # %entry +.Lpcrel6: + addi 3, 3, 42 + addi 3, 3, 42 + pld 3, vec@got@pcrel(0), 1 + .reloc .Lpcrel6+8,R_PPC64_PCREL_OPT,.-(.Lpcrel6+8) + lwa 3, 4(3) + blr + .long 0 + .quad 0 +# CHECK-LABEL: Plus +# CHECK: pld 3, 0(0), 1 +# CHECK-NEXT: R_PPC64_PCREL_OPT *ABS*+0x8 +# CHECK-NEXT: R_PPC64_GOT_PCREL34 vec +# CHECK-NEXT: lwa 3, 4(3) +# CHECK-NEXT: blr + +## +# This section of tests contains the variable MCSymbol as part of the +# MCSymbolRefExpr for the first parameter of the .reloc relocation. +## + .globl VarLabelMinimal # -- Begin function + .p2align 4 + .type VarLabelMinimal,@function +VarLabelMinimal: +.LVarLabelMinimal$local: +# %bb.0: # %entry + pld 3, vec@got@pcrel(0), 1 +.Lpcrel101=.-8 + .reloc .Lpcrel101,R_PPC64_PCREL_OPT,.-.Lpcrel101 + lwa 3, 4(3) + blr + .long 0 + .quad 0 +# CHECK-LABEL: VarLabelMinimal +# CHECK: pld 3, 0(0), 1 +# CHECK-NEXT: R_PPC64_GOT_PCREL34 vec +# CHECK-NEXT: R_PPC64_PCREL_OPT *ABS*+0x8 +# CHECK-NEXT: lwa 3, 4(3) +# CHECK-NEXT: blr + + + .globl VarLabelSingleInsnBetween + .p2align 4 + .type VarLabelSingleInsnBetween,@function +VarLabelSingleInsnBetween: +.LVarLabelSingleInsnBetween$local: +# %bb.0: # %entry + pld 3, vec@got@pcrel(0), 1 +.Lpcrel102: + addi 3, 3, 42 + .reloc .Lpcrel102-8,R_PPC64_PCREL_OPT,.-(.Lpcrel102-8) + lwa 3, 4(3) + blr + .long 0 + .quad 0 +# CHECK_LABEL: VarLabelSingleInsnBetween +# CHECK: pld 3, 0(0), 1 +# CHECK-NEXT: R_PPC64_GOT_PCREL34 vec +# CHECK-NEXT: R_PPC64_PCREL_OPT *ABS*+0xc +# CHECK-NEXT: addi 3, 3, 42 +# CHECK-NEXT: lwa 3, 4(3) +# CHECK-NEXT: blr + + .globl VarLabelMultiInsnBetween # -- Begin function + .p2align 4 + .type VarLabelMultiInsnBetween,@function +VarLabelMultiInsnBetween: +.LVarLabelMultiInsnBetween$local: +# %bb.0: # %entry + pld 3, vec@got@pcrel(0), 1 +.Lpcrel103: + addi 3, 3, 42 + addi 3, 3, 42 + addi 3, 3, 42 + addi 3, 3, 42 + addi 3, 3, 42 + .reloc .Lpcrel103-8,R_PPC64_PCREL_OPT,.-(.Lpcrel103-8) + lwa 3, 4(3) + blr + .long 0 + .quad 0 +# CHECK_LABEL: VarLabelMultiInsnBetween +# CHECK: pld 3, 0(0), 1 +# CHECK-NEXT: R_PPC64_GOT_PCREL34 vec +# CHECK-NEXT: R_PPC64_PCREL_OPT *ABS*+0x1c +# CHECK-NEXT: addi 3, 3, 42 +# CHECK-NEXT: addi 3, 3, 42 +# CHECK-NEXT: addi 3, 3, 42 +# CHECK-NEXT: addi 3, 3, 42 +# CHECK-NEXT: addi 3, 3, 42 +# CHECK-NEXT: lwa 3, 4(3) +# CHECK-NEXT: blr + + + .globl VarLabelPrefixInsnBetween # -- Begin function + .p2align 4 + .type VarLabelPrefixInsnBetween,@function +VarLabelPrefixInsnBetween: +.LVarLabelPrefixInsnBetween$local: +# %bb.0: # %entry + pld 3, vec@got@pcrel(0), 1 +.Lpcrel104: + addi 3, 3, 42 + paddi 3, 3, 42, 0 + addi 3, 3, 42 + paddi 3, 3, 42, 0 + addi 3, 3, 42 + .reloc .Lpcrel104-8,R_PPC64_PCREL_OPT,.-(.Lpcrel104-8) + lwa 3, 4(3) + blr + .long 0 + .quad 0 +# CHECK_LABEL: VarLabelPrefixInsnBetween +# CHECK: pld 3, 0(0), 1 +# CHECK-NEXT: R_PPC64_GOT_PCREL34 vec +# CHECK-NEXT: R_PPC64_PCREL_OPT *ABS*+0x24 +# CHECK-NEXT: addi 3, 3, 42 +# CHECK-NEXT: paddi 3, 3, 42, 0 +# CHECK-NEXT: addi 3, 3, 42 +# CHECK-NEXT: paddi 3, 3, 42, 0 +# CHECK-NEXT: addi 3, 3, 42 +# CHECK-NEXT: lwa 3, 4(3) +# CHECK-NEXT: blr + + + .globl VarLabelSpaceBetween # -- Begin function + .p2align 4 + .type VarLabelSpaceBetween,@function +VarLabelSpaceBetween: +.LVarLabelSpaceBetween$local: +# %bb.0: # %entry + pld 3, vec@got@pcrel(0), 1 +.Lpcrel105: + addi 3, 3, 42 + paddi 3, 3, 42, 0 + addi 3, 3, 42 + .space 40, 0 + paddi 3, 3, 42, 0 + addi 3, 3, 42 + .reloc .Lpcrel105-8,R_PPC64_PCREL_OPT,.-(.Lpcrel105-8) + lwa 3, 4(3) + blr + .long 0 + .quad 0 +# CHECK_LABEL: VarLabelSpaceBetween +# CHECK: pld 3, 0(0), 1 +# CHECK-NEXT: R_PPC64_GOT_PCREL34 vec +# CHECK-NEXT: R_PPC64_PCREL_OPT *ABS*+0x4c +# CHECK-NEXT: addi 3, 3, 42 +# CHECK-NEXT: paddi 3, 3, 42, 0 +# CHECK-NEXT: addi 3, 3, 42 +# CHECK: paddi 3, 3, 42, 0 +# CHECK-NEXT: addi 3, 3, 42 +# CHECK-NEXT: lwa 3, 4(3) +# CHECK-NEXT: blr + + + .globl VarLabelPlus + .p2align 4 + .type VarLabelPlus,@function +VarLabelPlus: +.LVarLabelPlus$local: +# %bb.0: # %entry +.Lpcrel106: + addi 3, 3, 42 + addi 3, 3, 42 + pld 3, vec@got@pcrel(0), 1 + .reloc .Lpcrel106+8,R_PPC64_PCREL_OPT,.-(.Lpcrel106+8) + lwa 3, 4(3) + blr + .long 0 + .quad 0 +# CHECK-LABEL: VarLabelPlus +# CHECK: pld 3, 0(0), 1 +# CHECK-NEXT: R_PPC64_PCREL_OPT *ABS*+0x8 +# CHECK-NEXT: R_PPC64_GOT_PCREL34 vec +# CHECK-NEXT: lwa 3, 4(3) +# CHECK-NEXT: blr + + + +