From 7d2b0f70e8f047c60ddc3537877269c066ce2303 Mon Sep 17 00:00:00 2001 From: Colin LeMahieu Date: Tue, 9 Feb 2016 19:18:02 +0000 Subject: [PATCH] [Hexagon] Fixing relocation generation and adding tests. llvm-svn: 260259 --- .../MCTargetDesc/HexagonELFObjectWriter.cpp | 53 +- .../MCTargetDesc/HexagonMCCodeEmitter.cpp | 470 ++++++++++-------- test/MC/Hexagon/relocations.s | 244 +++++++++ 3 files changed, 546 insertions(+), 221 deletions(-) create mode 100644 test/MC/Hexagon/relocations.s diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonELFObjectWriter.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonELFObjectWriter.cpp index cd5d7c7d3f6..6b662d8c989 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonELFObjectWriter.cpp +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonELFObjectWriter.cpp @@ -11,6 +11,7 @@ #include "MCTargetDesc/HexagonFixupKinds.h" #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCELFObjectWriter.h" +#include "llvm/MC/MCValue.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" @@ -39,20 +40,60 @@ HexagonELFObjectWriter::HexagonELFObjectWriter(uint8_t OSABI, StringRef C) CPU(C) {} unsigned HexagonELFObjectWriter::getRelocType(MCContext &Ctx, - MCValue const & /*Target*/, + MCValue const &Target, MCFixup const &Fixup, bool IsPCRel) const { + MCSymbolRefExpr::VariantKind Variant = Target.getAccessVariant(); switch ((unsigned)Fixup.getKind()) { default: - DEBUG(dbgs() << "unrecognized relocation " << Fixup.getKind() << "\n"); - llvm_unreachable("Unimplemented Fixup kind!"); - return ELF::R_HEX_NONE; + report_fatal_error("Unrecognized relocation type"); + break; case FK_Data_4: - return (IsPCRel) ? ELF::R_HEX_32_PCREL : ELF::R_HEX_32; + switch(Variant) { + case MCSymbolRefExpr::VariantKind::VK_PPC_DTPREL: + return ELF::R_HEX_DTPREL_32; + case MCSymbolRefExpr::VariantKind::VK_GOT: + return ELF::R_HEX_GOT_32; + case MCSymbolRefExpr::VariantKind::VK_GOTREL: + return ELF::R_HEX_GOTREL_32; + case MCSymbolRefExpr::VariantKind::VK_Hexagon_GD_GOT: + return ELF::R_HEX_GD_GOT_32; + case MCSymbolRefExpr::VariantKind::VK_Hexagon_IE: + return ELF::R_HEX_IE_32; + case MCSymbolRefExpr::VariantKind::VK_Hexagon_IE_GOT: + return ELF::R_HEX_IE_GOT_32; + case MCSymbolRefExpr::VariantKind::VK_Hexagon_LD_GOT: + return ELF::R_HEX_LD_GOT_32; + case MCSymbolRefExpr::VariantKind::VK_Hexagon_PCREL: + return ELF::R_HEX_32_PCREL; + case MCSymbolRefExpr::VariantKind::VK_PPC_TPREL: + return ELF::R_HEX_TPREL_32; + case MCSymbolRefExpr::VariantKind::VK_None: + return IsPCRel ? ELF::R_HEX_32_PCREL : ELF::R_HEX_32; + default: + report_fatal_error("Unrecognized variant type"); + }; case FK_PCRel_4: return ELF::R_HEX_32_PCREL; case FK_Data_2: - return ELF::R_HEX_16; + switch(Variant) { + case MCSymbolRefExpr::VariantKind::VK_PPC_DTPREL: + return ELF::R_HEX_DTPREL_16; + case MCSymbolRefExpr::VariantKind::VK_GOT: + return ELF::R_HEX_GOT_16; + case MCSymbolRefExpr::VariantKind::VK_Hexagon_GD_GOT: + return ELF::R_HEX_GD_GOT_16; + case MCSymbolRefExpr::VariantKind::VK_Hexagon_IE_GOT: + return ELF::R_HEX_IE_GOT_16; + case MCSymbolRefExpr::VariantKind::VK_Hexagon_LD_GOT: + return ELF::R_HEX_LD_GOT_16; + case MCSymbolRefExpr::VariantKind::VK_PPC_TPREL: + return ELF::R_HEX_TPREL_16; + case MCSymbolRefExpr::VariantKind::VK_None: + return ELF::R_HEX_16; + default: + report_fatal_error("Unrecognized variant type"); + }; case FK_Data_1: return ELF::R_HEX_8; case fixup_Hexagon_B22_PCREL: diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp index 4b07ca7490a..68c944c5726 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp @@ -251,7 +251,23 @@ void HexagonMCCodeEmitter::EncodeSingleInstruction( ++MCNumEmitted; } -static Hexagon::Fixups getFixupNoBits(MCInstrInfo const &MCII, const MCInst &MI, +namespace { +void raise_relocation_error(unsigned bits, unsigned kind) { + std::string Text; + { + llvm::raw_string_ostream Stream(Text); + Stream << "Unrecognized relocation combination bits: " << bits + << " kind: " << kind; + } + report_fatal_error(Text); +} +} + +/// getFixupNoBits - Some insns are not extended and thus have no +/// bits. These cases require a more brute force method for determining +/// the correct relocation. +namespace { +Hexagon::Fixups getFixupNoBits(MCInstrInfo const &MCII, const MCInst &MI, const MCOperand &MO, const MCSymbolRefExpr::VariantKind kind) { const MCInstrDesc &MCID = HexagonMCInstrInfo::getDesc(MCII, MI); @@ -259,83 +275,90 @@ static Hexagon::Fixups getFixupNoBits(MCInstrInfo const &MCII, const MCInst &MI, if (insnType == HexagonII::TypePREFIX) { switch (kind) { - case llvm::MCSymbolRefExpr::VK_GOTOFF: + case MCSymbolRefExpr::VK_GOTREL: return Hexagon::fixup_Hexagon_GOTREL_32_6_X; - case llvm::MCSymbolRefExpr::VK_GOT: + case MCSymbolRefExpr::VK_GOT: return Hexagon::fixup_Hexagon_GOT_32_6_X; - case llvm::MCSymbolRefExpr::VK_TPREL: + case MCSymbolRefExpr::VK_PPC_TPREL: return Hexagon::fixup_Hexagon_TPREL_32_6_X; - case llvm::MCSymbolRefExpr::VK_DTPREL: + case MCSymbolRefExpr::VK_PPC_DTPREL: return Hexagon::fixup_Hexagon_DTPREL_32_6_X; - case llvm::MCSymbolRefExpr::VK_Hexagon_GD_GOT: + case MCSymbolRefExpr::VK_Hexagon_GD_GOT: return Hexagon::fixup_Hexagon_GD_GOT_32_6_X; - case llvm::MCSymbolRefExpr::VK_Hexagon_LD_GOT: + case MCSymbolRefExpr::VK_Hexagon_LD_GOT: return Hexagon::fixup_Hexagon_LD_GOT_32_6_X; - case llvm::MCSymbolRefExpr::VK_Hexagon_IE: + case MCSymbolRefExpr::VK_Hexagon_IE: return Hexagon::fixup_Hexagon_IE_32_6_X; - case llvm::MCSymbolRefExpr::VK_Hexagon_IE_GOT: + case MCSymbolRefExpr::VK_Hexagon_IE_GOT: return Hexagon::fixup_Hexagon_IE_GOT_32_6_X; - default: + case MCSymbolRefExpr::VK_Hexagon_PCREL: + case MCSymbolRefExpr::VK_None: if (MCID.isBranch()) return Hexagon::fixup_Hexagon_B32_PCREL_X; else return Hexagon::fixup_Hexagon_32_6_X; + default: + raise_relocation_error(0, kind); } } else if (MCID.isBranch()) - return (Hexagon::fixup_Hexagon_B13_PCREL); + return Hexagon::fixup_Hexagon_B13_PCREL; switch (MCID.getOpcode()) { case Hexagon::HI: case Hexagon::A2_tfrih: switch (kind) { - case llvm::MCSymbolRefExpr::VK_GOT: + case MCSymbolRefExpr::VK_GOT: return Hexagon::fixup_Hexagon_GOT_HI16; - case llvm::MCSymbolRefExpr::VK_GOTOFF: + case MCSymbolRefExpr::VK_GOTREL: return Hexagon::fixup_Hexagon_GOTREL_HI16; - case llvm::MCSymbolRefExpr::VK_Hexagon_GD_GOT: + case MCSymbolRefExpr::VK_Hexagon_GD_GOT: return Hexagon::fixup_Hexagon_GD_GOT_HI16; - case llvm::MCSymbolRefExpr::VK_Hexagon_LD_GOT: + case MCSymbolRefExpr::VK_Hexagon_LD_GOT: return Hexagon::fixup_Hexagon_LD_GOT_HI16; - case llvm::MCSymbolRefExpr::VK_Hexagon_IE: + case MCSymbolRefExpr::VK_Hexagon_IE: return Hexagon::fixup_Hexagon_IE_HI16; - case llvm::MCSymbolRefExpr::VK_Hexagon_IE_GOT: + case MCSymbolRefExpr::VK_Hexagon_IE_GOT: return Hexagon::fixup_Hexagon_IE_GOT_HI16; - case llvm::MCSymbolRefExpr::VK_TPREL: + case MCSymbolRefExpr::VK_PPC_TPREL: return Hexagon::fixup_Hexagon_TPREL_HI16; - case llvm::MCSymbolRefExpr::VK_DTPREL: + case MCSymbolRefExpr::VK_PPC_DTPREL: return Hexagon::fixup_Hexagon_DTPREL_HI16; - default: + case MCSymbolRefExpr::VK_None: return Hexagon::fixup_Hexagon_HI16; + default: + raise_relocation_error(0, kind); } case Hexagon::LO: case Hexagon::A2_tfril: switch (kind) { - case llvm::MCSymbolRefExpr::VK_GOT: + case MCSymbolRefExpr::VK_GOT: return Hexagon::fixup_Hexagon_GOT_LO16; - case llvm::MCSymbolRefExpr::VK_GOTOFF: + case MCSymbolRefExpr::VK_GOTREL: return Hexagon::fixup_Hexagon_GOTREL_LO16; - case llvm::MCSymbolRefExpr::VK_Hexagon_GD_GOT: + case MCSymbolRefExpr::VK_Hexagon_GD_GOT: return Hexagon::fixup_Hexagon_GD_GOT_LO16; - case llvm::MCSymbolRefExpr::VK_Hexagon_LD_GOT: + case MCSymbolRefExpr::VK_Hexagon_LD_GOT: return Hexagon::fixup_Hexagon_LD_GOT_LO16; - case llvm::MCSymbolRefExpr::VK_Hexagon_IE: + case MCSymbolRefExpr::VK_Hexagon_IE: return Hexagon::fixup_Hexagon_IE_LO16; - case llvm::MCSymbolRefExpr::VK_Hexagon_IE_GOT: + case MCSymbolRefExpr::VK_Hexagon_IE_GOT: return Hexagon::fixup_Hexagon_IE_GOT_LO16; - case llvm::MCSymbolRefExpr::VK_TPREL: + case MCSymbolRefExpr::VK_PPC_TPREL: return Hexagon::fixup_Hexagon_TPREL_LO16; - case llvm::MCSymbolRefExpr::VK_DTPREL: + case MCSymbolRefExpr::VK_PPC_DTPREL: return Hexagon::fixup_Hexagon_DTPREL_LO16; - default: + case MCSymbolRefExpr::VK_None: return Hexagon::fixup_Hexagon_LO16; + default: + raise_relocation_error(0, kind); } // The only relocs left should be GP relative: default: if (MCID.mayStore() || MCID.mayLoad()) { for (const MCPhysReg *ImpUses = MCID.getImplicitUses(); - ImpUses && *ImpUses; ++ImpUses) { + *ImpUses && *ImpUses; ++ImpUses) { if (*ImpUses != Hexagon::GP) continue; switch (HexagonMCInstrInfo::getAccessSize(MCII, MI)) { @@ -348,14 +371,14 @@ static Hexagon::Fixups getFixupNoBits(MCInstrInfo const &MCII, const MCInst &MI, case HexagonII::MemAccessSize::DoubleWordAccess: return fixup_Hexagon_GPREL16_3; default: - llvm_unreachable("unhandled fixup"); + raise_relocation_error(0, kind); } } - } else - llvm_unreachable("unhandled fixup"); + } + raise_relocation_error(0, kind); } - - return LastTargetFixupKind; + llvm_unreachable("Relocation exit not taken"); +} } namespace llvm { @@ -395,23 +418,19 @@ unsigned HexagonMCCodeEmitter::getExprOpValue(const MCInst &MI, const MCSubtargetInfo &STI) const { - int64_t Res; - - if (ME->evaluateAsAbsolute(Res)) - return Res; - - MCExpr::ExprKind MK = ME->getKind(); - if (MK == MCExpr::Constant) { - return cast(ME)->getValue(); - } - if (MK == MCExpr::Binary) { - getExprOpValue(MI, MO, cast(ME)->getLHS(), Fixups, STI); - getExprOpValue(MI, MO, cast(ME)->getRHS(), Fixups, STI); + auto Wrapper = dyn_cast(ME); + if (Wrapper != nullptr) + ME = Wrapper->getExpr(); + int64_t Value; + if (ME->evaluateAsAbsolute(Value)) + return Value; + assert(ME->getKind() == MCExpr::SymbolRef || ME->getKind() == MCExpr::Binary); + if (ME->getKind() == MCExpr::Binary) { + MCBinaryExpr const *Binary = cast(ME); + getExprOpValue(MI, MO, Binary->getLHS(), Fixups, STI); + getExprOpValue(MI, MO, Binary->getRHS(), Fixups, STI); return 0; } - - assert(MK == MCExpr::SymbolRef); - Hexagon::Fixups FixupKind = Hexagon::Fixups(Hexagon::fixup_Hexagon_TPREL_LO16); const MCSymbolRefExpr *MCSRE = static_cast(ME); @@ -430,275 +449,295 @@ unsigned HexagonMCCodeEmitter::getExprOpValue(const MCInst &MI, switch (bits) { default: - DEBUG(dbgs() << "unrecognized bit count of " << bits << '\n'); - break; - + raise_relocation_error(bits, kind); case 32: switch (kind) { - case llvm::MCSymbolRefExpr::VK_Hexagon_PCREL: - FixupKind = Hexagon::fixup_Hexagon_32_PCREL; - break; - case llvm::MCSymbolRefExpr::VK_GOT: - FixupKind = *Extended ? Hexagon::fixup_Hexagon_GOT_32_6_X - : Hexagon::fixup_Hexagon_GOT_32; - break; - case llvm::MCSymbolRefExpr::VK_GOTOFF: - FixupKind = *Extended ? Hexagon::fixup_Hexagon_GOTREL_32_6_X - : Hexagon::fixup_Hexagon_GOTREL_32; - break; - case llvm::MCSymbolRefExpr::VK_Hexagon_GD_GOT: - FixupKind = *Extended ? Hexagon::fixup_Hexagon_GD_GOT_32_6_X - : Hexagon::fixup_Hexagon_GD_GOT_32; - break; - case llvm::MCSymbolRefExpr::VK_Hexagon_LD_GOT: - FixupKind = *Extended ? Hexagon::fixup_Hexagon_LD_GOT_32_6_X - : Hexagon::fixup_Hexagon_LD_GOT_32; - break; - case llvm::MCSymbolRefExpr::VK_Hexagon_IE: - FixupKind = *Extended ? Hexagon::fixup_Hexagon_IE_32_6_X - : Hexagon::fixup_Hexagon_IE_32; - break; - case llvm::MCSymbolRefExpr::VK_Hexagon_IE_GOT: - FixupKind = *Extended ? Hexagon::fixup_Hexagon_IE_GOT_32_6_X - : Hexagon::fixup_Hexagon_IE_GOT_32; - break; - case llvm::MCSymbolRefExpr::VK_TPREL: - FixupKind = *Extended ? Hexagon::fixup_Hexagon_TPREL_32_6_X - : Hexagon::fixup_Hexagon_TPREL_32; - break; - case llvm::MCSymbolRefExpr::VK_DTPREL: + case MCSymbolRefExpr::VK_PPC_DTPREL: FixupKind = *Extended ? Hexagon::fixup_Hexagon_DTPREL_32_6_X : Hexagon::fixup_Hexagon_DTPREL_32; break; - default: + case MCSymbolRefExpr::VK_GOT: + FixupKind = *Extended ? Hexagon::fixup_Hexagon_GOT_32_6_X + : Hexagon::fixup_Hexagon_GOT_32; + break; + case MCSymbolRefExpr::VK_GOTREL: + FixupKind = *Extended ? Hexagon::fixup_Hexagon_GOTREL_32_6_X + : Hexagon::fixup_Hexagon_GOTREL_32; + break; + case MCSymbolRefExpr::VK_Hexagon_GD_GOT: + FixupKind = *Extended ? Hexagon::fixup_Hexagon_GD_GOT_32_6_X + : Hexagon::fixup_Hexagon_GD_GOT_32; + break; + case MCSymbolRefExpr::VK_Hexagon_IE: + FixupKind = *Extended ? Hexagon::fixup_Hexagon_IE_32_6_X + : Hexagon::fixup_Hexagon_IE_32; + break; + case MCSymbolRefExpr::VK_Hexagon_IE_GOT: + FixupKind = *Extended ? Hexagon::fixup_Hexagon_IE_GOT_32_6_X + : Hexagon::fixup_Hexagon_IE_GOT_32; + break; + case MCSymbolRefExpr::VK_Hexagon_LD_GOT: + FixupKind = *Extended ? Hexagon::fixup_Hexagon_LD_GOT_32_6_X + : Hexagon::fixup_Hexagon_LD_GOT_32; + break; + case MCSymbolRefExpr::VK_Hexagon_PCREL: + FixupKind = Hexagon::fixup_Hexagon_32_PCREL; + break; + case MCSymbolRefExpr::VK_None: FixupKind = *Extended ? Hexagon::fixup_Hexagon_32_6_X : Hexagon::fixup_Hexagon_32; break; + case MCSymbolRefExpr::VK_PPC_TPREL: + FixupKind = *Extended ? Hexagon::fixup_Hexagon_TPREL_32_6_X + : Hexagon::fixup_Hexagon_TPREL_32; + break; + default: + raise_relocation_error(bits, kind); } break; case 22: switch (kind) { - case llvm::MCSymbolRefExpr::VK_Hexagon_GD_PLT: + case MCSymbolRefExpr::VK_Hexagon_GD_PLT: FixupKind = Hexagon::fixup_Hexagon_GD_PLT_B22_PCREL; break; - case llvm::MCSymbolRefExpr::VK_Hexagon_LD_PLT: + case MCSymbolRefExpr::VK_Hexagon_LD_PLT: FixupKind = Hexagon::fixup_Hexagon_LD_PLT_B22_PCREL; break; - default: - if (MCID.isBranch() || MCID.isCall()) { - FixupKind = *Extended ? Hexagon::fixup_Hexagon_B22_PCREL_X - : Hexagon::fixup_Hexagon_B22_PCREL; - } else { - errs() << "unrecognized relocation, bits: " << bits << "\n"; - errs() << "name = " << HexagonMCInstrInfo::getName(MCII, MI) << "\n"; - } + case MCSymbolRefExpr::VK_None: + FixupKind = *Extended ? Hexagon::fixup_Hexagon_B22_PCREL_X + : Hexagon::fixup_Hexagon_B22_PCREL; break; + case MCSymbolRefExpr::VK_PLT: + FixupKind = Hexagon::fixup_Hexagon_PLT_B22_PCREL; + break; + default: + raise_relocation_error(bits, kind); } break; case 16: if (*Extended) { switch (kind) { - default: - FixupKind = Hexagon::fixup_Hexagon_16_X; - break; - case llvm::MCSymbolRefExpr::VK_GOT: - FixupKind = Hexagon::fixup_Hexagon_GOT_16_X; - break; - case llvm::MCSymbolRefExpr::VK_GOTOFF: - FixupKind = Hexagon::fixup_Hexagon_GOTREL_16_X; - break; - case llvm::MCSymbolRefExpr::VK_Hexagon_GD_GOT: - FixupKind = Hexagon::fixup_Hexagon_GD_GOT_16_X; - break; - case llvm::MCSymbolRefExpr::VK_Hexagon_LD_GOT: - FixupKind = Hexagon::fixup_Hexagon_LD_GOT_16_X; - break; - case llvm::MCSymbolRefExpr::VK_Hexagon_IE: - FixupKind = Hexagon::fixup_Hexagon_IE_16_X; - break; - case llvm::MCSymbolRefExpr::VK_Hexagon_IE_GOT: - FixupKind = Hexagon::fixup_Hexagon_IE_GOT_16_X; - break; - case llvm::MCSymbolRefExpr::VK_TPREL: - FixupKind = Hexagon::fixup_Hexagon_TPREL_16_X; - break; - case llvm::MCSymbolRefExpr::VK_DTPREL: + case MCSymbolRefExpr::VK_PPC_DTPREL: FixupKind = Hexagon::fixup_Hexagon_DTPREL_16_X; break; + case MCSymbolRefExpr::VK_GOT: + FixupKind = Hexagon::fixup_Hexagon_GOT_16_X; + break; + case MCSymbolRefExpr::VK_GOTREL: + FixupKind = Hexagon::fixup_Hexagon_GOTREL_16_X; + break; + case MCSymbolRefExpr::VK_Hexagon_GD_GOT: + FixupKind = Hexagon::fixup_Hexagon_GD_GOT_16_X; + break; + case MCSymbolRefExpr::VK_Hexagon_IE: + FixupKind = Hexagon::fixup_Hexagon_IE_16_X; + break; + case MCSymbolRefExpr::VK_Hexagon_IE_GOT: + FixupKind = Hexagon::fixup_Hexagon_IE_GOT_16_X; + break; + case MCSymbolRefExpr::VK_Hexagon_LD_GOT: + FixupKind = Hexagon::fixup_Hexagon_LD_GOT_16_X; + break; + case MCSymbolRefExpr::VK_None: + FixupKind = Hexagon::fixup_Hexagon_16_X; + break; + case MCSymbolRefExpr::VK_PPC_TPREL: + FixupKind = Hexagon::fixup_Hexagon_TPREL_16_X; + break; + default: + raise_relocation_error(bits, kind); } } else switch (kind) { - default: - errs() << "unrecognized relocation, bits " << bits << "\n"; - errs() << "name = " << HexagonMCInstrInfo::getName(MCII, MI) << "\n"; + case MCSymbolRefExpr::VK_PPC_DTPREL: + FixupKind = Hexagon::fixup_Hexagon_DTPREL_16; break; - case llvm::MCSymbolRefExpr::VK_GOTOFF: - if ((MCID.getOpcode() == Hexagon::HI) || - (MCID.getOpcode() == Hexagon::LO_H)) + case MCSymbolRefExpr::VK_GOTREL: + if (MCID.getOpcode() == Hexagon::HI) FixupKind = Hexagon::fixup_Hexagon_GOTREL_HI16; else FixupKind = Hexagon::fixup_Hexagon_GOTREL_LO16; break; - case llvm::MCSymbolRefExpr::VK_Hexagon_GPREL: - FixupKind = Hexagon::fixup_Hexagon_GPREL16_0; - break; - case llvm::MCSymbolRefExpr::VK_Hexagon_LO16: - FixupKind = Hexagon::fixup_Hexagon_LO16; - break; - case llvm::MCSymbolRefExpr::VK_Hexagon_HI16: - FixupKind = Hexagon::fixup_Hexagon_HI16; - break; - case llvm::MCSymbolRefExpr::VK_Hexagon_GD_GOT: + case MCSymbolRefExpr::VK_Hexagon_GD_GOT: FixupKind = Hexagon::fixup_Hexagon_GD_GOT_16; break; - case llvm::MCSymbolRefExpr::VK_Hexagon_LD_GOT: - FixupKind = Hexagon::fixup_Hexagon_LD_GOT_16; + case MCSymbolRefExpr::VK_Hexagon_GPREL: + FixupKind = Hexagon::fixup_Hexagon_GPREL16_0; break; - case llvm::MCSymbolRefExpr::VK_Hexagon_IE_GOT: + case MCSymbolRefExpr::VK_Hexagon_HI16: + FixupKind = Hexagon::fixup_Hexagon_HI16; + break; + case MCSymbolRefExpr::VK_Hexagon_IE_GOT: FixupKind = Hexagon::fixup_Hexagon_IE_GOT_16; break; - case llvm::MCSymbolRefExpr::VK_TPREL: + case MCSymbolRefExpr::VK_Hexagon_LD_GOT: + FixupKind = Hexagon::fixup_Hexagon_LD_GOT_16; + break; + case MCSymbolRefExpr::VK_Hexagon_LO16: + FixupKind = Hexagon::fixup_Hexagon_LO16; + break; + case MCSymbolRefExpr::VK_PPC_TPREL: FixupKind = Hexagon::fixup_Hexagon_TPREL_16; break; - case llvm::MCSymbolRefExpr::VK_DTPREL: - FixupKind = Hexagon::fixup_Hexagon_DTPREL_16; - break; + default: + raise_relocation_error(bits, kind); } break; case 15: - if (MCID.isBranch() || MCID.isCall()) + switch (kind) { + case MCSymbolRefExpr::VK_None: FixupKind = *Extended ? Hexagon::fixup_Hexagon_B15_PCREL_X : Hexagon::fixup_Hexagon_B15_PCREL; + break; + default: + raise_relocation_error(bits, kind); + } break; case 13: - if (MCID.isBranch()) + switch (kind) { + case MCSymbolRefExpr::VK_None: FixupKind = Hexagon::fixup_Hexagon_B13_PCREL; - else { - errs() << "unrecognized relocation, bits " << bits << "\n"; - errs() << "name = " << HexagonMCInstrInfo::getName(MCII, MI) << "\n"; + break; + default: + raise_relocation_error(bits, kind); } break; case 12: if (*Extended) switch (kind) { - default: - FixupKind = Hexagon::fixup_Hexagon_12_X; - break; // There isn't a GOT_12_X, both 11_X and 16_X resolve to 6/26 - case llvm::MCSymbolRefExpr::VK_GOT: + case MCSymbolRefExpr::VK_GOT: FixupKind = Hexagon::fixup_Hexagon_GOT_16_X; break; - case llvm::MCSymbolRefExpr::VK_GOTOFF: + case MCSymbolRefExpr::VK_GOTREL: FixupKind = Hexagon::fixup_Hexagon_GOTREL_16_X; break; + case MCSymbolRefExpr::VK_None: + FixupKind = Hexagon::fixup_Hexagon_12_X; + break; + default: + raise_relocation_error(bits, kind); } - else { - errs() << "unrecognized relocation, bits " << bits << "\n"; - errs() << "name = " << HexagonMCInstrInfo::getName(MCII, MI) << "\n"; - } + else + raise_relocation_error(bits, kind); break; case 11: if (*Extended) switch (kind) { - default: - FixupKind = Hexagon::fixup_Hexagon_11_X; - break; - case llvm::MCSymbolRefExpr::VK_GOT: - FixupKind = Hexagon::fixup_Hexagon_GOT_11_X; - break; - case llvm::MCSymbolRefExpr::VK_GOTOFF: - FixupKind = Hexagon::fixup_Hexagon_GOTREL_11_X; - break; - case llvm::MCSymbolRefExpr::VK_Hexagon_GD_GOT: - FixupKind = Hexagon::fixup_Hexagon_GD_GOT_11_X; - break; - case llvm::MCSymbolRefExpr::VK_Hexagon_LD_GOT: - FixupKind = Hexagon::fixup_Hexagon_LD_GOT_11_X; - break; - case llvm::MCSymbolRefExpr::VK_Hexagon_IE_GOT: - FixupKind = Hexagon::fixup_Hexagon_IE_GOT_11_X; - break; - case llvm::MCSymbolRefExpr::VK_TPREL: - FixupKind = Hexagon::fixup_Hexagon_TPREL_11_X; - break; - case llvm::MCSymbolRefExpr::VK_DTPREL: + case MCSymbolRefExpr::VK_PPC_DTPREL: FixupKind = Hexagon::fixup_Hexagon_DTPREL_11_X; break; + case MCSymbolRefExpr::VK_GOT: + FixupKind = Hexagon::fixup_Hexagon_GOT_11_X; + break; + case MCSymbolRefExpr::VK_GOTREL: + FixupKind = Hexagon::fixup_Hexagon_GOTREL_11_X; + break; + case MCSymbolRefExpr::VK_Hexagon_GD_GOT: + FixupKind = Hexagon::fixup_Hexagon_GD_GOT_11_X; + break; + case MCSymbolRefExpr::VK_Hexagon_IE_GOT: + FixupKind = Hexagon::fixup_Hexagon_IE_GOT_11_X; + break; + case MCSymbolRefExpr::VK_Hexagon_LD_GOT: + FixupKind = Hexagon::fixup_Hexagon_LD_GOT_11_X; + break; + case MCSymbolRefExpr::VK_None: + FixupKind = Hexagon::fixup_Hexagon_11_X; + break; + case MCSymbolRefExpr::VK_PPC_TPREL: + FixupKind = Hexagon::fixup_Hexagon_TPREL_11_X; + break; + default: + raise_relocation_error(bits, kind); } else { - errs() << "unrecognized relocation, bits " << bits << "\n"; - errs() << "name = " << HexagonMCInstrInfo::getName(MCII, MI) << "\n"; + switch (kind) { + case MCSymbolRefExpr::VK_PPC_TPREL: + FixupKind = Hexagon::fixup_Hexagon_TPREL_11_X; + break; + default: + raise_relocation_error(bits, kind); + } } break; case 10: - if (*Extended) - FixupKind = Hexagon::fixup_Hexagon_10_X; + if (*Extended) { + switch (kind) { + case MCSymbolRefExpr::VK_None: + FixupKind = Hexagon::fixup_Hexagon_10_X; + break; + default: + raise_relocation_error(bits, kind); + } + } else + raise_relocation_error(bits, kind); break; case 9: if (MCID.isBranch() || - (llvm::HexagonMCInstrInfo::getType(MCII, MI) == HexagonII::TypeCR)) + (HexagonMCInstrInfo::getType(MCII, MI) == HexagonII::TypeCR)) FixupKind = *Extended ? Hexagon::fixup_Hexagon_B9_PCREL_X : Hexagon::fixup_Hexagon_B9_PCREL; else if (*Extended) FixupKind = Hexagon::fixup_Hexagon_9_X; - else { - errs() << "unrecognized relocation, bits " << bits << "\n"; - errs() << "name = " << HexagonMCInstrInfo::getName(MCII, MI) << "\n"; - } + else + raise_relocation_error(bits, kind); break; case 8: if (*Extended) FixupKind = Hexagon::fixup_Hexagon_8_X; - else { - errs() << "unrecognized relocation, bits " << bits << "\n"; - errs() << "name = " << HexagonMCInstrInfo::getName(MCII, MI) << "\n"; - } + else + raise_relocation_error(bits, kind); break; case 7: if (MCID.isBranch() || - (llvm::HexagonMCInstrInfo::getType(MCII, MI) == HexagonII::TypeCR)) + (HexagonMCInstrInfo::getType(MCII, MI) == HexagonII::TypeCR)) FixupKind = *Extended ? Hexagon::fixup_Hexagon_B7_PCREL_X : Hexagon::fixup_Hexagon_B7_PCREL; else if (*Extended) FixupKind = Hexagon::fixup_Hexagon_7_X; - else { - errs() << "unrecognized relocation, bits " << bits << "\n"; - errs() << "name = " << HexagonMCInstrInfo::getName(MCII, MI) << "\n"; - } + else + raise_relocation_error(bits, kind); break; case 6: if (*Extended) { switch (kind) { - default: - FixupKind = Hexagon::fixup_Hexagon_6_X; - break; - case llvm::MCSymbolRefExpr::VK_Hexagon_PCREL: - FixupKind = Hexagon::fixup_Hexagon_6_PCREL_X; + case MCSymbolRefExpr::VK_PPC_DTPREL: + FixupKind = Hexagon::fixup_Hexagon_DTPREL_16_X; break; // This is part of an extender, GOT_11 is a // Word32_U6 unsigned/truncated reloc. - case llvm::MCSymbolRefExpr::VK_GOT: + case MCSymbolRefExpr::VK_GOT: FixupKind = Hexagon::fixup_Hexagon_GOT_11_X; break; - case llvm::MCSymbolRefExpr::VK_GOTOFF: + case MCSymbolRefExpr::VK_GOTREL: FixupKind = Hexagon::fixup_Hexagon_GOTREL_11_X; break; + case MCSymbolRefExpr::VK_Hexagon_PCREL: + FixupKind = Hexagon::fixup_Hexagon_6_PCREL_X; + break; + case MCSymbolRefExpr::VK_PPC_TPREL: + FixupKind = Hexagon::fixup_Hexagon_TPREL_16_X; + break; + case MCSymbolRefExpr::VK_None: + FixupKind = Hexagon::fixup_Hexagon_6_X; + break; + default: + raise_relocation_error(bits, kind); } - } else { - errs() << "unrecognized relocation, bits " << bits << "\n"; - errs() << "name = " << HexagonMCInstrInfo::getName(MCII, MI) << "\n"; - } + } else + raise_relocation_error(bits, kind); break; case 0: @@ -706,16 +745,17 @@ unsigned HexagonMCCodeEmitter::getExprOpValue(const MCInst &MI, break; } - MCExpr const *FixupExpression = (*Addend > 0 && isPCRel(FixupKind)) ? - MCBinaryExpr::createAdd(MO.getExpr(), - MCConstantExpr::create(*Addend, MCT), MCT) : - MO.getExpr(); + MCExpr const *FixupExpression = + (*Addend > 0 && isPCRel(FixupKind)) + ? MCBinaryExpr::createAdd(MO.getExpr(), + MCConstantExpr::create(*Addend, MCT), MCT) + : MO.getExpr(); - MCFixup fixup = MCFixup::create(*Addend, FixupExpression, + MCFixup fixup = MCFixup::create(*Addend, FixupExpression, MCFixupKind(FixupKind), MI.getLoc()); Fixups.push_back(fixup); // All of the information is in the fixup. - return (0); + return 0; } unsigned diff --git a/test/MC/Hexagon/relocations.s b/test/MC/Hexagon/relocations.s new file mode 100644 index 00000000000..8b90bc7c0cd --- /dev/null +++ b/test/MC/Hexagon/relocations.s @@ -0,0 +1,244 @@ +# RUN: llvm-mc -filetype=obj -triple=hexagon %s | llvm-objdump -r - | FileCheck %s + +# CHECK: R_HEX_B22_PCREL +r_hex_b22_pcrel: +{ jump #undefined } + +# CHECK: R_HEX_B15_PCREL +r_hex_b15_pcrel: +{ if (p0) jump #undefined } + +# CHECK: R_HEX_B7_PCREL +r_hex_b7_pcrel: +{ loop1 (#undefined, #0) } + +# CHECK: R_HEX_32 +r_hex_32: +.word undefined + +# CHECK: R_HEX_16 +r_hex_16: +.half undefined +.half 0 + +# CHECK: R_HEX_8 +r_hex_8: +.byte undefined +.byte 0 +.byte 0 +.byte 0 + +# CHECK: R_HEX_GPREL16_0 +r_hex_gprel16_0: +{ r0 = memb (#undefined@gotrel) } + +# CHECK: R_HEX_GPREL16_1 +r_hex_gprel16_1: +{ r0 = memh (#undefined@gotrel) } + +# CHECK: R_HEX_GPREL16_2 +r_hex_gprel16_2: +{ r0 = memw (#undefined@gotrel) } + +# CHECK: R_HEX_GPREL16_3 +r_hex_gprel16_3: +{ r1:0 = memd (#undefined@gotrel) } + +# CHECK: R_HEX_B13_PCREL +r_hex_b13_pcrel: +{ if (r0 != #0) jump:nt #undefined } + +# CHECK: R_HEX_B9_PCREL +r_hex_b9_pcrel: +{ r0 = #0 ; jump #undefined } + +# CHECK: R_HEX_B32_PCREL_X +r_hex_b32_pcrel_x: +{ jump ##undefined } + +# CHECK: R_HEX_32_6_X +r_hex_32_6_x: +{ r0 = ##undefined } + +# CHECK: R_HEX_B22_PCREL_X +r_hex_b22_pcrel_x: +{ jump ##undefined } + +# CHECK: R_HEX_B15_PCREL_X +r_hex_b15_pcrel_x: +{ if (p0) jump ##undefined } + +# CHECK: R_HEX_B9_PCREL_X +r_hex_b9_pcrel_x: +{ r0 = #0 ; jump ##undefined } + +# CHECK: R_HEX_B7_PCREL_X +r_hex_b7_pcrel_x: +{ loop1 (##undefined, #0) } + +# CHECK: R_HEX_32_PCREL +r_hex_32_pcrel: +.word undefined@pcrel + +# CHECK: R_HEX_PLT_B22_PCREL +r_hex_plt_b22_pcrel: +jump undefined@plt + +# CHECK: R_HEX_GOTREL_32 +r_hex_gotrel_32: +.word undefined@gotrel + +# CHECK: R_HEX_GOT_32 +r_hex_got_32: +.word undefined@got + +# CHECK: R_HEX_GOT_16 +r_hex_got_16: +.half undefined@got +.half 0 + +# CHECK: R_HEX_DTPREL_32 +r_hex_dtprel_32: +.word undefined@dtprel + +# CHECK: R_HEX_DTPREL_16 +r_hex_dtprel_16: +.half undefined@dtprel +.half 0 + +# CHECK: R_HEX_GD_GOT_32 +r_hex_gd_got_32: +.word undefined@gdgot + +# CHECK: R_HEX_GD_GOT_16 +r_hex_gd_got_16: +.half undefined@gdgot +.half 0 + +# CHECK: R_HEX_IE_32 +r_hex_ie_32: +.word undefined@ie + +# CHECK: R_HEX_IE_GOT_32 +r_hex_ie_got_32: +.word undefined@iegot + +# CHECK: R_HEX_IE_GOT_16 +r_hex_ie_got_16: +.half undefined@iegot +.half 0 + +# CHECK: R_HEX_TPREL_32 +r_hex_tprel_32: +.word undefined@tprel + +# CHECK: R_HEX_TPREL_16 +r_hex_tprel_16: +r0 = #undefined@tprel + +# CHECK: R_HEX_6_PCREL_X +r_hex_6_pcrel_x: +{ r0 = ##undefined@pcrel + r1 = r1 } + +# CHECK: R_HEX_GOTREL_32_6_X +r_hex_gotrel_32_6_x: +{ r0 = ##undefined@gotrel } + +# CHECK: R_HEX_GOTREL_16_X +r_hex_gotrel_16_x: +{ r0 = ##undefined@gotrel } + +# CHECK: R_HEX_GOTREL_11_X +r_hex_gotrel_11_x: +{ r0 = memw(r0 + ##undefined@gotrel) } + +# CHECK: R_HEX_GOT_32_6_X +r_hex_got_32_6_x: +{ r0 = ##undefined@got } + +# CHECK: R_HEX_GOT_16_X +r_hex_got_16_x: +{ r0 = ##undefined@got } + +# CHECK: R_HEX_GOT_11_X +r_hex_got_11_x: +{ r0 = memw(r0 + ##undefined@got) } + +# CHECK: R_HEX_DTPREL_32_6_X +r_hex_dtprel_32_6_x: +{ r0 = ##undefined@dtprel } + +# CHECK: R_HEX_DTPREL_16_X +r_hex_dtprel_16_x: +{ r0 = ##undefined@dtprel } + +# CHECK: R_HEX_DTPREL_11_X +r_hex_dtprel_11_x: +{ r0 = memw(r0 + ##undefined@dtprel) } + +# CHECK: R_HEX_GD_GOT_32_6_X +r_hex_gd_got_32_6_x: +{ r0 = ##undefined@gdgot } + +# CHECK: R_HEX_GD_GOT_16_X +r_hex_gd_got_16_x: +{ r0 = ##undefined@gdgot } + +# CHECK: R_HEX_GD_GOT_11_X +r_hex_gd_got_11_x: +{ r0 = memw(r0 + ##undefined@gdgot) } + +# CHECK: R_HEX_IE_32_6_X +r_hex_ie_32_6_x: +{ r0 = ##undefined@ie } + +# CHECK: R_HEX_IE_16_X +r_hex_ie_16_x: +{ r0 = ##undefined@ie } + +# CHECK: R_HEX_IE_GOT_32_6_X +r_hex_ie_got_32_6_x: +{ r0 = ##undefined@iegot } + +# CHECK: R_HEX_IE_GOT_16_X +r_hex_ie_got_16_x: +{ r0 = ##undefined@iegot } + +# CHECK: R_HEX_IE_GOT_11_X +r_hex_ie_got_11_x: +{ r0 = memw(r0 + ##undefined@iegot) } + +# CHECK: R_HEX_TPREL_32_6_X +r_hex_tprel_32_6_x: +{ r0 = ##undefined@tprel } + +# CHECK: R_HEX_TPREL_16_X +r_hex_tprel_16_x: +{ r0 = ##undefined@tprel } + +# CHECK: R_HEX_TPREL_11_X +r_hex_tprel_11_x: +{ r0 = memw(r0 + ##undefined@tprel) } + +# CHECK: R_HEX_LD_GOT_32 +r_hex_ld_got_32: +.word undefined@ldgot + +# CHECK: R_HEX_LD_GOT_16 +r_hex_ld_got_16: +.half undefined@ldgot +.half 0 + +# CHECK: R_HEX_LD_GOT_32_6_X +r_hex_ld_got_32_6_x: +{ r0 = ##undefined@ldgot } + +# CHECK: R_HEX_LD_GOT_16_X +r_hex_ld_got_16_x: +{ r0 = ##undefined@ldgot } + +# CHECK: R_HEX_LD_GOT_11_X +r_hex_ld_got_11_x: +{ r0 = memw(r0 + ##undefined@ldgot) } +