38#define DEBUG_TYPE "mccodeemitter"
41using namespace Hexagon;
43STATISTIC(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),
_,
341 MCInst const &MCI)
const {
343 if (State.Index == 0) {
350 if (State.Index == 1) {
361 if (State.Index ==
Last)
376 State.Extended =
false;
392 unsigned Producer2) {
393 return (Consumer == Producer) || (Consumer == Producer2) ||
408 "pseudo-instruction found");
413 unsigned Opc =
MI.getOpcode();
417 if (!Binary && Opc != DuplexIClass0 && Opc != A4_ext) {
425 if (Opc >= Hexagon::DuplexIClass0 && Opc <= Hexagon::DuplexIClassF) {
427 "Emitting duplex without duplex parse bits");
428 unsigned DupIClass =
MI.getOpcode() - Hexagon::DuplexIClass0;
432 Binary = ((DupIClass & 0xE) << (29 - 1)) | ((DupIClass & 0x1) << 13);
434 const MCInst *Sub0 =
MI.getOperand(0).getInst();
435 const MCInst *Sub1 =
MI.getOperand(1).getInst();
440 State.SubInst1 =
true;
442 State.SubInst1 =
false;
444 Binary |= SubBits0 | (SubBits1 << 16);
453 Stream <<
"Unrecognized relocation combination: width=" << Width
465 using namespace Hexagon;
470 for (
auto I = Instrs.begin(),
N = Instrs.end();
I !=
N; ++
I) {
471 if (
I->getInst() != &
MI)
473 assert(
I+1 !=
N &&
"Extender cannot be last in packet");
474 const MCInst &NextI = *(
I+1)->getInst();
483 static const std::map<unsigned,unsigned> Relocs = {
497 auto F = Relocs.find(VarKind);
498 if (
F != Relocs.end())
506 static const std::map<unsigned,unsigned> RelocsLo = {
518 static const std::map<unsigned,unsigned> RelocsHi = {
532 case Hexagon::A2_tfril: {
533 auto F = RelocsLo.find(VarKind);
534 if (
F != RelocsLo.end())
539 case Hexagon::A2_tfrih: {
540 auto F = RelocsHi.find(VarKind);
541 if (
F != RelocsHi.end())
576unsigned HexagonMCCodeEmitter::getExprOpValue(
const MCInst &
MI,
579 if (isa<HexagonMCExpr>(ME))
582 if (ME->evaluateAsAbsolute(
Value)) {
589 if (State.Extended && InstExtendable && !IsSub0) {
590 unsigned OpIdx = ~0
u;
591 for (
unsigned I = 0, E =
MI.getNumOperands();
I != E; ++
I) {
592 if (&MO != &
MI.getOperand(
I))
625 <<
"\nOpcode: " << Opc <<
"\nRelocation bits: "
626 << FixupWidth <<
"\nAddend: " << State.Addend
627 <<
"\nVariant: " <<
unsigned(VarKind)
628 <<
"\n----------------------------------------\n");
633 if (FixupWidth == 16 && !State.Extended) {
645 assert(Shift < std::size(GPRelFixups));
654 if (Opc == Hexagon::LO)
656 else if (Opc == Hexagon::HI)
661 switch (FixupWidth) {
673 else if (FixupWidth == 7 && BranchOrCR)
686 auto FindVK = FixupTable.find(VarKind);
687 if (FindVK != FixupTable.end())
695 if (State.Addend != 0 &&
isPCRel(FixupKind)) {
711 size_t OperandNumber = ~0U;
712 for (
unsigned i = 0, n =
MI.getNumOperands(); i < n; ++i)
713 if (&
MI.getOperand(i) == &MO) {
717 assert((OperandNumber != ~0U) &&
"Operand not found");
722 unsigned SOffset = 0;
723 unsigned VOffset = 0;
725 unsigned DefReg1 = Hexagon::NoRegister;
726 unsigned DefReg2 = Hexagon::NoRegister;
729 const MCOperand *
I = Instrs.begin() + State.Index - 1;
732 assert(
I != Instrs.begin() - 1 &&
"Couldn't find producer");
733 MCInst const &Inst = *
I->getInst();
737 DefReg1 = Hexagon::NoRegister;
738 DefReg2 = Hexagon::NoRegister;
757 "Unpredicated consumer depending on predicated producer");
773 unsigned Reg = MO.
getReg();
775 .operands()[OperandNumber]
777 case GeneralSubRegsRegClassID:
778 case GeneralDoubleLow8RegsRegClassID:
794#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(unsigned Consumer, unsigned Producer, unsigned 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.
unsigned getReg() const
Returns the register number.
const MCExpr * getExpr() const
uint16_t getEncodingValue(MCRegister RegNo) const
Returns the encoding for RegNo.
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)
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 IsSingleConsumerRefPairProducer(unsigned Producer, unsigned Consumer)
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(unsigned Consumer, unsigned Producer, unsigned 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)
unsigned getDuplexRegisterNumbering(unsigned Reg)
bool isSubInstruction(MCInst const &MCI)
MCOperand const & getNewValueOperand2(MCInstrInfo const &MCII, MCInst const &MCI)
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.