mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-05 13:26:55 +00:00
[PowerPC] Revert r185476 and fix up TLS variant kinds
In the commit message to r185476 I wrote: >The PowerPC-specific modifiers VK_PPC_TLSGD and VK_PPC_TLSLD >correspond exactly to the generic modifiers VK_TLSGD and VK_TLSLD. >This causes some confusion with the asm parser, since VK_PPC_TLSGD >is output as @tlsgd, which is then read back in as VK_TLSGD. > >To avoid this confusion, this patch removes the PowerPC-specific >modifiers and uses the generic modifiers throughout. (The only >drawback is that the generic modifiers are printed in upper case >while the usual convention on PowerPC is to use lower-case modifiers. >But this is just a cosmetic issue.) This was unfortunately incorrect, there is is fact another, serious drawback to using the default VK_TLSLD/VK_TLSGD variant kinds: using these causes ELFObjectWriter::RelocNeedsGOT to return true, which in turn causes the ELFObjectWriter to emit an undefined reference to _GLOBAL_OFFSET_TABLE_. This is a problem on powerpc64, because it uses the TOC instead of the GOT, and the linker does not provide _GLOBAL_OFFSET_TABLE_, so the symbol remains undefined. This means shared libraries using TLS built with the integrated assembler are currently broken. While the whole RelocNeedsGOT / _GLOBAL_OFFSET_TABLE_ situation probably ought to be properly fixed at some point, for now I'm simply reverting the r185476 commit. Now this in turn exposes the breakage of handling @tlsgd/@tlsld in the asm parser that this check-in was originally intended to fix. To avoid this regression, I'm also adding a different fix for this problem: while common code now parses @tlsgd as VK_TLSGD, a special hack in the asm parser translates this code to the platform-specific VK_PPC_TLSGD that the back-end now expects. While this is not really pretty, it's self-contained and shouldn't hurt anything else for now. One the underlying problem is fixed, this hack can be reverted again. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@185945 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -190,6 +190,7 @@ class PPCAsmParser : public MCTargetAsmParser {
|
||||
|
||||
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);
|
||||
@@ -1006,6 +1007,57 @@ ExtractModifierFromExpr(const MCExpr *E,
|
||||
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::
|
||||
@@ -1013,6 +1065,8 @@ ParseExpression(const MCExpr *&EVal) {
|
||||
if (getParser().parseExpression(EVal))
|
||||
return true;
|
||||
|
||||
EVal = FixupVariantKind(EVal);
|
||||
|
||||
PPCMCExpr::VariantKind Variant;
|
||||
const MCExpr *E = ExtractModifierFromExpr(EVal, Variant);
|
||||
if (E)
|
||||
|
Reference in New Issue
Block a user