30using namespace Hexagon;
32#define DEBUG_TYPE "hexagon-asm-backend"
35 (
"mno-fixup",
cl::desc(
"Disable fixing up resolved relocations for Hexagon"));
44 std::unique_ptr <MCInstrInfo> MCII;
45 std::unique_ptr <MCInst *> RelaxTarget;
47 unsigned MaxPacketSize;
65 Extender(nullptr), MaxPacketSize(HexagonMCInstrInfo::
packetSize(CPU)) {}
67 std::unique_ptr<MCObjectTargetWriter>
72 void setExtender(
MCContext &Context)
const {
73 if (Extender ==
nullptr)
74 const_cast<HexagonAsmBackend *
>(
this)->Extender =
Context.createMCInst();
77 MCInst *takeExtender()
const {
78 assert(Extender !=
nullptr);
80 const_cast<HexagonAsmBackend *
>(
this)->Extender =
nullptr;
91 {
"fixup_Hexagon_B22_PCREL", 0, 32, 0 },
92 {
"fixup_Hexagon_B15_PCREL", 0, 32, 0 },
93 {
"fixup_Hexagon_B7_PCREL", 0, 32, 0 },
94 {
"fixup_Hexagon_LO16", 0, 32, 0 },
95 {
"fixup_Hexagon_HI16", 0, 32, 0 },
96 {
"fixup_Hexagon_32", 0, 32, 0 },
97 {
"fixup_Hexagon_16", 0, 32, 0 },
98 {
"fixup_Hexagon_8", 0, 32, 0 },
99 {
"fixup_Hexagon_GPREL16_0", 0, 32, 0 },
100 {
"fixup_Hexagon_GPREL16_1", 0, 32, 0 },
101 {
"fixup_Hexagon_GPREL16_2", 0, 32, 0 },
102 {
"fixup_Hexagon_GPREL16_3", 0, 32, 0 },
103 {
"fixup_Hexagon_HL16", 0, 32, 0 },
104 {
"fixup_Hexagon_B13_PCREL", 0, 32, 0 },
105 {
"fixup_Hexagon_B9_PCREL", 0, 32, 0 },
106 {
"fixup_Hexagon_B32_PCREL_X", 0, 32, 0 },
107 {
"fixup_Hexagon_32_6_X", 0, 32, 0 },
108 {
"fixup_Hexagon_B22_PCREL_X", 0, 32, 0 },
109 {
"fixup_Hexagon_B15_PCREL_X", 0, 32, 0 },
110 {
"fixup_Hexagon_B13_PCREL_X", 0, 32, 0 },
111 {
"fixup_Hexagon_B9_PCREL_X", 0, 32, 0 },
112 {
"fixup_Hexagon_B7_PCREL_X", 0, 32, 0 },
113 {
"fixup_Hexagon_16_X", 0, 32, 0 },
114 {
"fixup_Hexagon_12_X", 0, 32, 0 },
115 {
"fixup_Hexagon_11_X", 0, 32, 0 },
116 {
"fixup_Hexagon_10_X", 0, 32, 0 },
117 {
"fixup_Hexagon_9_X", 0, 32, 0 },
118 {
"fixup_Hexagon_8_X", 0, 32, 0 },
119 {
"fixup_Hexagon_7_X", 0, 32, 0 },
120 {
"fixup_Hexagon_6_X", 0, 32, 0 },
121 {
"fixup_Hexagon_32_PCREL", 0, 32, 0 },
122 {
"fixup_Hexagon_COPY", 0, 32, 0 },
123 {
"fixup_Hexagon_GLOB_DAT", 0, 32, 0 },
124 {
"fixup_Hexagon_JMP_SLOT", 0, 32, 0 },
125 {
"fixup_Hexagon_RELATIVE", 0, 32, 0 },
126 {
"fixup_Hexagon_PLT_B22_PCREL", 0, 32, 0 },
127 {
"fixup_Hexagon_GOTREL_LO16", 0, 32, 0 },
128 {
"fixup_Hexagon_GOTREL_HI16", 0, 32, 0 },
129 {
"fixup_Hexagon_GOTREL_32", 0, 32, 0 },
130 {
"fixup_Hexagon_GOT_LO16", 0, 32, 0 },
131 {
"fixup_Hexagon_GOT_HI16", 0, 32, 0 },
132 {
"fixup_Hexagon_GOT_32", 0, 32, 0 },
133 {
"fixup_Hexagon_GOT_16", 0, 32, 0 },
134 {
"fixup_Hexagon_DTPMOD_32", 0, 32, 0 },
135 {
"fixup_Hexagon_DTPREL_LO16", 0, 32, 0 },
136 {
"fixup_Hexagon_DTPREL_HI16", 0, 32, 0 },
137 {
"fixup_Hexagon_DTPREL_32", 0, 32, 0 },
138 {
"fixup_Hexagon_DTPREL_16", 0, 32, 0 },
139 {
"fixup_Hexagon_GD_PLT_B22_PCREL",0, 32, 0 },
140 {
"fixup_Hexagon_LD_PLT_B22_PCREL",0, 32, 0 },
141 {
"fixup_Hexagon_GD_GOT_LO16", 0, 32, 0 },
142 {
"fixup_Hexagon_GD_GOT_HI16", 0, 32, 0 },
143 {
"fixup_Hexagon_GD_GOT_32", 0, 32, 0 },
144 {
"fixup_Hexagon_GD_GOT_16", 0, 32, 0 },
145 {
"fixup_Hexagon_LD_GOT_LO16", 0, 32, 0 },
146 {
"fixup_Hexagon_LD_GOT_HI16", 0, 32, 0 },
147 {
"fixup_Hexagon_LD_GOT_32", 0, 32, 0 },
148 {
"fixup_Hexagon_LD_GOT_16", 0, 32, 0 },
149 {
"fixup_Hexagon_IE_LO16", 0, 32, 0 },
150 {
"fixup_Hexagon_IE_HI16", 0, 32, 0 },
151 {
"fixup_Hexagon_IE_32", 0, 32, 0 },
152 {
"fixup_Hexagon_IE_16", 0, 32, 0 },
153 {
"fixup_Hexagon_IE_GOT_LO16", 0, 32, 0 },
154 {
"fixup_Hexagon_IE_GOT_HI16", 0, 32, 0 },
155 {
"fixup_Hexagon_IE_GOT_32", 0, 32, 0 },
156 {
"fixup_Hexagon_IE_GOT_16", 0, 32, 0 },
157 {
"fixup_Hexagon_TPREL_LO16", 0, 32, 0 },
158 {
"fixup_Hexagon_TPREL_HI16", 0, 32, 0 },
159 {
"fixup_Hexagon_TPREL_32", 0, 32, 0 },
160 {
"fixup_Hexagon_TPREL_16", 0, 32, 0 },
161 {
"fixup_Hexagon_6_PCREL_X", 0, 32, 0 },
162 {
"fixup_Hexagon_GOTREL_32_6_X", 0, 32, 0 },
163 {
"fixup_Hexagon_GOTREL_16_X", 0, 32, 0 },
164 {
"fixup_Hexagon_GOTREL_11_X", 0, 32, 0 },
165 {
"fixup_Hexagon_GOT_32_6_X", 0, 32, 0 },
166 {
"fixup_Hexagon_GOT_16_X", 0, 32, 0 },
167 {
"fixup_Hexagon_GOT_11_X", 0, 32, 0 },
168 {
"fixup_Hexagon_DTPREL_32_6_X", 0, 32, 0 },
169 {
"fixup_Hexagon_DTPREL_16_X", 0, 32, 0 },
170 {
"fixup_Hexagon_DTPREL_11_X", 0, 32, 0 },
171 {
"fixup_Hexagon_GD_GOT_32_6_X", 0, 32, 0 },
172 {
"fixup_Hexagon_GD_GOT_16_X", 0, 32, 0 },
173 {
"fixup_Hexagon_GD_GOT_11_X", 0, 32, 0 },
174 {
"fixup_Hexagon_LD_GOT_32_6_X", 0, 32, 0 },
175 {
"fixup_Hexagon_LD_GOT_16_X", 0, 32, 0 },
176 {
"fixup_Hexagon_LD_GOT_11_X", 0, 32, 0 },
177 {
"fixup_Hexagon_IE_32_6_X", 0, 32, 0 },
178 {
"fixup_Hexagon_IE_16_X", 0, 32, 0 },
179 {
"fixup_Hexagon_IE_GOT_32_6_X", 0, 32, 0 },
180 {
"fixup_Hexagon_IE_GOT_16_X", 0, 32, 0 },
181 {
"fixup_Hexagon_IE_GOT_11_X", 0, 32, 0 },
182 {
"fixup_Hexagon_TPREL_32_6_X", 0, 32, 0 },
183 {
"fixup_Hexagon_TPREL_16_X", 0, 32, 0 },
184 {
"fixup_Hexagon_TPREL_11_X", 0, 32, 0 },
185 {
"fixup_Hexagon_GD_PLT_B22_PCREL_X", 0, 32, 0 },
186 {
"fixup_Hexagon_GD_PLT_B32_PCREL_X", 0, 32, 0 },
187 {
"fixup_Hexagon_LD_PLT_B22_PCREL_X", 0, 32, 0 },
188 {
"fixup_Hexagon_LD_PLT_B32_PCREL_X", 0, 32, 0 },
202 switch(
Fixup.getKind()) {
356 switch((
unsigned)Kind) {
385 void HandleFixupError(
const int bits,
const int align_bits,
386 const int64_t FixupValue,
const char *fixupStr)
const {
391 std::stringstream errStr;
392 errStr <<
"\nError: value " <<
398 " when resolving " <<
407 bool isInstRelaxable(
MCInst const &HMI)
const {
409 bool Relaxable =
false;
441 bool Resolved)
const override {
442 MCInst const &MCB = RelaxedMCB;
445 *RelaxTarget =
nullptr;
448 bool Relaxable = isInstRelaxable(MCI);
449 if (Relaxable ==
false)
453 switch (
Fixup.getKind()) {
478 int64_t sValue =
Value;
481 switch ((
unsigned)Kind) {
499 bool isFarAway = -maxValue > sValue || sValue > maxValue - 1;
516 "Hexagon relaxInstruction only works on bundles");
527 if (*RelaxTarget == &CrntHMI) {
530 "No room to insert extender for relaxation");
532 MCInst *HMIx = takeExtender();
537 *RelaxTarget =
nullptr;
543 Inst = std::move(Res);
545 assert(Update &&
"Didn't find relaxation target");
550 static const uint32_t Nopcode = 0x7f000000,
551 ParseIn = 0x00004000,
552 ParseEnd = 0x0000c000;
555 LLVM_DEBUG(
dbgs() <<
"Alignment not a multiple of the instruction size:"
567 support::endian::write<uint32_t>(
OS, Nopcode | ParseBits, Endian);
578 for (
size_t J = 0, E = Frags.
size(); J != E; ++J) {
579 switch (Frags[J]->getKind()) {
583 auto Size =
Asm.computeFragmentSize(*Frags[J]);
586 switch (Frags[K]->getKind()) {
596 auto &RF = *Frags[
K];
600 Asm.symbols(), [&Asm, &RF, &Inst](
MCSymbol const &sym) {
602 const bool HasOffset = Asm.getSymbolOffset(sym, Offset);
603 const unsigned PacketSizeBytes =
604 HexagonMCInstrInfo::bundleSize(Inst) *
606 const bool OffsetPastSym =
607 Offset <= (Asm.getFragmentOffset(RF) + PacketSizeBytes);
608 return !sym.isVariable() && Offset != 0 && HasOffset &&
611 if (WouldTraverseLabel) {
624 *
Context.getRegisterInfo(),
false)
634 ReplaceInstruction(
Asm.getEmitter(), RF, Inst);
652 uint64_t FixupValue,
bool IsResolved) {
655 maybeAddReloc(
F,
Fixup,
Target, FixupValue, IsResolved);
670 "Invalid fixup offset!");
675 int sValue = (int)
Value;
677 switch ((
unsigned)
Kind) {
683 HandleFixupError(7, 2, (int64_t)FixupValue,
"B7_PCREL");
686 InstMask = 0x00001f18;
687 Reloc = (((
Value >> 2) & 0x1f) << 8) |
688 ((
Value & 0x3) << 3);
693 HandleFixupError(9, 2, (int64_t)FixupValue,
"B9_PCREL");
696 InstMask = 0x003000fe;
697 Reloc = (((
Value >> 7) & 0x3) << 20) |
698 ((
Value & 0x7f) << 1);
704 if (!(
isIntN(13, sValue)))
705 HandleFixupError(13, 2, (int64_t)FixupValue,
"B13_PCREL");
708 InstMask = 0x00202ffe;
709 Reloc = (((
Value >> 12) & 0x1) << 21) |
710 (((
Value >> 11) & 0x1) << 13) |
711 ((
Value & 0x7ff) << 1);
715 if (!(
isIntN(15, sValue)))
716 HandleFixupError(15, 2, (int64_t)FixupValue,
"B15_PCREL");
719 InstMask = 0x00df20fe;
720 Reloc = (((
Value >> 13) & 0x3) << 22) |
721 (((
Value >> 8) & 0x1f) << 16) |
722 (((
Value >> 7) & 0x1) << 13) |
723 ((
Value & 0x7f) << 1);
727 if (!(
isIntN(22, sValue)))
728 HandleFixupError(22, 2, (int64_t)FixupValue,
"B22_PCREL");
731 InstMask = 0x01ff3ffe;
732 Reloc = (((
Value >> 13) & 0x1ff) << 16) |
733 ((
Value & 0x1fff) << 1);
737 InstMask = 0x0fff3fff;
738 Reloc = (((
Value >> 14) & 0xfff) << 16) |
746 InstMask = 0xffffffff;
752 << (
unsigned)Kind <<
")\n");
754 uint32_t OldData = 0;
for (
unsigned i = 0; i < NumBytes; i++) OldData |=
755 (InstAddr[i] << (i * 8)) & (0xff << (i * 8));
758 <<
": Size=" <<
F.getSize() <<
": OInst=0x";
764 for (
unsigned i = 0; i < NumBytes; i++) {
765 InstAddr[i] &=
uint8_t(~InstMask >> (i * 8)) & 0xff;
766 InstAddr[i] |=
uint8_t(Reloc >> (i * 8)) & 0xff;
770 for (
unsigned i = 0; i < NumBytes; i++) NewData |=
771 (InstAddr[i] << (i * 8)) & (0xff << (i * 8));
784 return new HexagonAsmBackend(
T, TT, OSABI, CPUString);
static unsigned getFixupKindNumBytes(unsigned Kind)
The number of bytes the fixup may change.
static uint64_t adjustFixupValue(const MCFixup &Fixup, const MCValue &Target, uint64_t Value, MCContext &Ctx, const Triple &TheTriple, bool IsResolved)
static bool shouldForceRelocation(const MCFixup &Fixup)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static cl::opt< bool > DisableFixup("mno-fixup", cl::desc("Disable fixing up resolved relocations for Hexagon"))
Definition for classes that emit Hexagon machine code from MCInsts.
#define HEXAGON_INSTR_SIZE
#define HEXAGON_PACKET_SIZE
mir Rename Register Operands
PowerPC TLS Dynamic Call Fixup
static MCInstrInfo * createMCInstrInfo()
Class for arbitrary precision integers.
static APInt getSignedMaxValue(unsigned numBits)
Gets maximum signed value of APInt for a specific bit width.
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
int64_t getSExtValue() const
Get sign extended value.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Lightweight error class with error context and mandatory checking.
Check for a valid bundle.
bool check(bool FullCheck=true)
Generic interface to target specific assembler backends.
virtual bool finishLayout(const MCAssembler &Asm) const
virtual bool writeNopData(raw_ostream &OS, uint64_t Count, const MCSubtargetInfo *STI) const =0
Write an (optimal) nop sequence of Count bytes to the given output.
virtual void relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI) const
Relax the instruction in the given fragment to the next wider instruction.
virtual MCFixupKindInfo getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.
virtual bool mayNeedRelaxation(unsigned Opcode, ArrayRef< MCOperand > Operands, const MCSubtargetInfo &STI) const
Check whether the given instruction (encoded as Opcode+Operands) may need relaxation.
virtual std::unique_ptr< MCObjectTargetWriter > createObjectTargetWriter() const =0
virtual bool fixupNeedsRelaxationAdvanced(const MCFragment &, const MCFixup &, const MCValue &, uint64_t, bool Resolved) const
Target specific predicate for whether a given fixup requires the associated instruction to be relaxed...
MCContext & getContext() const
virtual void applyFixup(const MCFragment &, const MCFixup &, const MCValue &Target, uint8_t *Data, uint64_t Value, bool IsResolved)=0
MCCodeEmitter - Generic instruction encoding interface.
virtual void encodeInstruction(const MCInst &Inst, SmallVectorImpl< char > &CB, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const =0
Encode the given Inst to bytes and append to CB.
Context object for machine code objects.
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
LLVM_ABI void setVarFixups(ArrayRef< MCFixup > Fixups)
LLVM_ABI void setVarContents(ArrayRef< char > Contents)
const MCSubtargetInfo * getSubtargetInfo() const
Retrieve the MCSubTargetInfo in effect when the instruction was encoded.
void setInst(const MCInst &Inst)
Instances of this class represent a single low-level machine instruction.
unsigned getOpcode() const
void setOperands(ArrayRef< MCOperand > Ops)
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
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.
Instances of this class represent operands of the MCInst class.
static MCOperand createImm(int64_t Val)
const MCExpr * getExpr() const
static MCOperand createInst(const MCInst *Val)
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Generic base class for all target subtargets.
const Triple & getTargetTriple() const
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
raw_ostream & write_hex(unsigned long long N)
Output N in hexadecimal, without any prefix or padding.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
size_t bundleSize(MCInst const &MCI)
unsigned short getExtendableOp(MCInstrInfo const &MCII, MCInst const &MCI)
bool mustNotExtend(MCExpr const &Expr)
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)
bool isExtendable(MCInstrInfo const &MCII, MCInst const &MCI)
unsigned getType(MCInstrInfo const &MCII, MCInst const &MCI)
Return the Hexagon ISA class for the insn.
MCInst const & instruction(MCInst const &MCB, size_t Index)
MCOperand const & getExtendableOperand(MCInstrInfo const &MCII, MCInst const &MCI)
unsigned packetSize(StringRef CPU)
MCInst deriveExtender(MCInstrInfo const &MCII, MCInst const &Inst, MCOperand const &MO)
StringRef selectHexagonCPU(StringRef CPU)
@ fixup_Hexagon_LD_PLT_B32_PCREL_X
@ fixup_Hexagon_GPREL16_3
@ fixup_Hexagon_GD_GOT_HI16
@ fixup_Hexagon_IE_GOT_16_X
@ fixup_Hexagon_LD_PLT_B22_PCREL
@ fixup_Hexagon_TPREL_32_6_X
@ fixup_Hexagon_TPREL_16_X
@ fixup_Hexagon_B7_PCREL_X
@ fixup_Hexagon_B13_PCREL
@ fixup_Hexagon_DTPREL_HI16
@ fixup_Hexagon_DTPMOD_32
@ 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_GD_GOT_16
@ fixup_Hexagon_PLT_B22_PCREL
@ fixup_Hexagon_B32_PCREL_X
@ fixup_Hexagon_GD_GOT_16_X
@ fixup_Hexagon_GD_GOT_11_X
@ fixup_Hexagon_DTPREL_32_6_X
@ fixup_Hexagon_GD_GOT_LO16
@ fixup_Hexagon_GD_PLT_B32_PCREL_X
@ fixup_Hexagon_DTPREL_16
@ fixup_Hexagon_DTPREL_11_X
@ fixup_Hexagon_GPREL16_2
@ fixup_Hexagon_GPREL16_1
@ fixup_Hexagon_DTPREL_32
@ fixup_Hexagon_GOTREL_32
@ fixup_Hexagon_DTPREL_LO16
@ fixup_Hexagon_LD_GOT_16_X
@ fixup_Hexagon_B15_PCREL
@ fixup_Hexagon_LD_GOT_16
@ fixup_Hexagon_GPREL16_0
@ fixup_Hexagon_6_PCREL_X
@ fixup_Hexagon_GD_GOT_32
@ fixup_Hexagon_GD_PLT_B22_PCREL_X
@ fixup_Hexagon_GD_PLT_B22_PCREL
@ fixup_Hexagon_IE_GOT_32
@ fixup_Hexagon_B22_PCREL
@ fixup_Hexagon_TPREL_LO16
@ fixup_Hexagon_TPREL_HI16
@ fixup_Hexagon_LD_GOT_32_6_X
@ fixup_Hexagon_IE_GOT_16
@ fixup_Hexagon_LD_GOT_LO16
@ fixup_Hexagon_TPREL_11_X
@ fixup_Hexagon_GOTREL_LO16
@ fixup_Hexagon_IE_GOT_HI16
@ fixup_Hexagon_GOT_32_6_X
@ fixup_Hexagon_LD_GOT_11_X
@ fixup_Hexagon_GOTREL_11_X
@ fixup_Hexagon_DTPREL_16_X
@ fixup_Hexagon_B15_PCREL_X
@ fixup_Hexagon_B22_PCREL_X
@ fixup_Hexagon_IE_32_6_X
@ fixup_Hexagon_IE_GOT_11_X
@ fixup_Hexagon_LD_GOT_32
@ fixup_Hexagon_GOTREL_32_6_X
@ fixup_Hexagon_B9_PCREL_X
@ fixup_Hexagon_GOTREL_16_X
This is an optimization pass for GlobalISel generic memory operations.
@ FK_Data_1
A one-byte fixup.
@ FK_Data_4
A four-byte fixup.
@ FK_Data_2
A two-byte fixup.
bool HexagonMCShuffle(MCContext &Context, bool ReportErrors, MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst &MCB)
std::unique_ptr< MCObjectTargetWriter > createHexagonELFObjectWriter(uint8_t OSABI, StringRef CPU)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
MCAsmBackend * createHexagonAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Target independent information on a fixup kind.