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