37#define DEBUG_TYPE "mccodeemitter"
40using namespace Hexagon;
42STATISTIC(MCNumEmitted,
"Number of MC instructions emitted");
47#define _ fixup_Invalid
48#define P(x) Hexagon::fixup_Hexagon##x
49static const std::map<unsigned, std::vector<unsigned>>
ExtFixups = {
52 _,
_,
P(_DTPREL_16_X),
P(_DTPREL_11_X),
53 P(_DTPREL_11_X),
P(_9_X),
_,
P(_DTPREL_11_X),
54 P(_DTPREL_16_X),
_,
_,
_,
55 P(_DTPREL_16_X),
_,
_,
_,
62 _,
_,
P(_GOT_11_X),
_ ,
63 _ ,
P(_9_X),
_,
P(_GOT_11_X),
64 P(_GOT_16_X),
_,
_,
_,
65 P(_GOT_16_X),
_,
_,
_,
72 _,
_,
P(_GOTREL_11_X),
P(_GOTREL_11_X),
73 P(_GOTREL_11_X),
P(_9_X),
_,
P(_GOTREL_11_X),
74 P(_GOTREL_16_X),
_,
_,
_,
75 P(_GOTREL_16_X),
_,
_,
_,
82 _,
_,
P(_TPREL_16_X),
P(_TPREL_11_X),
83 P(_TPREL_11_X),
P(_9_X),
_,
P(_TPREL_11_X),
84 P(_TPREL_16_X),
_,
_,
_,
85 P(_TPREL_16_X),
_,
_,
_,
92 _,
_,
P(_GD_GOT_16_X),
P(_GD_GOT_11_X),
93 P(_GD_GOT_11_X),
P(_9_X),
_,
P(_GD_GOT_11_X),
94 P(_GD_GOT_16_X),
_,
_,
_,
95 P(_GD_GOT_16_X),
_,
_,
_,
103 _,
P(_9_X),
_,
P(_GD_PLT_B22_PCREL_X),
106 _,
_,
P(_GD_PLT_B22_PCREL_X),
_,
112 _,
_,
P(_IE_16_X),
_,
114 P(_IE_16_X),
_,
_,
_,
115 P(_IE_16_X),
_,
_,
_,
122 _,
_,
P(_IE_GOT_11_X),
P(_IE_GOT_11_X),
123 P(_IE_GOT_11_X),
P(_9_X),
_,
P(_IE_GOT_11_X),
124 P(_IE_GOT_16_X),
_,
_,
_,
125 P(_IE_GOT_16_X),
_,
_,
_,
129 P(_IE_GOT_32_6_X) }},
132 _,
_,
P(_LD_GOT_11_X),
P(_LD_GOT_11_X),
133 P(_LD_GOT_11_X),
P(_9_X),
_,
P(_LD_GOT_11_X),
134 P(_LD_GOT_16_X),
_,
_,
_,
135 P(_LD_GOT_16_X),
_,
_,
_,
139 P(_LD_GOT_32_6_X) }},
143 _,
P(_9_X),
_,
P(_LD_PLT_B22_PCREL_X),
146 _,
_,
P(_LD_PLT_B22_PCREL_X),
_,
152 _,
_,
P(_6_PCREL_X),
_,
162 _,
_,
P(_6_X),
P(_8_X),
163 P(_8_X),
P(_9_X),
P(_10_X),
P(_11_X),
164 P(_12_X),
P(_B13_PCREL),
_,
P(_B15_PCREL_X),
166 _,
_,
P(_B22_PCREL_X),
_,
173static const std::map<unsigned, std::vector<unsigned>>
StdFixups = {
179 P(_DTPREL_16),
_,
_,
_,
210 _,
_,
P(_PLT_B22_PCREL),
_,
217 _,
_,
_,
P(_TPREL_11_X),
219 P(_TPREL_16),
_,
_,
_,
229 P(_GD_GOT_16),
_,
_,
_,
240 _,
_,
P(_GD_PLT_B22_PCREL),
_,
249 P(_GPREL16_0),
_,
_,
_,
279 P(_IE_GOT_16),
_,
_,
_,
289 P(_LD_GOT_16),
_,
_,
_,
300 _,
_,
P(_LD_PLT_B22_PCREL),
_,
328 _,
P(_B13_PCREL),
_,
P(_B15_PCREL),
330 _,
_,
P(_B22_PCREL),
_,
370 MCInst const &MCI)
const {
372 if (State.Index == 0) {
379 if (State.Index == 1) {
390 if (State.Index ==
Last)
405 State.Extended =
false;
422 return (Consumer == Producer) || (Consumer == Producer2) ||
437 "pseudo-instruction found");
442 unsigned Opc =
MI.getOpcode();
446 if (!Binary &&
Opc != DuplexIClass0 &&
Opc != A4_ext) {
454 if (
Opc >= Hexagon::DuplexIClass0 &&
Opc <= Hexagon::DuplexIClassF) {
456 "Emitting duplex without duplex parse bits");
457 unsigned DupIClass =
MI.getOpcode() - Hexagon::DuplexIClass0;
461 Binary = ((DupIClass & 0xE) << (29 - 1)) | ((DupIClass & 0x1) << 13);
463 const MCInst *Sub0 =
MI.getOperand(0).getInst();
464 const MCInst *Sub1 =
MI.getOperand(1).getInst();
469 State.SubInst1 =
true;
471 State.SubInst1 =
false;
473 Binary |= SubBits0 | (SubBits1 << 16);
482 Stream <<
"Unrecognized relocation combination: width=" << Width
495 using namespace Hexagon;
500 for (
auto I = Instrs.begin(),
N = Instrs.end();
I !=
N; ++
I) {
501 if (
I->getInst() != &
MI)
503 assert(
I+1 !=
N &&
"Extender cannot be last in packet");
504 const MCInst &NextI = *(
I+1)->getInst();
513 static const std::map<unsigned, unsigned> Relocs = {
527 auto F = Relocs.find(VarKind);
528 if (
F != Relocs.end())
536 static const std::map<unsigned, unsigned> RelocsLo = {
548 static const std::map<unsigned, unsigned> RelocsHi = {
562 case Hexagon::A2_tfril: {
563 auto F = RelocsLo.find(VarKind);
564 if (
F != RelocsLo.end())
569 case Hexagon::A2_tfrih: {
570 auto F = RelocsHi.find(VarKind);
571 if (
F != RelocsHi.end())
606unsigned HexagonMCCodeEmitter::getExprOpValue(
const MCInst &
MI,
609 if (isa<HexagonMCExpr>(ME))
612 if (ME->evaluateAsAbsolute(
Value)) {
619 if (State.Extended && InstExtendable && !IsSub0) {
621 for (
unsigned I = 0, E =
MI.getNumOperands();
I != E; ++
I) {
622 if (&MO != &
MI.getOperand(
I))
655 <<
"\nOpcode: " <<
Opc <<
"\nRelocation bits: "
656 << FixupWidth <<
"\nAddend: " << State.Addend
657 <<
"\nVariant: " <<
unsigned(VarKind)
658 <<
"\n----------------------------------------\n");
663 if (FixupWidth == 16 && !State.Extended) {
675 assert(Shift < std::size(GPRelFixups));
684 if (
Opc == Hexagon::LO)
686 else if (
Opc == Hexagon::HI)
691 switch (FixupWidth) {
703 else if (FixupWidth == 7 && BranchOrCR)
716 auto FindVK = FixupTable.find(VarKind);
717 if (FindVK != FixupTable.end())
725 if (State.Addend != 0 &&
isPCRel(FixupKind)) {
738 size_t OperandNumber = ~0U;
739 for (
unsigned i = 0, n =
MI.getNumOperands(); i < n; ++i)
740 if (&
MI.getOperand(i) == &MO) {
744 assert((OperandNumber != ~0U) &&
"Operand not found");
749 unsigned SOffset = 0;
750 unsigned VOffset = 0;
756 const MCOperand *
I = Instrs.begin() + State.Index - 1;
759 assert(
I != Instrs.begin() - 1 &&
"Couldn't find producer");
760 MCInst const &Inst = *
I->getInst();
784 "Unpredicated consumer depending on predicated producer");
802 .operands()[OperandNumber]
804 case GeneralSubRegsRegClassID:
805 case GeneralDoubleLow8RegsRegClassID:
821#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 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 void addFixup(SmallVectorImpl< MCFixup > &Fixups, uint32_t Offset, const MCExpr *Value, uint16_t 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.
Binary assembler expressions.
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.
const MCRegisterInfo * getRegisterInfo() const
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.
Describe properties that are true of each instruction in the target description file.
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
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
Wrapper class representing physical registers. Should be passed by value.
Generic base class for all target subtargets.
Represent a reference to a symbol from inside an expression.
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
This is an optimization pass for GlobalISel generic memory operations.
MCCodeEmitter * createHexagonMCCodeEmitter(const MCInstrInfo &MCII, MCContext &MCT)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
static void addFixup(SmallVectorImpl< MCFixup > &Fixups, uint32_t Offset, const MCExpr *Value, uint16_t Kind)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.