LLVM: lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
29#include
30#include
31#include
32#include
33#include
34#include
35
36#define DEBUG_TYPE "mccodeemitter"
37
38using namespace llvm;
40
41STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
42
44
45
46#define _ fixup_Invalid
47#define P(x) Hexagon::fixup_Hexagon##x
48static const std::map<unsigned, std::vector> ExtFixups = {
51 _, _, P(_DTPREL_16_X), P(_DTPREL_11_X),
52 P(_DTPREL_11_X), P(_9_X), _, P(_DTPREL_11_X),
58 P(_DTPREL_32_6_X) }},
62 _ , P(_9_X), _, P(_GOT_11_X),
68 P(_GOT_32_6_X) }},
71 _, _, P(_GOTREL_11_X), P(_GOTREL_11_X),
72 P(_GOTREL_11_X), P(_9_X), _, P(_GOTREL_11_X),
78 P(_GOTREL_32_6_X) }},
81 _, _, P(_TPREL_16_X), P(_TPREL_11_X),
82 P(_TPREL_11_X), P(_9_X), _, P(_TPREL_11_X),
88 P(_TPREL_32_6_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),
98 P(_GD_GOT_32_6_X) }},
102 _, P(_9_X), _, P(_GD_PLT_B22_PCREL_X),
105 _, _, P(_GD_PLT_B22_PCREL_X), _,
108 _ }},
118 P(_IE_32_6_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),
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),
138 P(_LD_GOT_32_6_X) }},
142 _, P(_9_X), _, P(_LD_PLT_B22_PCREL_X),
145 _, _, P(_LD_PLT_B22_PCREL_X), _,
148 _ }},
158 P(_32_PCREL) }},
162 P(_8_X), P(_9_X), P(_10_X), P(_11_X),
163 P(_12_X), P(_B13_PCREL), _, P(_B15_PCREL_X),
168 P(_32_6_X) }},
169};
170
171
172static const std::map<unsigned, std::vector> StdFixups = {
182 P(_DTPREL_32) }},
192 P(_GOT_32) }},
202 P(_GOTREL_32) }},
209 _, _, P(_PLT_B22_PCREL), _,
212 _ }},
222 P(_TPREL_32) }},
232 P(_GD_GOT_32) }},
239 _, _, P(_GD_PLT_B22_PCREL), _,
242 _ }},
252 _ }},
262 _ }},
272 P(_IE_32) }},
282 P(_IE_GOT_32) }},
292 P(_LD_GOT_32) }},
299 _, _, P(_LD_PLT_B22_PCREL), _,
302 _ }},
312 _ }},
322 P(_32_PCREL) }},
327 _, P(_B13_PCREL), _, P(_B15_PCREL),
332 P(_32) }},
333};
334
335
336#undef P
337#undef _
338
341 bool PCRel = false;
342 switch (Kind) {
363 PCRel = true;
364 }
366}
367
368uint32_t HexagonMCCodeEmitter::parseBits(size_t Last, MCInst const &MCB,
369 MCInst const &MCI) const {
371 if (State.Index == 0) {
376 }
377 }
378 if (State.Index == 1) {
383 }
384 }
385 if (Duplex) {
388 }
389 if (State.Index == Last)
392}
393
394
400
403 State.Addend = 0;
404 State.Extended = false;
405 State.Bundle = &MI;
406 State.Index = 0;
408
410 MCInst &HMI = const_cast<MCInst &>(*I.getInst());
411
415 ++State.Index;
416 }
417}
418
421 return (Consumer == Producer) || (Consumer == Producer2) ||
423 Consumer);
424}
425
432
433
434
436 "pseudo-instruction found");
439
441 unsigned Opc = MI.getOpcode();
442
443
444
445 if (!Binary && Opc != DuplexIClass0 && Opc != A4_ext) {
449 }
450 Binary |= Parse;
451
452
453 if (Opc >= Hexagon::DuplexIClass0 && Opc <= Hexagon::DuplexIClassF) {
455 "Emitting duplex without duplex parse bits");
456 unsigned DupIClass = MI.getOpcode() - Hexagon::DuplexIClass0;
457
458
459
460 Binary = ((DupIClass & 0xE) << (29 - 1)) | ((DupIClass & 0x1) << 13);
461
462 const MCInst *Sub0 = MI.getOperand(0).getInst();
463 const MCInst *Sub1 = MI.getOperand(1).getInst();
464
465
467
468 State.SubInst1 = true;
470 State.SubInst1 = false;
471
472 Binary |= SubBits0 | (SubBits1 << 16);
473 }
475 ++MCNumEmitted;
476}
477
479 std::string Text;
481 Stream << "Unrecognized relocation combination: width=" << Width
482 << " kind=" << Kind;
484}
485
486
487
489HexagonMCCodeEmitter::getFixupNoBits(MCInstrInfo const &MCII, const MCInst &MI,
494 using namespace Hexagon;
495
499 for (auto I = Instrs.begin(), N = Instrs.end(); I != N; ++I) {
501 continue;
502 assert(I+1 != N && "Extender cannot be last in packet");
503 const MCInst &NextI = *(I+1)->getInst();
509 }
510 }
511
512 static const std::map<unsigned, unsigned> Relocs = {
524 };
525
526 auto F = Relocs.find(VarKind);
527 if (F != Relocs.end())
530 }
531
534
535 static const std::map<unsigned, unsigned> RelocsLo = {
545 };
546
547 static const std::map<unsigned, unsigned> RelocsHi = {
557 };
558
560 case Hexagon::LO:
561 case Hexagon::A2_tfril: {
562 auto F = RelocsLo.find(VarKind);
563 if (F != RelocsLo.end())
565 break;
566 }
567 case Hexagon::HI:
568 case Hexagon::A2_tfrih: {
569 auto F = RelocsHi.find(VarKind);
570 if (F != RelocsHi.end())
572 break;
573 }
574 }
575
577}
578
580 switch (Kind){
599 return true;
600 default:
601 return false;
602 }
603}
604
605unsigned HexagonMCCodeEmitter::getExprOpValue(const MCInst &MI,
611 if (ME->evaluateAsAbsolute(Value)) {
614
615
616
618 if (State.Extended && InstExtendable && !IsSub0) {
620 for (unsigned I = 0, E = MI.getNumOperands(); I != E; ++I) {
621 if (&MO != &MI.getOperand(I))
622 continue;
624 break;
625 }
630 }
631 }
633 }
638 getExprOpValue(MI, MO, Binary->getLHS(), Fixups, STI);
639 getExprOpValue(MI, MO, Binary->getRHS(), Fixups, STI);
640 return 0;
641 }
642
644 const MCSymbolRefExpr *MCSRE = static_cast<const MCSymbolRefExpr *>(ME);
651
652 LLVM_DEBUG(dbgs() << "----------------------------------------\n"
654 << "\nOpcode: " << Opc << "\nRelocation bits: "
655 << FixupWidth << "\nAddend: " << State.Addend
656 << "\nVariant: " << unsigned(VarKind)
657 << "\n----------------------------------------\n");
658
659
660
661
662 if (FixupWidth == 16 && !State.Extended) {
665
667 } else {
668
673 };
674 assert(Shift < std::size(GPRelFixups));
675 auto UsesGP = [](const MCInstrDesc &D) {
676 return is_contained(D.implicit_uses(), Hexagon::GP);
677 };
678 if (UsesGP(MCID))
680 }
682
683 if (Opc == Hexagon::LO)
685 else if (Opc == Hexagon::HI)
687 }
688 } else {
690 switch (FixupWidth) {
691 case 9:
692 if (BranchOrCR)
695 break;
696 case 8:
697 case 7:
702 else if (FixupWidth == 7 && BranchOrCR)
705 break;
706 case 0:
707 FixupKind = getFixupNoBits(MCII, MI, MO, VarKind);
708 break;
709 }
710 }
711
714
715 auto FindVK = FixupTable.find(VarKind);
716 if (FindVK != FixupTable.end())
717 FixupKind = FindVK->second[FixupWidth];
718 }
719
722
723 const MCExpr *FixupExpr = MO.getExpr();
727 }
728
730 return 0;
731}
732
733unsigned
737 size_t OperandNumber = ~0U;
738 for (unsigned i = 0, n = MI.getNumOperands(); i < n; ++i)
739 if (&MI.getOperand(i) == &MO) {
740 OperandNumber = i;
741 break;
742 }
743 assert((OperandNumber != ~0U) && "Operand not found");
744
747
748 unsigned SOffset = 0;
749 unsigned VOffset = 0;
753
755 const MCOperand *I = Instrs.begin() + State.Index - 1;
756
757 for (;; --I) {
758 assert(I != Instrs.begin() - 1 && "Couldn't find producer");
759 MCInst const &Inst = *I->getInst();
761 continue;
762
765 ++SOffset;
767
768 ++VOffset;
769 }
775
776 continue;
777 }
779
780 break;
781 }
783 "Unpredicated consumer depending on predicated producer");
786
787 break;
788 }
789
791 : SOffset;
795 }
796
798 if (MO.isReg()) {
801 .operands()[OperandNumber]
802 .RegClass) {
803 case GeneralSubRegsRegClassID:
804 case GeneralDoubleLow8RegsRegClassID:
806 default:
807 break;
808 }
809 return MCT.getRegisterInfo()->getEncodingValue(Reg);
810 }
811
812 return getExprOpValue(MI, MO, MO.getExpr(), Fixups, STI);
813}
814
819
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
Definition HexagonMCCodeEmitter.cpp:48
#define P(x)
Definition HexagonMCCodeEmitter.cpp:47
static bool RegisterMatches(MCRegister Consumer, MCRegister Producer, MCRegister Producer2)
Definition HexagonMCCodeEmitter.cpp:419
static const unsigned fixup_Invalid
Definition HexagonMCCodeEmitter.cpp:43
static void raise_relocation_error(unsigned Width, unsigned Kind)
Definition HexagonMCCodeEmitter.cpp:478
static bool isPCRel(unsigned Kind)
Definition HexagonMCCodeEmitter.cpp:579
static const std::map< unsigned, std::vector< unsigned > > StdFixups
Definition HexagonMCCodeEmitter.cpp:172
#define _
Definition HexagonMCCodeEmitter.cpp:46
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
Definition HexagonMCCodeEmitter.cpp:426
unsigned getMachineOpValue(MCInst const &MI, MCOperand const &MO, SmallVectorImpl< MCFixup > &Fixups, MCSubtargetInfo const &STI) const
Return binary encoding of operand.
Definition HexagonMCCodeEmitter.cpp:734
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.
Definition HexagonMCCodeEmitter.cpp:395
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)
Definition HexagonMCCodeEmitter.cpp:815
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 - 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 - 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.