[llvm] r202571 - [Sparc] Teach SparcAsmParser to emit correct relocations for PIC code.
Venkatraman Govindaraju
venkatra at cs.wisc.edu
Fri Feb 28 21:07:21 PST 2014
Author: venkatra
Date: Fri Feb 28 23:07:21 2014
New Revision: 202571
URL: http://llvm.org/viewvc/llvm-project?rev=202571&view=rev
Log:
[Sparc] Teach SparcAsmParser to emit correct relocations for PIC code.
Added:
llvm/trunk/test/MC/Sparc/sparc-pic.s
Modified:
llvm/trunk/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
llvm/trunk/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
Modified: llvm/trunk/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp?rev=202571&r1=202570&r2=202571&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp Fri Feb 28 23:07:21 2014
@@ -12,9 +12,11 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCTargetAsmParser.h"
#include "llvm/Support/TargetRegistry.h"
@@ -66,7 +68,7 @@ class SparcAsmParser : public MCTargetAs
StringRef Name);
OperandMatchResultTy
- parseSparcAsmOperand(SparcOperand *&Operand);
+ parseSparcAsmOperand(SparcOperand *&Operand, bool isCall = false);
// returns true if Tok is matched to a register and returns register in RegNo.
bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo,
@@ -623,7 +625,7 @@ parseOperand(SmallVectorImpl<MCParsedAsm
}
SparcOperand *Op = 0;
- ResTy = parseSparcAsmOperand(Op);
+ ResTy = parseSparcAsmOperand(Op, (Mnemonic == "call"));
if (ResTy != MatchOperand_Success || !Op)
return MatchOperand_ParseFail;
@@ -634,7 +636,7 @@ parseOperand(SmallVectorImpl<MCParsedAsm
}
SparcAsmParser::OperandMatchResultTy
-SparcAsmParser::parseSparcAsmOperand(SparcOperand *&Op)
+SparcAsmParser::parseSparcAsmOperand(SparcOperand *&Op, bool isCall)
{
SMLoc S = Parser.getTok().getLoc();
@@ -695,6 +697,10 @@ SparcAsmParser::parseSparcAsmOperand(Spa
const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
getContext());
+ if (isCall &&
+ getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_)
+ Res = SparcMCExpr::Create(SparcMCExpr::VK_Sparc_WPLT30, Res,
+ getContext());
Op = SparcOperand::CreateImm(Res, S, E);
}
break;
@@ -813,6 +819,31 @@ bool SparcAsmParser::matchRegisterName(c
return false;
}
+static bool hasGOTReference(const MCExpr *Expr) {
+ switch (Expr->getKind()) {
+ case MCExpr::Target:
+ if (const SparcMCExpr *SE = dyn_cast<SparcMCExpr>(Expr))
+ return hasGOTReference(SE->getSubExpr());
+ break;
+
+ case MCExpr::Constant:
+ break;
+
+ case MCExpr::Binary: {
+ const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
+ return hasGOTReference(BE->getLHS()) || hasGOTReference(BE->getRHS());
+ }
+
+ case MCExpr::SymbolRef: {
+ const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);
+ return (SymRef.getSymbol().getName() == "_GLOBAL_OFFSET_TABLE_");
+ }
+
+ case MCExpr::Unary:
+ return hasGOTReference(cast<MCUnaryExpr>(Expr)->getSubExpr());
+ }
+ return false;
+}
bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
SMLoc &EndLoc)
@@ -836,6 +867,23 @@ bool SparcAsmParser::matchSparcAsmModifi
const MCExpr *subExpr;
if (Parser.parseParenExpression(subExpr, EndLoc))
return false;
+
+ bool isPIC = getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_;
+
+ 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());
return true;
}
Modified: llvm/trunk/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp?rev=202571&r1=202570&r2=202571&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp (original)
+++ llvm/trunk/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp Fri Feb 28 23:07:21 2014
@@ -11,8 +11,10 @@
#include "MCTargetDesc/SparcFixupKinds.h"
#include "MCTargetDesc/SparcMCTargetDesc.h"
#include "llvm/MC/MCELFObjectWriter.h"
+#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCFixupKindInfo.h"
#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/MC/MCValue.h"
#include "llvm/Support/TargetRegistry.h"
using namespace llvm;
@@ -154,6 +156,8 @@ namespace {
switch ((Sparc::Fixups)Fixup.getKind()) {
default: break;
case Sparc::fixup_sparc_wplt30:
+ if (Target.getSymA()->getSymbol().isTemporary())
+ return;
case Sparc::fixup_sparc_tls_gd_hi22:
case Sparc::fixup_sparc_tls_gd_lo10:
case Sparc::fixup_sparc_tls_gd_add:
Added: llvm/trunk/test/MC/Sparc/sparc-pic.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Sparc/sparc-pic.s?rev=202571&view=auto
==============================================================================
--- llvm/trunk/test/MC/Sparc/sparc-pic.s (added)
+++ llvm/trunk/test/MC/Sparc/sparc-pic.s Fri Feb 28 23:07:21 2014
@@ -0,0 +1,49 @@
+! RUN: llvm-mc %s -arch=sparcv9 --relocation-model=pic -filetype=obj | llvm-readobj -r | FileCheck %s
+
+
+! CHECK: Relocations [
+! CHECK-NOT: 0x{{[0-9,A-F]+}} R_SPARC_WPLT30 .text 0xC
+! CHECK: 0x{{[0-9,A-F]+}} R_SPARC_PC22 _GLOBAL_OFFSET_TABLE_ 0x4
+! CHECK-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_PC10 _GLOBAL_OFFSET_TABLE_ 0x8
+! CHECK-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_GOT22 AGlobalVar 0x0
+! CHECK-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_GOT10 AGlobalVar 0x0
+! CHECK-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_WPLT30 bar 0x0
+! CHECK: ]
+
+ .text
+ .globl foo
+ .align 4
+ .type foo, at function
+foo:
+ .cfi_startproc
+ save %sp, -176, %sp
+ .cfi_def_cfa_register %fp
+ .cfi_window_save
+ .cfi_register 15, 31
+.Ltmp4:
+ call .Ltmp5
+.Ltmp6:
+ sethi %hi(_GLOBAL_OFFSET_TABLE_+(.Ltmp6-.Ltmp4)), %i1
+.Ltmp5:
+ or %i1, %lo(_GLOBAL_OFFSET_TABLE_+(.Ltmp5-.Ltmp4)), %i1
+ add %i1, %o7, %i1
+ sethi %hi(AGlobalVar), %i2
+ add %i2, %lo(AGlobalVar), %i2
+ ldx [%i1+%i2], %i1
+ ldx [%i1], %i1
+ call bar
+ add %i0, %i1, %o0
+ ret
+ restore %g0, %o0, %o0
+.Ltmp7:
+ .size foo, .Ltmp7-foo
+ .cfi_endproc
+
+ .type AGlobalVar, at object ! @AGlobalVar
+ .section .bss
+ .globl AGlobalVar
+ .align 8
+AGlobalVar:
+ .xword 0 ! 0x0
+ .size AGlobalVar, 8
+
More information about the llvm-commits
mailing list