36#define DEBUG_TYPE "mccodeemitter"
41STATISTIC(MCNumEmitted,
"Number of MC instructions emitted");
46#define _ fixup_Invalid
47#define P(x) Hexagon::fixup_Hexagon##x
48static const std::map<unsigned, std::vector<unsigned>>
ExtFixups = {
51 _,
_,
P(_DTPREL_16_X),
P(_DTPREL_11_X),
52 P(_DTPREL_11_X),
P(_9_X),
_,
P(_DTPREL_11_X),
53 P(_DTPREL_16_X),
_,
_,
_,
54 P(_DTPREL_16_X),
_,
_,
_,
61 _,
_,
P(_GOT_11_X),
_ ,
62 _ ,
P(_9_X),
_,
P(_GOT_11_X),
63 P(_GOT_16_X),
_,
_,
_,
64 P(_GOT_16_X),
_,
_,
_,
71 _,
_,
P(_GOTREL_11_X),
P(_GOTREL_11_X),
72 P(_GOTREL_11_X),
P(_9_X),
_,
P(_GOTREL_11_X),
73 P(_GOTREL_16_X),
_,
_,
_,
74 P(_GOTREL_16_X),
_,
_,
_,
81 _,
_,
P(_TPREL_16_X),
P(_TPREL_11_X),
82 P(_TPREL_11_X),
P(_9_X),
_,
P(_TPREL_11_X),
83 P(_TPREL_16_X),
_,
_,
_,
84 P(_TPREL_16_X),
_,
_,
_,
91 _,
_,
P(_GD_GOT_16_X),
P(_GD_GOT_11_X),
92 P(_GD_GOT_11_X),
P(_9_X),
_,
P(_GD_GOT_11_X),
93 P(_GD_GOT_16_X),
_,
_,
_,
94 P(_GD_GOT_16_X),
_,
_,
_,
102 _,
P(_9_X),
_,
P(_GD_PLT_B22_PCREL_X),
105 _,
_,
P(_GD_PLT_B22_PCREL_X),
_,
111 _,
_,
P(_IE_16_X),
_,
113 P(_IE_16_X),
_,
_,
_,
114 P(_IE_16_X),
_,
_,
_,
121 _,
_,
P(_IE_GOT_11_X),
P(_IE_GOT_11_X),
122 P(_IE_GOT_11_X),
P(_9_X),
_,
P(_IE_GOT_11_X),
123 P(_IE_GOT_16_X),
_,
_,
_,
124 P(_IE_GOT_16_X),
_,
_,
_,
128 P(_IE_GOT_32_6_X) }},
131 _,
_,
P(_LD_GOT_11_X),
P(_LD_GOT_11_X),
132 P(_LD_GOT_11_X),
P(_9_X),
_,
P(_LD_GOT_11_X),
133 P(_LD_GOT_16_X),
_,
_,
_,
134 P(_LD_GOT_16_X),
_,
_,
_,
138 P(_LD_GOT_32_6_X) }},
142 _,
P(_9_X),
_,
P(_LD_PLT_B22_PCREL_X),
145 _,
_,
P(_LD_PLT_B22_PCREL_X),
_,
151 _,
_,
P(_6_PCREL_X),
_,
161 _,
_,
P(_6_X),
P(_8_X),
162 P(_8_X),
P(_9_X),
P(_10_X),
P(_11_X),
163 P(_12_X),
P(_B13_PCREL),
_,
P(_B15_PCREL_X),
165 _,
_,
P(_B22_PCREL_X),
_,
172static const std::map<unsigned, std::vector<unsigned>>
StdFixups = {
178 P(_DTPREL_16),
_,
_,
_,
209 _,
_,
P(_PLT_B22_PCREL),
_,
216 _,
_,
_,
P(_TPREL_11_X),
218 P(_TPREL_16),
_,
_,
_,
228 P(_GD_GOT_16),
_,
_,
_,
239 _,
_,
P(_GD_PLT_B22_PCREL),
_,
248 P(_GPREL16_0),
_,
_,
_,
278 P(_IE_GOT_16),
_,
_,
_,
288 P(_LD_GOT_16),
_,
_,
_,
299 _,
_,
P(_LD_PLT_B22_PCREL),
_,
327 _,
P(_B13_PCREL),
_,
P(_B15_PCREL),
329 _,
_,
P(_B22_PCREL),
_,
369 MCInst const &MCI)
const {
371 if (State.Index == 0) {
378 if (State.Index == 1) {
389 if (State.Index ==
Last)
404 State.Extended =
false;
421 return (Consumer == Producer) || (Consumer == Producer2) ||
436 "pseudo-instruction found");
441 unsigned Opc =
MI.getOpcode();
445 if (!Binary &&
Opc != DuplexIClass0 &&
Opc != A4_ext) {
453 if (
Opc >= Hexagon::DuplexIClass0 &&
Opc <= Hexagon::DuplexIClassF) {
455 "Emitting duplex without duplex parse bits");
456 unsigned DupIClass =
MI.getOpcode() - Hexagon::DuplexIClass0;
460 Binary = ((DupIClass & 0xE) << (29 - 1)) | ((DupIClass & 0x1) << 13);
462 const MCInst *Sub0 =
MI.getOperand(0).getInst();
463 const MCInst *Sub1 =
MI.getOperand(1).getInst();
468 State.SubInst1 =
true;
470 State.SubInst1 =
false;
472 Binary |= SubBits0 | (SubBits1 << 16);
481 Stream <<
"Unrecognized relocation combination: width=" << Width
494 using namespace Hexagon;
499 for (
auto I = Instrs.begin(),
N = Instrs.end();
I !=
N; ++
I) {
500 if (
I->getInst() != &
MI)
502 assert(
I+1 !=
N &&
"Extender cannot be last in packet");
503 const MCInst &NextI = *(
I+1)->getInst();
512 static const std::map<unsigned, unsigned> Relocs = {
526 auto F = Relocs.find(VarKind);
527 if (
F != Relocs.end())
535 static const std::map<unsigned, unsigned> RelocsLo = {
547 static const std::map<unsigned, unsigned> RelocsHi = {
561 case Hexagon::A2_tfril: {
562 auto F = RelocsLo.find(VarKind);
563 if (
F != RelocsLo.end())
568 case Hexagon::A2_tfrih: {
569 auto F = RelocsHi.find(VarKind);
570 if (
F != RelocsHi.end())
605unsigned HexagonMCCodeEmitter::getExprOpValue(
const MCInst &
MI,
611 if (ME->evaluateAsAbsolute(
Value)) {
618 if (State.Extended && InstExtendable && !IsSub0) {
620 for (
unsigned I = 0,
E =
MI.getNumOperands();
I !=
E; ++
I) {
621 if (&MO != &
MI.getOperand(
I))
644 const MCSymbolRefExpr *MCSRE =
static_cast<const MCSymbolRefExpr *
>(ME);
654 <<
"\nOpcode: " <<
Opc <<
"\nRelocation bits: "
655 << FixupWidth <<
"\nAddend: " << State.Addend
656 <<
"\nVariant: " <<
unsigned(VarKind)
657 <<
"\n----------------------------------------\n");
662 if (FixupWidth == 16 && !State.Extended) {
674 assert(Shift < std::size(GPRelFixups));
675 auto UsesGP = [](
const MCInstrDesc &
D) {
683 if (
Opc == Hexagon::LO)
685 else if (
Opc == Hexagon::HI)
690 switch (FixupWidth) {
702 else if (FixupWidth == 7 && BranchOrCR)
715 auto FindVK = FixupTable.find(VarKind);
716 if (FindVK != FixupTable.end())
723 const MCExpr *FixupExpr = MO.
getExpr();
737 size_t OperandNumber = ~0U;
738 for (
unsigned i = 0, n =
MI.getNumOperands(); i < n; ++i)
739 if (&
MI.getOperand(i) == &MO) {
743 assert((OperandNumber != ~0U) &&
"Operand not found");
748 unsigned SOffset = 0;
749 unsigned VOffset = 0;
755 const MCOperand *
I = Instrs.begin() + State.Index - 1;
758 assert(
I != Instrs.begin() - 1 &&
"Couldn't find producer");
759 MCInst const &Inst = *
I->getInst();
783 "Unpredicated consumer depending on predicated producer");
801 .operands()[OperandNumber]
803 case GeneralSubRegsRegClassID:
804 case GeneralDoubleLow8RegsRegClassID:
809 return MCT.getRegisterInfo()->getEncodingValue(Reg);
820#include "HexagonGenMCCodeEmitter.inc"
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static Register UseReg(const MachineOperand &MO)
static const std::map< unsigned, std::vector< unsigned > > ExtFixups
static bool RegisterMatches(MCRegister Consumer, MCRegister Producer, MCRegister Producer2)
static const unsigned fixup_Invalid
static void raise_relocation_error(unsigned Width, unsigned Kind)
static bool isPCRel(unsigned Kind)
static const std::map< unsigned, std::vector< unsigned > > StdFixups
Definition for classes that emit Hexagon machine code from MCInsts.
#define HEXAGON_INSTR_SIZE
MachineInstr unsigned OpIdx
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
void encodeSingleInstruction(const MCInst &MI, SmallVectorImpl< char > &CB, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI, uint32_t Parse) const
unsigned getMachineOpValue(MCInst const &MI, MCOperand const &MO, SmallVectorImpl< MCFixup > &Fixups, MCSubtargetInfo const &STI) const
Return binary encoding of operand.
uint64_t getBinaryCodeForInstr(MCInst const &MI, SmallVectorImpl< MCFixup > &Fixups, MCSubtargetInfo const &STI) const
void encodeInstruction(MCInst const &MI, SmallVectorImpl< char > &CB, SmallVectorImpl< MCFixup > &Fixups, MCSubtargetInfo const &STI) const override
Emit the bundle.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
MCCodeEmitter - Generic instruction encoding interface.
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
Base class for the full range of assembler expressions which are needed for parsing.
@ SymbolRef
References to labels and assigned expressions.
@ Binary
Binary expressions.
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, bool PCRel=false)
Consider bit fields if we need more flags.
Instances of this class represent a single low-level machine instruction.
bool isBranch() const
Returns true if this is a conditional, unconditional, or indirect branch.
bool isCall() const
Return true if the instruction is a call.
unsigned getOpcode() const
Return the opcode number for this descriptor.
Interface to description of machine instruction set.
Instances of this class represent operands of the MCInst class.
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
Wrapper class representing physical registers. Should be passed by value.
Generic base class for all target subtargets.
uint16_t getSpecifier() const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM Value Representation.
A raw_ostream that writes to an std::string.
std::string & str()
Returns the string's reference.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
bool isExtentSigned(MCInstrInfo const &MCII, MCInst const &MCI)
bool isOuterLoop(MCInst const &MCI)
size_t bundleSize(MCInst const &MCI)
bool isDuplex(MCInstrInfo const &MCII, MCInst const &MCI)
bool IsSingleConsumerRefPairProducer(MCRegister Producer, MCRegister Consumer)
unsigned getExtentBits(MCInstrInfo const &MCII, MCInst const &MCI)
bool isNewValue(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether the insn expects newly produced value.
unsigned short getExtendableOp(MCInstrInfo const &MCII, MCInst const &MCI)
MCInstrDesc const & getDesc(MCInstrInfo const &MCII, MCInst const &MCI)
iterator_range< Hexagon::PacketIterator > bundleInstructions(MCInstrInfo const &MCII, MCInst const &MCI)
bool isBundle(MCInst const &MCI)
MCExpr const & getExpr(MCExpr const &Expr)
bool isExtendable(MCInstrInfo const &MCII, MCInst const &MCI)
unsigned getType(MCInstrInfo const &MCII, MCInst const &MCI)
Return the Hexagon ISA class for the insn.
bool isImmext(MCInst const &MCI)
MCOperand const & getNewValueOperand(MCInstrInfo const &MCII, MCInst const &MCI)
bool isPredicated(MCInstrInfo const &MCII, MCInst const &MCI)
unsigned SubregisterBit(MCRegister Consumer, MCRegister Producer, MCRegister Producer2)
bool s27_2_reloc(MCExpr const &Expr)
bool isInnerLoop(MCInst const &MCI)
bool hasNewValue2(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether the insn produces a second value.
unsigned getExtentAlignment(MCInstrInfo const &MCII, MCInst const &MCI)
StringRef getName(MCInstrInfo const &MCII, MCInst const &MCI)
bool isPredicatedTrue(MCInstrInfo const &MCII, MCInst const &MCI)
bool isVector(MCInstrInfo const &MCII, MCInst const &MCI)
bool isSubInstruction(MCInst const &MCI)
MCOperand const & getNewValueOperand2(MCInstrInfo const &MCII, MCInst const &MCI)
unsigned getDuplexRegisterNumbering(MCRegister Reg)
bool isExtended(MCInstrInfo const &MCII, MCInst const &MCI)
bool hasNewValue(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether the insn produces a value.
@ fixup_Hexagon_LD_PLT_B32_PCREL_X
@ fixup_Hexagon_GPREL16_3
@ fixup_Hexagon_GD_GOT_HI16
@ fixup_Hexagon_LD_PLT_B22_PCREL
@ fixup_Hexagon_TPREL_32_6_X
@ fixup_Hexagon_B7_PCREL_X
@ fixup_Hexagon_B13_PCREL
@ fixup_Hexagon_DTPREL_HI16
@ fixup_Hexagon_IE_GOT_LO16
@ fixup_Hexagon_LD_PLT_B22_PCREL_X
@ fixup_Hexagon_GD_GOT_32_6_X
@ fixup_Hexagon_LD_GOT_HI16
@ fixup_Hexagon_B13_PCREL_X
@ fixup_Hexagon_GOTREL_HI16
@ fixup_Hexagon_IE_GOT_32_6_X
@ fixup_Hexagon_PLT_B22_PCREL
@ fixup_Hexagon_B32_PCREL_X
@ fixup_Hexagon_DTPREL_32_6_X
@ fixup_Hexagon_GD_GOT_LO16
@ fixup_Hexagon_GD_PLT_B32_PCREL_X
@ fixup_Hexagon_GPREL16_2
@ fixup_Hexagon_GPREL16_1
@ fixup_Hexagon_DTPREL_LO16
@ fixup_Hexagon_B15_PCREL
@ fixup_Hexagon_GPREL16_0
@ fixup_Hexagon_6_PCREL_X
@ fixup_Hexagon_GD_PLT_B22_PCREL_X
@ fixup_Hexagon_GD_PLT_B22_PCREL
@ fixup_Hexagon_B22_PCREL
@ fixup_Hexagon_TPREL_LO16
@ fixup_Hexagon_TPREL_HI16
@ fixup_Hexagon_LD_GOT_32_6_X
@ fixup_Hexagon_LD_GOT_LO16
@ fixup_Hexagon_GOTREL_LO16
@ fixup_Hexagon_IE_GOT_HI16
@ fixup_Hexagon_GOT_32_6_X
@ fixup_Hexagon_B15_PCREL_X
@ fixup_Hexagon_B22_PCREL_X
@ fixup_Hexagon_IE_32_6_X
@ fixup_Hexagon_GOTREL_32_6_X
@ fixup_Hexagon_B9_PCREL_X
void write(void *memory, value_type value, endianness endian)
Write a value to memory with a particular endianness.
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
MCCodeEmitter * createHexagonMCCodeEmitter(const MCInstrInfo &MCII, MCContext &MCT)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static Lanai::Fixups FixupKind(const MCExpr *Expr)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
static void addFixup(SmallVectorImpl< MCFixup > &Fixups, uint32_t Offset, const MCExpr *Value, uint16_t Kind)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.