Go to the documentation of this file.
32 using namespace Hexagon;
34 #define DEBUG_TYPE "hexagon-asm-backend"
37 (
"mno-fixup",
cl::desc(
"Disable fixing up resolved relocations for Hexagon"));
45 std::unique_ptr <MCInstrInfo> MCII;
46 std::unique_ptr <MCInst *> RelaxTarget;
48 unsigned MaxPacketSize;
64 HexagonAsmBackend(
const Target &
T,
const Triple &TT, uint8_t OSABI,
68 Extender(nullptr), MaxPacketSize(HexagonMCInstrInfo::
packetSize(CPU))
71 std::unique_ptr<MCObjectTargetWriter>
72 createObjectTargetWriter()
const override {
77 if (Extender ==
nullptr)
78 const_cast<HexagonAsmBackend *
>(
this)->Extender =
Context.createMCInst();
81 MCInst *takeExtender()
const {
82 assert(Extender !=
nullptr);
84 const_cast<HexagonAsmBackend *
>(
this)->Extender =
nullptr;
88 unsigned getNumFixupKinds()
const override {
101 {
"fixup_Hexagon_LO16", 0, 32, 0 },
102 {
"fixup_Hexagon_HI16", 0, 32, 0 },
103 {
"fixup_Hexagon_32", 0, 32, 0 },
104 {
"fixup_Hexagon_16", 0, 32, 0 },
105 {
"fixup_Hexagon_8", 0, 32, 0 },
106 {
"fixup_Hexagon_GPREL16_0", 0, 32, 0 },
107 {
"fixup_Hexagon_GPREL16_1", 0, 32, 0 },
108 {
"fixup_Hexagon_GPREL16_2", 0, 32, 0 },
109 {
"fixup_Hexagon_GPREL16_3", 0, 32, 0 },
110 {
"fixup_Hexagon_HL16", 0, 32, 0 },
114 {
"fixup_Hexagon_32_6_X", 0, 32, 0 },
120 {
"fixup_Hexagon_16_X", 0, 32, 0 },
121 {
"fixup_Hexagon_12_X", 0, 32, 0 },
122 {
"fixup_Hexagon_11_X", 0, 32, 0 },
123 {
"fixup_Hexagon_10_X", 0, 32, 0 },
124 {
"fixup_Hexagon_9_X", 0, 32, 0 },
125 {
"fixup_Hexagon_8_X", 0, 32, 0 },
126 {
"fixup_Hexagon_7_X", 0, 32, 0 },
127 {
"fixup_Hexagon_6_X", 0, 32, 0 },
129 {
"fixup_Hexagon_COPY", 0, 32, 0 },
130 {
"fixup_Hexagon_GLOB_DAT", 0, 32, 0 },
131 {
"fixup_Hexagon_JMP_SLOT", 0, 32, 0 },
132 {
"fixup_Hexagon_RELATIVE", 0, 32, 0 },
134 {
"fixup_Hexagon_GOTREL_LO16", 0, 32, 0 },
135 {
"fixup_Hexagon_GOTREL_HI16", 0, 32, 0 },
136 {
"fixup_Hexagon_GOTREL_32", 0, 32, 0 },
137 {
"fixup_Hexagon_GOT_LO16", 0, 32, 0 },
138 {
"fixup_Hexagon_GOT_HI16", 0, 32, 0 },
139 {
"fixup_Hexagon_GOT_32", 0, 32, 0 },
140 {
"fixup_Hexagon_GOT_16", 0, 32, 0 },
141 {
"fixup_Hexagon_DTPMOD_32", 0, 32, 0 },
142 {
"fixup_Hexagon_DTPREL_LO16", 0, 32, 0 },
143 {
"fixup_Hexagon_DTPREL_HI16", 0, 32, 0 },
144 {
"fixup_Hexagon_DTPREL_32", 0, 32, 0 },
145 {
"fixup_Hexagon_DTPREL_16", 0, 32, 0 },
148 {
"fixup_Hexagon_GD_GOT_LO16", 0, 32, 0 },
149 {
"fixup_Hexagon_GD_GOT_HI16", 0, 32, 0 },
150 {
"fixup_Hexagon_GD_GOT_32", 0, 32, 0 },
151 {
"fixup_Hexagon_GD_GOT_16", 0, 32, 0 },
152 {
"fixup_Hexagon_LD_GOT_LO16", 0, 32, 0 },
153 {
"fixup_Hexagon_LD_GOT_HI16", 0, 32, 0 },
154 {
"fixup_Hexagon_LD_GOT_32", 0, 32, 0 },
155 {
"fixup_Hexagon_LD_GOT_16", 0, 32, 0 },
156 {
"fixup_Hexagon_IE_LO16", 0, 32, 0 },
157 {
"fixup_Hexagon_IE_HI16", 0, 32, 0 },
158 {
"fixup_Hexagon_IE_32", 0, 32, 0 },
159 {
"fixup_Hexagon_IE_16", 0, 32, 0 },
160 {
"fixup_Hexagon_IE_GOT_LO16", 0, 32, 0 },
161 {
"fixup_Hexagon_IE_GOT_HI16", 0, 32, 0 },
162 {
"fixup_Hexagon_IE_GOT_32", 0, 32, 0 },
163 {
"fixup_Hexagon_IE_GOT_16", 0, 32, 0 },
164 {
"fixup_Hexagon_TPREL_LO16", 0, 32, 0 },
165 {
"fixup_Hexagon_TPREL_HI16", 0, 32, 0 },
166 {
"fixup_Hexagon_TPREL_32", 0, 32, 0 },
167 {
"fixup_Hexagon_TPREL_16", 0, 32, 0 },
169 {
"fixup_Hexagon_GOTREL_32_6_X", 0, 32, 0 },
170 {
"fixup_Hexagon_GOTREL_16_X", 0, 32, 0 },
171 {
"fixup_Hexagon_GOTREL_11_X", 0, 32, 0 },
172 {
"fixup_Hexagon_GOT_32_6_X", 0, 32, 0 },
173 {
"fixup_Hexagon_GOT_16_X", 0, 32, 0 },
174 {
"fixup_Hexagon_GOT_11_X", 0, 32, 0 },
175 {
"fixup_Hexagon_DTPREL_32_6_X", 0, 32, 0 },
176 {
"fixup_Hexagon_DTPREL_16_X", 0, 32, 0 },
177 {
"fixup_Hexagon_DTPREL_11_X", 0, 32, 0 },
178 {
"fixup_Hexagon_GD_GOT_32_6_X", 0, 32, 0 },
179 {
"fixup_Hexagon_GD_GOT_16_X", 0, 32, 0 },
180 {
"fixup_Hexagon_GD_GOT_11_X", 0, 32, 0 },
181 {
"fixup_Hexagon_LD_GOT_32_6_X", 0, 32, 0 },
182 {
"fixup_Hexagon_LD_GOT_16_X", 0, 32, 0 },
183 {
"fixup_Hexagon_LD_GOT_11_X", 0, 32, 0 },
184 {
"fixup_Hexagon_IE_32_6_X", 0, 32, 0 },
185 {
"fixup_Hexagon_IE_16_X", 0, 32, 0 },
186 {
"fixup_Hexagon_IE_GOT_32_6_X", 0, 32, 0 },
187 {
"fixup_Hexagon_IE_GOT_16_X", 0, 32, 0 },
188 {
"fixup_Hexagon_IE_GOT_11_X", 0, 32, 0 },
189 {
"fixup_Hexagon_TPREL_32_6_X", 0, 32, 0 },
190 {
"fixup_Hexagon_TPREL_16_X", 0, 32, 0 },
191 {
"fixup_Hexagon_TPREL_11_X", 0, 32, 0 },
208 switch(
Fixup.getTargetKind()) {
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!");
441 switch((
unsigned)
Kind) {
447 HandleFixupError(7, 2, (int64_t)FixupValue,
"B7_PCREL");
450 InstMask = 0x00001f18;
451 Reloc = (((
Value >> 2) & 0x1f) << 8) |
457 HandleFixupError(9, 2, (int64_t)FixupValue,
"B9_PCREL");
460 InstMask = 0x003000fe;
461 Reloc = (((
Value >> 7) & 0
x3) << 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) & 0
x3) << 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 (
Fixup.getTargetKind()) {
613 int64_t sValue =
Value;
616 switch ((
unsigned)
Kind) {
634 bool isFarAway = -maxValue > sValue || sValue > maxValue - 1;
655 void relaxInstruction(
MCInst &Inst,
658 "Hexagon relaxInstruction only works on bundles");
669 if (*RelaxTarget == &CrntHMI) {
672 "No room to insert extender for relaxation");
674 MCInst *HMIx = takeExtender();
679 *RelaxTarget =
nullptr;
687 assert(Update &&
"Didn't find relaxation target");
692 static const uint32_t Nopcode = 0x7f000000,
693 ParseIn = 0x00004000,
694 ParseEnd = 0x0000c000;
697 LLVM_DEBUG(
dbgs() <<
"Alignment not a multiple of the instruction size:"
709 support::endian::write<uint32_t>(OS, Nopcode | ParseBits, Endian);
717 auto &Fragments =
I->getFragmentList();
718 for (
auto &J : Fragments) {
719 switch (J.getKind()) {
723 auto Size =
Asm.computeFragmentSize(Layout, J);
724 for (
auto K = J.getIterator();
727 switch (K->getKind()) {
737 auto &RF = cast<MCRelaxableFragment>(*K);
742 Nop->setOpcode(Hexagon::A2_nop);
747 *
Context.getRegisterInfo(),
false)
757 ReplaceInstruction(
Asm.getEmitter(), RF, Inst);
782 return new HexagonAsmBackend(
T, TT, OSABI, CPUString);
@ fixup_Hexagon_GOTREL_16_X
@ fixup_Hexagon_DTPREL_LO16
bool mustNotExtend(MCExpr const &Expr)
@ fixup_Hexagon_TPREL_HI16
@ fixup_Hexagon_B22_PCREL
@ fixup_Hexagon_6_PCREL_X
This is an optimization pass for GlobalISel generic memory operations.
const MCInstrDesc & getDesc(MCInstrInfo const &MCII, MCInst const &MCI)
A relaxable fragment holds on to its MCInst, since it may need to be relaxed during the assembler lay...
@ fixup_Hexagon_LD_PLT_B22_PCREL_X
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.
@ fixup_Hexagon_B32_PCREL_X
static const unsigned Nop
Instruction opcodes emitted via means other than CodeGen.
@ fixup_Hexagon_GD_GOT_LO16
@ fixup_Hexagon_GD_GOT_32_6_X
bool isBranch() const
Returns true if this is a conditional, unconditional, or indirect branch.
@ fixup_Hexagon_IE_GOT_11_X
static MCOperand createImm(int64_t Val)
Context object for machine code objects.
@ fixup_Hexagon_DTPREL_32_6_X
@ fixup_Hexagon_GD_GOT_32
Target - Wrapper for Target specific information.
#define HEXAGON_INSTR_SIZE
@ fixup_Hexagon_IE_GOT_HI16
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
int64_t getSExtValue() const
Get sign extended value.
@ fixup_Hexagon_B9_PCREL_X
@ fixup_Hexagon_GPREL16_0
Triple - Helper class for working with autoconf configuration names.
bool HexagonMCShuffle(MCContext &Context, bool ReportErrors, MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst &MCB)
static MCInstrInfo * createMCInstrInfo()
static APInt getSignedMaxValue(unsigned numBits)
Gets maximum signed value of APInt for a specific bit width.
@ fixup_Hexagon_B13_PCREL_X
@ fixup_Hexagon_LD_GOT_11_X
@ fixup_Hexagon_GOTREL_32
@ fixup_Hexagon_LD_GOT_LO16
Instances of this class represent a single low-level machine instruction.
SmallVectorImpl< MCFixup > & getFixups()
@ fixup_Hexagon_GOTREL_32_6_X
@ fixup_Hexagon_DTPREL_HI16
Error applyFixup(LinkGraph &G, Block &B, const Edge &E)
Apply fixup expression for edge to block content.
@ fixup_Hexagon_DTPREL_16
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM ID Predecessors according to mbb< bb27, 0x8b0a7c0 > Note ADDri is not a two address instruction its result reg1037 is an operand of the PHI node in bb76 and its operand reg1039 is the result of the PHI node We should treat it as a two address code and make sure the ADDri is scheduled after any node that reads reg1039 Use info(i.e. register scavenger) to assign it a free register to allow reuse the collector could move the objects and invalidate the derived pointer This is bad enough in the first but safe points can crop up unpredictably **array_addr i32 n y store obj * new
void setOpcode(unsigned Op)
@ fixup_Hexagon_GPREL16_3
@ fixup_Hexagon_GD_GOT_16_X
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
@ fixup_Hexagon_IE_GOT_32_6_X
@ fixup_Hexagon_TPREL_11_X
In x86 we generate this spiffy xmm0 xmm0 ret in x86 we generate this which could be xmm1 movss xmm1 xmm0 ret In sse4 we could use insertps to make both better Here s another testcase that could use x3
@ FK_Data_4
A four-byte fixup.
Generic interface to target specific assembler backends.
@ fixup_Hexagon_TPREL_LO16
@ fixup_Hexagon_LD_GOT_16_X
void invalidateFragmentsFrom(MCFragment *F)
Invalidate the fragments starting with F because it has been resized.
@ fixup_Hexagon_GD_PLT_B22_PCREL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
MCContext & getContext() const
Clang compiles this i1 i64 store i64 i64 store i64 i64 store i64 i64 store i64 align Which gets codegen d xmm0 movaps rbp movaps rbp movaps rbp movaps rbp rbp rbp rbp rbp It would be better to have movq s of instead of the movaps s LLVM produces ret int
const Triple & getTargetTriple() const
bool isBundle(MCInst const &MCI)
@ fixup_Hexagon_LD_PLT_B32_PCREL_X
bool check(bool FullCheck=true)
void setInst(const MCInst &Value)
Describe properties that are true of each instruction in the target description file.
iterator_range< Hexagon::PacketIterator > bundleInstructions(MCInstrInfo const &MCII, MCInst const &MCI)
const MCInst & getInst() const
const char LLVMTargetMachineRef LLVMPassBuilderOptionsRef Options
This class implements an extremely fast bulk output stream that can only output to a stream.
@ fixup_Hexagon_DTPREL_11_X
@ fixup_Hexagon_DTPREL_32
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
size_t bundleSize(MCInst const &MCI)
static RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
static MCOperand createInst(const MCInst *Val)
void addOperand(const MCOperand Op)
@ fixup_Hexagon_GD_PLT_B22_PCREL_X
@ fixup_Hexagon_GPREL16_1
@ fixup_Hexagon_B15_PCREL_X
@ fixup_Hexagon_LD_GOT_HI16
llvm::SmallVectorImpl< MCSection * > & getSectionOrder()
static unsigned getFixupKindNumBytes(unsigned Kind)
The number of bytes the fixup may change.
unsigned packetSize(StringRef CPU)
@ fixup_Hexagon_IE_32_6_X
@ fixup_Hexagon_TPREL_32_6_X
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
@ FKF_IsPCRel
Is this fixup kind PCrelative? This is used by the assembler backend to evaluate fixup values in a ta...
@ fixup_Hexagon_GOTREL_HI16
static uint64_t adjustFixupValue(const MCFixup &Fixup, const MCValue &Target, uint64_t Value, MCContext &Ctx, const Triple &TheTriple, bool IsResolved)
@ fixup_Hexagon_GOT_32_6_X
MCInst deriveExtender(MCInstrInfo const &MCII, MCInst const &Inst, MCOperand const &MO)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
@ fixup_Hexagon_GOTREL_LO16
Target independent information on a fixup kind.
@ fixup_Hexagon_GD_GOT_HI16
@ FK_Data_1
A one-byte fixup.
@ FK_PCRel_4
A four-byte pc relative fixup.
Class for arbitrary precision integers.
@ fixup_Hexagon_LD_PLT_B22_PCREL
PowerPC TLS Dynamic Call Fixup
StringRef - Represent a constant reference to a string, i.e.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
unsigned short getExtendableOp(MCInstrInfo const &MCII, MCInst const &MCI)
@ fixup_Hexagon_GPREL16_2
@ fixup_Hexagon_LD_GOT_32
@ fixup_Hexagon_DTPMOD_32
static cl::opt< bool > DisableFixup("mno-fixup", cl::desc("Disable fixing up resolved relocations for Hexagon"))
@ fixup_Hexagon_GD_PLT_B32_PCREL_X
@ fixup_Hexagon_GD_GOT_16
@ fixup_Hexagon_B22_PCREL_X
Check for a valid bundle.
unsigned getType(MCInstrInfo const &MCII, MCInst const &MCI)
Return the Hexagon ISA class for the insn.
Encapsulates the layout of an assembly file at a particular point in time.
MCCodeEmitter - Generic instruction encoding interface.
Lightweight error class with error context and mandatory checking.
@ fixup_Hexagon_B7_PCREL_X
const MCSubtargetInfo * getSubtargetInfo() const
Retrieve the MCSubTargetInfo in effect when the instruction was encoded.
const MCExpr * getExpr() const
unsigned getOpcode() const
const MCOperand & getExtendableOperand(MCInstrInfo const &MCII, MCInst const &MCI)
@ fixup_Hexagon_IE_GOT_32
const MCInst & instruction(MCInst const &MCB, size_t Index)
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
@ fixup_Hexagon_PLT_B22_PCREL
@ fixup_Hexagon_LD_GOT_16
@ fixup_Hexagon_LD_GOT_32_6_X
MCFixupKind
Extensible enumeration to represent the type of a fixup.
StringRef selectHexagonCPU(StringRef CPU)
@ fixup_Hexagon_GD_GOT_11_X
@ fixup_Hexagon_B15_PCREL
@ fixup_Hexagon_IE_GOT_LO16
const MCOperand & getOperand(unsigned i) const
Reimplement select in terms of SEL *We would really like to support but we need to prove that the add doesn t need to overflow between the two bit chunks *Implement pre post increment support(e.g. PR935) *Implement smarter const ant generation for binops with large immediates. A few ARMv6T2 ops should be pattern matched
@ fixup_Hexagon_TPREL_16_X
A raw_ostream that writes to an SmallVector or SmallString.
@ fixup_Hexagon_B13_PCREL
@ fixup_Hexagon_IE_GOT_16_X
@ fixup_Hexagon_GOTREL_11_X
Instances of this class represent operands of the MCInst class.
MCAssembler & getAssembler() const
Get the assembler object this is a layout for.
This represents an "assembler immediate".
@ FK_Data_2
A two-byte fixup.
#define HEXAGON_PACKET_SIZE
@ fixup_Hexagon_IE_GOT_16
MCAsmBackend * createHexagonAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
Generic base class for all target subtargets.
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
LLVM Value Representation.
@ fixup_Hexagon_DTPREL_16_X
SmallVectorImpl< char > & getContents()
bool isExtendable(MCInstrInfo const &MCII, MCInst const &MCI)
raw_ostream & write_hex(unsigned long long N)
Output N in hexadecimal, without any prefix or padding.
std::unique_ptr< MCObjectTargetWriter > createHexagonELFObjectWriter(uint8_t OSABI, StringRef CPU)