diff options
author | dim <dim@FreeBSD.org> | 2014-03-26 07:31:57 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2014-03-26 07:31:57 +0000 |
commit | fb422e6d310915f9e2641190198698d922f7ef58 (patch) | |
tree | 8126abc77e6620e23932d186c7b2b75457af47a5 /contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp | |
parent | 5a582ae617991f602ee6f8a954a36fd749aa466c (diff) | |
download | FreeBSD-src-fb422e6d310915f9e2641190198698d922f7ef58.zip FreeBSD-src-fb422e6d310915f9e2641190198698d922f7ef58.tar.gz |
MFC r262613:
Merge the projects/clang-sparc64 branch back to head. This brings in
several updates from the llvm and clang trunks to make the sparc64
backend fully functional.
Apart from one patch to sys/sparc64/include/pcpu.h which is still under
discussion, this makes it possible to let clang fully build world and
kernel for sparc64.
Any assistance with testing this on actual sparc64 hardware is greatly
appreciated, as there will unavoidably be bugs left.
Many thanks go to Roman Divacky for his upstream work on getting the
sparc64 backend into shape.
MFC r262985:
Repair a few minor mismerges from r262261 in the clang-sparc64 project
branch. This is also to minimize differences with upstream.
Diffstat (limited to 'contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp')
-rw-r--r-- | contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp b/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp new file mode 100644 index 0000000..3a9929b --- /dev/null +++ b/contrib/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp @@ -0,0 +1,139 @@ +//===-- SparcELFObjectWriter.cpp - Sparc ELF Writer -----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#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" +#include "llvm/MC/MCValue.h" +#include "llvm/Support/ErrorHandling.h" + +using namespace llvm; + +namespace { + class SparcELFObjectWriter : public MCELFObjectTargetWriter { + public: + SparcELFObjectWriter(bool Is64Bit, uint8_t OSABI) + : MCELFObjectTargetWriter(Is64Bit, OSABI, + Is64Bit ? ELF::EM_SPARCV9 : ELF::EM_SPARC, + /*HasRelocationAddend*/ true) {} + + virtual ~SparcELFObjectWriter() {} + protected: + virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, + 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; + }; +} + + +unsigned SparcELFObjectWriter::GetRelocType(const MCValue &Target, + const MCFixup &Fixup, + 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: + llvm_unreachable("Unimplemented fixup -> relocation"); + case FK_Data_1: return ELF::R_SPARC_DISP8; + case FK_Data_2: return ELF::R_SPARC_DISP16; + case FK_Data_4: return ELF::R_SPARC_DISP32; + case FK_Data_8: return ELF::R_SPARC_DISP64; + 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; + } + } + + switch((unsigned)Fixup.getKind()) { + default: + llvm_unreachable("Unimplemented fixup -> relocation"); + case FK_Data_1: return ELF::R_SPARC_8; + case FK_Data_2: return ((Fixup.getOffset() % 2) + ? ELF::R_SPARC_UA16 + : ELF::R_SPARC_16); + case FK_Data_4: return ((Fixup.getOffset() % 4) + ? ELF::R_SPARC_UA32 + : ELF::R_SPARC_32); + case FK_Data_8: return ((Fixup.getOffset() % 8) + ? ELF::R_SPARC_UA64 + : ELF::R_SPARC_64); + case Sparc::fixup_sparc_hi22: return ELF::R_SPARC_HI22; + case Sparc::fixup_sparc_lo10: return ELF::R_SPARC_LO10; + case Sparc::fixup_sparc_h44: return ELF::R_SPARC_H44; + case Sparc::fixup_sparc_m44: return ELF::R_SPARC_M44; + 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; + 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; +} + +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) { + MCELFObjectTargetWriter *MOTW = new SparcELFObjectWriter(Is64Bit, OSABI); + return createELFObjectWriter(MOTW, OS, /*IsLittleEndian=*/false); +} |