diff options
author | Venkatraman Govindaraju <venkatra@cs.wisc.edu> | 2014-02-07 05:54:20 +0000 |
---|---|---|
committer | Venkatraman Govindaraju <venkatra@cs.wisc.edu> | 2014-02-07 05:54:20 +0000 |
commit | fabdd6632a8625915b76f8796ac55b233bd4a547 (patch) | |
tree | b57e71b9b76c584c4b8f5705d443348b886e0f5a /lib/Target/Sparc/MCTargetDesc | |
parent | 44ad4d00b497d0931c73136ca0ce14882a4a60e0 (diff) | |
download | llvm-fabdd6632a8625915b76f8796ac55b233bd4a547.tar.gz llvm-fabdd6632a8625915b76f8796ac55b233bd4a547.tar.bz2 llvm-fabdd6632a8625915b76f8796ac55b233bd4a547.tar.xz |
[Sparc] Emit relocations for Thread Local Storage (TLS) when integrated assembler is used.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@200962 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/Sparc/MCTargetDesc')
-rw-r--r-- | lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp | 75 | ||||
-rw-r--r-- | lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp | 18 | ||||
-rw-r--r-- | lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h | 20 | ||||
-rw-r--r-- | lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp | 31 | ||||
-rw-r--r-- | lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp | 47 |
5 files changed, 187 insertions, 4 deletions
diff --git a/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp b/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp index 6c14e5adfc..db1c361c8f 100644 --- a/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp +++ b/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp @@ -26,31 +26,65 @@ 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_tls_gd_hi22: + case Sparc::fixup_sparc_tls_ldm_hi22: + case Sparc::fixup_sparc_tls_ie_hi22: case Sparc::fixup_sparc_hi22: return (Value >> 10) & 0x3fffff; + case Sparc::fixup_sparc_pc10: case Sparc::fixup_sparc_got10: + case Sparc::fixup_sparc_tls_gd_lo10: + case Sparc::fixup_sparc_tls_ldm_lo10: + case Sparc::fixup_sparc_tls_ie_lo10: case Sparc::fixup_sparc_lo10: return Value & 0x3ff; + + case Sparc::fixup_sparc_tls_ldo_hix22: + case Sparc::fixup_sparc_tls_le_hix22: + return (~Value >> 10) & 0x3fffff; + + case Sparc::fixup_sparc_tls_ldo_lox10: + case Sparc::fixup_sparc_tls_le_lox10: + return (~(~Value & 0x3ff)) & 0x1fff; + case Sparc::fixup_sparc_h44: return (Value >> 22) & 0x3fffff; + case Sparc::fixup_sparc_m44: return (Value >> 12) & 0x3ff; + case Sparc::fixup_sparc_l44: return Value & 0xfff; + case Sparc::fixup_sparc_hh: return (Value >> 42) & 0x3fffff; + case Sparc::fixup_sparc_hm: return (Value >> 32) & 0x3ff; + + case Sparc::fixup_sparc_tls_gd_add: + case Sparc::fixup_sparc_tls_gd_call: + case Sparc::fixup_sparc_tls_ldm_add: + case Sparc::fixup_sparc_tls_ldm_call: + case Sparc::fixup_sparc_tls_ldo_add: + case Sparc::fixup_sparc_tls_ie_ld: + case Sparc::fixup_sparc_tls_ie_ldx: + case Sparc::fixup_sparc_tls_ie_add: + return 0; } } @@ -81,7 +115,25 @@ namespace { { "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 } + { "fixup_sparc_wplt30", 2, 30, MCFixupKindInfo::FKF_IsPCRel }, + { "fixup_sparc_tls_gd_hi22", 10, 22, 0 }, + { "fixup_sparc_tls_gd_lo10", 22, 10, 0 }, + { "fixup_sparc_tls_gd_add", 0, 0, 0 }, + { "fixup_sparc_tls_gd_call", 0, 0, 0 }, + { "fixup_sparc_tls_ldm_hi22", 10, 22, 0 }, + { "fixup_sparc_tls_ldm_lo10", 22, 10, 0 }, + { "fixup_sparc_tls_ldm_add", 0, 0, 0 }, + { "fixup_sparc_tls_ldm_call", 0, 0, 0 }, + { "fixup_sparc_tls_ldo_hix22", 10, 22, 0 }, + { "fixup_sparc_tls_ldo_lox10", 22, 10, 0 }, + { "fixup_sparc_tls_ldo_add", 0, 0, 0 }, + { "fixup_sparc_tls_ie_hi22", 10, 22, 0 }, + { "fixup_sparc_tls_ie_lo10", 22, 10, 0 }, + { "fixup_sparc_tls_ie_ld", 0, 0, 0 }, + { "fixup_sparc_tls_ie_ldx", 0, 0, 0 }, + { "fixup_sparc_tls_ie_add", 0, 0, 0 }, + { "fixup_sparc_tls_le_hix22", 0, 0, 0 }, + { "fixup_sparc_tls_le_lox10", 0, 0, 0 } }; if (Kind < FirstTargetFixupKind) @@ -101,11 +153,28 @@ namespace { bool &IsResolved) { switch ((Sparc::Fixups)Fixup.getKind()) { default: break; - case Sparc::fixup_sparc_wplt30: IsResolved = false; break; + case Sparc::fixup_sparc_wplt30: + case Sparc::fixup_sparc_tls_gd_hi22: + case Sparc::fixup_sparc_tls_gd_lo10: + case Sparc::fixup_sparc_tls_gd_add: + case Sparc::fixup_sparc_tls_gd_call: + case Sparc::fixup_sparc_tls_ldm_hi22: + case Sparc::fixup_sparc_tls_ldm_lo10: + case Sparc::fixup_sparc_tls_ldm_add: + case Sparc::fixup_sparc_tls_ldm_call: + case Sparc::fixup_sparc_tls_ldo_hix22: + case Sparc::fixup_sparc_tls_ldo_lox10: + case Sparc::fixup_sparc_tls_ldo_add: + case Sparc::fixup_sparc_tls_ie_hi22: + case Sparc::fixup_sparc_tls_ie_lo10: + case Sparc::fixup_sparc_tls_ie_ld: + case Sparc::fixup_sparc_tls_ie_ldx: + case Sparc::fixup_sparc_tls_ie_add: + case Sparc::fixup_sparc_tls_le_hix22: + case Sparc::fixup_sparc_tls_le_lox10: IsResolved = false; break; } } - bool mayNeedRelaxation(const MCInst &Inst) const { // FIXME. return false; diff --git a/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp b/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp index da1b9999c1..3a9929bc4c 100644 --- a/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp +++ b/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp @@ -91,6 +91,24 @@ unsigned SparcELFObjectWriter::GetRelocType(const MCValue &Target, 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; + case Sparc::fixup_sparc_tls_gd_hi22: return ELF::R_SPARC_TLS_GD_HI22; + case Sparc::fixup_sparc_tls_gd_lo10: return ELF::R_SPARC_TLS_GD_LO10; + case Sparc::fixup_sparc_tls_gd_add: return ELF::R_SPARC_TLS_GD_ADD; + case Sparc::fixup_sparc_tls_gd_call: return ELF::R_SPARC_TLS_GD_CALL; + case Sparc::fixup_sparc_tls_ldm_hi22: return ELF::R_SPARC_TLS_LDM_HI22; + case Sparc::fixup_sparc_tls_ldm_lo10: return ELF::R_SPARC_TLS_LDM_LO10; + case Sparc::fixup_sparc_tls_ldm_add: return ELF::R_SPARC_TLS_LDM_ADD; + case Sparc::fixup_sparc_tls_ldm_call: return ELF::R_SPARC_TLS_LDM_CALL; + case Sparc::fixup_sparc_tls_ldo_hix22: return ELF::R_SPARC_TLS_LDO_HIX22; + case Sparc::fixup_sparc_tls_ldo_lox10: return ELF::R_SPARC_TLS_LDO_LOX10; + case Sparc::fixup_sparc_tls_ldo_add: return ELF::R_SPARC_TLS_LDO_ADD; + case Sparc::fixup_sparc_tls_ie_hi22: return ELF::R_SPARC_TLS_IE_HI22; + case Sparc::fixup_sparc_tls_ie_lo10: return ELF::R_SPARC_TLS_IE_LO10; + case Sparc::fixup_sparc_tls_ie_ld: return ELF::R_SPARC_TLS_IE_LD; + case Sparc::fixup_sparc_tls_ie_ldx: return ELF::R_SPARC_TLS_IE_LDX; + case Sparc::fixup_sparc_tls_ie_add: return ELF::R_SPARC_TLS_IE_ADD; + case Sparc::fixup_sparc_tls_le_hix22: return ELF::R_SPARC_TLS_LE_HIX22; + case Sparc::fixup_sparc_tls_le_lox10: return ELF::R_SPARC_TLS_LE_LOX10; } return ELF::R_SPARC_NONE; diff --git a/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h b/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h index ff6e6cbadd..005a0242dc 100644 --- a/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h +++ b/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h @@ -63,6 +63,26 @@ namespace llvm { /// fixup_sparc_wplt30 fixup_sparc_wplt30, + /// fixups for Thread Local Storage + fixup_sparc_tls_gd_hi22, + fixup_sparc_tls_gd_lo10, + fixup_sparc_tls_gd_add, + fixup_sparc_tls_gd_call, + fixup_sparc_tls_ldm_hi22, + fixup_sparc_tls_ldm_lo10, + fixup_sparc_tls_ldm_add, + fixup_sparc_tls_ldm_call, + fixup_sparc_tls_ldo_hix22, + fixup_sparc_tls_ldo_lox10, + fixup_sparc_tls_ldo_add, + fixup_sparc_tls_ie_hi22, + fixup_sparc_tls_ie_lo10, + fixup_sparc_tls_ie_ld, + fixup_sparc_tls_ie_ldx, + fixup_sparc_tls_ie_add, + fixup_sparc_tls_le_hix22, + fixup_sparc_tls_le_lox10, + // Marker LastTargetFixupKind, NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind diff --git a/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp b/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp index 0328b3f737..16310d5024 100644 --- a/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp +++ b/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp @@ -21,6 +21,7 @@ #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCRegisterInfo.h" +#include "llvm/MC/MCSymbol.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -82,6 +83,21 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS, OS << (char)(Bits >> 24); Bits <<= 8; } + unsigned tlsOpNo = 0; + switch (MI.getOpcode()) { + default: break; + case SP::TLS_CALL: tlsOpNo = 1; break; + case SP::TLS_ADDrr: + case SP::TLS_ADDXrr: + case SP::TLS_LDrr: + case SP::TLS_LDXrr: tlsOpNo = 3; break; + } + if (tlsOpNo != 0) { + const MCOperand &MO = MI.getOperand(tlsOpNo); + uint64_t op = getMachineOpValue(MI, MO, Fixups, STI); + assert(op == 0 && "Unexpected operand value!"); + (void)op; // suppress warning. + } ++MCNumEmitted; // Keep track of the # of mi's emitted. } @@ -122,6 +138,21 @@ getCallTargetOpValue(const MCInst &MI, unsigned OpNo, if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI); + if (MI.getOpcode() == SP::TLS_CALL) { + // No fixups for __tls_get_addr. Will emit for fixups for tls_symbol in + // EncodeInstruction. +#ifndef NDEBUG + // Verify that the callee is actually __tls_get_addr. + const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(MO.getExpr()); + assert(SExpr && SExpr->getSubExpr()->getKind() == MCExpr::SymbolRef && + "Unexpected expression in TLS_CALL"); + const MCSymbolRefExpr *SymExpr = cast<MCSymbolRefExpr>(SExpr->getSubExpr()); + assert(SymExpr->getSymbol().getName() == "__tls_get_addr" && + "Unexpected function for TLS_CALL"); +#endif + return 0; + } + MCFixupKind fixupKind = (MCFixupKind)Sparc::fixup_sparc_call30; if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(MO.getExpr())) { diff --git a/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp b/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp index 4a83c96a92..7f2b25e408 100644 --- a/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp +++ b/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp @@ -135,6 +135,25 @@ Sparc::Fixups SparcMCExpr::getFixupKind(SparcMCExpr::VariantKind Kind) { 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; + case VK_Sparc_WPLT30: return Sparc::fixup_sparc_wplt30; + case VK_Sparc_TLS_GD_HI22: return Sparc::fixup_sparc_tls_gd_hi22; + case VK_Sparc_TLS_GD_LO10: return Sparc::fixup_sparc_tls_gd_lo10; + case VK_Sparc_TLS_GD_ADD: return Sparc::fixup_sparc_tls_gd_add; + case VK_Sparc_TLS_GD_CALL: return Sparc::fixup_sparc_tls_gd_call; + case VK_Sparc_TLS_LDM_HI22: return Sparc::fixup_sparc_tls_ldm_hi22; + case VK_Sparc_TLS_LDM_LO10: return Sparc::fixup_sparc_tls_ldm_lo10; + case VK_Sparc_TLS_LDM_ADD: return Sparc::fixup_sparc_tls_ldm_add; + case VK_Sparc_TLS_LDM_CALL: return Sparc::fixup_sparc_tls_ldm_call; + case VK_Sparc_TLS_LDO_HIX22: return Sparc::fixup_sparc_tls_ldo_hix22; + case VK_Sparc_TLS_LDO_LOX10: return Sparc::fixup_sparc_tls_ldo_lox10; + case VK_Sparc_TLS_LDO_ADD: return Sparc::fixup_sparc_tls_ldo_add; + case VK_Sparc_TLS_IE_HI22: return Sparc::fixup_sparc_tls_ie_hi22; + case VK_Sparc_TLS_IE_LO10: return Sparc::fixup_sparc_tls_ie_lo10; + case VK_Sparc_TLS_IE_LD: return Sparc::fixup_sparc_tls_ie_ld; + case VK_Sparc_TLS_IE_LDX: return Sparc::fixup_sparc_tls_ie_ldx; + case VK_Sparc_TLS_IE_ADD: return Sparc::fixup_sparc_tls_ie_add; + case VK_Sparc_TLS_LE_HIX22: return Sparc::fixup_sparc_tls_le_hix22; + case VK_Sparc_TLS_LE_LOX10: return Sparc::fixup_sparc_tls_le_lox10; } } @@ -147,7 +166,33 @@ SparcMCExpr::EvaluateAsRelocatableImpl(MCValue &Res, } static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) { - assert(0 && "Implement fixELFSymbolsInTLSFixupsImpl!"); + switch (Expr->getKind()) { + case MCExpr::Target: + llvm_unreachable("Can't handle nested target expr!"); + break; + + case MCExpr::Constant: + break; + + case MCExpr::Binary: { + const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr); + fixELFSymbolsInTLSFixupsImpl(BE->getLHS(), Asm); + fixELFSymbolsInTLSFixupsImpl(BE->getRHS(), Asm); + break; + } + + case MCExpr::SymbolRef: { + const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr); + MCSymbolData &SD = Asm.getOrCreateSymbolData(SymRef.getSymbol()); + MCELF::SetType(SD, ELF::STT_TLS); + break; + } + + case MCExpr::Unary: + fixELFSymbolsInTLSFixupsImpl(cast<MCUnaryExpr>(Expr)->getSubExpr(), Asm); + break; + } + } void SparcMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const { |