2014-10-03 21:18:11 +08:00
|
|
|
//===-- HexagonMCCodeEmitter.cpp - Hexagon Target Descriptions ------------===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "Hexagon.h"
|
|
|
|
#include "MCTargetDesc/HexagonBaseInfo.h"
|
2015-05-02 05:14:21 +08:00
|
|
|
#include "MCTargetDesc/HexagonFixupKinds.h"
|
2014-10-03 21:18:11 +08:00
|
|
|
#include "MCTargetDesc/HexagonMCCodeEmitter.h"
|
2015-02-20 03:00:00 +08:00
|
|
|
#include "MCTargetDesc/HexagonMCInstrInfo.h"
|
2015-01-14 19:23:27 +08:00
|
|
|
#include "MCTargetDesc/HexagonMCTargetDesc.h"
|
2014-10-03 21:18:11 +08:00
|
|
|
#include "llvm/ADT/Statistic.h"
|
|
|
|
#include "llvm/MC/MCCodeEmitter.h"
|
|
|
|
#include "llvm/MC/MCContext.h"
|
|
|
|
#include "llvm/MC/MCExpr.h"
|
|
|
|
#include "llvm/MC/MCInst.h"
|
|
|
|
#include "llvm/MC/MCInstrInfo.h"
|
|
|
|
#include "llvm/MC/MCRegisterInfo.h"
|
|
|
|
#include "llvm/MC/MCSubtargetInfo.h"
|
|
|
|
#include "llvm/Support/Debug.h"
|
2015-06-04 23:03:02 +08:00
|
|
|
#include "llvm/Support/EndianStream.h"
|
2014-10-03 21:18:11 +08:00
|
|
|
#include "llvm/Support/raw_ostream.h"
|
|
|
|
|
|
|
|
#define DEBUG_TYPE "mccodeemitter"
|
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
using namespace Hexagon;
|
|
|
|
|
|
|
|
STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
|
|
|
|
|
|
|
|
HexagonMCCodeEmitter::HexagonMCCodeEmitter(MCInstrInfo const &aMII,
|
|
|
|
MCContext &aMCT)
|
2015-05-02 05:14:21 +08:00
|
|
|
: MCT(aMCT), MCII(aMII), Addend(new unsigned(0)),
|
2017-02-02 23:32:26 +08:00
|
|
|
Extended(new bool(false)), CurrentBundle(new MCInst const *),
|
|
|
|
CurrentIndex(new size_t(0)) {}
|
2015-05-29 22:44:13 +08:00
|
|
|
|
2017-02-02 23:32:26 +08:00
|
|
|
uint32_t HexagonMCCodeEmitter::parseBits(size_t Last,
|
2015-05-29 22:44:13 +08:00
|
|
|
MCInst const &MCB,
|
|
|
|
MCInst const &MCI) const {
|
2015-06-06 00:00:11 +08:00
|
|
|
bool Duplex = HexagonMCInstrInfo::isDuplex(MCII, MCI);
|
2017-02-02 23:32:26 +08:00
|
|
|
if (*CurrentIndex == 0) {
|
2015-05-29 22:44:13 +08:00
|
|
|
if (HexagonMCInstrInfo::isInnerLoop(MCB)) {
|
2015-06-06 00:00:11 +08:00
|
|
|
assert(!Duplex);
|
2017-02-02 23:32:26 +08:00
|
|
|
assert(*CurrentIndex != Last);
|
2015-05-29 22:44:13 +08:00
|
|
|
return HexagonII::INST_PARSE_LOOP_END;
|
|
|
|
}
|
|
|
|
}
|
2017-02-02 23:32:26 +08:00
|
|
|
if (*CurrentIndex == 1) {
|
2015-05-29 22:44:13 +08:00
|
|
|
if (HexagonMCInstrInfo::isOuterLoop(MCB)) {
|
2015-06-06 00:00:11 +08:00
|
|
|
assert(!Duplex);
|
2017-02-02 23:32:26 +08:00
|
|
|
assert(*CurrentIndex != Last);
|
2015-05-29 22:44:13 +08:00
|
|
|
return HexagonII::INST_PARSE_LOOP_END;
|
|
|
|
}
|
|
|
|
}
|
2015-06-06 00:00:11 +08:00
|
|
|
if (Duplex) {
|
2017-02-02 23:32:26 +08:00
|
|
|
assert(*CurrentIndex == Last);
|
2015-06-06 00:00:11 +08:00
|
|
|
return HexagonII::INST_PARSE_DUPLEX;
|
|
|
|
}
|
2017-02-02 23:32:26 +08:00
|
|
|
if(*CurrentIndex == Last)
|
2015-05-29 22:44:13 +08:00
|
|
|
return HexagonII::INST_PARSE_PACKET_END;
|
|
|
|
return HexagonII::INST_PARSE_NOT_END;
|
|
|
|
}
|
2014-10-03 21:18:11 +08:00
|
|
|
|
2015-05-16 03:13:16 +08:00
|
|
|
void HexagonMCCodeEmitter::encodeInstruction(MCInst const &MI, raw_ostream &OS,
|
2014-10-03 21:18:11 +08:00
|
|
|
SmallVectorImpl<MCFixup> &Fixups,
|
|
|
|
MCSubtargetInfo const &STI) const {
|
2015-05-29 22:44:13 +08:00
|
|
|
MCInst &HMB = const_cast<MCInst &>(MI);
|
|
|
|
|
|
|
|
assert(HexagonMCInstrInfo::isBundle(HMB));
|
|
|
|
DEBUG(dbgs() << "Encoding bundle\n";);
|
|
|
|
*Addend = 0;
|
|
|
|
*Extended = false;
|
|
|
|
*CurrentBundle = &MI;
|
2017-02-02 23:32:26 +08:00
|
|
|
*CurrentIndex = 0;
|
2015-05-29 22:44:13 +08:00
|
|
|
size_t Last = HexagonMCInstrInfo::bundleSize(HMB) - 1;
|
|
|
|
for (auto &I : HexagonMCInstrInfo::bundleInstructions(HMB)) {
|
|
|
|
MCInst &HMI = const_cast<MCInst &>(*I.getInst());
|
Check that emitted instructions meet their predicates on all targets except ARM, Mips, and X86.
Summary:
* ARM is omitted from this patch because this check appears to expose bugs in this target.
* Mips is omitted from this patch because this check either detects bugs or deliberate
emission of instructions that don't satisfy their predicates. One deliberate
use is the SYNC instruction where the version with an operand is correctly
defined as requiring MIPS32 while the version without an operand is defined
as an alias of 'SYNC 0' and requires MIPS2.
* X86 is omitted from this patch because it doesn't use the tablegen-erated
MCCodeEmitter infrastructure.
Patches for ARM and Mips will follow.
Depends on D25617
Reviewers: tstellarAMD, jmolloy
Subscribers: wdng, jmolloy, aemerson, rengolin, arsenm, jyknight, nemanjai, nhaehnle, tstellarAMD, llvm-commits
Differential Revision: https://reviews.llvm.org/D25618
llvm-svn: 287439
2016-11-19 21:05:44 +08:00
|
|
|
verifyInstructionPredicates(HMI,
|
|
|
|
computeAvailableFeatures(STI.getFeatureBits()));
|
|
|
|
|
2015-05-29 22:44:13 +08:00
|
|
|
EncodeSingleInstruction(HMI, OS, Fixups, STI,
|
2017-02-02 23:32:26 +08:00
|
|
|
parseBits(Last, HMB, HMI));
|
2015-05-29 22:44:13 +08:00
|
|
|
*Extended = HexagonMCInstrInfo::isImmext(HMI);
|
|
|
|
*Addend += HEXAGON_INSTR_SIZE;
|
2017-02-02 23:32:26 +08:00
|
|
|
++*CurrentIndex;
|
2015-05-29 22:44:13 +08:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-04-28 23:54:48 +08:00
|
|
|
static bool RegisterMatches(unsigned Consumer, unsigned Producer,
|
|
|
|
unsigned Producer2) {
|
|
|
|
if (Consumer == Producer)
|
|
|
|
return true;
|
|
|
|
if (Consumer == Producer2)
|
|
|
|
return true;
|
|
|
|
// Calculate if we're a single vector consumer referencing a double producer
|
|
|
|
if (Producer >= Hexagon::W0 && Producer <= Hexagon::W15)
|
|
|
|
if (Consumer >= Hexagon::V0 && Consumer <= Hexagon::V31)
|
|
|
|
return ((Consumer - Hexagon::V0) >> 1) == (Producer - Hexagon::W0);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-05-29 22:44:13 +08:00
|
|
|
/// EncodeSingleInstruction - Emit a single
|
|
|
|
void HexagonMCCodeEmitter::EncodeSingleInstruction(
|
|
|
|
const MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups,
|
2017-02-02 23:32:26 +08:00
|
|
|
const MCSubtargetInfo &STI, uint32_t Parse) const {
|
|
|
|
assert(!HexagonMCInstrInfo::isBundle(MI));
|
2015-05-29 22:44:13 +08:00
|
|
|
uint64_t Binary;
|
|
|
|
|
|
|
|
// Pseudo instructions don't get encoded and shouldn't be here
|
|
|
|
// in the first place!
|
2017-02-02 23:32:26 +08:00
|
|
|
assert(!HexagonMCInstrInfo::getDesc(MCII, MI).isPseudo() &&
|
2015-05-29 22:44:13 +08:00
|
|
|
"pseudo-instruction found");
|
|
|
|
DEBUG(dbgs() << "Encoding insn"
|
2017-02-02 23:32:26 +08:00
|
|
|
" `" << HexagonMCInstrInfo::getName(MCII, MI) << "'"
|
2015-05-29 22:44:13 +08:00
|
|
|
"\n");
|
|
|
|
|
2017-02-02 23:32:26 +08:00
|
|
|
Binary = getBinaryCodeForInstr(MI, Fixups, STI);
|
2015-05-29 22:44:13 +08:00
|
|
|
// Check for unimplemented instructions. Immediate extenders
|
|
|
|
// are encoded as zero, so they need to be accounted for.
|
2017-02-03 03:58:22 +08:00
|
|
|
if (!Binary &&
|
|
|
|
MI.getOpcode() != DuplexIClass0 &&
|
|
|
|
MI.getOpcode() != A4_ext) {
|
2015-05-29 22:44:13 +08:00
|
|
|
DEBUG(dbgs() << "Unimplemented inst: "
|
2017-02-02 23:32:26 +08:00
|
|
|
" `" << HexagonMCInstrInfo::getName(MCII, MI) << "'"
|
2015-05-29 22:44:13 +08:00
|
|
|
"\n");
|
|
|
|
llvm_unreachable("Unimplemented Instruction");
|
|
|
|
}
|
|
|
|
Binary |= Parse;
|
2015-06-06 00:00:11 +08:00
|
|
|
|
|
|
|
// if we need to emit a duplexed instruction
|
2017-02-02 23:32:26 +08:00
|
|
|
if (MI.getOpcode() >= Hexagon::DuplexIClass0 &&
|
|
|
|
MI.getOpcode() <= Hexagon::DuplexIClassF) {
|
2015-06-06 00:00:11 +08:00
|
|
|
assert(Parse == HexagonII::INST_PARSE_DUPLEX &&
|
|
|
|
"Emitting duplex without duplex parse bits");
|
|
|
|
unsigned dupIClass;
|
2017-02-02 23:32:26 +08:00
|
|
|
switch (MI.getOpcode()) {
|
2015-06-06 00:00:11 +08:00
|
|
|
case Hexagon::DuplexIClass0:
|
|
|
|
dupIClass = 0;
|
|
|
|
break;
|
|
|
|
case Hexagon::DuplexIClass1:
|
|
|
|
dupIClass = 1;
|
|
|
|
break;
|
|
|
|
case Hexagon::DuplexIClass2:
|
|
|
|
dupIClass = 2;
|
|
|
|
break;
|
|
|
|
case Hexagon::DuplexIClass3:
|
|
|
|
dupIClass = 3;
|
|
|
|
break;
|
|
|
|
case Hexagon::DuplexIClass4:
|
|
|
|
dupIClass = 4;
|
|
|
|
break;
|
|
|
|
case Hexagon::DuplexIClass5:
|
|
|
|
dupIClass = 5;
|
|
|
|
break;
|
|
|
|
case Hexagon::DuplexIClass6:
|
|
|
|
dupIClass = 6;
|
|
|
|
break;
|
|
|
|
case Hexagon::DuplexIClass7:
|
|
|
|
dupIClass = 7;
|
|
|
|
break;
|
|
|
|
case Hexagon::DuplexIClass8:
|
|
|
|
dupIClass = 8;
|
|
|
|
break;
|
|
|
|
case Hexagon::DuplexIClass9:
|
|
|
|
dupIClass = 9;
|
|
|
|
break;
|
|
|
|
case Hexagon::DuplexIClassA:
|
|
|
|
dupIClass = 10;
|
|
|
|
break;
|
|
|
|
case Hexagon::DuplexIClassB:
|
|
|
|
dupIClass = 11;
|
|
|
|
break;
|
|
|
|
case Hexagon::DuplexIClassC:
|
|
|
|
dupIClass = 12;
|
|
|
|
break;
|
|
|
|
case Hexagon::DuplexIClassD:
|
|
|
|
dupIClass = 13;
|
|
|
|
break;
|
|
|
|
case Hexagon::DuplexIClassE:
|
|
|
|
dupIClass = 14;
|
|
|
|
break;
|
|
|
|
case Hexagon::DuplexIClassF:
|
|
|
|
dupIClass = 15;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
llvm_unreachable("Unimplemented DuplexIClass");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// 29 is the bit position.
|
|
|
|
// 0b1110 =0xE bits are masked off and down shifted by 1 bit.
|
|
|
|
// Last bit is moved to bit position 13
|
|
|
|
Binary = ((dupIClass & 0xE) << (29 - 1)) | ((dupIClass & 0x1) << 13);
|
|
|
|
|
2017-02-02 23:32:26 +08:00
|
|
|
const MCInst *subInst0 = MI.getOperand(0).getInst();
|
|
|
|
const MCInst *subInst1 = MI.getOperand(1).getInst();
|
2015-06-06 00:00:11 +08:00
|
|
|
|
|
|
|
// get subinstruction slot 0
|
|
|
|
unsigned subInstSlot0Bits = getBinaryCodeForInstr(*subInst0, Fixups, STI);
|
|
|
|
// get subinstruction slot 1
|
|
|
|
unsigned subInstSlot1Bits = getBinaryCodeForInstr(*subInst1, Fixups, STI);
|
|
|
|
|
|
|
|
Binary |= subInstSlot0Bits | (subInstSlot1Bits << 16);
|
|
|
|
}
|
2015-06-04 23:03:02 +08:00
|
|
|
support::endian::Writer<support::little>(OS).write<uint32_t>(Binary);
|
2014-10-03 21:18:11 +08:00
|
|
|
++MCNumEmitted;
|
|
|
|
}
|
|
|
|
|
2016-02-10 03:18:02 +08:00
|
|
|
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.
|
2017-02-03 03:58:22 +08:00
|
|
|
Hexagon::Fixups HexagonMCCodeEmitter::getFixupNoBits(
|
|
|
|
MCInstrInfo const &MCII, const MCInst &MI, const MCOperand &MO,
|
|
|
|
const MCSymbolRefExpr::VariantKind kind) const {
|
2015-05-02 05:14:21 +08:00
|
|
|
const MCInstrDesc &MCID = HexagonMCInstrInfo::getDesc(MCII, MI);
|
|
|
|
unsigned insnType = llvm::HexagonMCInstrInfo::getType(MCII, MI);
|
|
|
|
|
2017-02-03 03:58:22 +08:00
|
|
|
if (insnType == HexagonII::TypeEXTENDER) {
|
2015-05-02 05:14:21 +08:00
|
|
|
switch (kind) {
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_GOTREL:
|
2015-05-02 05:14:21 +08:00
|
|
|
return Hexagon::fixup_Hexagon_GOTREL_32_6_X;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_GOT:
|
2015-05-02 05:14:21 +08:00
|
|
|
return Hexagon::fixup_Hexagon_GOT_32_6_X;
|
2016-02-11 02:32:01 +08:00
|
|
|
case MCSymbolRefExpr::VK_TPREL:
|
2015-05-02 05:14:21 +08:00
|
|
|
return Hexagon::fixup_Hexagon_TPREL_32_6_X;
|
2016-02-11 02:32:01 +08:00
|
|
|
case MCSymbolRefExpr::VK_DTPREL:
|
2015-05-02 05:14:21 +08:00
|
|
|
return Hexagon::fixup_Hexagon_DTPREL_32_6_X;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_Hexagon_GD_GOT:
|
2015-05-02 05:14:21 +08:00
|
|
|
return Hexagon::fixup_Hexagon_GD_GOT_32_6_X;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_Hexagon_LD_GOT:
|
2015-05-02 05:14:21 +08:00
|
|
|
return Hexagon::fixup_Hexagon_LD_GOT_32_6_X;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_Hexagon_IE:
|
2015-05-02 05:14:21 +08:00
|
|
|
return Hexagon::fixup_Hexagon_IE_32_6_X;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_Hexagon_IE_GOT:
|
2015-05-02 05:14:21 +08:00
|
|
|
return Hexagon::fixup_Hexagon_IE_GOT_32_6_X;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_Hexagon_PCREL:
|
2017-02-03 03:58:22 +08:00
|
|
|
return Hexagon::fixup_Hexagon_B32_PCREL_X;
|
|
|
|
case MCSymbolRefExpr::VK_None: {
|
|
|
|
auto Insts = HexagonMCInstrInfo::bundleInstructions(**CurrentBundle);
|
|
|
|
for (auto I = Insts.begin(), N = Insts.end(); I != N; ++I)
|
|
|
|
if (I->getInst() == &MI) {
|
|
|
|
if (HexagonMCInstrInfo::getDesc(MCII, *(I + 1)->getInst()).isBranch() ||
|
|
|
|
(HexagonMCInstrInfo::getType(MCII, *(I + 1)->getInst()) == HexagonII::TypeCR))
|
|
|
|
return Hexagon::fixup_Hexagon_B32_PCREL_X;
|
|
|
|
else
|
|
|
|
return Hexagon::fixup_Hexagon_32_6_X;
|
|
|
|
}
|
|
|
|
raise_relocation_error(0, kind);
|
|
|
|
}
|
2016-02-10 03:18:02 +08:00
|
|
|
default:
|
|
|
|
raise_relocation_error(0, kind);
|
2015-05-02 05:14:21 +08:00
|
|
|
}
|
|
|
|
} else if (MCID.isBranch())
|
2016-02-10 03:18:02 +08:00
|
|
|
return Hexagon::fixup_Hexagon_B13_PCREL;
|
2015-05-02 05:14:21 +08:00
|
|
|
|
|
|
|
switch (MCID.getOpcode()) {
|
|
|
|
case Hexagon::HI:
|
|
|
|
case Hexagon::A2_tfrih:
|
|
|
|
switch (kind) {
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_GOT:
|
2015-05-02 05:14:21 +08:00
|
|
|
return Hexagon::fixup_Hexagon_GOT_HI16;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_GOTREL:
|
2015-05-02 05:14:21 +08:00
|
|
|
return Hexagon::fixup_Hexagon_GOTREL_HI16;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_Hexagon_GD_GOT:
|
2015-05-02 05:14:21 +08:00
|
|
|
return Hexagon::fixup_Hexagon_GD_GOT_HI16;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_Hexagon_LD_GOT:
|
2015-05-02 05:14:21 +08:00
|
|
|
return Hexagon::fixup_Hexagon_LD_GOT_HI16;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_Hexagon_IE:
|
2015-05-02 05:14:21 +08:00
|
|
|
return Hexagon::fixup_Hexagon_IE_HI16;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_Hexagon_IE_GOT:
|
2015-05-02 05:14:21 +08:00
|
|
|
return Hexagon::fixup_Hexagon_IE_GOT_HI16;
|
2016-02-11 02:32:01 +08:00
|
|
|
case MCSymbolRefExpr::VK_TPREL:
|
2015-05-02 05:14:21 +08:00
|
|
|
return Hexagon::fixup_Hexagon_TPREL_HI16;
|
2016-02-11 02:32:01 +08:00
|
|
|
case MCSymbolRefExpr::VK_DTPREL:
|
2015-05-02 05:14:21 +08:00
|
|
|
return Hexagon::fixup_Hexagon_DTPREL_HI16;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_None:
|
2015-05-02 05:14:21 +08:00
|
|
|
return Hexagon::fixup_Hexagon_HI16;
|
2016-02-10 03:18:02 +08:00
|
|
|
default:
|
|
|
|
raise_relocation_error(0, kind);
|
2015-05-02 05:14:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
case Hexagon::LO:
|
|
|
|
case Hexagon::A2_tfril:
|
|
|
|
switch (kind) {
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_GOT:
|
2015-05-02 05:14:21 +08:00
|
|
|
return Hexagon::fixup_Hexagon_GOT_LO16;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_GOTREL:
|
2015-05-02 05:14:21 +08:00
|
|
|
return Hexagon::fixup_Hexagon_GOTREL_LO16;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_Hexagon_GD_GOT:
|
2015-05-02 05:14:21 +08:00
|
|
|
return Hexagon::fixup_Hexagon_GD_GOT_LO16;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_Hexagon_LD_GOT:
|
2015-05-02 05:14:21 +08:00
|
|
|
return Hexagon::fixup_Hexagon_LD_GOT_LO16;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_Hexagon_IE:
|
2015-05-02 05:14:21 +08:00
|
|
|
return Hexagon::fixup_Hexagon_IE_LO16;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_Hexagon_IE_GOT:
|
2015-05-02 05:14:21 +08:00
|
|
|
return Hexagon::fixup_Hexagon_IE_GOT_LO16;
|
2016-02-11 02:32:01 +08:00
|
|
|
case MCSymbolRefExpr::VK_TPREL:
|
2015-05-02 05:14:21 +08:00
|
|
|
return Hexagon::fixup_Hexagon_TPREL_LO16;
|
2016-02-11 02:32:01 +08:00
|
|
|
case MCSymbolRefExpr::VK_DTPREL:
|
2015-05-02 05:14:21 +08:00
|
|
|
return Hexagon::fixup_Hexagon_DTPREL_LO16;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_None:
|
2015-05-02 05:14:21 +08:00
|
|
|
return Hexagon::fixup_Hexagon_LO16;
|
2016-02-10 03:18:02 +08:00
|
|
|
default:
|
|
|
|
raise_relocation_error(0, kind);
|
2015-05-02 05:14:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// The only relocs left should be GP relative:
|
|
|
|
default:
|
|
|
|
if (MCID.mayStore() || MCID.mayLoad()) {
|
2016-02-19 01:49:57 +08:00
|
|
|
for (const MCPhysReg *ImpUses = MCID.getImplicitUses(); *ImpUses;
|
|
|
|
++ImpUses) {
|
2016-01-11 23:51:53 +08:00
|
|
|
if (*ImpUses != Hexagon::GP)
|
|
|
|
continue;
|
|
|
|
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:
|
2016-02-10 03:18:02 +08:00
|
|
|
raise_relocation_error(0, kind);
|
2015-05-02 05:14:21 +08:00
|
|
|
}
|
|
|
|
}
|
2016-02-10 03:18:02 +08:00
|
|
|
}
|
|
|
|
raise_relocation_error(0, kind);
|
2015-05-02 05:14:21 +08:00
|
|
|
}
|
2016-02-10 03:18:02 +08:00
|
|
|
llvm_unreachable("Relocation exit not taken");
|
|
|
|
}
|
2015-05-02 05:14:21 +08:00
|
|
|
|
2015-06-16 05:52:13 +08:00
|
|
|
namespace llvm {
|
|
|
|
extern const MCInstrDesc HexagonInsts[];
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
bool isPCRel (unsigned Kind) {
|
|
|
|
switch(Kind){
|
|
|
|
case fixup_Hexagon_B22_PCREL:
|
|
|
|
case fixup_Hexagon_B15_PCREL:
|
|
|
|
case fixup_Hexagon_B7_PCREL:
|
|
|
|
case fixup_Hexagon_B13_PCREL:
|
|
|
|
case fixup_Hexagon_B9_PCREL:
|
|
|
|
case fixup_Hexagon_B32_PCREL_X:
|
|
|
|
case fixup_Hexagon_B22_PCREL_X:
|
|
|
|
case fixup_Hexagon_B15_PCREL_X:
|
|
|
|
case fixup_Hexagon_B13_PCREL_X:
|
|
|
|
case fixup_Hexagon_B9_PCREL_X:
|
|
|
|
case fixup_Hexagon_B7_PCREL_X:
|
|
|
|
case fixup_Hexagon_32_PCREL:
|
|
|
|
case fixup_Hexagon_PLT_B22_PCREL:
|
|
|
|
case fixup_Hexagon_GD_PLT_B22_PCREL:
|
|
|
|
case fixup_Hexagon_LD_PLT_B22_PCREL:
|
|
|
|
case fixup_Hexagon_6_PCREL_X:
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2015-06-23 17:49:53 +08:00
|
|
|
}
|
2015-06-16 05:52:13 +08:00
|
|
|
|
2015-05-02 05:14:21 +08:00
|
|
|
unsigned HexagonMCCodeEmitter::getExprOpValue(const MCInst &MI,
|
|
|
|
const MCOperand &MO,
|
|
|
|
const MCExpr *ME,
|
|
|
|
SmallVectorImpl<MCFixup> &Fixups,
|
|
|
|
const MCSubtargetInfo &STI) const
|
|
|
|
|
|
|
|
{
|
2016-02-16 02:42:07 +08:00
|
|
|
if (isa<HexagonMCExpr>(ME))
|
|
|
|
ME = &HexagonMCInstrInfo::getExpr(*ME);
|
2016-02-10 03:18:02 +08:00
|
|
|
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);
|
2015-06-16 05:52:13 +08:00
|
|
|
return 0;
|
2015-05-02 05:14:21 +08:00
|
|
|
}
|
|
|
|
Hexagon::Fixups FixupKind =
|
|
|
|
Hexagon::Fixups(Hexagon::fixup_Hexagon_TPREL_LO16);
|
|
|
|
const MCSymbolRefExpr *MCSRE = static_cast<const MCSymbolRefExpr *>(ME);
|
|
|
|
const MCInstrDesc &MCID = HexagonMCInstrInfo::getDesc(MCII, MI);
|
|
|
|
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");
|
2015-05-02 05:30:22 +08:00
|
|
|
DEBUG(dbgs() << "Opcode: " << MCID.getOpcode() << "\n");
|
2015-05-02 05:14:21 +08:00
|
|
|
DEBUG(dbgs() << "Relocation bits: " << bits << "\n");
|
|
|
|
DEBUG(dbgs() << "Addend: " << *Addend << "\n");
|
|
|
|
DEBUG(dbgs() << "----------------------------------------\n");
|
|
|
|
|
|
|
|
switch (bits) {
|
|
|
|
default:
|
2016-02-10 03:18:02 +08:00
|
|
|
raise_relocation_error(bits, kind);
|
2015-05-02 05:14:21 +08:00
|
|
|
case 32:
|
|
|
|
switch (kind) {
|
2016-02-11 02:32:01 +08:00
|
|
|
case MCSymbolRefExpr::VK_DTPREL:
|
2016-02-10 03:18:02 +08:00
|
|
|
FixupKind = *Extended ? Hexagon::fixup_Hexagon_DTPREL_32_6_X
|
|
|
|
: Hexagon::fixup_Hexagon_DTPREL_32;
|
2015-05-02 05:14:21 +08:00
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_GOT:
|
2015-05-02 05:14:21 +08:00
|
|
|
FixupKind = *Extended ? Hexagon::fixup_Hexagon_GOT_32_6_X
|
|
|
|
: Hexagon::fixup_Hexagon_GOT_32;
|
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_GOTREL:
|
2015-05-02 05:14:21 +08:00
|
|
|
FixupKind = *Extended ? Hexagon::fixup_Hexagon_GOTREL_32_6_X
|
|
|
|
: Hexagon::fixup_Hexagon_GOTREL_32;
|
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_Hexagon_GD_GOT:
|
2015-05-02 05:14:21 +08:00
|
|
|
FixupKind = *Extended ? Hexagon::fixup_Hexagon_GD_GOT_32_6_X
|
|
|
|
: Hexagon::fixup_Hexagon_GD_GOT_32;
|
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_Hexagon_IE:
|
2015-05-02 05:14:21 +08:00
|
|
|
FixupKind = *Extended ? Hexagon::fixup_Hexagon_IE_32_6_X
|
|
|
|
: Hexagon::fixup_Hexagon_IE_32;
|
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_Hexagon_IE_GOT:
|
2015-05-02 05:14:21 +08:00
|
|
|
FixupKind = *Extended ? Hexagon::fixup_Hexagon_IE_GOT_32_6_X
|
|
|
|
: Hexagon::fixup_Hexagon_IE_GOT_32;
|
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_Hexagon_LD_GOT:
|
|
|
|
FixupKind = *Extended ? Hexagon::fixup_Hexagon_LD_GOT_32_6_X
|
|
|
|
: Hexagon::fixup_Hexagon_LD_GOT_32;
|
2015-05-02 05:14:21 +08:00
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_Hexagon_PCREL:
|
|
|
|
FixupKind = Hexagon::fixup_Hexagon_32_PCREL;
|
2015-05-02 05:14:21 +08:00
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_None:
|
2015-05-02 05:14:21 +08:00
|
|
|
FixupKind =
|
|
|
|
*Extended ? Hexagon::fixup_Hexagon_32_6_X : Hexagon::fixup_Hexagon_32;
|
|
|
|
break;
|
2016-02-11 02:32:01 +08:00
|
|
|
case MCSymbolRefExpr::VK_TPREL:
|
2016-02-10 03:18:02 +08:00
|
|
|
FixupKind = *Extended ? Hexagon::fixup_Hexagon_TPREL_32_6_X
|
|
|
|
: Hexagon::fixup_Hexagon_TPREL_32;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
raise_relocation_error(bits, kind);
|
2015-05-02 05:14:21 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 22:
|
|
|
|
switch (kind) {
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_Hexagon_GD_PLT:
|
2015-05-02 05:14:21 +08:00
|
|
|
FixupKind = Hexagon::fixup_Hexagon_GD_PLT_B22_PCREL;
|
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_Hexagon_LD_PLT:
|
2015-05-02 05:14:21 +08:00
|
|
|
FixupKind = Hexagon::fixup_Hexagon_LD_PLT_B22_PCREL;
|
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
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;
|
2015-05-02 05:14:21 +08:00
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
default:
|
|
|
|
raise_relocation_error(bits, kind);
|
2015-05-02 05:14:21 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 16:
|
|
|
|
if (*Extended) {
|
|
|
|
switch (kind) {
|
2016-02-11 02:32:01 +08:00
|
|
|
case MCSymbolRefExpr::VK_DTPREL:
|
2016-02-10 03:18:02 +08:00
|
|
|
FixupKind = Hexagon::fixup_Hexagon_DTPREL_16_X;
|
2015-05-02 05:14:21 +08:00
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_GOT:
|
2015-05-02 05:14:21 +08:00
|
|
|
FixupKind = Hexagon::fixup_Hexagon_GOT_16_X;
|
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_GOTREL:
|
2015-05-02 05:14:21 +08:00
|
|
|
FixupKind = Hexagon::fixup_Hexagon_GOTREL_16_X;
|
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_Hexagon_GD_GOT:
|
2015-05-02 05:14:21 +08:00
|
|
|
FixupKind = Hexagon::fixup_Hexagon_GD_GOT_16_X;
|
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_Hexagon_IE:
|
2015-05-02 05:14:21 +08:00
|
|
|
FixupKind = Hexagon::fixup_Hexagon_IE_16_X;
|
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_Hexagon_IE_GOT:
|
2015-05-02 05:14:21 +08:00
|
|
|
FixupKind = Hexagon::fixup_Hexagon_IE_GOT_16_X;
|
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_Hexagon_LD_GOT:
|
|
|
|
FixupKind = Hexagon::fixup_Hexagon_LD_GOT_16_X;
|
2015-05-02 05:14:21 +08:00
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_None:
|
|
|
|
FixupKind = Hexagon::fixup_Hexagon_16_X;
|
|
|
|
break;
|
2016-02-11 02:32:01 +08:00
|
|
|
case MCSymbolRefExpr::VK_TPREL:
|
2016-02-10 03:18:02 +08:00
|
|
|
FixupKind = Hexagon::fixup_Hexagon_TPREL_16_X;
|
2015-05-02 05:14:21 +08:00
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
default:
|
|
|
|
raise_relocation_error(bits, kind);
|
2015-05-02 05:14:21 +08:00
|
|
|
}
|
|
|
|
} else
|
|
|
|
switch (kind) {
|
2016-02-17 04:38:17 +08:00
|
|
|
case MCSymbolRefExpr::VK_None: {
|
|
|
|
if (HexagonMCInstrInfo::s23_2_reloc(*MO.getExpr()))
|
|
|
|
FixupKind = Hexagon::fixup_Hexagon_23_REG;
|
|
|
|
else
|
|
|
|
raise_relocation_error(bits, kind);
|
|
|
|
break;
|
|
|
|
}
|
2016-02-11 02:32:01 +08:00
|
|
|
case MCSymbolRefExpr::VK_DTPREL:
|
2016-02-10 03:18:02 +08:00
|
|
|
FixupKind = Hexagon::fixup_Hexagon_DTPREL_16;
|
2015-05-02 05:14:21 +08:00
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_GOTREL:
|
|
|
|
if (MCID.getOpcode() == Hexagon::HI)
|
2015-05-02 05:14:21 +08:00
|
|
|
FixupKind = Hexagon::fixup_Hexagon_GOTREL_HI16;
|
|
|
|
else
|
|
|
|
FixupKind = Hexagon::fixup_Hexagon_GOTREL_LO16;
|
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_Hexagon_GD_GOT:
|
|
|
|
FixupKind = Hexagon::fixup_Hexagon_GD_GOT_16;
|
2015-05-02 05:14:21 +08:00
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_Hexagon_GPREL:
|
|
|
|
FixupKind = Hexagon::fixup_Hexagon_GPREL16_0;
|
2015-05-02 05:14:21 +08:00
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_Hexagon_HI16:
|
2015-05-02 05:14:21 +08:00
|
|
|
FixupKind = Hexagon::fixup_Hexagon_HI16;
|
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_Hexagon_IE_GOT:
|
|
|
|
FixupKind = Hexagon::fixup_Hexagon_IE_GOT_16;
|
2015-05-02 05:14:21 +08:00
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_Hexagon_LD_GOT:
|
2015-05-02 05:14:21 +08:00
|
|
|
FixupKind = Hexagon::fixup_Hexagon_LD_GOT_16;
|
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_Hexagon_LO16:
|
|
|
|
FixupKind = Hexagon::fixup_Hexagon_LO16;
|
2015-05-02 05:14:21 +08:00
|
|
|
break;
|
2016-02-11 02:32:01 +08:00
|
|
|
case MCSymbolRefExpr::VK_TPREL:
|
2015-05-02 05:14:21 +08:00
|
|
|
FixupKind = Hexagon::fixup_Hexagon_TPREL_16;
|
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
default:
|
|
|
|
raise_relocation_error(bits, kind);
|
2015-05-02 05:14:21 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 15:
|
2016-02-10 03:18:02 +08:00
|
|
|
switch (kind) {
|
|
|
|
case MCSymbolRefExpr::VK_None:
|
2015-05-02 05:14:21 +08:00
|
|
|
FixupKind = *Extended ? Hexagon::fixup_Hexagon_B15_PCREL_X
|
|
|
|
: Hexagon::fixup_Hexagon_B15_PCREL;
|
2016-02-10 03:18:02 +08:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
raise_relocation_error(bits, kind);
|
|
|
|
}
|
2015-05-02 05:14:21 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 13:
|
2016-02-10 03:18:02 +08:00
|
|
|
switch (kind) {
|
|
|
|
case MCSymbolRefExpr::VK_None:
|
2015-05-02 05:14:21 +08:00
|
|
|
FixupKind = Hexagon::fixup_Hexagon_B13_PCREL;
|
2016-02-10 03:18:02 +08:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
raise_relocation_error(bits, kind);
|
2015-05-02 05:14:21 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 12:
|
|
|
|
if (*Extended)
|
|
|
|
switch (kind) {
|
|
|
|
// There isn't a GOT_12_X, both 11_X and 16_X resolve to 6/26
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_GOT:
|
2015-05-02 05:14:21 +08:00
|
|
|
FixupKind = Hexagon::fixup_Hexagon_GOT_16_X;
|
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_GOTREL:
|
2015-05-02 05:14:21 +08:00
|
|
|
FixupKind = Hexagon::fixup_Hexagon_GOTREL_16_X;
|
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_None:
|
|
|
|
FixupKind = Hexagon::fixup_Hexagon_12_X;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
raise_relocation_error(bits, kind);
|
2015-05-02 05:14:21 +08:00
|
|
|
}
|
2016-02-10 03:18:02 +08:00
|
|
|
else
|
|
|
|
raise_relocation_error(bits, kind);
|
2015-05-02 05:14:21 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 11:
|
|
|
|
if (*Extended)
|
|
|
|
switch (kind) {
|
2016-02-11 02:32:01 +08:00
|
|
|
case MCSymbolRefExpr::VK_DTPREL:
|
2016-02-10 03:18:02 +08:00
|
|
|
FixupKind = Hexagon::fixup_Hexagon_DTPREL_11_X;
|
2015-05-02 05:14:21 +08:00
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_GOT:
|
2015-05-02 05:14:21 +08:00
|
|
|
FixupKind = Hexagon::fixup_Hexagon_GOT_11_X;
|
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_GOTREL:
|
2015-05-02 05:14:21 +08:00
|
|
|
FixupKind = Hexagon::fixup_Hexagon_GOTREL_11_X;
|
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_Hexagon_GD_GOT:
|
2015-05-02 05:14:21 +08:00
|
|
|
FixupKind = Hexagon::fixup_Hexagon_GD_GOT_11_X;
|
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_Hexagon_IE_GOT:
|
|
|
|
FixupKind = Hexagon::fixup_Hexagon_IE_GOT_11_X;
|
|
|
|
break;
|
|
|
|
case MCSymbolRefExpr::VK_Hexagon_LD_GOT:
|
2015-05-02 05:14:21 +08:00
|
|
|
FixupKind = Hexagon::fixup_Hexagon_LD_GOT_11_X;
|
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_None:
|
|
|
|
FixupKind = Hexagon::fixup_Hexagon_11_X;
|
2015-05-02 05:14:21 +08:00
|
|
|
break;
|
2016-02-11 02:32:01 +08:00
|
|
|
case MCSymbolRefExpr::VK_TPREL:
|
2015-05-02 05:14:21 +08:00
|
|
|
FixupKind = Hexagon::fixup_Hexagon_TPREL_11_X;
|
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
default:
|
|
|
|
raise_relocation_error(bits, kind);
|
2015-05-02 05:14:21 +08:00
|
|
|
}
|
|
|
|
else {
|
2016-02-10 03:18:02 +08:00
|
|
|
switch (kind) {
|
2016-02-11 02:32:01 +08:00
|
|
|
case MCSymbolRefExpr::VK_TPREL:
|
2016-02-10 03:18:02 +08:00
|
|
|
FixupKind = Hexagon::fixup_Hexagon_TPREL_11_X;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
raise_relocation_error(bits, kind);
|
|
|
|
}
|
2015-05-02 05:14:21 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 10:
|
2016-02-10 03:18:02 +08:00
|
|
|
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);
|
2015-05-02 05:14:21 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 9:
|
|
|
|
if (MCID.isBranch() ||
|
2016-02-10 03:18:02 +08:00
|
|
|
(HexagonMCInstrInfo::getType(MCII, MI) == HexagonII::TypeCR))
|
2015-05-02 05:14:21 +08:00
|
|
|
FixupKind = *Extended ? Hexagon::fixup_Hexagon_B9_PCREL_X
|
|
|
|
: Hexagon::fixup_Hexagon_B9_PCREL;
|
|
|
|
else if (*Extended)
|
|
|
|
FixupKind = Hexagon::fixup_Hexagon_9_X;
|
2016-02-10 03:18:02 +08:00
|
|
|
else
|
|
|
|
raise_relocation_error(bits, kind);
|
2015-05-02 05:14:21 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 8:
|
|
|
|
if (*Extended)
|
|
|
|
FixupKind = Hexagon::fixup_Hexagon_8_X;
|
2016-02-10 03:18:02 +08:00
|
|
|
else
|
|
|
|
raise_relocation_error(bits, kind);
|
2015-05-02 05:14:21 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 7:
|
|
|
|
if (MCID.isBranch() ||
|
2016-02-10 03:18:02 +08:00
|
|
|
(HexagonMCInstrInfo::getType(MCII, MI) == HexagonII::TypeCR))
|
2015-05-02 05:14:21 +08:00
|
|
|
FixupKind = *Extended ? Hexagon::fixup_Hexagon_B7_PCREL_X
|
|
|
|
: Hexagon::fixup_Hexagon_B7_PCREL;
|
|
|
|
else if (*Extended)
|
|
|
|
FixupKind = Hexagon::fixup_Hexagon_7_X;
|
2016-02-10 03:18:02 +08:00
|
|
|
else
|
|
|
|
raise_relocation_error(bits, kind);
|
2015-05-02 05:14:21 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 6:
|
|
|
|
if (*Extended) {
|
|
|
|
switch (kind) {
|
2016-02-11 02:32:01 +08:00
|
|
|
case MCSymbolRefExpr::VK_DTPREL:
|
2016-02-10 03:18:02 +08:00
|
|
|
FixupKind = Hexagon::fixup_Hexagon_DTPREL_16_X;
|
2015-05-02 05:14:21 +08:00
|
|
|
break;
|
|
|
|
// This is part of an extender, GOT_11 is a
|
|
|
|
// Word32_U6 unsigned/truncated reloc.
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_GOT:
|
2015-05-02 05:14:21 +08:00
|
|
|
FixupKind = Hexagon::fixup_Hexagon_GOT_11_X;
|
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_GOTREL:
|
2015-05-02 05:14:21 +08:00
|
|
|
FixupKind = Hexagon::fixup_Hexagon_GOTREL_11_X;
|
|
|
|
break;
|
2016-02-10 03:18:02 +08:00
|
|
|
case MCSymbolRefExpr::VK_Hexagon_PCREL:
|
|
|
|
FixupKind = Hexagon::fixup_Hexagon_6_PCREL_X;
|
|
|
|
break;
|
2016-02-11 02:32:01 +08:00
|
|
|
case MCSymbolRefExpr::VK_TPREL:
|
2016-02-10 03:18:02 +08:00
|
|
|
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);
|
2015-05-02 05:14:21 +08:00
|
|
|
}
|
2016-02-10 03:18:02 +08:00
|
|
|
} else
|
|
|
|
raise_relocation_error(bits, kind);
|
2015-05-02 05:14:21 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 0:
|
|
|
|
FixupKind = getFixupNoBits(MCII, MI, MO, kind);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2016-02-10 03:18:02 +08:00
|
|
|
MCExpr const *FixupExpression =
|
|
|
|
(*Addend > 0 && isPCRel(FixupKind))
|
|
|
|
? MCBinaryExpr::createAdd(MO.getExpr(),
|
|
|
|
MCConstantExpr::create(*Addend, MCT), MCT)
|
|
|
|
: MO.getExpr();
|
2015-06-16 05:52:13 +08:00
|
|
|
|
2016-02-10 03:18:02 +08:00
|
|
|
MCFixup fixup = MCFixup::create(*Addend, FixupExpression,
|
2015-06-16 05:52:13 +08:00
|
|
|
MCFixupKind(FixupKind), MI.getLoc());
|
2015-05-02 05:14:21 +08:00
|
|
|
Fixups.push_back(fixup);
|
|
|
|
// All of the information is in the fixup.
|
2016-02-10 03:18:02 +08:00
|
|
|
return 0;
|
2015-05-02 05:14:21 +08:00
|
|
|
}
|
|
|
|
|
2014-10-03 21:18:11 +08:00
|
|
|
unsigned
|
|
|
|
HexagonMCCodeEmitter::getMachineOpValue(MCInst const &MI, MCOperand const &MO,
|
|
|
|
SmallVectorImpl<MCFixup> &Fixups,
|
|
|
|
MCSubtargetInfo const &STI) const {
|
2017-02-02 23:32:26 +08:00
|
|
|
|
|
|
|
if (HexagonMCInstrInfo::isNewValue(MCII, MI) &&
|
|
|
|
&MO == &MI.getOperand(HexagonMCInstrInfo::getNewValueOp(MCII, MI))) {
|
|
|
|
// Calculate the new value distance to the associated producer
|
|
|
|
MCOperand const &MCO =
|
|
|
|
MI.getOperand(HexagonMCInstrInfo::getNewValueOp(MCII, MI));
|
|
|
|
unsigned SOffset = 0;
|
|
|
|
unsigned VOffset = 0;
|
|
|
|
unsigned Register = MCO.getReg();
|
|
|
|
unsigned Register1;
|
|
|
|
unsigned Register2;
|
|
|
|
auto Instructions = HexagonMCInstrInfo::bundleInstructions(**CurrentBundle);
|
|
|
|
auto i = Instructions.begin() + *CurrentIndex - 1;
|
|
|
|
for (;; --i) {
|
|
|
|
assert(i != Instructions.begin() - 1 && "Couldn't find producer");
|
|
|
|
MCInst const &Inst = *i->getInst();
|
|
|
|
if (HexagonMCInstrInfo::isImmext(Inst))
|
|
|
|
continue;
|
|
|
|
++SOffset;
|
|
|
|
if (HexagonMCInstrInfo::isVector(MCII, Inst))
|
|
|
|
// Vector instructions don't count scalars
|
|
|
|
++VOffset;
|
|
|
|
Register1 =
|
|
|
|
HexagonMCInstrInfo::hasNewValue(MCII, Inst)
|
|
|
|
? HexagonMCInstrInfo::getNewValueOperand(MCII, Inst).getReg()
|
|
|
|
: static_cast<unsigned>(Hexagon::NoRegister);
|
|
|
|
Register2 =
|
|
|
|
HexagonMCInstrInfo::hasNewValue2(MCII, Inst)
|
|
|
|
? HexagonMCInstrInfo::getNewValueOperand2(MCII, Inst).getReg()
|
|
|
|
: static_cast<unsigned>(Hexagon::NoRegister);
|
|
|
|
if (!RegisterMatches(Register, Register1, Register2))
|
|
|
|
// This isn't the register we're looking for
|
|
|
|
continue;
|
|
|
|
if (!HexagonMCInstrInfo::isPredicated(MCII, Inst))
|
|
|
|
// Producer is unpredicated
|
|
|
|
break;
|
|
|
|
assert(HexagonMCInstrInfo::isPredicated(MCII, MI) &&
|
|
|
|
"Unpredicated consumer depending on predicated producer");
|
|
|
|
if (HexagonMCInstrInfo::isPredicatedTrue(MCII, Inst) ==
|
|
|
|
HexagonMCInstrInfo::isPredicatedTrue(MCII, MI))
|
|
|
|
// Producer predicate sense matched ours
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// Hexagon PRM 10.11 Construct Nt from distance
|
|
|
|
unsigned Offset =
|
|
|
|
HexagonMCInstrInfo::isVector(MCII, MI) ? VOffset : SOffset;
|
|
|
|
Offset <<= 1;
|
|
|
|
Offset |=
|
|
|
|
HexagonMCInstrInfo::SubregisterBit(Register, Register1, Register2);
|
|
|
|
return Offset;
|
|
|
|
}
|
2016-03-22 04:13:33 +08:00
|
|
|
assert(!MO.isImm());
|
|
|
|
if (MO.isReg()) {
|
|
|
|
unsigned Reg = MO.getReg();
|
2017-02-02 23:32:26 +08:00
|
|
|
if (HexagonMCInstrInfo::isSubInstruction(MI) ||
|
|
|
|
llvm::HexagonMCInstrInfo::getType(MCII, MI) == HexagonII::TypeCJ)
|
2016-03-22 04:13:33 +08:00
|
|
|
return HexagonMCInstrInfo::getDuplexRegisterNumbering(Reg);
|
|
|
|
switch(MI.getOpcode()){
|
|
|
|
case Hexagon::A2_tfrrcr:
|
|
|
|
case Hexagon::A2_tfrcrr:
|
|
|
|
if(Reg == Hexagon::M0)
|
|
|
|
Reg = Hexagon::C6;
|
|
|
|
if(Reg == Hexagon::M1)
|
|
|
|
Reg = Hexagon::C7;
|
|
|
|
}
|
|
|
|
return MCT.getRegisterInfo()->getEncodingValue(Reg);
|
|
|
|
}
|
2015-05-02 05:14:21 +08:00
|
|
|
|
|
|
|
return getExprOpValue(MI, MO, MO.getExpr(), Fixups, STI);
|
2014-10-03 21:18:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
MCCodeEmitter *llvm::createHexagonMCCodeEmitter(MCInstrInfo const &MII,
|
|
|
|
MCRegisterInfo const &MRI,
|
|
|
|
MCContext &MCT) {
|
2015-03-11 06:03:14 +08:00
|
|
|
return new HexagonMCCodeEmitter(MII, MCT);
|
2014-10-03 21:18:11 +08:00
|
|
|
}
|
|
|
|
|
Check that emitted instructions meet their predicates on all targets except ARM, Mips, and X86.
Summary:
* ARM is omitted from this patch because this check appears to expose bugs in this target.
* Mips is omitted from this patch because this check either detects bugs or deliberate
emission of instructions that don't satisfy their predicates. One deliberate
use is the SYNC instruction where the version with an operand is correctly
defined as requiring MIPS32 while the version without an operand is defined
as an alias of 'SYNC 0' and requires MIPS2.
* X86 is omitted from this patch because it doesn't use the tablegen-erated
MCCodeEmitter infrastructure.
Patches for ARM and Mips will follow.
Depends on D25617
Reviewers: tstellarAMD, jmolloy
Subscribers: wdng, jmolloy, aemerson, rengolin, arsenm, jyknight, nemanjai, nhaehnle, tstellarAMD, llvm-commits
Differential Revision: https://reviews.llvm.org/D25618
llvm-svn: 287439
2016-11-19 21:05:44 +08:00
|
|
|
#define ENABLE_INSTR_PREDICATE_VERIFIER
|
2014-10-03 21:18:11 +08:00
|
|
|
#include "HexagonGenMCCodeEmitter.inc"
|