VK_PPC_GOT_TLSGD_LO, // symbol@got@tlsgd@l
VK_PPC_GOT_TLSGD_HI, // symbol@got@tlsgd@h
VK_PPC_GOT_TLSGD_HA, // symbol@got@tlsgd@ha
+ VK_PPC_TLSGD, // symbol@tlsgd
VK_PPC_GOT_TLSLD, // symbol@got@tlsld
VK_PPC_GOT_TLSLD_LO, // symbol@got@tlsld@l
VK_PPC_GOT_TLSLD_HI, // symbol@got@tlsld@h
VK_PPC_GOT_TLSLD_HA, // symbol@got@tlsld@ha
+ VK_PPC_TLSLD, // symbol@tlsld
VK_Mips_GPREL,
VK_Mips_GOT_CALL,
case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO:
case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI:
case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA:
+ case MCSymbolRefExpr::VK_PPC_TLSGD:
case MCSymbolRefExpr::VK_PPC_GOT_TLSLD:
case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO:
case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI:
case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA:
+ case MCSymbolRefExpr::VK_PPC_TLSLD:
break;
}
MCSymbolData &SD = getAssembler().getOrCreateSymbolData(symRef.getSymbol());
case VK_PPC_GOT_TLSGD_LO: return "got@tlsgd@l";
case VK_PPC_GOT_TLSGD_HI: return "got@tlsgd@h";
case VK_PPC_GOT_TLSGD_HA: return "got@tlsgd@ha";
+ case VK_PPC_TLSGD: return "tlsgd";
case VK_PPC_GOT_TLSLD: return "got@tlsld";
case VK_PPC_GOT_TLSLD_LO: return "got@tlsld@l";
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_Mips_GPREL: return "GPREL";
case VK_Mips_GOT_CALL: return "GOT_CALL";
case VK_Mips_GOT16: return "GOT16";
const MCExpr *ExtractModifierFromExpr(const MCExpr *E,
PPCMCExpr::VariantKind &Variant);
+ const MCExpr *FixupVariantKind(const MCExpr *E);
bool ParseExpression(const MCExpr *&EVal);
bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
llvm_unreachable("Invalid expression kind!");
}
+/// Find all VK_TLSGD/VK_TLSLD symbol references in expression and replace
+/// them by VK_PPC_TLSGD/VK_PPC_TLSLD. This is necessary to avoid having
+/// _GLOBAL_OFFSET_TABLE_ created via ELFObjectWriter::RelocNeedsGOT.
+/// FIXME: This is a hack.
+const MCExpr *PPCAsmParser::
+FixupVariantKind(const MCExpr *E) {
+ MCContext &Context = getParser().getContext();
+
+ switch (E->getKind()) {
+ case MCExpr::Target:
+ case MCExpr::Constant:
+ return E;
+
+ case MCExpr::SymbolRef: {
+ const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
+ MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
+
+ switch (SRE->getKind()) {
+ case MCSymbolRefExpr::VK_TLSGD:
+ Variant = MCSymbolRefExpr::VK_PPC_TLSGD;
+ break;
+ case MCSymbolRefExpr::VK_TLSLD:
+ Variant = MCSymbolRefExpr::VK_PPC_TLSLD;
+ break;
+ default:
+ return E;
+ }
+ return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, Context);
+ }
+
+ case MCExpr::Unary: {
+ const MCUnaryExpr *UE = cast<MCUnaryExpr>(E);
+ const MCExpr *Sub = FixupVariantKind(UE->getSubExpr());
+ if (Sub == UE->getSubExpr())
+ return E;
+ return MCUnaryExpr::Create(UE->getOpcode(), Sub, Context);
+ }
+
+ case MCExpr::Binary: {
+ const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
+ const MCExpr *LHS = FixupVariantKind(BE->getLHS());
+ const MCExpr *RHS = FixupVariantKind(BE->getRHS());
+ if (LHS == BE->getLHS() && RHS == BE->getRHS())
+ return E;
+ return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, Context);
+ }
+ }
+
+ llvm_unreachable("Invalid expression kind!");
+}
+
/// Parse an expression. This differs from the default "parseExpression"
/// in that it handles complex \code @l/@ha \endcode modifiers.
bool PPCAsmParser::
if (getParser().parseExpression(EVal))
return true;
+ EVal = FixupVariantKind(EVal);
+
PPCMCExpr::VariantKind Variant;
const MCExpr *E = ExtractModifierFromExpr(EVal, Variant);
if (E)
case PPC::fixup_ppc_nofixup:
switch (Modifier) {
default: llvm_unreachable("Unsupported Modifier");
- case MCSymbolRefExpr::VK_TLSGD:
+ case MCSymbolRefExpr::VK_PPC_TLSGD:
Type = ELF::R_PPC64_TLSGD;
break;
- case MCSymbolRefExpr::VK_TLSLD:
+ case MCSymbolRefExpr::VK_PPC_TLSLD:
Type = ELF::R_PPC64_TLSLD;
break;
case MCSymbolRefExpr::VK_PPC_TLS:
const GlobalValue *GValue = MO.getGlobal();
MCSymbol *MOSymbol = Mang->getSymbol(GValue);
const MCExpr *SymVar =
- MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_TLSGD, OutContext);
+ MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSGD,
+ OutContext);
OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_TLS)
.addExpr(TlsRef)
.addExpr(SymVar));
const GlobalValue *GValue = MO.getGlobal();
MCSymbol *MOSymbol = Mang->getSymbol(GValue);
const MCExpr *SymVar =
- MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_TLSLD, OutContext);
+ MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSLD,
+ OutContext);
OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_TLS)
.addExpr(TlsRef)
.addExpr(SymVar));
; CHECK: addis [[REG:[0-9]+]], 2, a@got@tlsgd@ha
; CHECK-NEXT: addi 3, [[REG]], a@got@tlsgd@l
-; CHECK: bl __tls_get_addr(a@TLSGD)
+; CHECK: bl __tls_get_addr(a@tlsgd)
; CHECK-NEXT: nop
; CHECK: addis [[REG:[0-9]+]], 2, a@got@tlsld@ha
; CHECK-NEXT: addi 3, [[REG]], a@got@tlsld@l
-; CHECK: bl __tls_get_addr(a@TLSLD)
+; CHECK: bl __tls_get_addr(a@tlsld)
; CHECK-NEXT: nop
; CHECK: addis [[REG2:[0-9]+]], 3, a@dtprel@ha
; CHECK-NEXT: lwa {{[0-9]+}}, a@dtprel@l([[REG2]])
; CHECK: addis [[REG:[0-9]+]], 2, a@got@tlsld@ha
; CHECK-NEXT: addi 3, [[REG]], a@got@tlsld@l
-; CHECK: bl __tls_get_addr(a@TLSLD)
+; CHECK: bl __tls_get_addr(a@tlsld)
; CHECK-NEXT: nop
; CHECK: addis [[REG2:[0-9]+]], 3, a@dtprel@ha
; CHECK-NEXT: addi {{[0-9]+}}, [[REG2]], a@dtprel@l
# CHECK-REL: 0x{{[0-9A-F]*[26AE]}} R_PPC64_GOT_TLSLD16 target 0x0
addi 3, 3, target@got@tlsld
-# CHECK: bl __tls_get_addr(target@TLSGD) # encoding: [0b010010BB,B,B,0bBBBBBB01]
-# CHECK-NEXT: # fixup A - offset: 0, value: target@TLSGD, kind: fixup_ppc_nofixup
+# CHECK: bl __tls_get_addr(target@tlsgd) # encoding: [0b010010BB,B,B,0bBBBBBB01]
+# CHECK-NEXT: # fixup A - offset: 0, value: target@tlsgd, kind: fixup_ppc_nofixup
# CHECK-NEXT: # fixup B - offset: 0, value: __tls_get_addr, kind: fixup_ppc_br24
# CHECK-REL: 0x{{[0-9A-F]*[048C]}} R_PPC64_TLSGD target 0x0
# CHECK-REL-NEXT: 0x{{[0-9A-F]*[048C]}} R_PPC64_REL24 __tls_get_addr 0x0
bl __tls_get_addr(target@tlsgd)
-# CHECK: bl __tls_get_addr(target@TLSLD) # encoding: [0b010010BB,B,B,0bBBBBBB01]
-# CHECK-NEXT: # fixup A - offset: 0, value: target@TLSLD, kind: fixup_ppc_nofixup
+# CHECK: bl __tls_get_addr(target@tlsld) # encoding: [0b010010BB,B,B,0bBBBBBB01]
+# CHECK-NEXT: # fixup A - offset: 0, value: target@tlsld, kind: fixup_ppc_nofixup
# CHECK-NEXT: # fixup B - offset: 0, value: __tls_get_addr, kind: fixup_ppc_br24
# CHECK-REL: 0x{{[0-9A-F]*[048C]}} R_PPC64_TLSLD target 0x0
# CHECK-REL-NEXT: 0x{{[0-9A-F]*[048C]}} R_PPC64_REL24 __tls_get_addr 0x0