From a036240a880d57f0830ac758325a36d6df868c96 Mon Sep 17 00:00:00 2001 From: Colin LeMahieu Date: Fri, 1 May 2015 21:14:21 +0000 Subject: [PATCH] [Hexagon] Adding expression MC emission and removing XFAIL from test that hits this code path. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@236348 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCExpr.h | 15 +- lib/MC/MCExpr.cpp | 12 + .../Hexagon/MCTargetDesc/HexagonBaseInfo.h | 2 +- .../Hexagon/MCTargetDesc/HexagonFixupKinds.h | 137 ++++++ .../MCTargetDesc/HexagonMCCodeEmitter.cpp | 449 +++++++++++++++++- .../MCTargetDesc/HexagonMCCodeEmitter.h | 7 + .../MCTargetDesc/HexagonMCInstrInfo.cpp | 25 + .../Hexagon/MCTargetDesc/HexagonMCInstrInfo.h | 23 +- test/CodeGen/Generic/MachineBranchProb.ll | 3 +- 9 files changed, 661 insertions(+), 12 deletions(-) create mode 100644 lib/Target/Hexagon/MCTargetDesc/HexagonFixupKinds.h diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h index 7379f22a048..2d24edc7de0 100644 --- a/include/llvm/MC/MCExpr.h +++ b/include/llvm/MC/MCExpr.h @@ -278,7 +278,20 @@ public: VK_Mips_PCREL_HI16, VK_Mips_PCREL_LO16, - VK_COFF_IMGREL32 // symbol@imgrel (image-relative) + VK_COFF_IMGREL32, // symbol@imgrel (image-relative) + + VK_Hexagon_PCREL, + VK_Hexagon_LO16, + VK_Hexagon_HI16, + VK_Hexagon_GPREL, + VK_Hexagon_GD_GOT, + VK_Hexagon_LD_GOT, + VK_Hexagon_GD_PLT, + VK_Hexagon_LD_PLT, + VK_Hexagon_IE, + VK_Hexagon_IE_GOT, + VK_TPREL, + VK_DTPREL }; private: diff --git a/lib/MC/MCExpr.cpp b/lib/MC/MCExpr.cpp index 93e49d6441c..7e103871988 100644 --- a/lib/MC/MCExpr.cpp +++ b/lib/MC/MCExpr.cpp @@ -283,6 +283,18 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) { case VK_Mips_PCREL_HI16: return "PCREL_HI16"; case VK_Mips_PCREL_LO16: return "PCREL_LO16"; case VK_COFF_IMGREL32: return "IMGREL"; + case VK_Hexagon_PCREL: return "PCREL"; + case VK_Hexagon_LO16: return "LO16"; + case VK_Hexagon_HI16: return "HI16"; + case VK_Hexagon_GPREL: return "GPREL"; + case VK_Hexagon_GD_GOT: return "GDGOT"; + case VK_Hexagon_LD_GOT: return "LDGOT"; + case VK_Hexagon_GD_PLT: return "GDPLT"; + case VK_Hexagon_LD_PLT: return "LDPLT"; + case VK_Hexagon_IE: return "IE"; + case VK_Hexagon_IE_GOT: return "IEGOT"; + case VK_TPREL: return "tprel"; + case VK_DTPREL: return "dtprel"; } llvm_unreachable("Invalid variant kind"); } diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h b/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h index 8e02f799d7e..6a72f205e9d 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h @@ -70,7 +70,7 @@ namespace HexagonII { PostInc = 6 // Post increment addressing mode }; - enum MemAccessSize { + enum class MemAccessSize { NoMemAccess = 0, // Not a memory acces instruction. ByteAccess = 1, // Byte access instruction (memb). HalfWordAccess = 2, // Half word access instruction (memh). diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonFixupKinds.h b/lib/Target/Hexagon/MCTargetDesc/HexagonFixupKinds.h new file mode 100644 index 00000000000..cac2f4aab97 --- /dev/null +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonFixupKinds.h @@ -0,0 +1,137 @@ +//===-- HexagonFixupKinds.h - Hexagon Specific Fixup Entries --------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_HEXAGON_HEXAGONFIXUPKINDS_H +#define LLVM_HEXAGON_HEXAGONFIXUPKINDS_H + +#include "llvm/MC/MCFixup.h" + +namespace llvm { +namespace Hexagon { +enum Fixups { + // Branch fixups for R_HEX_B{22,15,7}_PCREL. + fixup_Hexagon_B22_PCREL = FirstTargetFixupKind, + fixup_Hexagon_B15_PCREL, + fixup_Hexagon_B7_PCREL, + fixup_Hexagon_LO16, + fixup_Hexagon_HI16, + fixup_Hexagon_32, + fixup_Hexagon_16, + fixup_Hexagon_8, + fixup_Hexagon_GPREL16_0, + fixup_Hexagon_GPREL16_1, + fixup_Hexagon_GPREL16_2, + fixup_Hexagon_GPREL16_3, + fixup_Hexagon_HL16, + fixup_Hexagon_B13_PCREL, + fixup_Hexagon_B9_PCREL, + fixup_Hexagon_B32_PCREL_X, + fixup_Hexagon_32_6_X, + fixup_Hexagon_B22_PCREL_X, + fixup_Hexagon_B15_PCREL_X, + fixup_Hexagon_B13_PCREL_X, + fixup_Hexagon_B9_PCREL_X, + fixup_Hexagon_B7_PCREL_X, + fixup_Hexagon_16_X, + fixup_Hexagon_12_X, + fixup_Hexagon_11_X, + fixup_Hexagon_10_X, + fixup_Hexagon_9_X, + fixup_Hexagon_8_X, + fixup_Hexagon_7_X, + fixup_Hexagon_6_X, + fixup_Hexagon_32_PCREL, + fixup_Hexagon_COPY, + fixup_Hexagon_GLOB_DAT, + fixup_Hexagon_JMP_SLOT, + fixup_Hexagon_RELATIVE, + fixup_Hexagon_PLT_B22_PCREL, + fixup_Hexagon_GOTREL_LO16, + fixup_Hexagon_GOTREL_HI16, + fixup_Hexagon_GOTREL_32, + fixup_Hexagon_GOT_LO16, + fixup_Hexagon_GOT_HI16, + fixup_Hexagon_GOT_32, + fixup_Hexagon_GOT_16, + fixup_Hexagon_DTPMOD_32, + fixup_Hexagon_DTPREL_LO16, + fixup_Hexagon_DTPREL_HI16, + fixup_Hexagon_DTPREL_32, + fixup_Hexagon_DTPREL_16, + fixup_Hexagon_GD_PLT_B22_PCREL, + fixup_Hexagon_LD_PLT_B22_PCREL, + fixup_Hexagon_GD_GOT_LO16, + fixup_Hexagon_GD_GOT_HI16, + fixup_Hexagon_GD_GOT_32, + fixup_Hexagon_GD_GOT_16, + fixup_Hexagon_LD_GOT_LO16, + fixup_Hexagon_LD_GOT_HI16, + fixup_Hexagon_LD_GOT_32, + fixup_Hexagon_LD_GOT_16, + fixup_Hexagon_IE_LO16, + fixup_Hexagon_IE_HI16, + fixup_Hexagon_IE_32, + fixup_Hexagon_IE_16, + fixup_Hexagon_IE_GOT_LO16, + fixup_Hexagon_IE_GOT_HI16, + fixup_Hexagon_IE_GOT_32, + fixup_Hexagon_IE_GOT_16, + fixup_Hexagon_TPREL_LO16, + fixup_Hexagon_TPREL_HI16, + fixup_Hexagon_TPREL_32, + fixup_Hexagon_TPREL_16, + fixup_Hexagon_6_PCREL_X, + fixup_Hexagon_GOTREL_32_6_X, + fixup_Hexagon_GOTREL_16_X, + fixup_Hexagon_GOTREL_11_X, + fixup_Hexagon_GOT_32_6_X, + fixup_Hexagon_GOT_16_X, + fixup_Hexagon_GOT_11_X, + fixup_Hexagon_DTPREL_32_6_X, + fixup_Hexagon_DTPREL_16_X, + fixup_Hexagon_DTPREL_11_X, + fixup_Hexagon_GD_GOT_32_6_X, + fixup_Hexagon_GD_GOT_16_X, + fixup_Hexagon_GD_GOT_11_X, + fixup_Hexagon_LD_GOT_32_6_X, + fixup_Hexagon_LD_GOT_16_X, + fixup_Hexagon_LD_GOT_11_X, + fixup_Hexagon_IE_32_6_X, + fixup_Hexagon_IE_16_X, + fixup_Hexagon_IE_GOT_32_6_X, + fixup_Hexagon_IE_GOT_16_X, + fixup_Hexagon_IE_GOT_11_X, + fixup_Hexagon_TPREL_32_6_X, + fixup_Hexagon_TPREL_16_X, + fixup_Hexagon_TPREL_11_X, + + LastTargetFixupKind, + NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind +}; +enum FixupBitmaps { + Word8 = 0xff, + Word16 = 0xffff, + Word32 = 0xffffffff, + Word32_LO = 0x00c03fff, + Word32_HL = 0x0, // Not Implemented + Word32_GP = 0x0, // Not Implemented + Word32_B7 = 0x00001f18, + Word32_B9 = 0x003000fe, + Word32_B13 = 0x00202ffe, + Word32_B15 = 0x00df20fe, + Word32_B22 = 0x01ff3ffe, + Word32_R6 = 0x000007e0, + Word32_U6 = 0x0, // Not Implemented + Word32_U16 = 0x0, // Not Implemented + Word32_X26 = 0x0fff3fff +}; +} // namespace Hexagon +} // namespace llvm + +#endif // LLVM_HEXAGON_HEXAGONFIXUPKINDS_H diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp index eac7d6d2c4e..1d9e5c531bb 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp @@ -9,6 +9,7 @@ #include "Hexagon.h" #include "MCTargetDesc/HexagonBaseInfo.h" +#include "MCTargetDesc/HexagonFixupKinds.h" #include "MCTargetDesc/HexagonMCCodeEmitter.h" #include "MCTargetDesc/HexagonMCInstrInfo.h" #include "MCTargetDesc/HexagonMCTargetDesc.h" @@ -37,8 +38,9 @@ enum class ParseField { duplex = 0x0, last0 = 0x1, last1 = 0x2, end = 0x3 }; /// \brief Returns the packet bits based on instruction position. uint32_t getPacketBits(MCInst const &HMI) { unsigned const ParseFieldOffset = 14; - ParseField Field = HexagonMCInstrInfo::isPacketEnd(HMI) ? ParseField::end : ParseField::last0; - return static_cast (Field) << ParseFieldOffset; + ParseField Field = HexagonMCInstrInfo::isPacketEnd(HMI) ? ParseField::end + : ParseField::last0; + return static_cast(Field) << ParseFieldOffset; } void emitLittleEndian(uint64_t Binary, raw_ostream &OS) { OS << static_cast((Binary >> 0x00) & 0xff); @@ -50,7 +52,8 @@ void emitLittleEndian(uint64_t Binary, raw_ostream &OS) { HexagonMCCodeEmitter::HexagonMCCodeEmitter(MCInstrInfo const &aMII, MCContext &aMCT) - : MCT(aMCT), MCII(aMII) {} + : MCT(aMCT), MCII(aMII), Addend(new unsigned(0)), + Extended(new bool(false)) {} void HexagonMCCodeEmitter::EncodeInstruction(MCInst const &MI, raw_ostream &OS, SmallVectorImpl &Fixups, @@ -63,6 +66,441 @@ void HexagonMCCodeEmitter::EncodeInstruction(MCInst const &MI, raw_ostream &OS, ++MCNumEmitted; } +static Hexagon::Fixups getFixupNoBits(MCInstrInfo const &MCII, const MCInst &MI, + const MCOperand &MO, + const MCSymbolRefExpr::VariantKind kind) { + const MCInstrDesc &MCID = HexagonMCInstrInfo::getDesc(MCII, MI); + unsigned insnType = llvm::HexagonMCInstrInfo::getType(MCII, MI); + + if (insnType == HexagonII::TypePREFIX) { + switch (kind) { + case llvm::MCSymbolRefExpr::VK_GOTOFF: + return Hexagon::fixup_Hexagon_GOTREL_32_6_X; + case llvm::MCSymbolRefExpr::VK_GOT: + return Hexagon::fixup_Hexagon_GOT_32_6_X; + case llvm::MCSymbolRefExpr::VK_TPREL: + return Hexagon::fixup_Hexagon_TPREL_32_6_X; + case llvm::MCSymbolRefExpr::VK_DTPREL: + return Hexagon::fixup_Hexagon_DTPREL_32_6_X; + case llvm::MCSymbolRefExpr::VK_Hexagon_GD_GOT: + return Hexagon::fixup_Hexagon_GD_GOT_32_6_X; + case llvm::MCSymbolRefExpr::VK_Hexagon_LD_GOT: + return Hexagon::fixup_Hexagon_LD_GOT_32_6_X; + case llvm::MCSymbolRefExpr::VK_Hexagon_IE: + return Hexagon::fixup_Hexagon_IE_32_6_X; + case llvm::MCSymbolRefExpr::VK_Hexagon_IE_GOT: + return Hexagon::fixup_Hexagon_IE_GOT_32_6_X; + default: + if (MCID.isBranch()) + return Hexagon::fixup_Hexagon_B32_PCREL_X; + else + return Hexagon::fixup_Hexagon_32_6_X; + } + } else if (MCID.isBranch()) + return (Hexagon::fixup_Hexagon_B13_PCREL); + + switch (MCID.getOpcode()) { + case Hexagon::HI: + case Hexagon::A2_tfrih: + switch (kind) { + case llvm::MCSymbolRefExpr::VK_GOT: + return Hexagon::fixup_Hexagon_GOT_HI16; + case llvm::MCSymbolRefExpr::VK_GOTOFF: + return Hexagon::fixup_Hexagon_GOTREL_HI16; + case llvm::MCSymbolRefExpr::VK_Hexagon_GD_GOT: + return Hexagon::fixup_Hexagon_GD_GOT_HI16; + case llvm::MCSymbolRefExpr::VK_Hexagon_LD_GOT: + return Hexagon::fixup_Hexagon_LD_GOT_HI16; + case llvm::MCSymbolRefExpr::VK_Hexagon_IE: + return Hexagon::fixup_Hexagon_IE_HI16; + case llvm::MCSymbolRefExpr::VK_Hexagon_IE_GOT: + return Hexagon::fixup_Hexagon_IE_GOT_HI16; + case llvm::MCSymbolRefExpr::VK_TPREL: + return Hexagon::fixup_Hexagon_TPREL_HI16; + case llvm::MCSymbolRefExpr::VK_DTPREL: + return Hexagon::fixup_Hexagon_DTPREL_HI16; + default: + return Hexagon::fixup_Hexagon_HI16; + } + + case Hexagon::LO: + case Hexagon::A2_tfril: + switch (kind) { + case llvm::MCSymbolRefExpr::VK_GOT: + return Hexagon::fixup_Hexagon_GOT_LO16; + case llvm::MCSymbolRefExpr::VK_GOTOFF: + return Hexagon::fixup_Hexagon_GOTREL_LO16; + case llvm::MCSymbolRefExpr::VK_Hexagon_GD_GOT: + return Hexagon::fixup_Hexagon_GD_GOT_LO16; + case llvm::MCSymbolRefExpr::VK_Hexagon_LD_GOT: + return Hexagon::fixup_Hexagon_LD_GOT_LO16; + case llvm::MCSymbolRefExpr::VK_Hexagon_IE: + return Hexagon::fixup_Hexagon_IE_LO16; + case llvm::MCSymbolRefExpr::VK_Hexagon_IE_GOT: + return Hexagon::fixup_Hexagon_IE_GOT_LO16; + case llvm::MCSymbolRefExpr::VK_TPREL: + return Hexagon::fixup_Hexagon_TPREL_LO16; + case llvm::MCSymbolRefExpr::VK_DTPREL: + return Hexagon::fixup_Hexagon_DTPREL_LO16; + default: + return Hexagon::fixup_Hexagon_LO16; + } + + // The only relocs left should be GP relative: + default: + if (MCID.mayStore() || MCID.mayLoad()) { + for (const uint16_t *ImpUses = MCID.getImplicitUses(); *ImpUses; + ++ImpUses) { + if (*ImpUses == Hexagon::GP) { + switch (HexagonMCInstrInfo::getAccessSize(MCII, MI)) { + case HexagonII::MemAccessSize::ByteAccess: + return fixup_Hexagon_GPREL16_0; + case HexagonII::MemAccessSize::HalfWordAccess: + return fixup_Hexagon_GPREL16_1; + case HexagonII::MemAccessSize::WordAccess: + return fixup_Hexagon_GPREL16_2; + case HexagonII::MemAccessSize::DoubleWordAccess: + return fixup_Hexagon_GPREL16_3; + default: + llvm_unreachable("unhandled fixup"); + } + } + } + } else + llvm_unreachable("unhandled fixup"); + } + + return LastTargetFixupKind; +} + +unsigned HexagonMCCodeEmitter::getExprOpValue(const MCInst &MI, + const MCOperand &MO, + const MCExpr *ME, + SmallVectorImpl &Fixups, + 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) { + unsigned Res; + Res = getExprOpValue(MI, MO, cast(ME)->getLHS(), Fixups, STI); + Res += + getExprOpValue(MI, MO, cast(ME)->getRHS(), Fixups, STI); + return Res; + } + + assert(MK == MCExpr::SymbolRef); + + Hexagon::Fixups FixupKind = + Hexagon::Fixups(Hexagon::fixup_Hexagon_TPREL_LO16); + const MCSymbolRefExpr *MCSRE = static_cast(ME); + const MCInstrDesc &MCID = HexagonMCInstrInfo::getDesc(MCII, MI); + unsigned opcode = MCID.getOpcode(); + unsigned bits = HexagonMCInstrInfo::getExtentBits(MCII, MI) - + HexagonMCInstrInfo::getExtentAlignment(MCII, MI); + const MCSymbolRefExpr::VariantKind kind = MCSRE->getKind(); + + DEBUG(dbgs() << "----------------------------------------\n"); + DEBUG(dbgs() << "Opcode Name: " << HexagonMCInstrInfo::getName(MCII, MI) + << "\n"); + DEBUG(dbgs() << "Opcode: " << opcode << "\n"); + DEBUG(dbgs() << "Relocation bits: " << bits << "\n"); + DEBUG(dbgs() << "Addend: " << *Addend << "\n"); + DEBUG(dbgs() << "----------------------------------------\n"); + + switch (bits) { + default: + DEBUG(dbgs() << "unrecognized bit count of " << bits << '\n'); + break; + + 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: + FixupKind = *Extended ? Hexagon::fixup_Hexagon_DTPREL_32_6_X + : Hexagon::fixup_Hexagon_DTPREL_32; + break; + default: + FixupKind = + *Extended ? Hexagon::fixup_Hexagon_32_6_X : Hexagon::fixup_Hexagon_32; + break; + } + break; + + case 22: + switch (kind) { + case llvm::MCSymbolRefExpr::VK_Hexagon_GD_PLT: + FixupKind = Hexagon::fixup_Hexagon_GD_PLT_B22_PCREL; + break; + case llvm::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"; + } + break; + } + 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: + FixupKind = Hexagon::fixup_Hexagon_DTPREL_16_X; + break; + } + } else + switch (kind) { + default: + errs() << "unrecognized relocation, bits " << bits << "\n"; + errs() << "name = " << HexagonMCInstrInfo::getName(MCII, MI) << "\n"; + break; + case llvm::MCSymbolRefExpr::VK_GOTOFF: + if ((MCID.getOpcode() == Hexagon::HI) || + (MCID.getOpcode() == Hexagon::LO_H)) + 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: + FixupKind = Hexagon::fixup_Hexagon_GD_GOT_16; + break; + case llvm::MCSymbolRefExpr::VK_Hexagon_LD_GOT: + FixupKind = Hexagon::fixup_Hexagon_LD_GOT_16; + break; + case llvm::MCSymbolRefExpr::VK_Hexagon_IE_GOT: + FixupKind = Hexagon::fixup_Hexagon_IE_GOT_16; + break; + case llvm::MCSymbolRefExpr::VK_TPREL: + FixupKind = Hexagon::fixup_Hexagon_TPREL_16; + break; + case llvm::MCSymbolRefExpr::VK_DTPREL: + FixupKind = Hexagon::fixup_Hexagon_DTPREL_16; + break; + } + break; + + case 15: + if (MCID.isBranch() || MCID.isCall()) + FixupKind = *Extended ? Hexagon::fixup_Hexagon_B15_PCREL_X + : Hexagon::fixup_Hexagon_B15_PCREL; + break; + + case 13: + if (MCID.isBranch()) + FixupKind = Hexagon::fixup_Hexagon_B13_PCREL; + else { + errs() << "unrecognized relocation, bits " << bits << "\n"; + errs() << "name = " << HexagonMCInstrInfo::getName(MCII, MI) << "\n"; + } + 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: + FixupKind = Hexagon::fixup_Hexagon_GOT_16_X; + break; + case llvm::MCSymbolRefExpr::VK_GOTOFF: + FixupKind = Hexagon::fixup_Hexagon_GOTREL_16_X; + break; + } + else { + errs() << "unrecognized relocation, bits " << bits << "\n"; + errs() << "name = " << HexagonMCInstrInfo::getName(MCII, MI) << "\n"; + } + 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: + FixupKind = Hexagon::fixup_Hexagon_DTPREL_11_X; + break; + } + else { + errs() << "unrecognized relocation, bits " << bits << "\n"; + errs() << "name = " << HexagonMCInstrInfo::getName(MCII, MI) << "\n"; + } + break; + + case 10: + if (*Extended) + FixupKind = Hexagon::fixup_Hexagon_10_X; + break; + + case 9: + if (MCID.isBranch() || + (llvm::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"; + } + 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"; + } + break; + + case 7: + if (MCID.isBranch() || + (llvm::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"; + } + 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; + break; + // This is part of an extender, GOT_11 is a + // Word32_U6 unsigned/truncated reloc. + 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; + } + } else { + errs() << "unrecognized relocation, bits " << bits << "\n"; + errs() << "name = " << HexagonMCInstrInfo::getName(MCII, MI) << "\n"; + } + break; + + case 0: + FixupKind = getFixupNoBits(MCII, MI, MO, kind); + break; + } + + MCFixup fixup = + MCFixup::Create(*Addend, MO.getExpr(), MCFixupKind(FixupKind)); + Fixups.push_back(fixup); + // All of the information is in the fixup. + return (0); +} + unsigned HexagonMCCodeEmitter::getMachineOpValue(MCInst const &MI, MCOperand const &MO, SmallVectorImpl &Fixups, @@ -71,7 +509,10 @@ HexagonMCCodeEmitter::getMachineOpValue(MCInst const &MI, MCOperand const &MO, return MCT.getRegisterInfo()->getEncodingValue(MO.getReg()); if (MO.isImm()) return static_cast(MO.getImm()); - llvm_unreachable("Only Immediates and Registers implemented right now"); + + // MO must be an ME. + assert(MO.isExpr()); + return getExprOpValue(MI, MO, MO.getExpr(), Fixups, STI); } MCCodeEmitter *llvm::createHexagonMCCodeEmitter(MCInstrInfo const &MII, diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.h b/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.h index 768c10ed92d..7b790ccd9a5 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.h +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.h @@ -28,6 +28,13 @@ namespace llvm { class HexagonMCCodeEmitter : public MCCodeEmitter { MCContext &MCT; MCInstrInfo const &MCII; + std::unique_ptr Addend; + std::unique_ptr Extended; + + // helper routine for getMachineOpValue() + unsigned getExprOpValue(const MCInst &MI, const MCOperand &MO, + const MCExpr *ME, SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; public: HexagonMCCodeEmitter(MCInstrInfo const &aMII, MCContext &aMCT); diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp index 33e7c81904f..1effad6c2aa 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp @@ -20,6 +20,14 @@ void HexagonMCInstrInfo::AppendImplicitOperands(MCInst &MCI) { MCI.addOperand(MCOperand::CreateInst(nullptr)); } +HexagonII::MemAccessSize +HexagonMCInstrInfo::getAccessSize(MCInstrInfo const &MCII, MCInst const &MCI) { + const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; + + return (HexagonII::MemAccessSize((F >> HexagonII::MemAccessSizePos) & + HexagonII::MemAccesSizeMask)); +} + unsigned HexagonMCInstrInfo::getBitCount(MCInstrInfo const &MCII, MCInst const &MCI) { uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; @@ -38,6 +46,18 @@ MCInstrDesc const &HexagonMCInstrInfo::getDesc(MCInstrInfo const &MCII, return (MCII.get(MCI.getOpcode())); } +unsigned HexagonMCInstrInfo::getExtentAlignment(MCInstrInfo const &MCII, + MCInst const &MCI) { + const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; + return ((F >> HexagonII::ExtentAlignPos) & HexagonII::ExtentAlignMask); +} + +unsigned HexagonMCInstrInfo::getExtentBits(MCInstrInfo const &MCII, + MCInst const &MCI) { + const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; + return ((F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask); +} + std::bitset<16> HexagonMCInstrInfo::GetImplicitBits(MCInst const &MCI) { SanityCheckImplicitOperands(MCI); std::bitset<16> Bits(MCI.getOperand(MCI.getNumOperands() - 2).getImm()); @@ -74,6 +94,11 @@ int HexagonMCInstrInfo::getMinValue(MCInstrInfo const &MCII, return 0; } +char const *HexagonMCInstrInfo::getName(MCInstrInfo const &MCII, + MCInst const &MCI) { + return MCII.getName(MCI.getOpcode()); +} + // Return the operand that consumes or produces a new value. MCOperand const &HexagonMCInstrInfo::getNewValue(MCInstrInfo const &MCII, MCInst const &MCI) { diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h b/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h index 10fc0f3bdeb..6a3edec607a 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h @@ -23,9 +23,16 @@ class MCInstrDesc; class MCInstrInfo; class MCInst; class MCOperand; +namespace HexagonII { +enum class MemAccessSize; +} namespace HexagonMCInstrInfo { void AppendImplicitOperands(MCInst &MCI); +// Return memory access size +HexagonII::MemAccessSize getAccessSize(MCInstrInfo const &MCII, + MCInst const &MCI); + // Return number of bits in the constant extended operand. unsigned getBitCount(MCInstrInfo const &MCII, MCInst const &MCI); @@ -34,6 +41,12 @@ unsigned short getCExtOpNum(MCInstrInfo const &MCII, MCInst const &MCI); MCInstrDesc const &getDesc(MCInstrInfo const &MCII, MCInst const &MCI); +// Return the implicit alignment of the extendable operand +unsigned getExtentAlignment(MCInstrInfo const &MCII, MCInst const &MCI); + +// Return the number of logical bits of the extendable operand +unsigned getExtentBits(MCInstrInfo const &MCII, MCInst const &MCI); + std::bitset<16> GetImplicitBits(MCInst const &MCI); // Return the max value that a constant extendable operand can have @@ -44,6 +57,9 @@ int getMaxValue(MCInstrInfo const &MCII, MCInst const &MCI); // without being extended. int getMinValue(MCInstrInfo const &MCII, MCInst const &MCI); +// Return instruction name +char const *getName(MCInstrInfo const &MCII, MCInst const &MCI); + // Return the operand that consumes or produces a new value. MCOperand const &getNewValue(MCInstrInfo const &MCII, MCInst const &MCI); @@ -52,7 +68,7 @@ unsigned getType(MCInstrInfo const &MCII, MCInst const &MCI); // Return whether the instruction is a legal new-value producer. bool hasNewValue(MCInstrInfo const &MCII, MCInst const &MCI); - + // Return whether the insn is an actual insn. bool isCanon(MCInstrInfo const &MCII, MCInst const &MCI); @@ -90,9 +106,8 @@ void resetPacket(MCInst &MCI); inline void SanityCheckImplicitOperands(MCInst const &MCI) { assert(MCI.getNumOperands() >= 2 && "At least the two implicit operands"); assert(MCI.getOperand(MCI.getNumOperands() - 1).isInst() && - "Implicit bits and flags"); - assert(MCI.getOperand(MCI.getNumOperands() - 2).isImm() && - "Parent pointer"); + "Implicit bits and flags"); + assert(MCI.getOperand(MCI.getNumOperands() - 2).isImm() && "Parent pointer"); } void SetImplicitBits(MCInst &MCI, std::bitset<16> Bits); diff --git a/test/CodeGen/Generic/MachineBranchProb.ll b/test/CodeGen/Generic/MachineBranchProb.ll index 8288e45ee50..f030775d535 100644 --- a/test/CodeGen/Generic/MachineBranchProb.ll +++ b/test/CodeGen/Generic/MachineBranchProb.ll @@ -1,8 +1,7 @@ ; RUN: llc < %s -print-machineinstrs=expand-isel-pseudos -o /dev/null 2>&1 | FileCheck %s ; ARM & AArch64 run an extra SimplifyCFG which disrupts this test. -; Hexagon crashes (PR23377) -; XFAIL: arm,aarch64,hexagon +; XFAIL: arm,aarch64 ; Make sure we have the correct weight attached to each successor. define i32 @test2(i32 %x) nounwind uwtable readnone ssp { -- 2.34.1