37#define DEBUG_TYPE "mccodeemitter"
40using namespace Hexagon;
42STATISTIC(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),
_,
340 MCInst const &MCI)
const {
342 if (State.Index == 0) {
349 if (State.Index == 1) {
360 if (State.Index ==
Last)
375 State.Extended =
false;
392 return (Consumer == Producer) || (Consumer == Producer2) ||
407 "pseudo-instruction found");
412 unsigned Opc =
MI.getOpcode();
416 if (!Binary && Opc != DuplexIClass0 && Opc != A4_ext) {
424 if (Opc >= Hexagon::DuplexIClass0 && Opc <= Hexagon::DuplexIClassF) {
426 "Emitting duplex without duplex parse bits");
427 unsigned DupIClass =
MI.getOpcode() - Hexagon::DuplexIClass0;
431 Binary = ((DupIClass & 0xE) << (29 - 1)) | ((DupIClass & 0x1) << 13);
433 const MCInst *Sub0 =
MI.getOperand(0).getInst();
434 const MCInst *Sub1 =
MI.getOperand(1).getInst();
439 State.SubInst1 =
true;
441 State.SubInst1 =
false;
443 Binary |= SubBits0 | (SubBits1 << 16);
452 Stream <<
"Unrecognized relocation combination: width=" << Width
464 using namespace Hexagon;
469 for (
auto I = Instrs.begin(),
N = Instrs.end();
I !=
N; ++
I) {
470 if (
I->getInst() != &
MI)
472 assert(
I+1 !=
N &&
"Extender cannot be last in packet");
473 const MCInst &NextI = *(
I+1)->getInst();
482 static const std::map<unsigned,unsigned> Relocs = {
496 auto F = Relocs.find(VarKind);
497 if (
F != Relocs.end())
505 static const std::map<unsigned,unsigned> RelocsLo = {
517 static const std::map<unsigned,unsigned> RelocsHi = {
531 case Hexagon::A2_tfril: {
532 auto F = RelocsLo.find(VarKind);
533 if (
F != RelocsLo.end())
538 case Hexagon::A2_tfrih: {
539 auto F = RelocsHi.find(VarKind);
540 if (
F != RelocsHi.end())
575unsigned HexagonMCCodeEmitter::getExprOpValue(
const MCInst &
MI,
578 if (isa<HexagonMCExpr>(ME))
581 if (ME->evaluateAsAbsolute(
Value)) {
588 if (State.Extended && InstExtendable && !IsSub0) {
589 unsigned OpIdx = ~0
u;
590 for (
unsigned I = 0, E =
MI.getNumOperands();
I != E; ++
I) {
591 if (&MO != &
MI.getOperand(
I))
624 <<
"\nOpcode: " << Opc <<
"\nRelocation bits: "
625 << FixupWidth <<
"\nAddend: " << State.Addend
626 <<
"\nVariant: " <<
unsigned(VarKind)
627 <<
"\n----------------------------------------\n");
632 if (FixupWidth == 16 && !State.Extended) {
644 assert(Shift < std::size(GPRelFixups));
653 if (Opc == Hexagon::LO)
655 else if (Opc == Hexagon::HI)
660 switch (FixupWidth) {
672 else if (FixupWidth == 7 && BranchOrCR)
685 auto FindVK = FixupTable.find(VarKind);
686 if (FindVK != FixupTable.end())
694 if (State.Addend != 0 &&
isPCRel(FixupKind)) {
710 size_t OperandNumber = ~0U;
711 for (
unsigned i = 0, n =
MI.getNumOperands(); i < n; ++i)
712 if (&
MI.getOperand(i) == &MO) {
716 assert((OperandNumber != ~0U) &&
"Operand not found");
721 unsigned SOffset = 0;
722 unsigned VOffset = 0;
728 const MCOperand *
I = Instrs.begin() + State.Index - 1;
731 assert(
I != Instrs.begin() - 1 &&
"Couldn't find producer");
732 MCInst const &Inst = *
I->getInst();
756 "Unpredicated consumer depending on predicated producer");
774 .operands()[OperandNumber]
776 case GeneralSubRegsRegClassID:
777 case GeneralDoubleLow8RegsRegClassID:
793#include "HexagonGenMCCodeEmitter.inc"
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 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
PowerPC TLS Dynamic Call Fixup
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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)
MCCodeEmitter - Generic instruction encoding interface.
static 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.
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, SMLoc Loc=SMLoc())
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.
VariantKind getKind() 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)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
MCFixupKind
Extensible enumeration to represent the type of a fixup.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.