diff options
author | Joerg Sonnenberger <joerg@bec.de> | 2015-10-01 22:08:20 +0000 |
---|---|---|
committer | Joerg Sonnenberger <joerg@bec.de> | 2015-10-01 22:08:20 +0000 |
commit | c8d50d6347ba14f27b923f193ff0ff2fa95cf7bb (patch) | |
tree | 5d272cfc8a818a35c3812be50bba80c2c122b5a2 /llvm/lib/Target/Sparc/AsmParser | |
parent | f686a445db7c381e6cbae810f82ae9b31fa11851 (diff) | |
download | bcm5719-llvm-c8d50d6347ba14f27b923f193ff0ff2fa95cf7bb.tar.gz bcm5719-llvm-c8d50d6347ba14f27b923f193ff0ff2fa95cf7bb.zip |
Fix relocation used for GOT references in non-PIC mode. Fix relocations
for "set" pseudo op in PIC mode.
Differential Revision: http://reviews.llvm.org/D13173
llvm-svn: 249086
Diffstat (limited to 'llvm/lib/Target/Sparc/AsmParser')
-rw-r--r-- | llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp | 61 |
1 files changed, 33 insertions, 28 deletions
diff --git a/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp b/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp index 6f13993fd01..d6bc3d0f888 100644 --- a/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp +++ b/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp @@ -69,6 +69,10 @@ class SparcAsmParser : public MCTargetAsmParser { OperandMatchResultTy parseBranchModifiers(OperandVector &Operands); + // Helper function for dealing with %lo / %hi in PIC mode. + const SparcMCExpr *adjustPICRelocation(SparcMCExpr::VariantKind VK, + const MCExpr *subExpr); + // returns true if Tok is matched to a register and returns register in RegNo. bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo, unsigned &RegKind); @@ -466,8 +470,7 @@ void SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc, // In either case, start with the 'sethi'. if (!IsEffectivelyImm13) { MCInst TmpInst; - const MCExpr *Expr = - SparcMCExpr::create(SparcMCExpr::VK_Sparc_HI, ValExpr, getContext()); + const MCExpr *Expr = adjustPICRelocation(SparcMCExpr::VK_Sparc_HI, ValExpr); TmpInst.setLoc(IDLoc); TmpInst.setOpcode(SP::SETHIi); TmpInst.addOperand(MCRegOp); @@ -492,8 +495,7 @@ void SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc, if (IsEffectivelyImm13) Expr = ValExpr; else - Expr = - SparcMCExpr::create(SparcMCExpr::VK_Sparc_LO, ValExpr, getContext()); + Expr = adjustPICRelocation(SparcMCExpr::VK_Sparc_LO, ValExpr); TmpInst.setLoc(IDLoc); TmpInst.setOpcode(SP::ORri); TmpInst.addOperand(MCRegOp); @@ -1054,6 +1056,32 @@ static bool hasGOTReference(const MCExpr *Expr) { return false; } +const SparcMCExpr * +SparcAsmParser::adjustPICRelocation(SparcMCExpr::VariantKind VK, + const MCExpr *subExpr) +{ + // When in PIC mode, "%lo(...)" and "%hi(...)" behave differently. + // If the expression refers contains _GLOBAL_OFFSETE_TABLE, it is + // actually a %pc10 or %pc22 relocation. Otherwise, they are interpreted + // as %got10 or %got22 relocation. + + if (getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_) { + switch(VK) { + default: break; + case SparcMCExpr::VK_Sparc_LO: + VK = (hasGOTReference(subExpr) ? SparcMCExpr::VK_Sparc_PC10 + : SparcMCExpr::VK_Sparc_GOT10); + break; + case SparcMCExpr::VK_Sparc_HI: + VK = (hasGOTReference(subExpr) ? SparcMCExpr::VK_Sparc_PC22 + : SparcMCExpr::VK_Sparc_GOT22); + break; + } + } + + return SparcMCExpr::create(VK, subExpr, getContext()); +} + bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal, SMLoc &EndLoc) { @@ -1077,30 +1105,7 @@ bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal, if (Parser.parseParenExpression(subExpr, EndLoc)) return false; - bool isPIC = getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_; - - // Ugly: if a sparc assembly expression says "%hi(...)" but the - // expression within contains _GLOBAL_OFFSET_TABLE_, it REALLY means - // %pc22. Same with %lo -> %pc10. Worse, if it doesn't contain that, - // the meaning depends on whether the assembler was invoked with - // -KPIC or not: if so, it really means %got22/%got10; if not, it - // actually means what it said! Sigh, historical mistakes... - - switch(VK) { - default: break; - case SparcMCExpr::VK_Sparc_LO: - VK = (hasGOTReference(subExpr) - ? SparcMCExpr::VK_Sparc_PC10 - : (isPIC ? SparcMCExpr::VK_Sparc_GOT10 : VK)); - break; - case SparcMCExpr::VK_Sparc_HI: - VK = (hasGOTReference(subExpr) - ? SparcMCExpr::VK_Sparc_PC22 - : (isPIC ? SparcMCExpr::VK_Sparc_GOT22 : VK)); - break; - } - - EVal = SparcMCExpr::create(VK, subExpr, getContext()); + EVal = adjustPICRelocation(VK, subExpr); return true; } |