31using namespace Hexagon;
33#define DEBUG_TYPE "hexagon-asm-backend"
36 (
"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;
62 HexagonAsmBackend(
const Target &
T,
const Triple &TT, uint8_t OSABI,
66 Extender(nullptr), MaxPacketSize(HexagonMCInstrInfo::
packetSize(CPU)) {}
68 std::unique_ptr<MCObjectTargetWriter>
73 void setExtender(
MCContext &Context)
const {
74 if (Extender ==
nullptr)
75 const_cast<HexagonAsmBackend *
>(
this)->Extender = Context.
createMCInst();
78 MCInst *takeExtender()
const {
79 assert(Extender !=
nullptr);
81 const_cast<HexagonAsmBackend *
>(
this)->Extender =
nullptr;
98 {
"fixup_Hexagon_LO16", 0, 32, 0 },
99 {
"fixup_Hexagon_HI16", 0, 32, 0 },
100 {
"fixup_Hexagon_32", 0, 32, 0 },
101 {
"fixup_Hexagon_16", 0, 32, 0 },
102 {
"fixup_Hexagon_8", 0, 32, 0 },
103 {
"fixup_Hexagon_GPREL16_0", 0, 32, 0 },
104 {
"fixup_Hexagon_GPREL16_1", 0, 32, 0 },
105 {
"fixup_Hexagon_GPREL16_2", 0, 32, 0 },
106 {
"fixup_Hexagon_GPREL16_3", 0, 32, 0 },
107 {
"fixup_Hexagon_HL16", 0, 32, 0 },
111 {
"fixup_Hexagon_32_6_X", 0, 32, 0 },
117 {
"fixup_Hexagon_16_X", 0, 32, 0 },
118 {
"fixup_Hexagon_12_X", 0, 32, 0 },
119 {
"fixup_Hexagon_11_X", 0, 32, 0 },
120 {
"fixup_Hexagon_10_X", 0, 32, 0 },
121 {
"fixup_Hexagon_9_X", 0, 32, 0 },
122 {
"fixup_Hexagon_8_X", 0, 32, 0 },
123 {
"fixup_Hexagon_7_X", 0, 32, 0 },
124 {
"fixup_Hexagon_6_X", 0, 32, 0 },
126 {
"fixup_Hexagon_COPY", 0, 32, 0 },
127 {
"fixup_Hexagon_GLOB_DAT", 0, 32, 0 },
128 {
"fixup_Hexagon_JMP_SLOT", 0, 32, 0 },
129 {
"fixup_Hexagon_RELATIVE", 0, 32, 0 },
131 {
"fixup_Hexagon_GOTREL_LO16", 0, 32, 0 },
132 {
"fixup_Hexagon_GOTREL_HI16", 0, 32, 0 },
133 {
"fixup_Hexagon_GOTREL_32", 0, 32, 0 },
134 {
"fixup_Hexagon_GOT_LO16", 0, 32, 0 },
135 {
"fixup_Hexagon_GOT_HI16", 0, 32, 0 },
136 {
"fixup_Hexagon_GOT_32", 0, 32, 0 },
137 {
"fixup_Hexagon_GOT_16", 0, 32, 0 },
138 {
"fixup_Hexagon_DTPMOD_32", 0, 32, 0 },
139 {
"fixup_Hexagon_DTPREL_LO16", 0, 32, 0 },
140 {
"fixup_Hexagon_DTPREL_HI16", 0, 32, 0 },
141 {
"fixup_Hexagon_DTPREL_32", 0, 32, 0 },
142 {
"fixup_Hexagon_DTPREL_16", 0, 32, 0 },
145 {
"fixup_Hexagon_GD_GOT_LO16", 0, 32, 0 },
146 {
"fixup_Hexagon_GD_GOT_HI16", 0, 32, 0 },
147 {
"fixup_Hexagon_GD_GOT_32", 0, 32, 0 },
148 {
"fixup_Hexagon_GD_GOT_16", 0, 32, 0 },
149 {
"fixup_Hexagon_LD_GOT_LO16", 0, 32, 0 },
150 {
"fixup_Hexagon_LD_GOT_HI16", 0, 32, 0 },
151 {
"fixup_Hexagon_LD_GOT_32", 0, 32, 0 },
152 {
"fixup_Hexagon_LD_GOT_16", 0, 32, 0 },
153 {
"fixup_Hexagon_IE_LO16", 0, 32, 0 },
154 {
"fixup_Hexagon_IE_HI16", 0, 32, 0 },
155 {
"fixup_Hexagon_IE_32", 0, 32, 0 },
156 {
"fixup_Hexagon_IE_16", 0, 32, 0 },
157 {
"fixup_Hexagon_IE_GOT_LO16", 0, 32, 0 },
158 {
"fixup_Hexagon_IE_GOT_HI16", 0, 32, 0 },
159 {
"fixup_Hexagon_IE_GOT_32", 0, 32, 0 },
160 {
"fixup_Hexagon_IE_GOT_16", 0, 32, 0 },
161 {
"fixup_Hexagon_TPREL_LO16", 0, 32, 0 },
162 {
"fixup_Hexagon_TPREL_HI16", 0, 32, 0 },
163 {
"fixup_Hexagon_TPREL_32", 0, 32, 0 },
164 {
"fixup_Hexagon_TPREL_16", 0, 32, 0 },
166 {
"fixup_Hexagon_GOTREL_32_6_X", 0, 32, 0 },
167 {
"fixup_Hexagon_GOTREL_16_X", 0, 32, 0 },
168 {
"fixup_Hexagon_GOTREL_11_X", 0, 32, 0 },
169 {
"fixup_Hexagon_GOT_32_6_X", 0, 32, 0 },
170 {
"fixup_Hexagon_GOT_16_X", 0, 32, 0 },
171 {
"fixup_Hexagon_GOT_11_X", 0, 32, 0 },
172 {
"fixup_Hexagon_DTPREL_32_6_X", 0, 32, 0 },
173 {
"fixup_Hexagon_DTPREL_16_X", 0, 32, 0 },
174 {
"fixup_Hexagon_DTPREL_11_X", 0, 32, 0 },
175 {
"fixup_Hexagon_GD_GOT_32_6_X", 0, 32, 0 },
176 {
"fixup_Hexagon_GD_GOT_16_X", 0, 32, 0 },
177 {
"fixup_Hexagon_GD_GOT_11_X", 0, 32, 0 },
178 {
"fixup_Hexagon_LD_GOT_32_6_X", 0, 32, 0 },
179 {
"fixup_Hexagon_LD_GOT_16_X", 0, 32, 0 },
180 {
"fixup_Hexagon_LD_GOT_11_X", 0, 32, 0 },
181 {
"fixup_Hexagon_IE_32_6_X", 0, 32, 0 },
182 {
"fixup_Hexagon_IE_16_X", 0, 32, 0 },
183 {
"fixup_Hexagon_IE_GOT_32_6_X", 0, 32, 0 },
184 {
"fixup_Hexagon_IE_GOT_16_X", 0, 32, 0 },
185 {
"fixup_Hexagon_IE_GOT_11_X", 0, 32, 0 },
186 {
"fixup_Hexagon_TPREL_32_6_X", 0, 32, 0 },
187 {
"fixup_Hexagon_TPREL_16_X", 0, 32, 0 },
188 {
"fixup_Hexagon_TPREL_11_X", 0, 32, 0 },
206 switch(
Fixup.getTargetKind()) {
362 switch((
unsigned)Kind) {
391 void HandleFixupError(
const int bits,
const int align_bits,
392 const int64_t FixupValue,
const char *fixupStr)
const {
397 std::stringstream errStr;
398 errStr <<
"\nError: value " <<
404 " when resolving " <<
415 uint64_t FixupValue,
bool IsResolved,
420 if (!FixupValue)
return;
431 assert(
Offset + NumBytes <= Data.size() &&
"Invalid fixup offset!");
432 char *InstAddr = Data.data() +
Offset;
437 int sValue = (int)
Value;
439 switch((
unsigned)
Kind) {
445 HandleFixupError(7, 2, (int64_t)FixupValue,
"B7_PCREL");
448 InstMask = 0x00001f18;
449 Reloc = (((
Value >> 2) & 0x1f) << 8) |
450 ((
Value & 0x3) << 3);
455 HandleFixupError(9, 2, (int64_t)FixupValue,
"B9_PCREL");
458 InstMask = 0x003000fe;
459 Reloc = (((
Value >> 7) & 0x3) << 20) |
460 ((
Value & 0x7f) << 1);
466 if (!(
isIntN(13, sValue)))
467 HandleFixupError(13, 2, (int64_t)FixupValue,
"B13_PCREL");
470 InstMask = 0x00202ffe;
471 Reloc = (((
Value >> 12) & 0x1) << 21) |
472 (((
Value >> 11) & 0x1) << 13) |
473 ((
Value & 0x7ff) << 1);
477 if (!(
isIntN(15, sValue)))
478 HandleFixupError(15, 2, (int64_t)FixupValue,
"B15_PCREL");
481 InstMask = 0x00df20fe;
482 Reloc = (((
Value >> 13) & 0x3) << 22) |
483 (((
Value >> 8) & 0x1f) << 16) |
484 (((
Value >> 7) & 0x1) << 13) |
485 ((
Value & 0x7f) << 1);
489 if (!(
isIntN(22, sValue)))
490 HandleFixupError(22, 2, (int64_t)FixupValue,
"B22_PCREL");
493 InstMask = 0x01ff3ffe;
494 Reloc = (((
Value >> 13) & 0x1ff) << 16) |
495 ((
Value & 0x1fff) << 1);
499 InstMask = 0x0fff3fff;
500 Reloc = (((
Value >> 14) & 0xfff) << 16) |
508 InstMask = 0xffffffff;
514 << (
unsigned)Kind <<
")\n");
516 uint32_t OldData = 0;
for (
unsigned i = 0; i < NumBytes; i++) OldData |=
517 (InstAddr[i] << (i * 8)) & (0xff << (i * 8));
520 <<
": Offset=" <<
Offset <<
": Size=" << Data.size() <<
": OInst=0x";
526 for (
unsigned i = 0; i < NumBytes; i++){
527 InstAddr[i] &= uint8_t(~InstMask >> (i * 8)) & 0xff;
528 InstAddr[i] |= uint8_t(Reloc >> (i * 8)) & 0xff;
532 for (
unsigned i = 0; i < NumBytes; i++) NewData |=
533 (InstAddr[i] << (i * 8)) & (0xff << (i * 8));
537 bool isInstRelaxable(
MCInst const &HMI)
const {
539 bool Relaxable =
false;
574 const bool WasForced)
const override {
578 *RelaxTarget =
nullptr;
581 bool Relaxable = isInstRelaxable(MCI);
582 if (Relaxable ==
false)
586 switch (
Fixup.getTargetKind()) {
600 setExtender(
Asm.getContext());
611 int64_t sValue =
Value;
614 switch ((
unsigned)Kind) {
632 bool isFarAway = -maxValue > sValue || sValue > maxValue - 1;
638 setExtender(
Asm.getContext());
649 "Hexagon relaxInstruction only works on bundles");
660 if (*RelaxTarget == &CrntHMI) {
663 "No room to insert extender for relaxation");
665 MCInst *HMIx = takeExtender();
670 *RelaxTarget =
nullptr;
676 Inst = std::move(Res);
678 assert(Update &&
"Didn't find relaxation target");
683 static const uint32_t Nopcode = 0x7f000000,
684 ParseIn = 0x00004000,
685 ParseEnd = 0x0000c000;
688 LLVM_DEBUG(
dbgs() <<
"Alignment not a multiple of the instruction size:"
700 support::endian::write<uint32_t>(
OS, Nopcode | ParseBits, Endian);
711 for (
size_t J = 0, E = Frags.
size(); J != E; ++J) {
712 switch (Frags[J]->getKind()) {
716 auto Size =
Asm.computeFragmentSize(*Frags[J]);
719 switch (Frags[K]->getKind()) {
729 auto &RF = cast<MCRelaxableFragment>(*Frags[K]);
749 ReplaceInstruction(
Asm.getEmitter(), RF, Inst);
750 Sec.setHasLayout(
false);
774 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 RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
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
PowerPC TLS Dynamic Call Fixup
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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.
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 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 bool mayNeedRelaxation(const MCInst &Inst, const MCSubtargetInfo &STI) const
Check whether the given instruction may need relaxation.
virtual bool fixupNeedsRelaxationAdvanced(const MCAssembler &Asm, const MCFixup &Fixup, bool Resolved, uint64_t Value, const MCRelaxableFragment *DF, const bool WasForced) const
Target specific predicate for whether a given fixup requires the associated instruction to be relaxed...
virtual std::unique_ptr< MCObjectTargetWriter > createObjectTargetWriter() const =0
virtual void finishLayout(MCAssembler const &Asm) const
Give backend an opportunity to finish layout after relaxation.
virtual bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target, const MCSubtargetInfo *STI)
Hook to check if a relocation is needed for some target specific reason.
virtual unsigned getNumFixupKinds() const =0
Get the number of target specific fixup kinds.
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.
virtual void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target, MutableArrayRef< char > Data, uint64_t Value, bool IsResolved, const MCSubtargetInfo *STI) const =0
Apply the Value for given Fixup into the provided data fragment, at the offset specified by the fixup...
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.
MCInst * createMCInst()
Create and return a new MC instruction.
const MCRegisterInfo * getRegisterInfo() const
SmallVectorImpl< MCFixup > & getFixups()
SmallVectorImpl< char > & getContents()
const MCSubtargetInfo * getSubtargetInfo() const
Retrieve the MCSubTargetInfo in effect when the instruction was encoded.
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Instances of this class represent a single low-level machine instruction.
unsigned getOpcode() const
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...
A relaxable fragment holds on to its MCInst, since it may need to be relaxed during the assembler lay...
const MCInst & getInst() const
void setInst(const MCInst &Value)
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
This represents an "assembler immediate".
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
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.
bool HexagonMCShuffle(MCContext &Context, bool ReportErrors, MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst &MCB)
std::unique_ptr< MCObjectTargetWriter > createHexagonELFObjectWriter(uint8_t OSABI, StringRef CPU)
MCAsmBackend * createHexagonAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
MCFixupKind
Extensible enumeration to represent the type of a fixup.
@ FK_PCRel_4
A four-byte pc relative fixup.
@ FK_Data_1
A one-byte fixup.
@ FK_Data_4
A four-byte fixup.
@ FK_Data_2
A two-byte fixup.
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.
@ FKF_IsPCRel
Is this fixup kind PCrelative? This is used by the assembler backend to evaluate fixup values in a ta...