summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Sparc/MCTargetDesc
diff options
context:
space:
mode:
authorVenkatraman Govindaraju <venkatra@cs.wisc.edu>2014-02-07 04:24:35 +0000
committerVenkatraman Govindaraju <venkatra@cs.wisc.edu>2014-02-07 04:24:35 +0000
commit104643d0aac89dbfab348426507b57de942cc011 (patch)
treeb28b6ba8a7e1b3b4cf63864604e679bd2b3b9938 /llvm/lib/Target/Sparc/MCTargetDesc
parentdfe09b1b5bce82effc956c6b9b27f10bba3da1bb (diff)
downloadbcm5719-llvm-104643d0aac89dbfab348426507b57de942cc011.tar.gz
bcm5719-llvm-104643d0aac89dbfab348426507b57de942cc011.zip
[Sparc] Emit correct relocations for PIC code when integrated assembler is used.
llvm-svn: 200961
Diffstat (limited to 'llvm/lib/Target/Sparc/MCTargetDesc')
-rw-r--r--llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp24
-rw-r--r--llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp37
-rw-r--r--llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h15
-rw-r--r--llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp44
-rw-r--r--llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp31
-rw-r--r--llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h10
6 files changed, 126 insertions, 35 deletions
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
index 6a42d281178..6c14e5adfc8 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
@@ -26,14 +26,19 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
case FK_Data_4:
case FK_Data_8:
return Value;
+ case Sparc::fixup_sparc_wplt30:
case Sparc::fixup_sparc_call30:
return (Value >> 2) & 0x3fffffff;
case Sparc::fixup_sparc_br22:
return (Value >> 2) & 0x3fffff;
case Sparc::fixup_sparc_br19:
return (Value >> 2) & 0x7ffff;
+ case Sparc::fixup_sparc_pc22:
+ case Sparc::fixup_sparc_got22:
case Sparc::fixup_sparc_hi22:
return (Value >> 10) & 0x3fffff;
+ case Sparc::fixup_sparc_pc10:
+ case Sparc::fixup_sparc_got10:
case Sparc::fixup_sparc_lo10:
return Value & 0x3ff;
case Sparc::fixup_sparc_h44:
@@ -72,6 +77,11 @@ namespace {
{ "fixup_sparc_l44", 20, 12, 0 },
{ "fixup_sparc_hh", 10, 22, 0 },
{ "fixup_sparc_hm", 22, 10, 0 },
+ { "fixup_sparc_pc22", 10, 22, MCFixupKindInfo::FKF_IsPCRel },
+ { "fixup_sparc_pc10", 22, 10, MCFixupKindInfo::FKF_IsPCRel },
+ { "fixup_sparc_got22", 10, 22, 0 },
+ { "fixup_sparc_got10", 22, 10, 0 },
+ { "fixup_sparc_wplt30", 2, 30, MCFixupKindInfo::FKF_IsPCRel }
};
if (Kind < FirstTargetFixupKind)
@@ -82,6 +92,20 @@ namespace {
return Infos[Kind - FirstTargetFixupKind];
}
+ void processFixupValue(const MCAssembler &Asm,
+ const MCAsmLayout &Layout,
+ const MCFixup &Fixup,
+ const MCFragment *DF,
+ MCValue & Target,
+ uint64_t &Value,
+ bool &IsResolved) {
+ switch ((Sparc::Fixups)Fixup.getKind()) {
+ default: break;
+ case Sparc::fixup_sparc_wplt30: IsResolved = false; break;
+ }
+ }
+
+
bool mayNeedRelaxation(const MCInst &Inst) const {
// FIXME.
return false;
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
index 7410c9395bc..da1b9999c13 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
@@ -7,8 +7,9 @@
//
//===----------------------------------------------------------------------===//
-#include "MCTargetDesc/SparcMCTargetDesc.h"
#include "MCTargetDesc/SparcFixupKinds.h"
+#include "MCTargetDesc/SparcMCExpr.h"
+#include "MCTargetDesc/SparcMCTargetDesc.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/MC/MCELFObjectWriter.h"
#include "llvm/MC/MCExpr.h"
@@ -31,6 +32,11 @@ namespace {
bool IsPCRel, bool IsRelocWithSymbol,
int64_t Addend) const;
+ virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm,
+ const MCValue &Target,
+ const MCFragment &F,
+ const MCFixup &Fixup,
+ bool IsPCRel) const;
};
}
@@ -40,6 +46,12 @@ unsigned SparcELFObjectWriter::GetRelocType(const MCValue &Target,
bool IsPCRel,
bool IsRelocWithSymbol,
int64_t Addend) const {
+
+ if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(Fixup.getValue())) {
+ if (SExpr->getKind() == SparcMCExpr::VK_Sparc_R_DISP32)
+ return ELF::R_SPARC_DISP32;
+ }
+
if (IsPCRel) {
switch((unsigned)Fixup.getKind()) {
default:
@@ -51,6 +63,9 @@ unsigned SparcELFObjectWriter::GetRelocType(const MCValue &Target,
case Sparc::fixup_sparc_call30: return ELF::R_SPARC_WDISP30;
case Sparc::fixup_sparc_br22: return ELF::R_SPARC_WDISP22;
case Sparc::fixup_sparc_br19: return ELF::R_SPARC_WDISP19;
+ case Sparc::fixup_sparc_pc22: return ELF::R_SPARC_PC22;
+ case Sparc::fixup_sparc_pc10: return ELF::R_SPARC_PC10;
+ case Sparc::fixup_sparc_wplt30: return ELF::R_SPARC_WPLT30;
}
}
@@ -74,10 +89,30 @@ unsigned SparcELFObjectWriter::GetRelocType(const MCValue &Target,
case Sparc::fixup_sparc_l44: return ELF::R_SPARC_L44;
case Sparc::fixup_sparc_hh: return ELF::R_SPARC_HH22;
case Sparc::fixup_sparc_hm: return ELF::R_SPARC_HM10;
+ case Sparc::fixup_sparc_got22: return ELF::R_SPARC_GOT22;
+ case Sparc::fixup_sparc_got10: return ELF::R_SPARC_GOT10;
}
+
return ELF::R_SPARC_NONE;
}
+const MCSymbol *SparcELFObjectWriter::ExplicitRelSym(const MCAssembler &Asm,
+ const MCValue &Target,
+ const MCFragment &F,
+ const MCFixup &Fixup,
+ bool IsPCRel) const {
+
+ if (!Target.getSymA())
+ return NULL;
+ switch((unsigned)Fixup.getKind()) {
+ default: break;
+ case Sparc::fixup_sparc_got22:
+ case Sparc::fixup_sparc_got10:
+ return &Target.getSymA()->getSymbol().AliasedSymbol();
+ }
+ return NULL;
+}
+
MCObjectWriter *llvm::createSparcELFObjectWriter(raw_ostream &OS,
bool Is64Bit,
uint8_t OSABI) {
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h b/llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
index 48b5f905497..ff6e6cbadd7 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
@@ -48,6 +48,21 @@ namespace llvm {
/// fixup_sparc_hm - 10-bit fixup corresponding to %hm(foo)
fixup_sparc_hm,
+ /// fixup_sparc_pc22 - 22-bit fixup corresponding to %pc22(foo)
+ fixup_sparc_pc22,
+
+ /// fixup_sparc_pc10 - 10-bit fixup corresponding to %pc10(foo)
+ fixup_sparc_pc10,
+
+ /// fixup_sparc_got22 - 22-bit fixup corresponding to %got22(foo)
+ fixup_sparc_got22,
+
+ /// fixup_sparc_got10 - 10-bit fixup corresponding to %got10(foo)
+ fixup_sparc_got10,
+
+ /// fixup_sparc_wplt30
+ fixup_sparc_wplt30,
+
// Marker
LastTargetFixupKind,
NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
index 8c318274a45..0328b3f7376 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
@@ -101,37 +101,8 @@ getMachineOpValue(const MCInst &MI, const MCOperand &MO,
assert(MO.isExpr());
const MCExpr *Expr = MO.getExpr();
if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(Expr)) {
- switch(SExpr->getKind()) {
- default: assert(0 && "Unhandled sparc expression!"); break;
- case SparcMCExpr::VK_Sparc_LO:
- Fixups.push_back(MCFixup::Create(0, Expr,
- (MCFixupKind)Sparc::fixup_sparc_lo10));
- break;
- case SparcMCExpr::VK_Sparc_HI:
- Fixups.push_back(MCFixup::Create(0, Expr,
- (MCFixupKind)Sparc::fixup_sparc_hi22));
- break;
- case SparcMCExpr::VK_Sparc_H44:
- Fixups.push_back(MCFixup::Create(0, Expr,
- (MCFixupKind)Sparc::fixup_sparc_h44));
- break;
- case SparcMCExpr::VK_Sparc_M44:
- Fixups.push_back(MCFixup::Create(0, Expr,
- (MCFixupKind)Sparc::fixup_sparc_m44));
- break;
- case SparcMCExpr::VK_Sparc_L44:
- Fixups.push_back(MCFixup::Create(0, Expr,
- (MCFixupKind)Sparc::fixup_sparc_l44));
- break;
- case SparcMCExpr::VK_Sparc_HH:
- Fixups.push_back(MCFixup::Create(0, Expr,
- (MCFixupKind)Sparc::fixup_sparc_hh));
- break;
- case SparcMCExpr::VK_Sparc_HM:
- Fixups.push_back(MCFixup::Create(0, Expr,
- (MCFixupKind)Sparc::fixup_sparc_hm));
- break;
- }
+ MCFixupKind Kind = (MCFixupKind)SExpr->getFixupKind();
+ Fixups.push_back(MCFixup::Create(0, Expr, Kind));
return 0;
}
@@ -151,8 +122,15 @@ getCallTargetOpValue(const MCInst &MI, unsigned OpNo,
if (MO.isReg() || MO.isImm())
return getMachineOpValue(MI, MO, Fixups, STI);
- Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
- (MCFixupKind)Sparc::fixup_sparc_call30));
+ MCFixupKind fixupKind = (MCFixupKind)Sparc::fixup_sparc_call30;
+
+ if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(MO.getExpr())) {
+ if (SExpr->getKind() == SparcMCExpr::VK_Sparc_WPLT30)
+ fixupKind = (MCFixupKind)Sparc::fixup_sparc_wplt30;
+ }
+
+ Fixups.push_back(MCFixup::Create(0, MO.getExpr(), fixupKind));
+
return 0;
}
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
index f38e3118184..4a83c96a924 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
@@ -17,6 +17,7 @@
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCELF.h"
+#include "llvm/MC/MCSymbol.h"
#include "llvm/Object/ELF.h"
@@ -54,6 +55,13 @@ bool SparcMCExpr::printVariantKind(raw_ostream &OS, VariantKind Kind)
case VK_Sparc_L44: OS << "%l44("; break;
case VK_Sparc_HH: OS << "%hh("; break;
case VK_Sparc_HM: OS << "%hm("; break;
+ // FIXME: use %pc22/%pc10, if system assembler supports them.
+ case VK_Sparc_PC22: OS << "%hi("; break;
+ case VK_Sparc_PC10: OS << "%lo("; break;
+ // FIXME: use %got22/%got10, if system assembler supports them.
+ case VK_Sparc_GOT22: OS << "%hi("; break;
+ case VK_Sparc_GOT10: OS << "%lo("; break;
+ case VK_Sparc_WPLT30: closeParen = false; break;
case VK_Sparc_R_DISP32: OS << "%r_disp32("; break;
case VK_Sparc_TLS_GD_HI22: OS << "%tgd_hi22("; break;
case VK_Sparc_TLS_GD_LO10: OS << "%tgd_lo10("; break;
@@ -87,6 +95,10 @@ SparcMCExpr::VariantKind SparcMCExpr::parseVariantKind(StringRef name)
.Case("l44", VK_Sparc_L44)
.Case("hh", VK_Sparc_HH)
.Case("hm", VK_Sparc_HM)
+ .Case("pc22", VK_Sparc_PC22)
+ .Case("pc10", VK_Sparc_PC10)
+ .Case("got22", VK_Sparc_GOT22)
+ .Case("got10", VK_Sparc_GOT10)
.Case("r_disp32", VK_Sparc_R_DISP32)
.Case("tgd_hi22", VK_Sparc_TLS_GD_HI22)
.Case("tgd_lo10", VK_Sparc_TLS_GD_LO10)
@@ -109,9 +121,26 @@ SparcMCExpr::VariantKind SparcMCExpr::parseVariantKind(StringRef name)
.Default(VK_Sparc_None);
}
+Sparc::Fixups SparcMCExpr::getFixupKind(SparcMCExpr::VariantKind Kind) {
+ switch (Kind) {
+ default: assert(0 && "Unhandled SparcMCExpr::VariantKind");
+ case VK_Sparc_LO: return Sparc::fixup_sparc_lo10;
+ case VK_Sparc_HI: return Sparc::fixup_sparc_hi22;
+ case VK_Sparc_H44: return Sparc::fixup_sparc_h44;
+ case VK_Sparc_M44: return Sparc::fixup_sparc_m44;
+ case VK_Sparc_L44: return Sparc::fixup_sparc_l44;
+ case VK_Sparc_HH: return Sparc::fixup_sparc_hh;
+ case VK_Sparc_HM: return Sparc::fixup_sparc_hm;
+ case VK_Sparc_PC22: return Sparc::fixup_sparc_pc22;
+ case VK_Sparc_PC10: return Sparc::fixup_sparc_pc10;
+ case VK_Sparc_GOT22: return Sparc::fixup_sparc_got22;
+ case VK_Sparc_GOT10: return Sparc::fixup_sparc_got10;
+ }
+}
+
bool
SparcMCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
- const MCAsmLayout *Layout) const {
+ const MCAsmLayout *Layout) const {
if (!Layout)
return false;
return getSubExpr()->EvaluateAsRelocatable(Res, *Layout);
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
index ebe3a752a6f..be6526e8ade 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
@@ -15,6 +15,7 @@
#ifndef LLVM_SPARCMCEXPR_H
#define LLVM_SPARCMCEXPR_H
+#include "SparcFixupKinds.h"
#include "llvm/MC/MCExpr.h"
namespace llvm {
@@ -31,6 +32,11 @@ public:
VK_Sparc_L44,
VK_Sparc_HH,
VK_Sparc_HM,
+ VK_Sparc_PC22,
+ VK_Sparc_PC10,
+ VK_Sparc_GOT22,
+ VK_Sparc_GOT10,
+ VK_Sparc_WPLT30,
VK_Sparc_R_DISP32,
VK_Sparc_TLS_GD_HI22,
VK_Sparc_TLS_GD_LO10,
@@ -75,6 +81,9 @@ public:
/// getSubExpr - Get the child of this expression.
const MCExpr *getSubExpr() const { return Expr; }
+ /// getFixupKind - Get the fixup kind of this expression.
+ Sparc::Fixups getFixupKind() const { return getFixupKind(Kind); }
+
/// @}
void PrintImpl(raw_ostream &OS) const;
bool EvaluateAsRelocatableImpl(MCValue &Res,
@@ -94,6 +103,7 @@ public:
static VariantKind parseVariantKind(StringRef name);
static bool printVariantKind(raw_ostream &OS, VariantKind Kind);
+ static Sparc::Fixups getFixupKind(VariantKind Kind);
};
} // end namespace llvm.
OpenPOWER on IntegriCloud