1 //===-- HexagonAsmBackend.cpp - Hexagon Assembler Backend -----------------===//
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
7 //===----------------------------------------------------------------------===//
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/EndianStream.h"
26 #include "llvm/Support/TargetRegistry.h"
31 using namespace Hexagon
;
33 #define DEBUG_TYPE "hexagon-asm-backend"
35 static cl::opt
<bool> DisableFixup
36 ("mno-fixup", cl::desc("Disable fixing up resolved relocations for Hexagon"));
40 class HexagonAsmBackend
: public MCAsmBackend
{
43 mutable uint64_t relaxedCnt
;
44 std::unique_ptr
<MCInstrInfo
> MCII
;
45 std::unique_ptr
<MCInst
*> RelaxTarget
;
47 unsigned MaxPacketSize
;
49 void ReplaceInstruction(MCCodeEmitter
&E
, MCRelaxableFragment
&RF
,
51 SmallVector
<MCFixup
, 4> Fixups
;
52 SmallString
<256> Code
;
53 raw_svector_ostream
VecOS(Code
);
54 E
.encodeInstruction(HMB
, VecOS
, Fixups
, *RF
.getSubtargetInfo());
56 // Update the fragment.
58 RF
.getContents() = Code
;
59 RF
.getFixups() = Fixups
;
63 HexagonAsmBackend(const Target
&T
, const Triple
&TT
, uint8_t OSABI
,
65 : MCAsmBackend(support::little
), OSABI(OSABI
), CPU(CPU
), relaxedCnt(0),
66 MCII(T
.createMCInstrInfo()), RelaxTarget(new MCInst
*),
67 Extender(nullptr), MaxPacketSize(HexagonMCInstrInfo::packetSize(CPU
))
70 std::unique_ptr
<MCObjectTargetWriter
>
71 createObjectTargetWriter() const override
{
72 return createHexagonELFObjectWriter(OSABI
, CPU
);
75 void setExtender(MCContext
&Context
) const {
76 if (Extender
== nullptr)
77 const_cast<HexagonAsmBackend
*>(this)->Extender
= Context
.createMCInst();
80 MCInst
*takeExtender() const {
81 assert(Extender
!= nullptr);
82 MCInst
* Result
= Extender
;
83 const_cast<HexagonAsmBackend
*>(this)->Extender
= nullptr;
87 unsigned getNumFixupKinds() const override
{
88 return Hexagon::NumTargetFixupKinds
;
91 const MCFixupKindInfo
&getFixupKindInfo(MCFixupKind Kind
) const override
{
92 const static MCFixupKindInfo Infos
[Hexagon::NumTargetFixupKinds
] = {
93 // This table *must* be in same the order of fixup_* kinds in
94 // HexagonFixupKinds.h.
96 // namei offset bits flags
97 { "fixup_Hexagon_B22_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel
},
98 { "fixup_Hexagon_B15_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel
},
99 { "fixup_Hexagon_B7_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel
},
100 { "fixup_Hexagon_LO16", 0, 32, 0 },
101 { "fixup_Hexagon_HI16", 0, 32, 0 },
102 { "fixup_Hexagon_32", 0, 32, 0 },
103 { "fixup_Hexagon_16", 0, 32, 0 },
104 { "fixup_Hexagon_8", 0, 32, 0 },
105 { "fixup_Hexagon_GPREL16_0", 0, 32, 0 },
106 { "fixup_Hexagon_GPREL16_1", 0, 32, 0 },
107 { "fixup_Hexagon_GPREL16_2", 0, 32, 0 },
108 { "fixup_Hexagon_GPREL16_3", 0, 32, 0 },
109 { "fixup_Hexagon_HL16", 0, 32, 0 },
110 { "fixup_Hexagon_B13_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel
},
111 { "fixup_Hexagon_B9_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel
},
112 { "fixup_Hexagon_B32_PCREL_X", 0, 32, MCFixupKindInfo::FKF_IsPCRel
},
113 { "fixup_Hexagon_32_6_X", 0, 32, 0 },
114 { "fixup_Hexagon_B22_PCREL_X", 0, 32, MCFixupKindInfo::FKF_IsPCRel
},
115 { "fixup_Hexagon_B15_PCREL_X", 0, 32, MCFixupKindInfo::FKF_IsPCRel
},
116 { "fixup_Hexagon_B13_PCREL_X", 0, 32, MCFixupKindInfo::FKF_IsPCRel
},
117 { "fixup_Hexagon_B9_PCREL_X", 0, 32, MCFixupKindInfo::FKF_IsPCRel
},
118 { "fixup_Hexagon_B7_PCREL_X", 0, 32, MCFixupKindInfo::FKF_IsPCRel
},
119 { "fixup_Hexagon_16_X", 0, 32, 0 },
120 { "fixup_Hexagon_12_X", 0, 32, 0 },
121 { "fixup_Hexagon_11_X", 0, 32, 0 },
122 { "fixup_Hexagon_10_X", 0, 32, 0 },
123 { "fixup_Hexagon_9_X", 0, 32, 0 },
124 { "fixup_Hexagon_8_X", 0, 32, 0 },
125 { "fixup_Hexagon_7_X", 0, 32, 0 },
126 { "fixup_Hexagon_6_X", 0, 32, 0 },
127 { "fixup_Hexagon_32_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel
},
128 { "fixup_Hexagon_COPY", 0, 32, 0 },
129 { "fixup_Hexagon_GLOB_DAT", 0, 32, 0 },
130 { "fixup_Hexagon_JMP_SLOT", 0, 32, 0 },
131 { "fixup_Hexagon_RELATIVE", 0, 32, 0 },
132 { "fixup_Hexagon_PLT_B22_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel
},
133 { "fixup_Hexagon_GOTREL_LO16", 0, 32, 0 },
134 { "fixup_Hexagon_GOTREL_HI16", 0, 32, 0 },
135 { "fixup_Hexagon_GOTREL_32", 0, 32, 0 },
136 { "fixup_Hexagon_GOT_LO16", 0, 32, 0 },
137 { "fixup_Hexagon_GOT_HI16", 0, 32, 0 },
138 { "fixup_Hexagon_GOT_32", 0, 32, 0 },
139 { "fixup_Hexagon_GOT_16", 0, 32, 0 },
140 { "fixup_Hexagon_DTPMOD_32", 0, 32, 0 },
141 { "fixup_Hexagon_DTPREL_LO16", 0, 32, 0 },
142 { "fixup_Hexagon_DTPREL_HI16", 0, 32, 0 },
143 { "fixup_Hexagon_DTPREL_32", 0, 32, 0 },
144 { "fixup_Hexagon_DTPREL_16", 0, 32, 0 },
145 { "fixup_Hexagon_GD_PLT_B22_PCREL",0, 32, MCFixupKindInfo::FKF_IsPCRel
},
146 { "fixup_Hexagon_LD_PLT_B22_PCREL",0, 32, MCFixupKindInfo::FKF_IsPCRel
},
147 { "fixup_Hexagon_GD_GOT_LO16", 0, 32, 0 },
148 { "fixup_Hexagon_GD_GOT_HI16", 0, 32, 0 },
149 { "fixup_Hexagon_GD_GOT_32", 0, 32, 0 },
150 { "fixup_Hexagon_GD_GOT_16", 0, 32, 0 },
151 { "fixup_Hexagon_LD_GOT_LO16", 0, 32, 0 },
152 { "fixup_Hexagon_LD_GOT_HI16", 0, 32, 0 },
153 { "fixup_Hexagon_LD_GOT_32", 0, 32, 0 },
154 { "fixup_Hexagon_LD_GOT_16", 0, 32, 0 },
155 { "fixup_Hexagon_IE_LO16", 0, 32, 0 },
156 { "fixup_Hexagon_IE_HI16", 0, 32, 0 },
157 { "fixup_Hexagon_IE_32", 0, 32, 0 },
158 { "fixup_Hexagon_IE_16", 0, 32, 0 },
159 { "fixup_Hexagon_IE_GOT_LO16", 0, 32, 0 },
160 { "fixup_Hexagon_IE_GOT_HI16", 0, 32, 0 },
161 { "fixup_Hexagon_IE_GOT_32", 0, 32, 0 },
162 { "fixup_Hexagon_IE_GOT_16", 0, 32, 0 },
163 { "fixup_Hexagon_TPREL_LO16", 0, 32, 0 },
164 { "fixup_Hexagon_TPREL_HI16", 0, 32, 0 },
165 { "fixup_Hexagon_TPREL_32", 0, 32, 0 },
166 { "fixup_Hexagon_TPREL_16", 0, 32, 0 },
167 { "fixup_Hexagon_6_PCREL_X", 0, 32, MCFixupKindInfo::FKF_IsPCRel
},
168 { "fixup_Hexagon_GOTREL_32_6_X", 0, 32, 0 },
169 { "fixup_Hexagon_GOTREL_16_X", 0, 32, 0 },
170 { "fixup_Hexagon_GOTREL_11_X", 0, 32, 0 },
171 { "fixup_Hexagon_GOT_32_6_X", 0, 32, 0 },
172 { "fixup_Hexagon_GOT_16_X", 0, 32, 0 },
173 { "fixup_Hexagon_GOT_11_X", 0, 32, 0 },
174 { "fixup_Hexagon_DTPREL_32_6_X", 0, 32, 0 },
175 { "fixup_Hexagon_DTPREL_16_X", 0, 32, 0 },
176 { "fixup_Hexagon_DTPREL_11_X", 0, 32, 0 },
177 { "fixup_Hexagon_GD_GOT_32_6_X", 0, 32, 0 },
178 { "fixup_Hexagon_GD_GOT_16_X", 0, 32, 0 },
179 { "fixup_Hexagon_GD_GOT_11_X", 0, 32, 0 },
180 { "fixup_Hexagon_LD_GOT_32_6_X", 0, 32, 0 },
181 { "fixup_Hexagon_LD_GOT_16_X", 0, 32, 0 },
182 { "fixup_Hexagon_LD_GOT_11_X", 0, 32, 0 },
183 { "fixup_Hexagon_IE_32_6_X", 0, 32, 0 },
184 { "fixup_Hexagon_IE_16_X", 0, 32, 0 },
185 { "fixup_Hexagon_IE_GOT_32_6_X", 0, 32, 0 },
186 { "fixup_Hexagon_IE_GOT_16_X", 0, 32, 0 },
187 { "fixup_Hexagon_IE_GOT_11_X", 0, 32, 0 },
188 { "fixup_Hexagon_TPREL_32_6_X", 0, 32, 0 },
189 { "fixup_Hexagon_TPREL_16_X", 0, 32, 0 },
190 { "fixup_Hexagon_TPREL_11_X", 0, 32, 0 },
191 { "fixup_Hexagon_GD_PLT_B22_PCREL_X",0, 32, MCFixupKindInfo::FKF_IsPCRel
},
192 { "fixup_Hexagon_GD_PLT_B32_PCREL_X",0, 32, MCFixupKindInfo::FKF_IsPCRel
},
193 { "fixup_Hexagon_LD_PLT_B22_PCREL_X",0, 32, MCFixupKindInfo::FKF_IsPCRel
},
194 { "fixup_Hexagon_LD_PLT_B32_PCREL_X",0, 32, MCFixupKindInfo::FKF_IsPCRel
}
197 if (Kind
< FirstTargetFixupKind
)
198 return MCAsmBackend::getFixupKindInfo(Kind
);
200 assert(unsigned(Kind
- FirstTargetFixupKind
) < getNumFixupKinds() &&
202 return Infos
[Kind
- FirstTargetFixupKind
];
205 bool shouldForceRelocation(const MCAssembler
&Asm
, const MCFixup
&Fixup
,
206 const MCValue
&Target
) override
{
207 switch(Fixup
.getTargetKind()) {
209 llvm_unreachable("Unknown Fixup Kind!");
211 case fixup_Hexagon_LO16
:
212 case fixup_Hexagon_HI16
:
213 case fixup_Hexagon_16
:
214 case fixup_Hexagon_8
:
215 case fixup_Hexagon_GPREL16_0
:
216 case fixup_Hexagon_GPREL16_1
:
217 case fixup_Hexagon_GPREL16_2
:
218 case fixup_Hexagon_GPREL16_3
:
219 case fixup_Hexagon_HL16
:
220 case fixup_Hexagon_32_6_X
:
221 case fixup_Hexagon_16_X
:
222 case fixup_Hexagon_12_X
:
223 case fixup_Hexagon_11_X
:
224 case fixup_Hexagon_10_X
:
225 case fixup_Hexagon_9_X
:
226 case fixup_Hexagon_8_X
:
227 case fixup_Hexagon_7_X
:
228 case fixup_Hexagon_6_X
:
229 case fixup_Hexagon_COPY
:
230 case fixup_Hexagon_GLOB_DAT
:
231 case fixup_Hexagon_JMP_SLOT
:
232 case fixup_Hexagon_RELATIVE
:
233 case fixup_Hexagon_PLT_B22_PCREL
:
234 case fixup_Hexagon_GOTREL_LO16
:
235 case fixup_Hexagon_GOTREL_HI16
:
236 case fixup_Hexagon_GOTREL_32
:
237 case fixup_Hexagon_GOT_LO16
:
238 case fixup_Hexagon_GOT_HI16
:
239 case fixup_Hexagon_GOT_32
:
240 case fixup_Hexagon_GOT_16
:
241 case fixup_Hexagon_DTPMOD_32
:
242 case fixup_Hexagon_DTPREL_LO16
:
243 case fixup_Hexagon_DTPREL_HI16
:
244 case fixup_Hexagon_DTPREL_32
:
245 case fixup_Hexagon_DTPREL_16
:
246 case fixup_Hexagon_GD_PLT_B22_PCREL
:
247 case fixup_Hexagon_LD_PLT_B22_PCREL
:
248 case fixup_Hexagon_GD_GOT_LO16
:
249 case fixup_Hexagon_GD_GOT_HI16
:
250 case fixup_Hexagon_GD_GOT_32
:
251 case fixup_Hexagon_GD_GOT_16
:
252 case fixup_Hexagon_LD_GOT_LO16
:
253 case fixup_Hexagon_LD_GOT_HI16
:
254 case fixup_Hexagon_LD_GOT_32
:
255 case fixup_Hexagon_LD_GOT_16
:
256 case fixup_Hexagon_IE_LO16
:
257 case fixup_Hexagon_IE_HI16
:
258 case fixup_Hexagon_IE_32
:
259 case fixup_Hexagon_IE_16
:
260 case fixup_Hexagon_IE_GOT_LO16
:
261 case fixup_Hexagon_IE_GOT_HI16
:
262 case fixup_Hexagon_IE_GOT_32
:
263 case fixup_Hexagon_IE_GOT_16
:
264 case fixup_Hexagon_TPREL_LO16
:
265 case fixup_Hexagon_TPREL_HI16
:
266 case fixup_Hexagon_TPREL_32
:
267 case fixup_Hexagon_TPREL_16
:
268 case fixup_Hexagon_GOTREL_32_6_X
:
269 case fixup_Hexagon_GOTREL_16_X
:
270 case fixup_Hexagon_GOTREL_11_X
:
271 case fixup_Hexagon_GOT_32_6_X
:
272 case fixup_Hexagon_GOT_16_X
:
273 case fixup_Hexagon_GOT_11_X
:
274 case fixup_Hexagon_DTPREL_32_6_X
:
275 case fixup_Hexagon_DTPREL_16_X
:
276 case fixup_Hexagon_DTPREL_11_X
:
277 case fixup_Hexagon_GD_GOT_32_6_X
:
278 case fixup_Hexagon_GD_GOT_16_X
:
279 case fixup_Hexagon_GD_GOT_11_X
:
280 case fixup_Hexagon_LD_GOT_32_6_X
:
281 case fixup_Hexagon_LD_GOT_16_X
:
282 case fixup_Hexagon_LD_GOT_11_X
:
283 case fixup_Hexagon_IE_32_6_X
:
284 case fixup_Hexagon_IE_16_X
:
285 case fixup_Hexagon_IE_GOT_32_6_X
:
286 case fixup_Hexagon_IE_GOT_16_X
:
287 case fixup_Hexagon_IE_GOT_11_X
:
288 case fixup_Hexagon_TPREL_32_6_X
:
289 case fixup_Hexagon_TPREL_16_X
:
290 case fixup_Hexagon_TPREL_11_X
:
291 case fixup_Hexagon_32_PCREL
:
292 case fixup_Hexagon_6_PCREL_X
:
293 case fixup_Hexagon_23_REG
:
294 case fixup_Hexagon_27_REG
:
295 case fixup_Hexagon_GD_PLT_B22_PCREL_X
:
296 case fixup_Hexagon_GD_PLT_B32_PCREL_X
:
297 case fixup_Hexagon_LD_PLT_B22_PCREL_X
:
298 case fixup_Hexagon_LD_PLT_B32_PCREL_X
:
299 // These relocations should always have a relocation recorded
302 case fixup_Hexagon_B22_PCREL
:
303 //IsResolved = false;
306 case fixup_Hexagon_B13_PCREL
:
307 case fixup_Hexagon_B13_PCREL_X
:
308 case fixup_Hexagon_B32_PCREL_X
:
309 case fixup_Hexagon_B22_PCREL_X
:
310 case fixup_Hexagon_B15_PCREL
:
311 case fixup_Hexagon_B15_PCREL_X
:
312 case fixup_Hexagon_B9_PCREL
:
313 case fixup_Hexagon_B9_PCREL_X
:
314 case fixup_Hexagon_B7_PCREL
:
315 case fixup_Hexagon_B7_PCREL_X
:
324 case fixup_Hexagon_32
:
325 // Leave these relocations alone as they are used for EH.
331 /// getFixupKindNumBytes - The number of bytes the fixup may change.
332 static unsigned getFixupKindNumBytes(unsigned Kind
) {
341 case FK_Data_4
: // this later gets mapped to R_HEX_32
342 case FK_PCRel_4
: // this later gets mapped to R_HEX_32_PCREL
343 case fixup_Hexagon_32
:
344 case fixup_Hexagon_B32_PCREL_X
:
345 case fixup_Hexagon_B22_PCREL
:
346 case fixup_Hexagon_B22_PCREL_X
:
347 case fixup_Hexagon_B15_PCREL
:
348 case fixup_Hexagon_B15_PCREL_X
:
349 case fixup_Hexagon_B13_PCREL
:
350 case fixup_Hexagon_B13_PCREL_X
:
351 case fixup_Hexagon_B9_PCREL
:
352 case fixup_Hexagon_B9_PCREL_X
:
353 case fixup_Hexagon_B7_PCREL
:
354 case fixup_Hexagon_B7_PCREL_X
:
355 case fixup_Hexagon_GD_PLT_B32_PCREL_X
:
356 case fixup_Hexagon_LD_PLT_B32_PCREL_X
:
361 // Make up for left shift when encoding the operand.
362 static uint64_t adjustFixupValue(MCFixupKind Kind
, uint64_t Value
) {
363 switch((unsigned)Kind
) {
367 case fixup_Hexagon_B7_PCREL
:
368 case fixup_Hexagon_B9_PCREL
:
369 case fixup_Hexagon_B13_PCREL
:
370 case fixup_Hexagon_B15_PCREL
:
371 case fixup_Hexagon_B22_PCREL
:
375 case fixup_Hexagon_B7_PCREL_X
:
376 case fixup_Hexagon_B9_PCREL_X
:
377 case fixup_Hexagon_B13_PCREL_X
:
378 case fixup_Hexagon_B15_PCREL_X
:
379 case fixup_Hexagon_B22_PCREL_X
:
383 case fixup_Hexagon_B32_PCREL_X
:
384 case fixup_Hexagon_GD_PLT_B32_PCREL_X
:
385 case fixup_Hexagon_LD_PLT_B32_PCREL_X
:
392 void HandleFixupError(const int bits
, const int align_bits
,
393 const int64_t FixupValue
, const char *fixupStr
) const {
394 // Error: value 1124 out of range: -1024-1023 when resolving
395 // symbol in file xprtsock.S
396 const APInt IntMin
= APInt::getSignedMinValue(bits
+align_bits
);
397 const APInt IntMax
= APInt::getSignedMaxValue(bits
+align_bits
);
398 std::stringstream errStr
;
399 errStr
<< "\nError: value " <<
402 IntMin
.getSExtValue() <<
404 IntMax
.getSExtValue() <<
405 " when resolving " <<
408 llvm_unreachable(errStr
.str().c_str());
411 /// ApplyFixup - Apply the \arg Value for given \arg Fixup into the provided
412 /// data fragment, at the offset specified by the fixup and following the
413 /// fixup kind as appropriate.
414 void applyFixup(const MCAssembler
&Asm
, const MCFixup
&Fixup
,
415 const MCValue
&Target
, MutableArrayRef
<char> Data
,
416 uint64_t FixupValue
, bool IsResolved
,
417 const MCSubtargetInfo
*STI
) const override
{
419 // When FixupValue is 0 the relocation is external and there
420 // is nothing for us to do.
421 if (!FixupValue
) return;
423 MCFixupKind Kind
= Fixup
.getKind();
428 // LLVM gives us an encoded value, we have to convert it back
429 // to a real offset before we can use it.
430 uint32_t Offset
= Fixup
.getOffset();
431 unsigned NumBytes
= getFixupKindNumBytes(Kind
);
432 assert(Offset
+ NumBytes
<= Data
.size() && "Invalid fixup offset!");
433 char *InstAddr
= Data
.data() + Offset
;
435 Value
= adjustFixupValue(Kind
, FixupValue
);
438 int sValue
= (int)Value
;
440 switch((unsigned)Kind
) {
444 case fixup_Hexagon_B7_PCREL
:
445 if (!(isIntN(7, sValue
)))
446 HandleFixupError(7, 2, (int64_t)FixupValue
, "B7_PCREL");
448 case fixup_Hexagon_B7_PCREL_X
:
449 InstMask
= 0x00001f18; // Word32_B7
450 Reloc
= (((Value
>> 2) & 0x1f) << 8) | // Value 6-2 = Target 12-8
451 ((Value
& 0x3) << 3); // Value 1-0 = Target 4-3
454 case fixup_Hexagon_B9_PCREL
:
455 if (!(isIntN(9, sValue
)))
456 HandleFixupError(9, 2, (int64_t)FixupValue
, "B9_PCREL");
458 case fixup_Hexagon_B9_PCREL_X
:
459 InstMask
= 0x003000fe; // Word32_B9
460 Reloc
= (((Value
>> 7) & 0x3) << 20) | // Value 8-7 = Target 21-20
461 ((Value
& 0x7f) << 1); // Value 6-0 = Target 7-1
464 // Since the existing branches that use this relocation cannot be
465 // extended, they should only be fixed up if the target is within range.
466 case fixup_Hexagon_B13_PCREL
:
467 if (!(isIntN(13, sValue
)))
468 HandleFixupError(13, 2, (int64_t)FixupValue
, "B13_PCREL");
470 case fixup_Hexagon_B13_PCREL_X
:
471 InstMask
= 0x00202ffe; // Word32_B13
472 Reloc
= (((Value
>> 12) & 0x1) << 21) | // Value 12 = Target 21
473 (((Value
>> 11) & 0x1) << 13) | // Value 11 = Target 13
474 ((Value
& 0x7ff) << 1); // Value 10-0 = Target 11-1
477 case fixup_Hexagon_B15_PCREL
:
478 if (!(isIntN(15, sValue
)))
479 HandleFixupError(15, 2, (int64_t)FixupValue
, "B15_PCREL");
481 case fixup_Hexagon_B15_PCREL_X
:
482 InstMask
= 0x00df20fe; // Word32_B15
483 Reloc
= (((Value
>> 13) & 0x3) << 22) | // Value 14-13 = Target 23-22
484 (((Value
>> 8) & 0x1f) << 16) | // Value 12-8 = Target 20-16
485 (((Value
>> 7) & 0x1) << 13) | // Value 7 = Target 13
486 ((Value
& 0x7f) << 1); // Value 6-0 = Target 7-1
489 case fixup_Hexagon_B22_PCREL
:
490 if (!(isIntN(22, sValue
)))
491 HandleFixupError(22, 2, (int64_t)FixupValue
, "B22_PCREL");
493 case fixup_Hexagon_B22_PCREL_X
:
494 InstMask
= 0x01ff3ffe; // Word32_B22
495 Reloc
= (((Value
>> 13) & 0x1ff) << 16) | // Value 21-13 = Target 24-16
496 ((Value
& 0x1fff) << 1); // Value 12-0 = Target 13-1
499 case fixup_Hexagon_B32_PCREL_X
:
500 InstMask
= 0x0fff3fff; // Word32_X26
501 Reloc
= (((Value
>> 14) & 0xfff) << 16) | // Value 25-14 = Target 27-16
502 (Value
& 0x3fff); // Value 13-0 = Target 13-0
508 case fixup_Hexagon_32
:
509 InstMask
= 0xffffffff; // Word32
514 LLVM_DEBUG(dbgs() << "Name=" << getFixupKindInfo(Kind
).Name
<< "("
515 << (unsigned)Kind
<< ")\n");
517 uint32_t OldData
= 0; for (unsigned i
= 0; i
< NumBytes
; i
++) OldData
|=
518 (InstAddr
[i
] << (i
* 8)) & (0xff << (i
* 8));
519 dbgs() << "\tBValue=0x"; dbgs().write_hex(Value
) << ": AValue=0x";
520 dbgs().write_hex(FixupValue
)
521 << ": Offset=" << Offset
<< ": Size=" << Data
.size() << ": OInst=0x";
522 dbgs().write_hex(OldData
) << ": Reloc=0x"; dbgs().write_hex(Reloc
););
524 // For each byte of the fragment that the fixup touches, mask in the
525 // bits from the fixup value. The Value has been "split up" into the
526 // appropriate bitfields above.
527 for (unsigned i
= 0; i
< NumBytes
; i
++){
528 InstAddr
[i
] &= uint8_t(~InstMask
>> (i
* 8)) & 0xff; // Clear reloc bits
529 InstAddr
[i
] |= uint8_t(Reloc
>> (i
* 8)) & 0xff; // Apply new reloc
532 LLVM_DEBUG(uint32_t NewData
= 0;
533 for (unsigned i
= 0; i
< NumBytes
; i
++) NewData
|=
534 (InstAddr
[i
] << (i
* 8)) & (0xff << (i
* 8));
535 dbgs() << ": NInst=0x"; dbgs().write_hex(NewData
) << "\n";);
538 bool isInstRelaxable(MCInst
const &HMI
) const {
539 const MCInstrDesc
&MCID
= HexagonMCInstrInfo::getDesc(*MCII
, HMI
);
540 bool Relaxable
= false;
541 // Branches and loop-setup insns are handled as necessary by relaxation.
542 if (llvm::HexagonMCInstrInfo::getType(*MCII
, HMI
) == HexagonII::TypeJ
||
543 (llvm::HexagonMCInstrInfo::getType(*MCII
, HMI
) == HexagonII::TypeCJ
&&
545 (llvm::HexagonMCInstrInfo::getType(*MCII
, HMI
) == HexagonII::TypeNCJ
&&
547 (llvm::HexagonMCInstrInfo::getType(*MCII
, HMI
) == HexagonII::TypeCR
&&
548 HMI
.getOpcode() != Hexagon::C4_addipc
))
549 if (HexagonMCInstrInfo::isExtendable(*MCII
, HMI
)) {
551 MCOperand
const &Operand
=
552 HMI
.getOperand(HexagonMCInstrInfo::getExtendableOp(*MCII
, HMI
));
553 if (HexagonMCInstrInfo::mustNotExtend(*Operand
.getExpr()))
560 /// MayNeedRelaxation - Check whether the given instruction may need
563 /// \param Inst - The instruction to test.
564 bool mayNeedRelaxation(MCInst
const &Inst
,
565 const MCSubtargetInfo
&STI
) const override
{
569 /// fixupNeedsRelaxation - Target specific predicate for whether a given
570 /// fixup requires the associated instruction to be relaxed.
571 bool fixupNeedsRelaxationAdvanced(const MCFixup
&Fixup
, bool Resolved
,
573 const MCRelaxableFragment
*DF
,
574 const MCAsmLayout
&Layout
,
575 const bool WasForced
) const override
{
576 MCInst
const &MCB
= DF
->getInst();
577 assert(HexagonMCInstrInfo::isBundle(MCB
));
579 *RelaxTarget
= nullptr;
580 MCInst
&MCI
= const_cast<MCInst
&>(HexagonMCInstrInfo::instruction(
581 MCB
, Fixup
.getOffset() / HEXAGON_INSTR_SIZE
));
582 bool Relaxable
= isInstRelaxable(MCI
);
583 if (Relaxable
== false)
585 // If we cannot resolve the fixup value, it requires relaxation.
587 switch (Fixup
.getTargetKind()) {
588 case fixup_Hexagon_B22_PCREL
:
589 // GetFixupCount assumes B22 won't relax
594 case fixup_Hexagon_B13_PCREL
:
595 case fixup_Hexagon_B15_PCREL
:
596 case fixup_Hexagon_B9_PCREL
:
597 case fixup_Hexagon_B7_PCREL
: {
598 if (HexagonMCInstrInfo::bundleSize(MCB
) < HEXAGON_PACKET_SIZE
) {
601 setExtender(Layout
.getAssembler().getContext());
611 MCFixupKind Kind
= Fixup
.getKind();
612 int64_t sValue
= Value
;
615 switch ((unsigned)Kind
) {
616 case fixup_Hexagon_B7_PCREL
:
619 case fixup_Hexagon_B9_PCREL
:
622 case fixup_Hexagon_B15_PCREL
:
625 case fixup_Hexagon_B22_PCREL
:
629 maxValue
= INT64_MAX
;
633 bool isFarAway
= -maxValue
> sValue
|| sValue
> maxValue
- 1;
636 if (HexagonMCInstrInfo::bundleSize(MCB
) < HEXAGON_PACKET_SIZE
) {
639 setExtender(Layout
.getAssembler().getContext());
647 /// Simple predicate for targets where !Resolved implies requiring relaxation
648 bool fixupNeedsRelaxation(const MCFixup
&Fixup
, uint64_t Value
,
649 const MCRelaxableFragment
*DF
,
650 const MCAsmLayout
&Layout
) const override
{
651 llvm_unreachable("Handled by fixupNeedsRelaxationAdvanced");
654 void relaxInstruction(MCInst
&Inst
,
655 const MCSubtargetInfo
&STI
) const override
{
656 assert(HexagonMCInstrInfo::isBundle(Inst
) &&
657 "Hexagon relaxInstruction only works on bundles");
660 Res
.setOpcode(Hexagon::BUNDLE
);
661 Res
.addOperand(MCOperand::createImm(Inst
.getOperand(0).getImm()));
662 // Copy the results into the bundle.
664 for (auto &I
: HexagonMCInstrInfo::bundleInstructions(Inst
)) {
665 MCInst
&CrntHMI
= const_cast<MCInst
&>(*I
.getInst());
667 // if immediate extender needed, add it in
668 if (*RelaxTarget
== &CrntHMI
) {
670 assert((HexagonMCInstrInfo::bundleSize(Res
) < HEXAGON_PACKET_SIZE
) &&
671 "No room to insert extender for relaxation");
673 MCInst
*HMIx
= takeExtender();
674 *HMIx
= HexagonMCInstrInfo::deriveExtender(
676 HexagonMCInstrInfo::getExtendableOperand(*MCII
, CrntHMI
));
677 Res
.addOperand(MCOperand::createInst(HMIx
));
678 *RelaxTarget
= nullptr;
680 // now copy over the original instruction(the one we may have extended)
681 Res
.addOperand(MCOperand::createInst(I
.getInst()));
684 Inst
= std::move(Res
);
686 assert(Update
&& "Didn't find relaxation target");
689 bool writeNopData(raw_ostream
&OS
, uint64_t Count
) const override
{
690 static const uint32_t Nopcode
= 0x7f000000, // Hard-coded NOP.
691 ParseIn
= 0x00004000, // In packet parse-bits.
692 ParseEnd
= 0x0000c000; // End of packet parse-bits.
694 while (Count
% HEXAGON_INSTR_SIZE
) {
695 LLVM_DEBUG(dbgs() << "Alignment not a multiple of the instruction size:"
696 << Count
% HEXAGON_INSTR_SIZE
<< "/"
697 << HEXAGON_INSTR_SIZE
<< "\n");
703 Count
-= HEXAGON_INSTR_SIZE
;
704 // Close the packet whenever a multiple of the maximum packet size remains
705 uint32_t ParseBits
= (Count
% (MaxPacketSize
* HEXAGON_INSTR_SIZE
)) ?
707 support::endian::write
<uint32_t>(OS
, Nopcode
| ParseBits
, Endian
);
712 void finishLayout(MCAssembler
const &Asm
,
713 MCAsmLayout
&Layout
) const override
{
714 for (auto I
: Layout
.getSectionOrder()) {
715 auto &Fragments
= I
->getFragmentList();
716 for (auto &J
: Fragments
) {
717 switch (J
.getKind()) {
720 case MCFragment::FT_Align
: {
721 auto Size
= Asm
.computeFragmentSize(Layout
, J
);
722 for (auto K
= J
.getIterator();
723 K
!= Fragments
.begin() && Size
>= HEXAGON_PACKET_SIZE
;) {
725 switch (K
->getKind()) {
728 case MCFragment::FT_Align
: {
729 // Don't pad before other alignments
733 case MCFragment::FT_Relaxable
: {
734 MCContext
&Context
= Asm
.getContext();
735 auto &RF
= cast
<MCRelaxableFragment
>(*K
);
736 auto &Inst
= const_cast<MCInst
&>(RF
.getInst());
738 HexagonMCInstrInfo::bundleSize(Inst
) < MaxPacketSize
) {
739 MCInst
*Nop
= Context
.createMCInst();
740 Nop
->setOpcode(Hexagon::A2_nop
);
741 Inst
.addOperand(MCOperand::createInst(Nop
));
743 if (!HexagonMCChecker(
744 Context
, *MCII
, *RF
.getSubtargetInfo(), Inst
,
745 *Context
.getRegisterInfo(), false)
747 Inst
.erase(Inst
.end() - 1);
751 bool Error
= HexagonMCShuffle(Context
, true, *MCII
,
752 *RF
.getSubtargetInfo(), Inst
);
755 ReplaceInstruction(Asm
.getEmitter(), RF
, Inst
);
756 Layout
.invalidateFragmentsFrom(&RF
);
757 Size
= 0; // Only look back one instruction
767 }; // class HexagonAsmBackend
772 MCAsmBackend
*llvm::createHexagonAsmBackend(Target
const &T
,
773 const MCSubtargetInfo
&STI
,
774 MCRegisterInfo
const & /*MRI*/,
775 const MCTargetOptions
&Options
) {
776 const Triple
&TT
= STI
.getTargetTriple();
777 uint8_t OSABI
= MCELFObjectTargetWriter::getOSABI(TT
.getOS());
779 StringRef CPUString
= Hexagon_MC::selectHexagonCPU(STI
.getCPU());
780 return new HexagonAsmBackend(T
, TT
, OSABI
, CPUString
);