1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 19:52:54 +01:00

[Hexagon] Fixing relocation generation and adding tests.

llvm-svn: 260259
This commit is contained in:
Colin LeMahieu 2016-02-09 19:18:02 +00:00
parent 270ce6c950
commit 7d2b0f70e8
3 changed files with 546 additions and 221 deletions

View File

@ -11,6 +11,7 @@
#include "MCTargetDesc/HexagonFixupKinds.h" #include "MCTargetDesc/HexagonFixupKinds.h"
#include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCELFObjectWriter.h" #include "llvm/MC/MCELFObjectWriter.h"
#include "llvm/MC/MCValue.h"
#include "llvm/Support/Debug.h" #include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
@ -39,20 +40,60 @@ HexagonELFObjectWriter::HexagonELFObjectWriter(uint8_t OSABI, StringRef C)
CPU(C) {} CPU(C) {}
unsigned HexagonELFObjectWriter::getRelocType(MCContext &Ctx, unsigned HexagonELFObjectWriter::getRelocType(MCContext &Ctx,
MCValue const & /*Target*/, MCValue const &Target,
MCFixup const &Fixup, MCFixup const &Fixup,
bool IsPCRel) const { bool IsPCRel) const {
MCSymbolRefExpr::VariantKind Variant = Target.getAccessVariant();
switch ((unsigned)Fixup.getKind()) { switch ((unsigned)Fixup.getKind()) {
default: default:
DEBUG(dbgs() << "unrecognized relocation " << Fixup.getKind() << "\n"); report_fatal_error("Unrecognized relocation type");
llvm_unreachable("Unimplemented Fixup kind!"); break;
return ELF::R_HEX_NONE;
case FK_Data_4: 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: case FK_PCRel_4:
return ELF::R_HEX_32_PCREL; return ELF::R_HEX_32_PCREL;
case FK_Data_2: 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: case FK_Data_1:
return ELF::R_HEX_8; return ELF::R_HEX_8;
case fixup_Hexagon_B22_PCREL: case fixup_Hexagon_B22_PCREL:

View File

@ -251,7 +251,23 @@ void HexagonMCCodeEmitter::EncodeSingleInstruction(
++MCNumEmitted; ++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 MCOperand &MO,
const MCSymbolRefExpr::VariantKind kind) { const MCSymbolRefExpr::VariantKind kind) {
const MCInstrDesc &MCID = HexagonMCInstrInfo::getDesc(MCII, MI); 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) { if (insnType == HexagonII::TypePREFIX) {
switch (kind) { switch (kind) {
case llvm::MCSymbolRefExpr::VK_GOTOFF: case MCSymbolRefExpr::VK_GOTREL:
return Hexagon::fixup_Hexagon_GOTREL_32_6_X; 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; 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; 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; 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; 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; 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; 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; return Hexagon::fixup_Hexagon_IE_GOT_32_6_X;
default: case MCSymbolRefExpr::VK_Hexagon_PCREL:
case MCSymbolRefExpr::VK_None:
if (MCID.isBranch()) if (MCID.isBranch())
return Hexagon::fixup_Hexagon_B32_PCREL_X; return Hexagon::fixup_Hexagon_B32_PCREL_X;
else else
return Hexagon::fixup_Hexagon_32_6_X; return Hexagon::fixup_Hexagon_32_6_X;
default:
raise_relocation_error(0, kind);
} }
} else if (MCID.isBranch()) } else if (MCID.isBranch())
return (Hexagon::fixup_Hexagon_B13_PCREL); return Hexagon::fixup_Hexagon_B13_PCREL;
switch (MCID.getOpcode()) { switch (MCID.getOpcode()) {
case Hexagon::HI: case Hexagon::HI:
case Hexagon::A2_tfrih: case Hexagon::A2_tfrih:
switch (kind) { switch (kind) {
case llvm::MCSymbolRefExpr::VK_GOT: case MCSymbolRefExpr::VK_GOT:
return Hexagon::fixup_Hexagon_GOT_HI16; return Hexagon::fixup_Hexagon_GOT_HI16;
case llvm::MCSymbolRefExpr::VK_GOTOFF: case MCSymbolRefExpr::VK_GOTREL:
return Hexagon::fixup_Hexagon_GOTREL_HI16; 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; 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; return Hexagon::fixup_Hexagon_LD_GOT_HI16;
case llvm::MCSymbolRefExpr::VK_Hexagon_IE: case MCSymbolRefExpr::VK_Hexagon_IE:
return Hexagon::fixup_Hexagon_IE_HI16; 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; return Hexagon::fixup_Hexagon_IE_GOT_HI16;
case llvm::MCSymbolRefExpr::VK_TPREL: case MCSymbolRefExpr::VK_PPC_TPREL:
return Hexagon::fixup_Hexagon_TPREL_HI16; return Hexagon::fixup_Hexagon_TPREL_HI16;
case llvm::MCSymbolRefExpr::VK_DTPREL: case MCSymbolRefExpr::VK_PPC_DTPREL:
return Hexagon::fixup_Hexagon_DTPREL_HI16; return Hexagon::fixup_Hexagon_DTPREL_HI16;
default: case MCSymbolRefExpr::VK_None:
return Hexagon::fixup_Hexagon_HI16; return Hexagon::fixup_Hexagon_HI16;
default:
raise_relocation_error(0, kind);
} }
case Hexagon::LO: case Hexagon::LO:
case Hexagon::A2_tfril: case Hexagon::A2_tfril:
switch (kind) { switch (kind) {
case llvm::MCSymbolRefExpr::VK_GOT: case MCSymbolRefExpr::VK_GOT:
return Hexagon::fixup_Hexagon_GOT_LO16; return Hexagon::fixup_Hexagon_GOT_LO16;
case llvm::MCSymbolRefExpr::VK_GOTOFF: case MCSymbolRefExpr::VK_GOTREL:
return Hexagon::fixup_Hexagon_GOTREL_LO16; 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; 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; return Hexagon::fixup_Hexagon_LD_GOT_LO16;
case llvm::MCSymbolRefExpr::VK_Hexagon_IE: case MCSymbolRefExpr::VK_Hexagon_IE:
return Hexagon::fixup_Hexagon_IE_LO16; 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; return Hexagon::fixup_Hexagon_IE_GOT_LO16;
case llvm::MCSymbolRefExpr::VK_TPREL: case MCSymbolRefExpr::VK_PPC_TPREL:
return Hexagon::fixup_Hexagon_TPREL_LO16; return Hexagon::fixup_Hexagon_TPREL_LO16;
case llvm::MCSymbolRefExpr::VK_DTPREL: case MCSymbolRefExpr::VK_PPC_DTPREL:
return Hexagon::fixup_Hexagon_DTPREL_LO16; return Hexagon::fixup_Hexagon_DTPREL_LO16;
default: case MCSymbolRefExpr::VK_None:
return Hexagon::fixup_Hexagon_LO16; return Hexagon::fixup_Hexagon_LO16;
default:
raise_relocation_error(0, kind);
} }
// The only relocs left should be GP relative: // The only relocs left should be GP relative:
default: default:
if (MCID.mayStore() || MCID.mayLoad()) { if (MCID.mayStore() || MCID.mayLoad()) {
for (const MCPhysReg *ImpUses = MCID.getImplicitUses(); for (const MCPhysReg *ImpUses = MCID.getImplicitUses();
ImpUses && *ImpUses; ++ImpUses) { *ImpUses && *ImpUses; ++ImpUses) {
if (*ImpUses != Hexagon::GP) if (*ImpUses != Hexagon::GP)
continue; continue;
switch (HexagonMCInstrInfo::getAccessSize(MCII, MI)) { switch (HexagonMCInstrInfo::getAccessSize(MCII, MI)) {
@ -348,14 +371,14 @@ static Hexagon::Fixups getFixupNoBits(MCInstrInfo const &MCII, const MCInst &MI,
case HexagonII::MemAccessSize::DoubleWordAccess: case HexagonII::MemAccessSize::DoubleWordAccess:
return fixup_Hexagon_GPREL16_3; return fixup_Hexagon_GPREL16_3;
default: default:
llvm_unreachable("unhandled fixup"); raise_relocation_error(0, kind);
} }
} }
} else }
llvm_unreachable("unhandled fixup"); raise_relocation_error(0, kind);
} }
llvm_unreachable("Relocation exit not taken");
return LastTargetFixupKind; }
} }
namespace llvm { namespace llvm {
@ -395,23 +418,19 @@ unsigned HexagonMCCodeEmitter::getExprOpValue(const MCInst &MI,
const MCSubtargetInfo &STI) const const MCSubtargetInfo &STI) const
{ {
int64_t Res; auto Wrapper = dyn_cast<HexagonNoExtendOperand>(ME);
if (Wrapper != nullptr)
if (ME->evaluateAsAbsolute(Res)) ME = Wrapper->getExpr();
return Res; int64_t Value;
if (ME->evaluateAsAbsolute(Value))
MCExpr::ExprKind MK = ME->getKind(); return Value;
if (MK == MCExpr::Constant) { assert(ME->getKind() == MCExpr::SymbolRef || ME->getKind() == MCExpr::Binary);
return cast<MCConstantExpr>(ME)->getValue(); if (ME->getKind() == MCExpr::Binary) {
} MCBinaryExpr const *Binary = cast<MCBinaryExpr>(ME);
if (MK == MCExpr::Binary) { getExprOpValue(MI, MO, Binary->getLHS(), Fixups, STI);
getExprOpValue(MI, MO, cast<MCBinaryExpr>(ME)->getLHS(), Fixups, STI); getExprOpValue(MI, MO, Binary->getRHS(), Fixups, STI);
getExprOpValue(MI, MO, cast<MCBinaryExpr>(ME)->getRHS(), Fixups, STI);
return 0; return 0;
} }
assert(MK == MCExpr::SymbolRef);
Hexagon::Fixups FixupKind = Hexagon::Fixups FixupKind =
Hexagon::Fixups(Hexagon::fixup_Hexagon_TPREL_LO16); Hexagon::Fixups(Hexagon::fixup_Hexagon_TPREL_LO16);
const MCSymbolRefExpr *MCSRE = static_cast<const MCSymbolRefExpr *>(ME); const MCSymbolRefExpr *MCSRE = static_cast<const MCSymbolRefExpr *>(ME);
@ -430,275 +449,295 @@ unsigned HexagonMCCodeEmitter::getExprOpValue(const MCInst &MI,
switch (bits) { switch (bits) {
default: default:
DEBUG(dbgs() << "unrecognized bit count of " << bits << '\n'); raise_relocation_error(bits, kind);
break;
case 32: case 32:
switch (kind) { switch (kind) {
case llvm::MCSymbolRefExpr::VK_Hexagon_PCREL: case MCSymbolRefExpr::VK_PPC_DTPREL:
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:
FixupKind = *Extended ? Hexagon::fixup_Hexagon_DTPREL_32_6_X FixupKind = *Extended ? Hexagon::fixup_Hexagon_DTPREL_32_6_X
: Hexagon::fixup_Hexagon_DTPREL_32; : Hexagon::fixup_Hexagon_DTPREL_32;
break; 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 = FixupKind =
*Extended ? Hexagon::fixup_Hexagon_32_6_X : Hexagon::fixup_Hexagon_32; *Extended ? Hexagon::fixup_Hexagon_32_6_X : Hexagon::fixup_Hexagon_32;
break; 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; break;
case 22: case 22:
switch (kind) { switch (kind) {
case llvm::MCSymbolRefExpr::VK_Hexagon_GD_PLT: case MCSymbolRefExpr::VK_Hexagon_GD_PLT:
FixupKind = Hexagon::fixup_Hexagon_GD_PLT_B22_PCREL; FixupKind = Hexagon::fixup_Hexagon_GD_PLT_B22_PCREL;
break; break;
case llvm::MCSymbolRefExpr::VK_Hexagon_LD_PLT: case MCSymbolRefExpr::VK_Hexagon_LD_PLT:
FixupKind = Hexagon::fixup_Hexagon_LD_PLT_B22_PCREL; FixupKind = Hexagon::fixup_Hexagon_LD_PLT_B22_PCREL;
break; break;
default: case MCSymbolRefExpr::VK_None:
if (MCID.isBranch() || MCID.isCall()) { FixupKind = *Extended ? Hexagon::fixup_Hexagon_B22_PCREL_X
FixupKind = *Extended ? Hexagon::fixup_Hexagon_B22_PCREL_X : Hexagon::fixup_Hexagon_B22_PCREL;
: Hexagon::fixup_Hexagon_B22_PCREL;
} else {
errs() << "unrecognized relocation, bits: " << bits << "\n";
errs() << "name = " << HexagonMCInstrInfo::getName(MCII, MI) << "\n";
}
break; break;
case MCSymbolRefExpr::VK_PLT:
FixupKind = Hexagon::fixup_Hexagon_PLT_B22_PCREL;
break;
default:
raise_relocation_error(bits, kind);
} }
break; break;
case 16: case 16:
if (*Extended) { if (*Extended) {
switch (kind) { switch (kind) {
default: case MCSymbolRefExpr::VK_PPC_DTPREL:
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:
FixupKind = Hexagon::fixup_Hexagon_DTPREL_16_X; FixupKind = Hexagon::fixup_Hexagon_DTPREL_16_X;
break; 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 } else
switch (kind) { switch (kind) {
default: case MCSymbolRefExpr::VK_PPC_DTPREL:
errs() << "unrecognized relocation, bits " << bits << "\n"; FixupKind = Hexagon::fixup_Hexagon_DTPREL_16;
errs() << "name = " << HexagonMCInstrInfo::getName(MCII, MI) << "\n";
break; break;
case llvm::MCSymbolRefExpr::VK_GOTOFF: case MCSymbolRefExpr::VK_GOTREL:
if ((MCID.getOpcode() == Hexagon::HI) || if (MCID.getOpcode() == Hexagon::HI)
(MCID.getOpcode() == Hexagon::LO_H))
FixupKind = Hexagon::fixup_Hexagon_GOTREL_HI16; FixupKind = Hexagon::fixup_Hexagon_GOTREL_HI16;
else else
FixupKind = Hexagon::fixup_Hexagon_GOTREL_LO16; FixupKind = Hexagon::fixup_Hexagon_GOTREL_LO16;
break; break;
case llvm::MCSymbolRefExpr::VK_Hexagon_GPREL: case MCSymbolRefExpr::VK_Hexagon_GD_GOT:
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:
FixupKind = Hexagon::fixup_Hexagon_GD_GOT_16; FixupKind = Hexagon::fixup_Hexagon_GD_GOT_16;
break; break;
case llvm::MCSymbolRefExpr::VK_Hexagon_LD_GOT: case MCSymbolRefExpr::VK_Hexagon_GPREL:
FixupKind = Hexagon::fixup_Hexagon_LD_GOT_16; FixupKind = Hexagon::fixup_Hexagon_GPREL16_0;
break; 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; FixupKind = Hexagon::fixup_Hexagon_IE_GOT_16;
break; 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; FixupKind = Hexagon::fixup_Hexagon_TPREL_16;
break; break;
case llvm::MCSymbolRefExpr::VK_DTPREL: default:
FixupKind = Hexagon::fixup_Hexagon_DTPREL_16; raise_relocation_error(bits, kind);
break;
} }
break; break;
case 15: case 15:
if (MCID.isBranch() || MCID.isCall()) switch (kind) {
case MCSymbolRefExpr::VK_None:
FixupKind = *Extended ? Hexagon::fixup_Hexagon_B15_PCREL_X FixupKind = *Extended ? Hexagon::fixup_Hexagon_B15_PCREL_X
: Hexagon::fixup_Hexagon_B15_PCREL; : Hexagon::fixup_Hexagon_B15_PCREL;
break;
default:
raise_relocation_error(bits, kind);
}
break; break;
case 13: case 13:
if (MCID.isBranch()) switch (kind) {
case MCSymbolRefExpr::VK_None:
FixupKind = Hexagon::fixup_Hexagon_B13_PCREL; FixupKind = Hexagon::fixup_Hexagon_B13_PCREL;
else { break;
errs() << "unrecognized relocation, bits " << bits << "\n"; default:
errs() << "name = " << HexagonMCInstrInfo::getName(MCII, MI) << "\n"; raise_relocation_error(bits, kind);
} }
break; break;
case 12: case 12:
if (*Extended) if (*Extended)
switch (kind) { 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 // 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; FixupKind = Hexagon::fixup_Hexagon_GOT_16_X;
break; break;
case llvm::MCSymbolRefExpr::VK_GOTOFF: case MCSymbolRefExpr::VK_GOTREL:
FixupKind = Hexagon::fixup_Hexagon_GOTREL_16_X; FixupKind = Hexagon::fixup_Hexagon_GOTREL_16_X;
break; break;
case MCSymbolRefExpr::VK_None:
FixupKind = Hexagon::fixup_Hexagon_12_X;
break;
default:
raise_relocation_error(bits, kind);
} }
else { else
errs() << "unrecognized relocation, bits " << bits << "\n"; raise_relocation_error(bits, kind);
errs() << "name = " << HexagonMCInstrInfo::getName(MCII, MI) << "\n";
}
break; break;
case 11: case 11:
if (*Extended) if (*Extended)
switch (kind) { switch (kind) {
default: case MCSymbolRefExpr::VK_PPC_DTPREL:
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:
FixupKind = Hexagon::fixup_Hexagon_DTPREL_11_X; FixupKind = Hexagon::fixup_Hexagon_DTPREL_11_X;
break; 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 { else {
errs() << "unrecognized relocation, bits " << bits << "\n"; switch (kind) {
errs() << "name = " << HexagonMCInstrInfo::getName(MCII, MI) << "\n"; case MCSymbolRefExpr::VK_PPC_TPREL:
FixupKind = Hexagon::fixup_Hexagon_TPREL_11_X;
break;
default:
raise_relocation_error(bits, kind);
}
} }
break; break;
case 10: case 10:
if (*Extended) if (*Extended) {
FixupKind = Hexagon::fixup_Hexagon_10_X; 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; break;
case 9: case 9:
if (MCID.isBranch() || if (MCID.isBranch() ||
(llvm::HexagonMCInstrInfo::getType(MCII, MI) == HexagonII::TypeCR)) (HexagonMCInstrInfo::getType(MCII, MI) == HexagonII::TypeCR))
FixupKind = *Extended ? Hexagon::fixup_Hexagon_B9_PCREL_X FixupKind = *Extended ? Hexagon::fixup_Hexagon_B9_PCREL_X
: Hexagon::fixup_Hexagon_B9_PCREL; : Hexagon::fixup_Hexagon_B9_PCREL;
else if (*Extended) else if (*Extended)
FixupKind = Hexagon::fixup_Hexagon_9_X; FixupKind = Hexagon::fixup_Hexagon_9_X;
else { else
errs() << "unrecognized relocation, bits " << bits << "\n"; raise_relocation_error(bits, kind);
errs() << "name = " << HexagonMCInstrInfo::getName(MCII, MI) << "\n";
}
break; break;
case 8: case 8:
if (*Extended) if (*Extended)
FixupKind = Hexagon::fixup_Hexagon_8_X; FixupKind = Hexagon::fixup_Hexagon_8_X;
else { else
errs() << "unrecognized relocation, bits " << bits << "\n"; raise_relocation_error(bits, kind);
errs() << "name = " << HexagonMCInstrInfo::getName(MCII, MI) << "\n";
}
break; break;
case 7: case 7:
if (MCID.isBranch() || if (MCID.isBranch() ||
(llvm::HexagonMCInstrInfo::getType(MCII, MI) == HexagonII::TypeCR)) (HexagonMCInstrInfo::getType(MCII, MI) == HexagonII::TypeCR))
FixupKind = *Extended ? Hexagon::fixup_Hexagon_B7_PCREL_X FixupKind = *Extended ? Hexagon::fixup_Hexagon_B7_PCREL_X
: Hexagon::fixup_Hexagon_B7_PCREL; : Hexagon::fixup_Hexagon_B7_PCREL;
else if (*Extended) else if (*Extended)
FixupKind = Hexagon::fixup_Hexagon_7_X; FixupKind = Hexagon::fixup_Hexagon_7_X;
else { else
errs() << "unrecognized relocation, bits " << bits << "\n"; raise_relocation_error(bits, kind);
errs() << "name = " << HexagonMCInstrInfo::getName(MCII, MI) << "\n";
}
break; break;
case 6: case 6:
if (*Extended) { if (*Extended) {
switch (kind) { switch (kind) {
default: case MCSymbolRefExpr::VK_PPC_DTPREL:
FixupKind = Hexagon::fixup_Hexagon_6_X; FixupKind = Hexagon::fixup_Hexagon_DTPREL_16_X;
break;
case llvm::MCSymbolRefExpr::VK_Hexagon_PCREL:
FixupKind = Hexagon::fixup_Hexagon_6_PCREL_X;
break; break;
// This is part of an extender, GOT_11 is a // This is part of an extender, GOT_11 is a
// Word32_U6 unsigned/truncated reloc. // Word32_U6 unsigned/truncated reloc.
case llvm::MCSymbolRefExpr::VK_GOT: case MCSymbolRefExpr::VK_GOT:
FixupKind = Hexagon::fixup_Hexagon_GOT_11_X; FixupKind = Hexagon::fixup_Hexagon_GOT_11_X;
break; break;
case llvm::MCSymbolRefExpr::VK_GOTOFF: case MCSymbolRefExpr::VK_GOTREL:
FixupKind = Hexagon::fixup_Hexagon_GOTREL_11_X; FixupKind = Hexagon::fixup_Hexagon_GOTREL_11_X;
break; 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 { } else
errs() << "unrecognized relocation, bits " << bits << "\n"; raise_relocation_error(bits, kind);
errs() << "name = " << HexagonMCInstrInfo::getName(MCII, MI) << "\n";
}
break; break;
case 0: case 0:
@ -706,16 +745,17 @@ unsigned HexagonMCCodeEmitter::getExprOpValue(const MCInst &MI,
break; break;
} }
MCExpr const *FixupExpression = (*Addend > 0 && isPCRel(FixupKind)) ? MCExpr const *FixupExpression =
MCBinaryExpr::createAdd(MO.getExpr(), (*Addend > 0 && isPCRel(FixupKind))
MCConstantExpr::create(*Addend, MCT), MCT) : ? MCBinaryExpr::createAdd(MO.getExpr(),
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()); MCFixupKind(FixupKind), MI.getLoc());
Fixups.push_back(fixup); Fixups.push_back(fixup);
// All of the information is in the fixup. // All of the information is in the fixup.
return (0); return 0;
} }
unsigned unsigned

View File

@ -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) }