1 | //===-- HexagonAsmBackend.cpp - Hexagon Assembler Backend -----------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "HexagonFixupKinds.h" |
10 | #include "MCTargetDesc/HexagonBaseInfo.h" |
11 | #include "MCTargetDesc/HexagonMCChecker.h" |
12 | #include "MCTargetDesc/HexagonMCCodeEmitter.h" |
13 | #include "MCTargetDesc/HexagonMCInstrInfo.h" |
14 | #include "MCTargetDesc/HexagonMCShuffler.h" |
15 | #include "MCTargetDesc/HexagonMCTargetDesc.h" |
16 | #include "llvm/MC/MCAsmBackend.h" |
17 | #include "llvm/MC/MCAssembler.h" |
18 | #include "llvm/MC/MCContext.h" |
19 | #include "llvm/MC/MCELFObjectWriter.h" |
20 | #include "llvm/MC/MCFixupKindInfo.h" |
21 | #include "llvm/MC/MCInstrInfo.h" |
22 | #include "llvm/MC/MCObjectWriter.h" |
23 | #include "llvm/MC/MCSubtargetInfo.h" |
24 | #include "llvm/MC/TargetRegistry.h" |
25 | #include "llvm/Support/Debug.h" |
26 | #include "llvm/Support/EndianStream.h" |
27 | |
28 | #include <sstream> |
29 | |
30 | using namespace llvm; |
31 | using namespace Hexagon; |
32 | |
33 | #define DEBUG_TYPE "hexagon-asm-backend" |
34 | |
35 | static cl::opt<bool> DisableFixup |
36 | ("mno-fixup" , cl::desc("Disable fixing up resolved relocations for Hexagon" )); |
37 | |
38 | namespace { |
39 | |
40 | class HexagonAsmBackend : public MCAsmBackend { |
41 | uint8_t OSABI; |
42 | StringRef CPU; |
43 | mutable uint64_t relaxedCnt; |
44 | mutable const MCInst *RelaxedMCB = nullptr; |
45 | std::unique_ptr <MCInstrInfo> MCII; |
46 | std::unique_ptr <MCInst *> RelaxTarget; |
47 | MCInst * Extender; |
48 | unsigned MaxPacketSize; |
49 | |
50 | void ReplaceInstruction(MCCodeEmitter &E, MCRelaxableFragment &RF, |
51 | MCInst &HMB) const { |
52 | SmallVector<MCFixup, 4> Fixups; |
53 | SmallString<256> Code; |
54 | E.encodeInstruction(Inst: HMB, CB&: Code, Fixups, STI: *RF.getSubtargetInfo()); |
55 | |
56 | // Update the fragment. |
57 | RF.setInst(HMB); |
58 | RF.setContents(Code); |
59 | RF.getFixups() = Fixups; |
60 | } |
61 | |
62 | public: |
63 | HexagonAsmBackend(const Target &T, const Triple &TT, uint8_t OSABI, |
64 | StringRef CPU) |
65 | : MCAsmBackend(llvm::endianness::little), OSABI(OSABI), CPU(CPU), |
66 | relaxedCnt(0), MCII(T.createMCInstrInfo()), RelaxTarget(new MCInst *), |
67 | Extender(nullptr), MaxPacketSize(HexagonMCInstrInfo::packetSize(CPU)) {} |
68 | |
69 | std::unique_ptr<MCObjectTargetWriter> |
70 | createObjectTargetWriter() const override { |
71 | return createHexagonELFObjectWriter(OSABI, CPU); |
72 | } |
73 | |
74 | void setExtender(MCContext &Context) const { |
75 | if (Extender == nullptr) |
76 | const_cast<HexagonAsmBackend *>(this)->Extender = Context.createMCInst(); |
77 | } |
78 | |
79 | MCInst *takeExtender() const { |
80 | assert(Extender != nullptr); |
81 | MCInst * Result = Extender; |
82 | const_cast<HexagonAsmBackend *>(this)->Extender = nullptr; |
83 | return Result; |
84 | } |
85 | |
86 | MCFixupKindInfo getFixupKindInfo(MCFixupKind Kind) const override { |
87 | const static MCFixupKindInfo Infos[Hexagon::NumTargetFixupKinds] = { |
88 | // This table *must* be in same the order of fixup_* kinds in |
89 | // HexagonFixupKinds.h. |
90 | // |
91 | // namei offset bits flags |
92 | { .Name: "fixup_Hexagon_B22_PCREL" , .TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
93 | { .Name: "fixup_Hexagon_B15_PCREL" , .TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
94 | { .Name: "fixup_Hexagon_B7_PCREL" , .TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
95 | { .Name: "fixup_Hexagon_LO16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
96 | { .Name: "fixup_Hexagon_HI16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
97 | { .Name: "fixup_Hexagon_32" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
98 | { .Name: "fixup_Hexagon_16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
99 | { .Name: "fixup_Hexagon_8" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
100 | { .Name: "fixup_Hexagon_GPREL16_0" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
101 | { .Name: "fixup_Hexagon_GPREL16_1" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
102 | { .Name: "fixup_Hexagon_GPREL16_2" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
103 | { .Name: "fixup_Hexagon_GPREL16_3" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
104 | { .Name: "fixup_Hexagon_HL16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
105 | { .Name: "fixup_Hexagon_B13_PCREL" , .TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
106 | { .Name: "fixup_Hexagon_B9_PCREL" , .TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
107 | { .Name: "fixup_Hexagon_B32_PCREL_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
108 | { .Name: "fixup_Hexagon_32_6_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
109 | { .Name: "fixup_Hexagon_B22_PCREL_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
110 | { .Name: "fixup_Hexagon_B15_PCREL_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
111 | { .Name: "fixup_Hexagon_B13_PCREL_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
112 | { .Name: "fixup_Hexagon_B9_PCREL_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
113 | { .Name: "fixup_Hexagon_B7_PCREL_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
114 | { .Name: "fixup_Hexagon_16_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
115 | { .Name: "fixup_Hexagon_12_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
116 | { .Name: "fixup_Hexagon_11_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
117 | { .Name: "fixup_Hexagon_10_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
118 | { .Name: "fixup_Hexagon_9_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
119 | { .Name: "fixup_Hexagon_8_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
120 | { .Name: "fixup_Hexagon_7_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
121 | { .Name: "fixup_Hexagon_6_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
122 | { .Name: "fixup_Hexagon_32_PCREL" , .TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
123 | { .Name: "fixup_Hexagon_COPY" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
124 | { .Name: "fixup_Hexagon_GLOB_DAT" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
125 | { .Name: "fixup_Hexagon_JMP_SLOT" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
126 | { .Name: "fixup_Hexagon_RELATIVE" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
127 | { .Name: "fixup_Hexagon_PLT_B22_PCREL" , .TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
128 | { .Name: "fixup_Hexagon_GOTREL_LO16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
129 | { .Name: "fixup_Hexagon_GOTREL_HI16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
130 | { .Name: "fixup_Hexagon_GOTREL_32" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
131 | { .Name: "fixup_Hexagon_GOT_LO16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
132 | { .Name: "fixup_Hexagon_GOT_HI16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
133 | { .Name: "fixup_Hexagon_GOT_32" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
134 | { .Name: "fixup_Hexagon_GOT_16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
135 | { .Name: "fixup_Hexagon_DTPMOD_32" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
136 | { .Name: "fixup_Hexagon_DTPREL_LO16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
137 | { .Name: "fixup_Hexagon_DTPREL_HI16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
138 | { .Name: "fixup_Hexagon_DTPREL_32" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
139 | { .Name: "fixup_Hexagon_DTPREL_16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
140 | { .Name: "fixup_Hexagon_GD_PLT_B22_PCREL" ,.TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
141 | { .Name: "fixup_Hexagon_LD_PLT_B22_PCREL" ,.TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
142 | { .Name: "fixup_Hexagon_GD_GOT_LO16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
143 | { .Name: "fixup_Hexagon_GD_GOT_HI16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
144 | { .Name: "fixup_Hexagon_GD_GOT_32" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
145 | { .Name: "fixup_Hexagon_GD_GOT_16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
146 | { .Name: "fixup_Hexagon_LD_GOT_LO16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
147 | { .Name: "fixup_Hexagon_LD_GOT_HI16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
148 | { .Name: "fixup_Hexagon_LD_GOT_32" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
149 | { .Name: "fixup_Hexagon_LD_GOT_16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
150 | { .Name: "fixup_Hexagon_IE_LO16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
151 | { .Name: "fixup_Hexagon_IE_HI16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
152 | { .Name: "fixup_Hexagon_IE_32" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
153 | { .Name: "fixup_Hexagon_IE_16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
154 | { .Name: "fixup_Hexagon_IE_GOT_LO16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
155 | { .Name: "fixup_Hexagon_IE_GOT_HI16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
156 | { .Name: "fixup_Hexagon_IE_GOT_32" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
157 | { .Name: "fixup_Hexagon_IE_GOT_16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
158 | { .Name: "fixup_Hexagon_TPREL_LO16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
159 | { .Name: "fixup_Hexagon_TPREL_HI16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
160 | { .Name: "fixup_Hexagon_TPREL_32" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
161 | { .Name: "fixup_Hexagon_TPREL_16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
162 | { .Name: "fixup_Hexagon_6_PCREL_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
163 | { .Name: "fixup_Hexagon_GOTREL_32_6_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
164 | { .Name: "fixup_Hexagon_GOTREL_16_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
165 | { .Name: "fixup_Hexagon_GOTREL_11_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
166 | { .Name: "fixup_Hexagon_GOT_32_6_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
167 | { .Name: "fixup_Hexagon_GOT_16_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
168 | { .Name: "fixup_Hexagon_GOT_11_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
169 | { .Name: "fixup_Hexagon_DTPREL_32_6_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
170 | { .Name: "fixup_Hexagon_DTPREL_16_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
171 | { .Name: "fixup_Hexagon_DTPREL_11_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
172 | { .Name: "fixup_Hexagon_GD_GOT_32_6_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
173 | { .Name: "fixup_Hexagon_GD_GOT_16_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
174 | { .Name: "fixup_Hexagon_GD_GOT_11_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
175 | { .Name: "fixup_Hexagon_LD_GOT_32_6_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
176 | { .Name: "fixup_Hexagon_LD_GOT_16_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
177 | { .Name: "fixup_Hexagon_LD_GOT_11_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
178 | { .Name: "fixup_Hexagon_IE_32_6_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
179 | { .Name: "fixup_Hexagon_IE_16_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
180 | { .Name: "fixup_Hexagon_IE_GOT_32_6_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
181 | { .Name: "fixup_Hexagon_IE_GOT_16_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
182 | { .Name: "fixup_Hexagon_IE_GOT_11_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
183 | { .Name: "fixup_Hexagon_TPREL_32_6_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
184 | { .Name: "fixup_Hexagon_TPREL_16_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
185 | { .Name: "fixup_Hexagon_TPREL_11_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
186 | { .Name: "fixup_Hexagon_GD_PLT_B22_PCREL_X" ,.TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
187 | { .Name: "fixup_Hexagon_GD_PLT_B32_PCREL_X" ,.TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
188 | { .Name: "fixup_Hexagon_LD_PLT_B22_PCREL_X" ,.TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
189 | { .Name: "fixup_Hexagon_LD_PLT_B32_PCREL_X" ,.TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel } |
190 | }; |
191 | |
192 | if (Kind < FirstTargetFixupKind) |
193 | return MCAsmBackend::getFixupKindInfo(Kind); |
194 | |
195 | assert(unsigned(Kind - FirstTargetFixupKind) < |
196 | Hexagon::NumTargetFixupKinds && |
197 | "Invalid kind!" ); |
198 | return Infos[Kind - FirstTargetFixupKind]; |
199 | } |
200 | |
201 | bool shouldForceRelocation(const MCFixup &Fixup) { |
202 | switch(Fixup.getTargetKind()) { |
203 | default: |
204 | llvm_unreachable("Unknown Fixup Kind!" ); |
205 | |
206 | case fixup_Hexagon_LO16: |
207 | case fixup_Hexagon_HI16: |
208 | case fixup_Hexagon_16: |
209 | case fixup_Hexagon_8: |
210 | case fixup_Hexagon_GPREL16_0: |
211 | case fixup_Hexagon_GPREL16_1: |
212 | case fixup_Hexagon_GPREL16_2: |
213 | case fixup_Hexagon_GPREL16_3: |
214 | case fixup_Hexagon_HL16: |
215 | case fixup_Hexagon_32_6_X: |
216 | case fixup_Hexagon_16_X: |
217 | case fixup_Hexagon_12_X: |
218 | case fixup_Hexagon_11_X: |
219 | case fixup_Hexagon_10_X: |
220 | case fixup_Hexagon_9_X: |
221 | case fixup_Hexagon_8_X: |
222 | case fixup_Hexagon_7_X: |
223 | case fixup_Hexagon_6_X: |
224 | case fixup_Hexagon_COPY: |
225 | case fixup_Hexagon_GLOB_DAT: |
226 | case fixup_Hexagon_JMP_SLOT: |
227 | case fixup_Hexagon_RELATIVE: |
228 | case fixup_Hexagon_PLT_B22_PCREL: |
229 | case fixup_Hexagon_GOTREL_LO16: |
230 | case fixup_Hexagon_GOTREL_HI16: |
231 | case fixup_Hexagon_GOTREL_32: |
232 | case fixup_Hexagon_GOT_LO16: |
233 | case fixup_Hexagon_GOT_HI16: |
234 | case fixup_Hexagon_GOT_32: |
235 | case fixup_Hexagon_GOT_16: |
236 | case fixup_Hexagon_DTPMOD_32: |
237 | case fixup_Hexagon_DTPREL_LO16: |
238 | case fixup_Hexagon_DTPREL_HI16: |
239 | case fixup_Hexagon_DTPREL_32: |
240 | case fixup_Hexagon_DTPREL_16: |
241 | case fixup_Hexagon_GD_PLT_B22_PCREL: |
242 | case fixup_Hexagon_LD_PLT_B22_PCREL: |
243 | case fixup_Hexagon_GD_GOT_LO16: |
244 | case fixup_Hexagon_GD_GOT_HI16: |
245 | case fixup_Hexagon_GD_GOT_32: |
246 | case fixup_Hexagon_GD_GOT_16: |
247 | case fixup_Hexagon_LD_GOT_LO16: |
248 | case fixup_Hexagon_LD_GOT_HI16: |
249 | case fixup_Hexagon_LD_GOT_32: |
250 | case fixup_Hexagon_LD_GOT_16: |
251 | case fixup_Hexagon_IE_LO16: |
252 | case fixup_Hexagon_IE_HI16: |
253 | case fixup_Hexagon_IE_32: |
254 | case fixup_Hexagon_IE_16: |
255 | case fixup_Hexagon_IE_GOT_LO16: |
256 | case fixup_Hexagon_IE_GOT_HI16: |
257 | case fixup_Hexagon_IE_GOT_32: |
258 | case fixup_Hexagon_IE_GOT_16: |
259 | case fixup_Hexagon_TPREL_LO16: |
260 | case fixup_Hexagon_TPREL_HI16: |
261 | case fixup_Hexagon_TPREL_32: |
262 | case fixup_Hexagon_TPREL_16: |
263 | case fixup_Hexagon_GOTREL_32_6_X: |
264 | case fixup_Hexagon_GOTREL_16_X: |
265 | case fixup_Hexagon_GOTREL_11_X: |
266 | case fixup_Hexagon_GOT_32_6_X: |
267 | case fixup_Hexagon_GOT_16_X: |
268 | case fixup_Hexagon_GOT_11_X: |
269 | case fixup_Hexagon_DTPREL_32_6_X: |
270 | case fixup_Hexagon_DTPREL_16_X: |
271 | case fixup_Hexagon_DTPREL_11_X: |
272 | case fixup_Hexagon_GD_GOT_32_6_X: |
273 | case fixup_Hexagon_GD_GOT_16_X: |
274 | case fixup_Hexagon_GD_GOT_11_X: |
275 | case fixup_Hexagon_LD_GOT_32_6_X: |
276 | case fixup_Hexagon_LD_GOT_16_X: |
277 | case fixup_Hexagon_LD_GOT_11_X: |
278 | case fixup_Hexagon_IE_32_6_X: |
279 | case fixup_Hexagon_IE_16_X: |
280 | case fixup_Hexagon_IE_GOT_32_6_X: |
281 | case fixup_Hexagon_IE_GOT_16_X: |
282 | case fixup_Hexagon_IE_GOT_11_X: |
283 | case fixup_Hexagon_TPREL_32_6_X: |
284 | case fixup_Hexagon_TPREL_16_X: |
285 | case fixup_Hexagon_TPREL_11_X: |
286 | case fixup_Hexagon_32_PCREL: |
287 | case fixup_Hexagon_6_PCREL_X: |
288 | case fixup_Hexagon_23_REG: |
289 | case fixup_Hexagon_27_REG: |
290 | case fixup_Hexagon_GD_PLT_B22_PCREL_X: |
291 | case fixup_Hexagon_GD_PLT_B32_PCREL_X: |
292 | case fixup_Hexagon_LD_PLT_B22_PCREL_X: |
293 | case fixup_Hexagon_LD_PLT_B32_PCREL_X: |
294 | // These relocations should always have a relocation recorded |
295 | return true; |
296 | |
297 | case fixup_Hexagon_B22_PCREL: |
298 | //IsResolved = false; |
299 | break; |
300 | |
301 | case fixup_Hexagon_B13_PCREL: |
302 | case fixup_Hexagon_B13_PCREL_X: |
303 | case fixup_Hexagon_B32_PCREL_X: |
304 | case fixup_Hexagon_B22_PCREL_X: |
305 | case fixup_Hexagon_B15_PCREL: |
306 | case fixup_Hexagon_B15_PCREL_X: |
307 | case fixup_Hexagon_B9_PCREL: |
308 | case fixup_Hexagon_B9_PCREL_X: |
309 | case fixup_Hexagon_B7_PCREL: |
310 | case fixup_Hexagon_B7_PCREL_X: |
311 | if (DisableFixup) |
312 | return true; |
313 | break; |
314 | |
315 | case FK_Data_1: |
316 | case FK_Data_2: |
317 | case FK_Data_4: |
318 | case FK_PCRel_4: |
319 | case fixup_Hexagon_32: |
320 | // Leave these relocations alone as they are used for EH. |
321 | return false; |
322 | } |
323 | return false; |
324 | } |
325 | |
326 | /// getFixupKindNumBytes - The number of bytes the fixup may change. |
327 | static unsigned getFixupKindNumBytes(unsigned Kind) { |
328 | switch (Kind) { |
329 | default: |
330 | return 0; |
331 | |
332 | case FK_Data_1: |
333 | return 1; |
334 | case FK_Data_2: |
335 | return 2; |
336 | case FK_Data_4: // this later gets mapped to R_HEX_32 |
337 | case FK_PCRel_4: // this later gets mapped to R_HEX_32_PCREL |
338 | case fixup_Hexagon_32: |
339 | case fixup_Hexagon_B32_PCREL_X: |
340 | case fixup_Hexagon_B22_PCREL: |
341 | case fixup_Hexagon_B22_PCREL_X: |
342 | case fixup_Hexagon_B15_PCREL: |
343 | case fixup_Hexagon_B15_PCREL_X: |
344 | case fixup_Hexagon_B13_PCREL: |
345 | case fixup_Hexagon_B13_PCREL_X: |
346 | case fixup_Hexagon_B9_PCREL: |
347 | case fixup_Hexagon_B9_PCREL_X: |
348 | case fixup_Hexagon_B7_PCREL: |
349 | case fixup_Hexagon_B7_PCREL_X: |
350 | case fixup_Hexagon_GD_PLT_B32_PCREL_X: |
351 | case fixup_Hexagon_LD_PLT_B32_PCREL_X: |
352 | return 4; |
353 | } |
354 | } |
355 | |
356 | // Make up for left shift when encoding the operand. |
357 | static uint64_t adjustFixupValue(MCFixupKind Kind, uint64_t Value) { |
358 | switch((unsigned)Kind) { |
359 | default: |
360 | break; |
361 | |
362 | case fixup_Hexagon_B7_PCREL: |
363 | case fixup_Hexagon_B9_PCREL: |
364 | case fixup_Hexagon_B13_PCREL: |
365 | case fixup_Hexagon_B15_PCREL: |
366 | case fixup_Hexagon_B22_PCREL: |
367 | Value >>= 2; |
368 | break; |
369 | |
370 | case fixup_Hexagon_B7_PCREL_X: |
371 | case fixup_Hexagon_B9_PCREL_X: |
372 | case fixup_Hexagon_B13_PCREL_X: |
373 | case fixup_Hexagon_B15_PCREL_X: |
374 | case fixup_Hexagon_B22_PCREL_X: |
375 | Value &= 0x3f; |
376 | break; |
377 | |
378 | case fixup_Hexagon_B32_PCREL_X: |
379 | case fixup_Hexagon_GD_PLT_B32_PCREL_X: |
380 | case fixup_Hexagon_LD_PLT_B32_PCREL_X: |
381 | Value >>= 6; |
382 | break; |
383 | } |
384 | return (Value); |
385 | } |
386 | |
387 | void HandleFixupError(const int bits, const int align_bits, |
388 | const int64_t FixupValue, const char *fixupStr) const { |
389 | // Error: value 1124 out of range: -1024-1023 when resolving |
390 | // symbol in file xprtsock.S |
391 | const APInt IntMin = APInt::getSignedMinValue(numBits: bits+align_bits); |
392 | const APInt IntMax = APInt::getSignedMaxValue(numBits: bits+align_bits); |
393 | std::stringstream errStr; |
394 | errStr << "\nError: value " << |
395 | FixupValue << |
396 | " out of range: " << |
397 | IntMin.getSExtValue() << |
398 | "-" << |
399 | IntMax.getSExtValue() << |
400 | " when resolving " << |
401 | fixupStr << |
402 | " fixup\n" ; |
403 | llvm_unreachable(errStr.str().c_str()); |
404 | } |
405 | |
406 | void applyFixup(const MCFragment &, const MCFixup &, const MCValue &, |
407 | MutableArrayRef<char> Data, uint64_t FixupValue, |
408 | bool IsResolved) override; |
409 | |
410 | bool isInstRelaxable(MCInst const &HMI) const { |
411 | const MCInstrDesc &MCID = HexagonMCInstrInfo::getDesc(MCII: *MCII, MCI: HMI); |
412 | bool Relaxable = false; |
413 | // Branches and loop-setup insns are handled as necessary by relaxation. |
414 | if (llvm::HexagonMCInstrInfo::getType(MCII: *MCII, MCI: HMI) == HexagonII::TypeJ || |
415 | (llvm::HexagonMCInstrInfo::getType(MCII: *MCII, MCI: HMI) == HexagonII::TypeCJ && |
416 | MCID.isBranch()) || |
417 | (llvm::HexagonMCInstrInfo::getType(MCII: *MCII, MCI: HMI) == HexagonII::TypeNCJ && |
418 | MCID.isBranch()) || |
419 | (llvm::HexagonMCInstrInfo::getType(MCII: *MCII, MCI: HMI) == HexagonII::TypeCR && |
420 | HMI.getOpcode() != Hexagon::C4_addipc)) |
421 | if (HexagonMCInstrInfo::isExtendable(MCII: *MCII, MCI: HMI)) { |
422 | Relaxable = true; |
423 | MCOperand const &Operand = |
424 | HMI.getOperand(i: HexagonMCInstrInfo::getExtendableOp(MCII: *MCII, MCI: HMI)); |
425 | if (HexagonMCInstrInfo::mustNotExtend(Expr: *Operand.getExpr())) |
426 | Relaxable = false; |
427 | } |
428 | |
429 | return Relaxable; |
430 | } |
431 | |
432 | /// MayNeedRelaxation - Check whether the given instruction may need |
433 | /// relaxation. |
434 | /// |
435 | /// \param Inst - The instruction to test. |
436 | bool mayNeedRelaxation(MCInst const &Inst, |
437 | const MCSubtargetInfo &STI) const override { |
438 | RelaxedMCB = &Inst; |
439 | return true; |
440 | } |
441 | |
442 | /// fixupNeedsRelaxation - Target specific predicate for whether a given |
443 | /// fixup requires the associated instruction to be relaxed. |
444 | bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, const MCValue &, |
445 | uint64_t Value, |
446 | bool Resolved) const override { |
447 | MCInst const &MCB = *RelaxedMCB; |
448 | assert(HexagonMCInstrInfo::isBundle(MCB)); |
449 | |
450 | *RelaxTarget = nullptr; |
451 | MCInst &MCI = const_cast<MCInst &>(HexagonMCInstrInfo::instruction( |
452 | MCB, Index: Fixup.getOffset() / HEXAGON_INSTR_SIZE)); |
453 | bool Relaxable = isInstRelaxable(HMI: MCI); |
454 | if (Relaxable == false) |
455 | return false; |
456 | // If we cannot resolve the fixup value, it requires relaxation. |
457 | if (!Resolved) { |
458 | switch (Fixup.getTargetKind()) { |
459 | case fixup_Hexagon_B22_PCREL: |
460 | // GetFixupCount assumes B22 won't relax |
461 | [[fallthrough]]; |
462 | default: |
463 | return false; |
464 | break; |
465 | case fixup_Hexagon_B13_PCREL: |
466 | case fixup_Hexagon_B15_PCREL: |
467 | case fixup_Hexagon_B9_PCREL: |
468 | case fixup_Hexagon_B7_PCREL: { |
469 | if (HexagonMCInstrInfo::bundleSize(MCI: MCB) < HEXAGON_PACKET_SIZE) { |
470 | ++relaxedCnt; |
471 | *RelaxTarget = &MCI; |
472 | setExtender(getContext()); |
473 | return true; |
474 | } else { |
475 | return false; |
476 | } |
477 | break; |
478 | } |
479 | } |
480 | } |
481 | |
482 | MCFixupKind Kind = Fixup.getKind(); |
483 | int64_t sValue = Value; |
484 | int64_t maxValue; |
485 | |
486 | switch ((unsigned)Kind) { |
487 | case fixup_Hexagon_B7_PCREL: |
488 | maxValue = 1 << 8; |
489 | break; |
490 | case fixup_Hexagon_B9_PCREL: |
491 | maxValue = 1 << 10; |
492 | break; |
493 | case fixup_Hexagon_B15_PCREL: |
494 | maxValue = 1 << 16; |
495 | break; |
496 | case fixup_Hexagon_B22_PCREL: |
497 | maxValue = 1 << 23; |
498 | break; |
499 | default: |
500 | maxValue = INT64_MAX; |
501 | break; |
502 | } |
503 | |
504 | bool isFarAway = -maxValue > sValue || sValue > maxValue - 1; |
505 | |
506 | if (isFarAway) { |
507 | if (HexagonMCInstrInfo::bundleSize(MCI: MCB) < HEXAGON_PACKET_SIZE) { |
508 | ++relaxedCnt; |
509 | *RelaxTarget = &MCI; |
510 | setExtender(getContext()); |
511 | return true; |
512 | } |
513 | } |
514 | |
515 | return false; |
516 | } |
517 | |
518 | void relaxInstruction(MCInst &Inst, |
519 | const MCSubtargetInfo &STI) const override { |
520 | assert(HexagonMCInstrInfo::isBundle(Inst) && |
521 | "Hexagon relaxInstruction only works on bundles" ); |
522 | |
523 | MCInst Res; |
524 | Res.setOpcode(Hexagon::BUNDLE); |
525 | Res.addOperand(Op: MCOperand::createImm(Val: Inst.getOperand(i: 0).getImm())); |
526 | // Copy the results into the bundle. |
527 | bool Update = false; |
528 | for (auto &I : HexagonMCInstrInfo::bundleInstructions(MCI: Inst)) { |
529 | MCInst &CrntHMI = const_cast<MCInst &>(*I.getInst()); |
530 | |
531 | // if immediate extender needed, add it in |
532 | if (*RelaxTarget == &CrntHMI) { |
533 | Update = true; |
534 | assert((HexagonMCInstrInfo::bundleSize(Res) < HEXAGON_PACKET_SIZE) && |
535 | "No room to insert extender for relaxation" ); |
536 | |
537 | MCInst *HMIx = takeExtender(); |
538 | *HMIx = HexagonMCInstrInfo::deriveExtender( |
539 | MCII: *MCII, Inst: CrntHMI, |
540 | MO: HexagonMCInstrInfo::getExtendableOperand(MCII: *MCII, MCI: CrntHMI)); |
541 | Res.addOperand(Op: MCOperand::createInst(Val: HMIx)); |
542 | *RelaxTarget = nullptr; |
543 | } |
544 | // now copy over the original instruction(the one we may have extended) |
545 | Res.addOperand(Op: MCOperand::createInst(Val: I.getInst())); |
546 | } |
547 | |
548 | Inst = std::move(Res); |
549 | (void)Update; |
550 | assert(Update && "Didn't find relaxation target" ); |
551 | } |
552 | |
553 | bool writeNopData(raw_ostream &OS, uint64_t Count, |
554 | const MCSubtargetInfo *STI) const override { |
555 | static const uint32_t Nopcode = 0x7f000000, // Hard-coded NOP. |
556 | ParseIn = 0x00004000, // In packet parse-bits. |
557 | ParseEnd = 0x0000c000; // End of packet parse-bits. |
558 | |
559 | while (Count % HEXAGON_INSTR_SIZE) { |
560 | LLVM_DEBUG(dbgs() << "Alignment not a multiple of the instruction size:" |
561 | << Count % HEXAGON_INSTR_SIZE << "/" |
562 | << HEXAGON_INSTR_SIZE << "\n" ); |
563 | --Count; |
564 | OS << '\0'; |
565 | } |
566 | |
567 | while (Count) { |
568 | Count -= HEXAGON_INSTR_SIZE; |
569 | // Close the packet whenever a multiple of the maximum packet size remains |
570 | uint32_t ParseBits = (Count % (MaxPacketSize * HEXAGON_INSTR_SIZE)) ? |
571 | ParseIn : ParseEnd; |
572 | support::endian::write<uint32_t>(os&: OS, value: Nopcode | ParseBits, endian: Endian); |
573 | } |
574 | return true; |
575 | } |
576 | |
577 | bool finishLayout(const MCAssembler &Asm) const override { |
578 | SmallVector<MCFragment *> Frags; |
579 | for (MCSection &Sec : Asm) { |
580 | Frags.clear(); |
581 | for (MCFragment &F : Sec) |
582 | Frags.push_back(Elt: &F); |
583 | for (size_t J = 0, E = Frags.size(); J != E; ++J) { |
584 | switch (Frags[J]->getKind()) { |
585 | default: |
586 | break; |
587 | case MCFragment::FT_Align: { |
588 | auto Size = Asm.computeFragmentSize(F: *Frags[J]); |
589 | for (auto K = J; K != 0 && Size >= HEXAGON_PACKET_SIZE;) { |
590 | --K; |
591 | switch (Frags[K]->getKind()) { |
592 | default: |
593 | break; |
594 | case MCFragment::FT_Align: { |
595 | // Don't pad before other alignments |
596 | Size = 0; |
597 | break; |
598 | } |
599 | case MCFragment::FT_Relaxable: { |
600 | MCContext &Context = getContext(); |
601 | auto &RF = cast<MCRelaxableFragment>(Val&: *Frags[K]); |
602 | auto &Inst = const_cast<MCInst &>(RF.getInst()); |
603 | |
604 | const bool WouldTraverseLabel = llvm::any_of( |
605 | Range: Asm.symbols(), P: [&Asm, &RF, &Inst](MCSymbol const &sym) { |
606 | uint64_t Offset = 0; |
607 | const bool HasOffset = Asm.getSymbolOffset(S: sym, Val&: Offset); |
608 | const unsigned PacketSizeBytes = |
609 | HexagonMCInstrInfo::bundleSize(MCI: Inst) * |
610 | HEXAGON_INSTR_SIZE; |
611 | const bool OffsetPastSym = |
612 | Offset <= (Asm.getFragmentOffset(F: RF) + PacketSizeBytes); |
613 | return !sym.isVariable() && Offset != 0 && HasOffset && |
614 | OffsetPastSym; |
615 | }); |
616 | if (WouldTraverseLabel) { |
617 | Size = 0; |
618 | break; |
619 | } |
620 | |
621 | while (Size > 0 && |
622 | HexagonMCInstrInfo::bundleSize(MCI: Inst) < MaxPacketSize) { |
623 | MCInst *Nop = Context.createMCInst(); |
624 | Nop->setOpcode(Hexagon::A2_nop); |
625 | Inst.addOperand(Op: MCOperand::createInst(Val: Nop)); |
626 | Size -= 4; |
627 | if (!HexagonMCChecker( |
628 | Context, *MCII, *RF.getSubtargetInfo(), Inst, |
629 | *Context.getRegisterInfo(), false) |
630 | .check()) { |
631 | Inst.erase(I: Inst.end() - 1); |
632 | Size = 0; |
633 | } |
634 | } |
635 | bool Error = HexagonMCShuffle(Context, ReportErrors: true, MCII: *MCII, |
636 | STI: *RF.getSubtargetInfo(), MCB&: Inst); |
637 | //assert(!Error); |
638 | (void)Error; |
639 | ReplaceInstruction(E&: Asm.getEmitter(), RF, HMB&: Inst); |
640 | Size = 0; // Only look back one instruction |
641 | break; |
642 | } |
643 | } |
644 | } |
645 | } |
646 | } |
647 | } |
648 | } |
649 | return true; |
650 | } |
651 | }; // class HexagonAsmBackend |
652 | |
653 | } // namespace |
654 | |
655 | void HexagonAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup, |
656 | const MCValue &Target, |
657 | MutableArrayRef<char> Data, |
658 | uint64_t FixupValue, bool IsResolved) { |
659 | if (IsResolved && shouldForceRelocation(Fixup)) |
660 | IsResolved = false; |
661 | maybeAddReloc(F, Fixup, Target, Value&: FixupValue, IsResolved); |
662 | // When FixupValue is 0 the relocation is external and there |
663 | // is nothing for us to do. |
664 | if (!FixupValue) |
665 | return; |
666 | |
667 | MCFixupKind Kind = Fixup.getKind(); |
668 | uint64_t Value; |
669 | uint32_t InstMask; |
670 | uint32_t Reloc; |
671 | |
672 | // LLVM gives us an encoded value, we have to convert it back |
673 | // to a real offset before we can use it. |
674 | uint32_t Offset = Fixup.getOffset(); |
675 | unsigned NumBytes = getFixupKindNumBytes(Kind); |
676 | assert(Offset + NumBytes <= Data.size() && "Invalid fixup offset!" ); |
677 | char *InstAddr = Data.data() + Offset; |
678 | |
679 | Value = adjustFixupValue(Kind, Value: FixupValue); |
680 | if (!Value) |
681 | return; |
682 | int sValue = (int)Value; |
683 | |
684 | switch ((unsigned)Kind) { |
685 | default: |
686 | return; |
687 | |
688 | case fixup_Hexagon_B7_PCREL: |
689 | if (!(isIntN(N: 7, x: sValue))) |
690 | HandleFixupError(bits: 7, align_bits: 2, FixupValue: (int64_t)FixupValue, fixupStr: "B7_PCREL" ); |
691 | [[fallthrough]]; |
692 | case fixup_Hexagon_B7_PCREL_X: |
693 | InstMask = 0x00001f18; // Word32_B7 |
694 | Reloc = (((Value >> 2) & 0x1f) << 8) | // Value 6-2 = Target 12-8 |
695 | ((Value & 0x3) << 3); // Value 1-0 = Target 4-3 |
696 | break; |
697 | |
698 | case fixup_Hexagon_B9_PCREL: |
699 | if (!(isIntN(N: 9, x: sValue))) |
700 | HandleFixupError(bits: 9, align_bits: 2, FixupValue: (int64_t)FixupValue, fixupStr: "B9_PCREL" ); |
701 | [[fallthrough]]; |
702 | case fixup_Hexagon_B9_PCREL_X: |
703 | InstMask = 0x003000fe; // Word32_B9 |
704 | Reloc = (((Value >> 7) & 0x3) << 20) | // Value 8-7 = Target 21-20 |
705 | ((Value & 0x7f) << 1); // Value 6-0 = Target 7-1 |
706 | break; |
707 | |
708 | // Since the existing branches that use this relocation cannot be |
709 | // extended, they should only be fixed up if the target is within range. |
710 | case fixup_Hexagon_B13_PCREL: |
711 | if (!(isIntN(N: 13, x: sValue))) |
712 | HandleFixupError(bits: 13, align_bits: 2, FixupValue: (int64_t)FixupValue, fixupStr: "B13_PCREL" ); |
713 | [[fallthrough]]; |
714 | case fixup_Hexagon_B13_PCREL_X: |
715 | InstMask = 0x00202ffe; // Word32_B13 |
716 | Reloc = (((Value >> 12) & 0x1) << 21) | // Value 12 = Target 21 |
717 | (((Value >> 11) & 0x1) << 13) | // Value 11 = Target 13 |
718 | ((Value & 0x7ff) << 1); // Value 10-0 = Target 11-1 |
719 | break; |
720 | |
721 | case fixup_Hexagon_B15_PCREL: |
722 | if (!(isIntN(N: 15, x: sValue))) |
723 | HandleFixupError(bits: 15, align_bits: 2, FixupValue: (int64_t)FixupValue, fixupStr: "B15_PCREL" ); |
724 | [[fallthrough]]; |
725 | case fixup_Hexagon_B15_PCREL_X: |
726 | InstMask = 0x00df20fe; // Word32_B15 |
727 | Reloc = (((Value >> 13) & 0x3) << 22) | // Value 14-13 = Target 23-22 |
728 | (((Value >> 8) & 0x1f) << 16) | // Value 12-8 = Target 20-16 |
729 | (((Value >> 7) & 0x1) << 13) | // Value 7 = Target 13 |
730 | ((Value & 0x7f) << 1); // Value 6-0 = Target 7-1 |
731 | break; |
732 | |
733 | case fixup_Hexagon_B22_PCREL: |
734 | if (!(isIntN(N: 22, x: sValue))) |
735 | HandleFixupError(bits: 22, align_bits: 2, FixupValue: (int64_t)FixupValue, fixupStr: "B22_PCREL" ); |
736 | [[fallthrough]]; |
737 | case fixup_Hexagon_B22_PCREL_X: |
738 | InstMask = 0x01ff3ffe; // Word32_B22 |
739 | Reloc = (((Value >> 13) & 0x1ff) << 16) | // Value 21-13 = Target 24-16 |
740 | ((Value & 0x1fff) << 1); // Value 12-0 = Target 13-1 |
741 | break; |
742 | |
743 | case fixup_Hexagon_B32_PCREL_X: |
744 | InstMask = 0x0fff3fff; // Word32_X26 |
745 | Reloc = (((Value >> 14) & 0xfff) << 16) | // Value 25-14 = Target 27-16 |
746 | (Value & 0x3fff); // Value 13-0 = Target 13-0 |
747 | break; |
748 | |
749 | case FK_Data_1: |
750 | case FK_Data_2: |
751 | case FK_Data_4: |
752 | case fixup_Hexagon_32: |
753 | InstMask = 0xffffffff; // Word32 |
754 | Reloc = Value; |
755 | break; |
756 | } |
757 | |
758 | LLVM_DEBUG(dbgs() << "Name=" << getFixupKindInfo(Kind).Name << "(" |
759 | << (unsigned)Kind << ")\n" ); |
760 | LLVM_DEBUG( |
761 | uint32_t OldData = 0; for (unsigned i = 0; i < NumBytes; i++) OldData |= |
762 | (InstAddr[i] << (i * 8)) & (0xff << (i * 8)); |
763 | dbgs() << "\tBValue=0x" ; dbgs().write_hex(Value) << ": AValue=0x" ; |
764 | dbgs().write_hex(FixupValue) |
765 | << ": Offset=" << Offset << ": Size=" << Data.size() << ": OInst=0x" ; |
766 | dbgs().write_hex(OldData) << ": Reloc=0x" ; dbgs().write_hex(Reloc);); |
767 | |
768 | // For each byte of the fragment that the fixup touches, mask in the |
769 | // bits from the fixup value. The Value has been "split up" into the |
770 | // appropriate bitfields above. |
771 | for (unsigned i = 0; i < NumBytes; i++) { |
772 | InstAddr[i] &= uint8_t(~InstMask >> (i * 8)) & 0xff; // Clear reloc bits |
773 | InstAddr[i] |= uint8_t(Reloc >> (i * 8)) & 0xff; // Apply new reloc |
774 | } |
775 | |
776 | LLVM_DEBUG(uint32_t NewData = 0; |
777 | for (unsigned i = 0; i < NumBytes; i++) NewData |= |
778 | (InstAddr[i] << (i * 8)) & (0xff << (i * 8)); |
779 | dbgs() << ": NInst=0x" ; dbgs().write_hex(NewData) << "\n" ;); |
780 | } |
781 | |
782 | // MCAsmBackend |
783 | MCAsmBackend *llvm::createHexagonAsmBackend(Target const &T, |
784 | const MCSubtargetInfo &STI, |
785 | MCRegisterInfo const & /*MRI*/, |
786 | const MCTargetOptions &Options) { |
787 | const Triple &TT = STI.getTargetTriple(); |
788 | uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(OSType: TT.getOS()); |
789 | |
790 | StringRef CPUString = Hexagon_MC::selectHexagonCPU(CPU: STI.getCPU()); |
791 | return new HexagonAsmBackend(T, TT, OSABI, CPUString); |
792 | } |
793 | |