LLVM: lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
30#include
31#include
32#include
33#include
34#include
35#include
36
37#define DEBUG_TYPE "mccodeemitter"
38
39using namespace llvm;
40using namespace Hexagon;
41
42STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
43
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
339uint32_t HexagonMCCodeEmitter::parseBits(size_t Last, MCInst const &MCB,
340 MCInst const &MCI) const {
342 if (State.Index == 0) {
347 }
348 }
349 if (State.Index == 1) {
354 }
355 }
356 if (Duplex) {
359 }
360 if (State.Index == Last)
363}
364
365
371
374 State.Addend = 0;
375 State.Extended = false;
376 State.Bundle = &MI;
377 State.Index = 0;
379
381 MCInst &HMI = const_cast<MCInst &>(*I.getInst());
382
386 ++State.Index;
387 }
388}
389
392 return (Consumer == Producer) || (Consumer == Producer2) ||
394 Consumer);
395}
396
403
404
405
407 "pseudo-instruction found");
410
412 unsigned Opc = MI.getOpcode();
413
414
415
416 if (!Binary && Opc != DuplexIClass0 && Opc != A4_ext) {
420 }
421 Binary |= Parse;
422
423
424 if (Opc >= Hexagon::DuplexIClass0 && Opc <= Hexagon::DuplexIClassF) {
426 "Emitting duplex without duplex parse bits");
427 unsigned DupIClass = MI.getOpcode() - Hexagon::DuplexIClass0;
428
429
430
431 Binary = ((DupIClass & 0xE) << (29 - 1)) | ((DupIClass & 0x1) << 13);
432
433 const MCInst *Sub0 = MI.getOperand(0).getInst();
434 const MCInst *Sub1 = MI.getOperand(1).getInst();
435
436
438
439 State.SubInst1 = true;
441 State.SubInst1 = false;
442
443 Binary |= SubBits0 | (SubBits1 << 16);
444 }
446 ++MCNumEmitted;
447}
448
450 std::string Text;
452 Stream << "Unrecognized relocation combination: width=" << Width
453 << " kind=" << Kind;
455}
456
457
458
464 using namespace Hexagon;
465
469 for (auto I = Instrs.begin(), N = Instrs.end(); I != N; ++I) {
471 continue;
472 assert(I+1 != N && "Extender cannot be last in packet");
473 const MCInst &NextI = *(I+1)->getInst();
479 }
480 }
481
482 static const std::map<unsigned,unsigned> Relocs = {
494 };
495
496 auto F = Relocs.find(VarKind);
497 if (F != Relocs.end())
500 }
501
504
505 static const std::map<unsigned,unsigned> RelocsLo = {
515 };
516
517 static const std::map<unsigned,unsigned> RelocsHi = {
527 };
528
530 case Hexagon::LO:
531 case Hexagon::A2_tfril: {
532 auto F = RelocsLo.find(VarKind);
533 if (F != RelocsLo.end())
535 break;
536 }
537 case Hexagon::HI:
538 case Hexagon::A2_tfrih: {
539 auto F = RelocsHi.find(VarKind);
540 if (F != RelocsHi.end())
542 break;
543 }
544 }
545
547}
548
550 switch (Kind){
569 return true;
570 default:
571 return false;
572 }
573}
574
575unsigned HexagonMCCodeEmitter::getExprOpValue(const MCInst &MI,
578 if (isa(ME))
581 if (ME->evaluateAsAbsolute(Value)) {
584
585
586
588 if (State.Extended && InstExtendable && !IsSub0) {
589 unsigned OpIdx = ~0u;
590 for (unsigned I = 0, E = MI.getNumOperands(); I != E; ++I) {
591 if (&MO != &MI.getOperand(I))
592 continue;
593 OpIdx = I;
594 break;
595 }
596 assert(OpIdx != ~0u);
600 }
601 }
603 }
608 getExprOpValue(MI, MO, Binary->getLHS(), Fixups, STI);
609 getExprOpValue(MI, MO, Binary->getRHS(), Fixups, STI);
610 return 0;
611 }
612
621
622 LLVM_DEBUG(dbgs() << "----------------------------------------\n"
624 << "\nOpcode: " << Opc << "\nRelocation bits: "
625 << FixupWidth << "\nAddend: " << State.Addend
626 << "\nVariant: " << unsigned(VarKind)
627 << "\n----------------------------------------\n");
628
629
630
631
632 if (FixupWidth == 16 && !State.Extended) {
635
637 } else {
638
643 };
644 assert(Shift < std::size(GPRelFixups));
646 return is_contained(D.implicit_uses(), Hexagon::GP);
647 };
648 if (UsesGP(MCID))
650 }
652
653 if (Opc == Hexagon::LO)
655 else if (Opc == Hexagon::HI)
657 }
658 } else {
660 switch (FixupWidth) {
661 case 9:
662 if (BranchOrCR)
665 break;
666 case 8:
667 case 7:
672 else if (FixupWidth == 7 && BranchOrCR)
675 break;
676 case 0:
677 FixupKind = getFixupNoBits(MCII, MI, MO, VarKind);
678 break;
679 }
680 }
681
684
685 auto FindVK = FixupTable.find(VarKind);
686 if (FindVK != FixupTable.end())
687 FixupKind = FindVK->second[FixupWidth];
688 }
689
692
694 if (State.Addend != 0 && isPCRel(FixupKind)) {
697 }
698
702
703 return 0;
704}
705
706unsigned
710 size_t OperandNumber = ~0U;
711 for (unsigned i = 0, n = MI.getNumOperands(); i < n; ++i)
712 if (&MI.getOperand(i) == &MO) {
713 OperandNumber = i;
714 break;
715 }
716 assert((OperandNumber != ~0U) && "Operand not found");
717
720
721 unsigned SOffset = 0;
722 unsigned VOffset = 0;
726
728 const MCOperand *I = Instrs.begin() + State.Index - 1;
729
730 for (;; --I) {
731 assert(I != Instrs.begin() - 1 && "Couldn't find producer");
732 MCInst const &Inst = *I->getInst();
734 continue;
735
738 ++SOffset;
740
741 ++VOffset;
742 }
748
749 continue;
750 }
752
753 break;
754 }
756 "Unpredicated consumer depending on predicated producer");
759
760 break;
761 }
762
764 : SOffset;
768 }
769
771 if (MO.isReg()) {
774 .operands()[OperandNumber]
775 .RegClass) {
776 case GeneralSubRegsRegClassID:
777 case GeneralDoubleLow8RegsRegClassID:
779 default:
780 break;
781 }
783 }
784
785 return getExprOpValue(MI, MO, MO.getExpr(), Fixups, STI);
786}
787
791}
792
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.