[Hexagon] Fixing relocation generation and adding tests.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@260259 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Colin LeMahieu 2016-02-09 19:18:02 +00:00
parent 3f9e772b2c
commit 4ea9b605fc
3 changed files with 546 additions and 221 deletions

View File

@ -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:

View File

@ -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<MCConstantExpr>(ME)->getValue();
}
if (MK == MCExpr::Binary) {
getExprOpValue(MI, MO, cast<MCBinaryExpr>(ME)->getLHS(), Fixups, STI);
getExprOpValue(MI, MO, cast<MCBinaryExpr>(ME)->getRHS(), Fixups, STI);
auto Wrapper = dyn_cast<HexagonNoExtendOperand>(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<MCBinaryExpr>(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<const MCSymbolRefExpr *>(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

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