32 using namespace Hexagon;
34 #define DEBUG_TYPE "hexagon-asm-backend" 37 (
"mno-fixup",
cl::desc(
"Disable fixing up resolved relocations for Hexagon"));
44 mutable uint64_t relaxedCnt;
45 std::unique_ptr <MCInstrInfo> MCII;
46 std::unique_ptr <MCInst *> RelaxTarget;
63 HexagonAsmBackend(
const Target &
T,
const Triple &TT, uint8_t OSABI,
69 std::unique_ptr<MCObjectTargetWriter>
70 createObjectTargetWriter()
const override {
75 if (Extender ==
nullptr)
76 const_cast<HexagonAsmBackend *
>(
this)->Extender =
new (Context)
MCInst;
79 MCInst *takeExtender()
const {
80 assert(Extender !=
nullptr);
81 MCInst * Result = Extender;
82 const_cast<HexagonAsmBackend *
>(
this)->Extender =
nullptr;
86 unsigned getNumFixupKinds()
const override {
99 {
"fixup_Hexagon_LO16", 0, 32, 0 },
100 {
"fixup_Hexagon_HI16", 0, 32, 0 },
101 {
"fixup_Hexagon_32", 0, 32, 0 },
102 {
"fixup_Hexagon_16", 0, 32, 0 },
103 {
"fixup_Hexagon_8", 0, 32, 0 },
104 {
"fixup_Hexagon_GPREL16_0", 0, 32, 0 },
105 {
"fixup_Hexagon_GPREL16_1", 0, 32, 0 },
106 {
"fixup_Hexagon_GPREL16_2", 0, 32, 0 },
107 {
"fixup_Hexagon_GPREL16_3", 0, 32, 0 },
108 {
"fixup_Hexagon_HL16", 0, 32, 0 },
112 {
"fixup_Hexagon_32_6_X", 0, 32, 0 },
118 {
"fixup_Hexagon_16_X", 0, 32, 0 },
119 {
"fixup_Hexagon_12_X", 0, 32, 0 },
120 {
"fixup_Hexagon_11_X", 0, 32, 0 },
121 {
"fixup_Hexagon_10_X", 0, 32, 0 },
122 {
"fixup_Hexagon_9_X", 0, 32, 0 },
123 {
"fixup_Hexagon_8_X", 0, 32, 0 },
124 {
"fixup_Hexagon_7_X", 0, 32, 0 },
125 {
"fixup_Hexagon_6_X", 0, 32, 0 },
127 {
"fixup_Hexagon_COPY", 0, 32, 0 },
128 {
"fixup_Hexagon_GLOB_DAT", 0, 32, 0 },
129 {
"fixup_Hexagon_JMP_SLOT", 0, 32, 0 },
130 {
"fixup_Hexagon_RELATIVE", 0, 32, 0 },
132 {
"fixup_Hexagon_GOTREL_LO16", 0, 32, 0 },
133 {
"fixup_Hexagon_GOTREL_HI16", 0, 32, 0 },
134 {
"fixup_Hexagon_GOTREL_32", 0, 32, 0 },
135 {
"fixup_Hexagon_GOT_LO16", 0, 32, 0 },
136 {
"fixup_Hexagon_GOT_HI16", 0, 32, 0 },
137 {
"fixup_Hexagon_GOT_32", 0, 32, 0 },
138 {
"fixup_Hexagon_GOT_16", 0, 32, 0 },
139 {
"fixup_Hexagon_DTPMOD_32", 0, 32, 0 },
140 {
"fixup_Hexagon_DTPREL_LO16", 0, 32, 0 },
141 {
"fixup_Hexagon_DTPREL_HI16", 0, 32, 0 },
142 {
"fixup_Hexagon_DTPREL_32", 0, 32, 0 },
143 {
"fixup_Hexagon_DTPREL_16", 0, 32, 0 },
146 {
"fixup_Hexagon_GD_GOT_LO16", 0, 32, 0 },
147 {
"fixup_Hexagon_GD_GOT_HI16", 0, 32, 0 },
148 {
"fixup_Hexagon_GD_GOT_32", 0, 32, 0 },
149 {
"fixup_Hexagon_GD_GOT_16", 0, 32, 0 },
150 {
"fixup_Hexagon_LD_GOT_LO16", 0, 32, 0 },
151 {
"fixup_Hexagon_LD_GOT_HI16", 0, 32, 0 },
152 {
"fixup_Hexagon_LD_GOT_32", 0, 32, 0 },
153 {
"fixup_Hexagon_LD_GOT_16", 0, 32, 0 },
154 {
"fixup_Hexagon_IE_LO16", 0, 32, 0 },
155 {
"fixup_Hexagon_IE_HI16", 0, 32, 0 },
156 {
"fixup_Hexagon_IE_32", 0, 32, 0 },
157 {
"fixup_Hexagon_IE_16", 0, 32, 0 },
158 {
"fixup_Hexagon_IE_GOT_LO16", 0, 32, 0 },
159 {
"fixup_Hexagon_IE_GOT_HI16", 0, 32, 0 },
160 {
"fixup_Hexagon_IE_GOT_32", 0, 32, 0 },
161 {
"fixup_Hexagon_IE_GOT_16", 0, 32, 0 },
162 {
"fixup_Hexagon_TPREL_LO16", 0, 32, 0 },
163 {
"fixup_Hexagon_TPREL_HI16", 0, 32, 0 },
164 {
"fixup_Hexagon_TPREL_32", 0, 32, 0 },
165 {
"fixup_Hexagon_TPREL_16", 0, 32, 0 },
167 {
"fixup_Hexagon_GOTREL_32_6_X", 0, 32, 0 },
168 {
"fixup_Hexagon_GOTREL_16_X", 0, 32, 0 },
169 {
"fixup_Hexagon_GOTREL_11_X", 0, 32, 0 },
170 {
"fixup_Hexagon_GOT_32_6_X", 0, 32, 0 },
171 {
"fixup_Hexagon_GOT_16_X", 0, 32, 0 },
172 {
"fixup_Hexagon_GOT_11_X", 0, 32, 0 },
173 {
"fixup_Hexagon_DTPREL_32_6_X", 0, 32, 0 },
174 {
"fixup_Hexagon_DTPREL_16_X", 0, 32, 0 },
175 {
"fixup_Hexagon_DTPREL_11_X", 0, 32, 0 },
176 {
"fixup_Hexagon_GD_GOT_32_6_X", 0, 32, 0 },
177 {
"fixup_Hexagon_GD_GOT_16_X", 0, 32, 0 },
178 {
"fixup_Hexagon_GD_GOT_11_X", 0, 32, 0 },
179 {
"fixup_Hexagon_LD_GOT_32_6_X", 0, 32, 0 },
180 {
"fixup_Hexagon_LD_GOT_16_X", 0, 32, 0 },
181 {
"fixup_Hexagon_LD_GOT_11_X", 0, 32, 0 },
182 {
"fixup_Hexagon_IE_32_6_X", 0, 32, 0 },
183 {
"fixup_Hexagon_IE_16_X", 0, 32, 0 },
184 {
"fixup_Hexagon_IE_GOT_32_6_X", 0, 32, 0 },
185 {
"fixup_Hexagon_IE_GOT_16_X", 0, 32, 0 },
186 {
"fixup_Hexagon_IE_GOT_11_X", 0, 32, 0 },
187 {
"fixup_Hexagon_TPREL_32_6_X", 0, 32, 0 },
188 {
"fixup_Hexagon_TPREL_16_X", 0, 32, 0 },
189 {
"fixup_Hexagon_TPREL_11_X", 0, 32, 0 },
208 switch((
unsigned)Kind) {
364 switch((
unsigned)Kind) {
393 void HandleFixupError(
const int bits,
const int align_bits,
394 const int64_t FixupValue,
const char *fixupStr)
const {
399 std::stringstream errStr;
400 errStr <<
"\nError: value " <<
406 " when resolving " <<
417 uint64_t FixupValue,
bool IsResolved,
422 if (!FixupValue)
return;
433 assert(Offset + NumBytes <= Data.
size() &&
"Invalid fixup offset!");
439 int sValue = (int)Value;
441 switch((
unsigned)
Kind) {
447 HandleFixupError(7, 2, (int64_t)FixupValue,
"B7_PCREL");
450 InstMask = 0x00001f18;
451 Reloc = (((Value >> 2) & 0x1f) << 8) |
452 ((Value & 0x3) << 3);
457 HandleFixupError(9, 2, (int64_t)FixupValue,
"B9_PCREL");
460 InstMask = 0x003000fe;
461 Reloc = (((Value >> 7) & 0x3) << 20) |
462 ((Value & 0x7f) << 1);
468 if (!(
isIntN(13, sValue)))
469 HandleFixupError(13, 2, (int64_t)FixupValue,
"B13_PCREL");
472 InstMask = 0x00202ffe;
473 Reloc = (((Value >> 12) & 0x1) << 21) |
474 (((Value >> 11) & 0x1) << 13) |
475 ((Value & 0x7ff) << 1);
479 if (!(
isIntN(15, sValue)))
480 HandleFixupError(15, 2, (int64_t)FixupValue,
"B15_PCREL");
483 InstMask = 0x00df20fe;
484 Reloc = (((Value >> 13) & 0x3) << 22) |
485 (((Value >> 8) & 0x1f) << 16) |
486 (((Value >> 7) & 0x1) << 13) |
487 ((Value & 0x7f) << 1);
491 if (!(
isIntN(22, sValue)))
492 HandleFixupError(22, 2, (int64_t)FixupValue,
"B22_PCREL");
495 InstMask = 0x01ff3ffe;
496 Reloc = (((Value >> 13) & 0x1ff) << 16) |
497 ((Value & 0x1fff) << 1);
501 InstMask = 0x0fff3fff;
502 Reloc = (((Value >> 14) & 0xfff) << 16) |
510 InstMask = 0xffffffff;
516 << (
unsigned)Kind <<
")\n");
518 uint32_t OldData = 0;
for (
unsigned i = 0; i < NumBytes; i++) OldData |=
519 (InstAddr[i] << (i * 8)) & (0xff << (i * 8));
522 <<
": Offset=" << Offset <<
": Size=" << Data.
size() <<
": OInst=0x";
528 for (
unsigned i = 0; i < NumBytes; i++){
529 InstAddr[i] &= uint8_t(~InstMask >> (i * 8)) & 0xff;
530 InstAddr[i] |= uint8_t(Reloc >> (i * 8)) & 0xff;
534 for (
unsigned i = 0; i < NumBytes; i++) NewData |=
535 (InstAddr[i] << (i * 8)) & (0xff << (i * 8));
539 bool isInstRelaxable(
MCInst const &HMI)
const {
541 bool Relaxable =
false;
565 bool mayNeedRelaxation(
MCInst const &Inst,
572 bool fixupNeedsRelaxationAdvanced(
const MCFixup &Fixup,
bool Resolved,
576 const bool WasForced)
const override {
580 *RelaxTarget =
nullptr;
583 bool Relaxable = isInstRelaxable(MCI);
584 if (Relaxable ==
false)
588 switch ((
unsigned)Fixup.
getKind()) {
613 int64_t sValue = Value;
616 switch ((
unsigned)Kind) {
634 bool isFarAway = -maxValue > sValue || sValue > maxValue - 1;
649 bool fixupNeedsRelaxation(
const MCFixup &Fixup, uint64_t Value,
656 MCInst &Res)
const override {
658 "Hexagon relaxInstruction only works on bundles");
668 if (*RelaxTarget == &CrntHMI) {
671 "No room to insert extender for relaxation");
673 MCInst *HMIx = takeExtender();
678 *RelaxTarget =
nullptr;
684 assert(Update &&
"Didn't find relaxation target");
687 bool writeNopData(
raw_ostream &OS, uint64_t Count)
const override {
688 static const uint32_t Nopcode = 0x7f000000,
689 ParseIn = 0x00004000,
690 ParseEnd = 0x0000c000;
693 LLVM_DEBUG(
dbgs() <<
"Alignment not a multiple of the instruction size:" 694 << Count % HEXAGON_INSTR_SIZE <<
"/" 695 << HEXAGON_INSTR_SIZE <<
"\n");
705 support::endian::write<uint32_t>(OS, Nopcode | ParseBits, Endian);
713 auto &Fragments =
I->getFragmentList();
714 for (
auto &J : Fragments) {
715 switch (J.getKind()) {
720 for (
auto K = J.getIterator();
723 switch (K->getKind()) {
733 auto &RF = cast<MCRelaxableFragment>(*K);
752 ReplaceInstruction(Asm.
getEmitter(), RF, Inst);
777 return new HexagonAsmBackend(T, TT, OSABI, CPUString);
static MCInstrInfo * createMCInstrInfo()
This class represents lattice values for constants.
This represents an "assembler immediate".
OSType getOS() const
getOS - Get the parsed operating system type of this triple.
Describe properties that are true of each instruction in the target description file.
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.
bool isBundle(MCInst const &MCI)
A raw_ostream that writes to an SmallVector or SmallString.
#define HEXAGON_INSTR_SIZE
MCInst deriveExtender(MCInstrInfo const &MCII, MCInst const &Inst, MCOperand const &MO)
static APInt getSignedMaxValue(unsigned numBits)
Gets maximum signed value of APInt for a specific bit width.
bool isBranch() const
Returns true if this is a conditional, unconditional, or indirect branch.
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
const Triple & getTargetTriple() const
Is this fixup kind PCrelative? This is used by the assembler backend to evaluate fixup values in a ta...
MCContext & getContext() const
amdgpu Simplify well known AMD library false Value Value const Twine & Name
Encapsulates the layout of an assembly file at a particular point in time.
MCCodeEmitter & getEmitter() const
virtual void encodeInstruction(const MCInst &Inst, raw_ostream &OS, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const =0
EncodeInstruction - Encode the given Inst to bytes on the output stream OS.
MCAsmBackend * createHexagonAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
MCOperand const & getExtendableOperand(MCInstrInfo const &MCII, MCInst const &MCI)
iterator_range< Hexagon::PacketIterator > bundleInstructions(MCInstrInfo const &MCII, MCInst const &MCI)
Context object for machine code objects.
static cl::opt< bool > DisableFixup("mno-fixup", cl::desc("Disable fixing up resolved relocations for Hexagon"))
MCInst const & instruction(MCInst const &MCB, size_t Index)
int64_t getSExtValue() const
Get sign extended value.
raw_ostream & write_hex(unsigned long long N)
Output N in hexadecimal, without any prefix or padding.
MCAssembler & getAssembler() const
Get the assembler object this is a layout for.
const MCExpr * getExpr() const
bool HexagonMCShuffle(MCContext &Context, bool Fatal, MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst &MCB)
SmallVectorImpl< char > & getContents()
Instances of this class represent a single low-level machine instruction.
StringRef selectHexagonCPU(StringRef CPU)
static unsigned getFixupKindNumBytes(unsigned Kind)
The number of bytes the fixup may change.
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...
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
size_t size() const
size - Get the array size.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
void invalidateFragmentsFrom(MCFragment *F)
Invalidate the fragments starting with F because it has been resized.
MCCodeEmitter - Generic instruction encoding interface.
MCFixupKind
Extensible enumeration to represent the type of a fixup.
static uint64_t adjustFixupValue(const MCFixup &Fixup, const MCValue &Target, uint64_t Value, MCContext &Ctx, const Triple &TheTriple, bool IsResolved)
SmallVectorImpl< MCFixup > & getFixups()
MCInstrDesc const & getDesc(MCInstrInfo const &MCII, MCInst const &MCI)
llvm::SmallVectorImpl< MCSection * > & getSectionOrder()
uint32_t getOffset() const
Definition for classes that emit Hexagon machine code from MCInsts.
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned short getExtendableOp(MCInstrInfo const &MCII, MCInst const &MCI)
Triple - Helper class for working with autoconf configuration names.
void setOpcode(unsigned Op)
bool isExtendable(MCInstrInfo const &MCII, MCInst const &MCI)
A four-byte pc relative fixup.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
std::unique_ptr< MCObjectTargetWriter > createHexagonELFObjectWriter(uint8_t OSABI, StringRef CPU)
const MCOperand & getOperand(unsigned i) const
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Target - Wrapper for Target specific information.
Class for arbitrary precision integers.
const MCSubtargetInfo * getSubtargetInfo() const
Retrieve the MCSubTargetInfo in effect when the instruction was encoded.
static MCOperand createInst(const MCInst *Val)
const MCInst & getInst() const
Generic base class for all target subtargets.
uint64_t computeFragmentSize(const MCAsmLayout &Layout, const MCFragment &F) const
Compute the effective fragment size assuming it is laid out at the given SectionAddress and FragmentO...
size_t bundleSize(MCInst const &MCI)
Target independent information on a fixup kind.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
const MCRegisterInfo * getRegisterInfo() const
#define HEXAGON_PACKET_SIZE
LLVM Value Representation.
Generic interface to target specific assembler backends.
static const unsigned Nop
Instruction opcodes emitted via means other than CodeGen.
Lightweight error class with error context and mandatory checking.
Check for a valid bundle.
This class implements an extremely fast bulk output stream that can only output to a stream...
void addOperand(const MCOperand &Op)
StringRef - Represent a constant reference to a string, i.e.
unsigned getType(MCInstrInfo const &MCII, MCInst const &MCI)
Return the Hexagon ISA class for the insn.
unsigned getOpcode() const
Instances of this class represent operands of the MCInst class.
bool mustNotExtend(MCExpr const &Expr)
static MCOperand createImm(int64_t Val)
void setInst(const MCInst &Value)
MCFixupKind getKind() const