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 | std::unique_ptr <MCInstrInfo> MCII; |
45 | std::unique_ptr <MCInst *> RelaxTarget; |
46 | MCInst * Extender; |
47 | unsigned MaxPacketSize; |
48 | |
49 | void ReplaceInstruction(MCCodeEmitter &E, MCRelaxableFragment &RF, |
50 | MCInst &HMB) const { |
51 | SmallVector<MCFixup, 4> Fixups; |
52 | SmallString<256> Code; |
53 | E.encodeInstruction(Inst: HMB, CB&: Code, Fixups, STI: *RF.getSubtargetInfo()); |
54 | |
55 | // Update the fragment. |
56 | RF.setInst(HMB); |
57 | RF.getContents() = Code; |
58 | RF.getFixups() = Fixups; |
59 | } |
60 | |
61 | public: |
62 | HexagonAsmBackend(const Target &T, const Triple &TT, uint8_t OSABI, |
63 | StringRef CPU) |
64 | : MCAsmBackend(llvm::endianness::little), OSABI(OSABI), CPU(CPU), |
65 | relaxedCnt(0), MCII(T.createMCInstrInfo()), RelaxTarget(new MCInst *), |
66 | Extender(nullptr), MaxPacketSize(HexagonMCInstrInfo::packetSize(CPU)) {} |
67 | |
68 | std::unique_ptr<MCObjectTargetWriter> |
69 | createObjectTargetWriter() const override { |
70 | return createHexagonELFObjectWriter(OSABI, CPU); |
71 | } |
72 | |
73 | void setExtender(MCContext &Context) const { |
74 | if (Extender == nullptr) |
75 | const_cast<HexagonAsmBackend *>(this)->Extender = Context.createMCInst(); |
76 | } |
77 | |
78 | MCInst *takeExtender() const { |
79 | assert(Extender != nullptr); |
80 | MCInst * Result = Extender; |
81 | const_cast<HexagonAsmBackend *>(this)->Extender = nullptr; |
82 | return Result; |
83 | } |
84 | |
85 | unsigned getNumFixupKinds() const override { |
86 | return Hexagon::NumTargetFixupKinds; |
87 | } |
88 | |
89 | const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override { |
90 | const static MCFixupKindInfo Infos[Hexagon::NumTargetFixupKinds] = { |
91 | // This table *must* be in same the order of fixup_* kinds in |
92 | // HexagonFixupKinds.h. |
93 | // |
94 | // namei offset bits flags |
95 | { .Name: "fixup_Hexagon_B22_PCREL" , .TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
96 | { .Name: "fixup_Hexagon_B15_PCREL" , .TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
97 | { .Name: "fixup_Hexagon_B7_PCREL" , .TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
98 | { .Name: "fixup_Hexagon_LO16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
99 | { .Name: "fixup_Hexagon_HI16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
100 | { .Name: "fixup_Hexagon_32" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
101 | { .Name: "fixup_Hexagon_16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
102 | { .Name: "fixup_Hexagon_8" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
103 | { .Name: "fixup_Hexagon_GPREL16_0" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
104 | { .Name: "fixup_Hexagon_GPREL16_1" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
105 | { .Name: "fixup_Hexagon_GPREL16_2" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
106 | { .Name: "fixup_Hexagon_GPREL16_3" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
107 | { .Name: "fixup_Hexagon_HL16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
108 | { .Name: "fixup_Hexagon_B13_PCREL" , .TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
109 | { .Name: "fixup_Hexagon_B9_PCREL" , .TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
110 | { .Name: "fixup_Hexagon_B32_PCREL_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
111 | { .Name: "fixup_Hexagon_32_6_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
112 | { .Name: "fixup_Hexagon_B22_PCREL_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
113 | { .Name: "fixup_Hexagon_B15_PCREL_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
114 | { .Name: "fixup_Hexagon_B13_PCREL_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
115 | { .Name: "fixup_Hexagon_B9_PCREL_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
116 | { .Name: "fixup_Hexagon_B7_PCREL_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
117 | { .Name: "fixup_Hexagon_16_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
118 | { .Name: "fixup_Hexagon_12_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
119 | { .Name: "fixup_Hexagon_11_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
120 | { .Name: "fixup_Hexagon_10_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
121 | { .Name: "fixup_Hexagon_9_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
122 | { .Name: "fixup_Hexagon_8_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
123 | { .Name: "fixup_Hexagon_7_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
124 | { .Name: "fixup_Hexagon_6_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
125 | { .Name: "fixup_Hexagon_32_PCREL" , .TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
126 | { .Name: "fixup_Hexagon_COPY" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
127 | { .Name: "fixup_Hexagon_GLOB_DAT" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
128 | { .Name: "fixup_Hexagon_JMP_SLOT" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
129 | { .Name: "fixup_Hexagon_RELATIVE" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
130 | { .Name: "fixup_Hexagon_PLT_B22_PCREL" , .TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
131 | { .Name: "fixup_Hexagon_GOTREL_LO16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
132 | { .Name: "fixup_Hexagon_GOTREL_HI16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
133 | { .Name: "fixup_Hexagon_GOTREL_32" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
134 | { .Name: "fixup_Hexagon_GOT_LO16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
135 | { .Name: "fixup_Hexagon_GOT_HI16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
136 | { .Name: "fixup_Hexagon_GOT_32" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
137 | { .Name: "fixup_Hexagon_GOT_16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
138 | { .Name: "fixup_Hexagon_DTPMOD_32" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
139 | { .Name: "fixup_Hexagon_DTPREL_LO16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
140 | { .Name: "fixup_Hexagon_DTPREL_HI16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
141 | { .Name: "fixup_Hexagon_DTPREL_32" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
142 | { .Name: "fixup_Hexagon_DTPREL_16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
143 | { .Name: "fixup_Hexagon_GD_PLT_B22_PCREL" ,.TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
144 | { .Name: "fixup_Hexagon_LD_PLT_B22_PCREL" ,.TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
145 | { .Name: "fixup_Hexagon_GD_GOT_LO16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
146 | { .Name: "fixup_Hexagon_GD_GOT_HI16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
147 | { .Name: "fixup_Hexagon_GD_GOT_32" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
148 | { .Name: "fixup_Hexagon_GD_GOT_16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
149 | { .Name: "fixup_Hexagon_LD_GOT_LO16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
150 | { .Name: "fixup_Hexagon_LD_GOT_HI16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
151 | { .Name: "fixup_Hexagon_LD_GOT_32" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
152 | { .Name: "fixup_Hexagon_LD_GOT_16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
153 | { .Name: "fixup_Hexagon_IE_LO16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
154 | { .Name: "fixup_Hexagon_IE_HI16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
155 | { .Name: "fixup_Hexagon_IE_32" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
156 | { .Name: "fixup_Hexagon_IE_16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
157 | { .Name: "fixup_Hexagon_IE_GOT_LO16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
158 | { .Name: "fixup_Hexagon_IE_GOT_HI16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
159 | { .Name: "fixup_Hexagon_IE_GOT_32" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
160 | { .Name: "fixup_Hexagon_IE_GOT_16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
161 | { .Name: "fixup_Hexagon_TPREL_LO16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
162 | { .Name: "fixup_Hexagon_TPREL_HI16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
163 | { .Name: "fixup_Hexagon_TPREL_32" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
164 | { .Name: "fixup_Hexagon_TPREL_16" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
165 | { .Name: "fixup_Hexagon_6_PCREL_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
166 | { .Name: "fixup_Hexagon_GOTREL_32_6_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
167 | { .Name: "fixup_Hexagon_GOTREL_16_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
168 | { .Name: "fixup_Hexagon_GOTREL_11_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
169 | { .Name: "fixup_Hexagon_GOT_32_6_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
170 | { .Name: "fixup_Hexagon_GOT_16_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
171 | { .Name: "fixup_Hexagon_GOT_11_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
172 | { .Name: "fixup_Hexagon_DTPREL_32_6_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
173 | { .Name: "fixup_Hexagon_DTPREL_16_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
174 | { .Name: "fixup_Hexagon_DTPREL_11_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
175 | { .Name: "fixup_Hexagon_GD_GOT_32_6_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
176 | { .Name: "fixup_Hexagon_GD_GOT_16_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
177 | { .Name: "fixup_Hexagon_GD_GOT_11_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
178 | { .Name: "fixup_Hexagon_LD_GOT_32_6_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
179 | { .Name: "fixup_Hexagon_LD_GOT_16_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
180 | { .Name: "fixup_Hexagon_LD_GOT_11_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
181 | { .Name: "fixup_Hexagon_IE_32_6_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
182 | { .Name: "fixup_Hexagon_IE_16_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
183 | { .Name: "fixup_Hexagon_IE_GOT_32_6_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
184 | { .Name: "fixup_Hexagon_IE_GOT_16_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
185 | { .Name: "fixup_Hexagon_IE_GOT_11_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
186 | { .Name: "fixup_Hexagon_TPREL_32_6_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
187 | { .Name: "fixup_Hexagon_TPREL_16_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
188 | { .Name: "fixup_Hexagon_TPREL_11_X" , .TargetOffset: 0, .TargetSize: 32, .Flags: 0 }, |
189 | { .Name: "fixup_Hexagon_GD_PLT_B22_PCREL_X" ,.TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
190 | { .Name: "fixup_Hexagon_GD_PLT_B32_PCREL_X" ,.TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
191 | { .Name: "fixup_Hexagon_LD_PLT_B22_PCREL_X" ,.TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
192 | { .Name: "fixup_Hexagon_LD_PLT_B32_PCREL_X" ,.TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel } |
193 | }; |
194 | |
195 | if (Kind < FirstTargetFixupKind) |
196 | return MCAsmBackend::getFixupKindInfo(Kind); |
197 | |
198 | assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && |
199 | "Invalid kind!" ); |
200 | return Infos[Kind - FirstTargetFixupKind]; |
201 | } |
202 | |
203 | bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, |
204 | const MCValue &Target, |
205 | const MCSubtargetInfo *STI) override { |
206 | switch(Fixup.getTargetKind()) { |
207 | default: |
208 | llvm_unreachable("Unknown Fixup Kind!" ); |
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(numBits: bits+align_bits); |
396 | const APInt IntMax = APInt::getSignedMaxValue(numBits: 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()); |
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!" ); |
432 | char *InstAddr = Data.data() + Offset; |
433 | |
434 | Value = adjustFixupValue(Kind, Value: 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(N: 7, x: sValue))) |
445 | HandleFixupError(bits: 7, align_bits: 2, FixupValue: (int64_t)FixupValue, fixupStr: "B7_PCREL" ); |
446 | [[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(N: 9, x: sValue))) |
455 | HandleFixupError(bits: 9, align_bits: 2, FixupValue: (int64_t)FixupValue, fixupStr: "B9_PCREL" ); |
456 | [[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(N: 13, x: sValue))) |
467 | HandleFixupError(bits: 13, align_bits: 2, FixupValue: (int64_t)FixupValue, fixupStr: "B13_PCREL" ); |
468 | [[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(N: 15, x: sValue))) |
478 | HandleFixupError(bits: 15, align_bits: 2, FixupValue: (int64_t)FixupValue, fixupStr: "B15_PCREL" ); |
479 | [[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(N: 22, x: sValue))) |
490 | HandleFixupError(bits: 22, align_bits: 2, FixupValue: (int64_t)FixupValue, fixupStr: "B22_PCREL" ); |
491 | [[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 << "(" |
514 | << (unsigned)Kind << ")\n" ); |
515 | LLVM_DEBUG( |
516 | uint32_t OldData = 0; for (unsigned i = 0; i < NumBytes; i++) OldData |= |
517 | (InstAddr[i] << (i * 8)) & (0xff << (i * 8)); |
518 | dbgs() << "\tBValue=0x" ; dbgs().write_hex(Value) << ": AValue=0x" ; |
519 | dbgs().write_hex(FixupValue) |
520 | << ": Offset=" << Offset << ": Size=" << Data.size() << ": OInst=0x" ; |
521 | dbgs().write_hex(OldData) << ": Reloc=0x" ; dbgs().write_hex(Reloc);); |
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; |
532 | for (unsigned i = 0; i < NumBytes; i++) NewData |= |
533 | (InstAddr[i] << (i * 8)) & (0xff << (i * 8)); |
534 | dbgs() << ": NInst=0x" ; dbgs().write_hex(NewData) << "\n" ;); |
535 | } |
536 | |
537 | bool isInstRelaxable(MCInst const &HMI) const { |
538 | const MCInstrDesc &MCID = HexagonMCInstrInfo::getDesc(MCII: *MCII, MCI: HMI); |
539 | bool Relaxable = false; |
540 | // Branches and loop-setup insns are handled as necessary by relaxation. |
541 | if (llvm::HexagonMCInstrInfo::getType(MCII: *MCII, MCI: HMI) == HexagonII::TypeJ || |
542 | (llvm::HexagonMCInstrInfo::getType(MCII: *MCII, MCI: HMI) == HexagonII::TypeCJ && |
543 | MCID.isBranch()) || |
544 | (llvm::HexagonMCInstrInfo::getType(MCII: *MCII, MCI: HMI) == HexagonII::TypeNCJ && |
545 | MCID.isBranch()) || |
546 | (llvm::HexagonMCInstrInfo::getType(MCII: *MCII, MCI: HMI) == HexagonII::TypeCR && |
547 | HMI.getOpcode() != Hexagon::C4_addipc)) |
548 | if (HexagonMCInstrInfo::isExtendable(MCII: *MCII, MCI: HMI)) { |
549 | Relaxable = true; |
550 | MCOperand const &Operand = |
551 | HMI.getOperand(i: HexagonMCInstrInfo::getExtendableOp(MCII: *MCII, MCI: HMI)); |
552 | if (HexagonMCInstrInfo::mustNotExtend(Expr: *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 MCAssembler &Asm, |
571 | const MCFixup &Fixup, bool Resolved, |
572 | uint64_t Value, |
573 | const MCRelaxableFragment *DF, |
574 | const bool WasForced) const override { |
575 | MCInst const &MCB = DF->getInst(); |
576 | assert(HexagonMCInstrInfo::isBundle(MCB)); |
577 | |
578 | *RelaxTarget = nullptr; |
579 | MCInst &MCI = const_cast<MCInst &>(HexagonMCInstrInfo::instruction( |
580 | MCB, Index: Fixup.getOffset() / HEXAGON_INSTR_SIZE)); |
581 | bool Relaxable = isInstRelaxable(HMI: MCI); |
582 | if (Relaxable == false) |
583 | return false; |
584 | // If we cannot resolve the fixup value, it requires relaxation. |
585 | if (!Resolved) { |
586 | switch (Fixup.getTargetKind()) { |
587 | case fixup_Hexagon_B22_PCREL: |
588 | // GetFixupCount assumes B22 won't relax |
589 | [[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(MCI: MCB) < HEXAGON_PACKET_SIZE) { |
598 | ++relaxedCnt; |
599 | *RelaxTarget = &MCI; |
600 | setExtender(Asm.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; |
629 | break; |
630 | } |
631 | |
632 | bool isFarAway = -maxValue > sValue || sValue > maxValue - 1; |
633 | |
634 | if (isFarAway) { |
635 | if (HexagonMCInstrInfo::bundleSize(MCI: MCB) < HEXAGON_PACKET_SIZE) { |
636 | ++relaxedCnt; |
637 | *RelaxTarget = &MCI; |
638 | setExtender(Asm.getContext()); |
639 | return true; |
640 | } |
641 | } |
642 | |
643 | return false; |
644 | } |
645 | |
646 | void relaxInstruction(MCInst &Inst, |
647 | const MCSubtargetInfo &STI) const override { |
648 | assert(HexagonMCInstrInfo::isBundle(Inst) && |
649 | "Hexagon relaxInstruction only works on bundles" ); |
650 | |
651 | MCInst Res; |
652 | Res.setOpcode(Hexagon::BUNDLE); |
653 | Res.addOperand(Op: MCOperand::createImm(Val: Inst.getOperand(i: 0).getImm())); |
654 | // Copy the results into the bundle. |
655 | bool Update = false; |
656 | for (auto &I : HexagonMCInstrInfo::bundleInstructions(MCI: Inst)) { |
657 | MCInst &CrntHMI = const_cast<MCInst &>(*I.getInst()); |
658 | |
659 | // if immediate extender needed, add it in |
660 | if (*RelaxTarget == &CrntHMI) { |
661 | Update = true; |
662 | assert((HexagonMCInstrInfo::bundleSize(Res) < HEXAGON_PACKET_SIZE) && |
663 | "No room to insert extender for relaxation" ); |
664 | |
665 | MCInst *HMIx = takeExtender(); |
666 | *HMIx = HexagonMCInstrInfo::deriveExtender( |
667 | MCII: *MCII, Inst: CrntHMI, |
668 | MO: HexagonMCInstrInfo::getExtendableOperand(MCII: *MCII, MCI: CrntHMI)); |
669 | Res.addOperand(Op: MCOperand::createInst(Val: HMIx)); |
670 | *RelaxTarget = nullptr; |
671 | } |
672 | // now copy over the original instruction(the one we may have extended) |
673 | Res.addOperand(Op: MCOperand::createInst(Val: I.getInst())); |
674 | } |
675 | |
676 | Inst = std::move(Res); |
677 | (void)Update; |
678 | assert(Update && "Didn't find relaxation target" ); |
679 | } |
680 | |
681 | bool writeNopData(raw_ostream &OS, uint64_t Count, |
682 | const MCSubtargetInfo *STI) const override { |
683 | static const uint32_t Nopcode = 0x7f000000, // Hard-coded NOP. |
684 | ParseIn = 0x00004000, // In packet parse-bits. |
685 | ParseEnd = 0x0000c000; // End of packet parse-bits. |
686 | |
687 | while (Count % HEXAGON_INSTR_SIZE) { |
688 | LLVM_DEBUG(dbgs() << "Alignment not a multiple of the instruction size:" |
689 | << Count % HEXAGON_INSTR_SIZE << "/" |
690 | << HEXAGON_INSTR_SIZE << "\n" ); |
691 | --Count; |
692 | OS << '\0'; |
693 | } |
694 | |
695 | while (Count) { |
696 | Count -= HEXAGON_INSTR_SIZE; |
697 | // Close the packet whenever a multiple of the maximum packet size remains |
698 | uint32_t ParseBits = (Count % (MaxPacketSize * HEXAGON_INSTR_SIZE)) ? |
699 | ParseIn : ParseEnd; |
700 | support::endian::write<uint32_t>(os&: OS, value: Nopcode | ParseBits, endian: Endian); |
701 | } |
702 | return true; |
703 | } |
704 | |
705 | void finishLayout(MCAssembler const &Asm) const override { |
706 | SmallVector<MCFragment *> Frags; |
707 | for (MCSection &Sec : Asm) { |
708 | Frags.clear(); |
709 | for (MCFragment &F : Sec) |
710 | Frags.push_back(Elt: &F); |
711 | for (size_t J = 0, E = Frags.size(); J != E; ++J) { |
712 | switch (Frags[J]->getKind()) { |
713 | default: |
714 | break; |
715 | case MCFragment::FT_Align: { |
716 | auto Size = Asm.computeFragmentSize(F: *Frags[J]); |
717 | for (auto K = J; K != 0 && Size >= HEXAGON_PACKET_SIZE;) { |
718 | --K; |
719 | switch (Frags[K]->getKind()) { |
720 | default: |
721 | break; |
722 | case MCFragment::FT_Align: { |
723 | // Don't pad before other alignments |
724 | Size = 0; |
725 | break; |
726 | } |
727 | case MCFragment::FT_Relaxable: { |
728 | MCContext &Context = Asm.getContext(); |
729 | auto &RF = cast<MCRelaxableFragment>(Val&: *Frags[K]); |
730 | auto &Inst = const_cast<MCInst &>(RF.getInst()); |
731 | while (Size > 0 && |
732 | HexagonMCInstrInfo::bundleSize(MCI: Inst) < MaxPacketSize) { |
733 | MCInst *Nop = Context.createMCInst(); |
734 | Nop->setOpcode(Hexagon::A2_nop); |
735 | Inst.addOperand(Op: MCOperand::createInst(Val: Nop)); |
736 | Size -= 4; |
737 | if (!HexagonMCChecker( |
738 | Context, *MCII, *RF.getSubtargetInfo(), Inst, |
739 | *Context.getRegisterInfo(), false) |
740 | .check()) { |
741 | Inst.erase(I: Inst.end() - 1); |
742 | Size = 0; |
743 | } |
744 | } |
745 | bool Error = HexagonMCShuffle(Context, ReportErrors: true, MCII: *MCII, |
746 | STI: *RF.getSubtargetInfo(), MCB&: Inst); |
747 | //assert(!Error); |
748 | (void)Error; |
749 | ReplaceInstruction(E&: Asm.getEmitter(), RF, HMB&: Inst); |
750 | Sec.setHasLayout(false); |
751 | Size = 0; // Only look back one instruction |
752 | break; |
753 | } |
754 | } |
755 | } |
756 | } |
757 | } |
758 | } |
759 | } |
760 | } |
761 | }; // class HexagonAsmBackend |
762 | |
763 | } // namespace |
764 | |
765 | // MCAsmBackend |
766 | MCAsmBackend *llvm::createHexagonAsmBackend(Target const &T, |
767 | const MCSubtargetInfo &STI, |
768 | MCRegisterInfo const & /*MRI*/, |
769 | const MCTargetOptions &Options) { |
770 | const Triple &TT = STI.getTargetTriple(); |
771 | uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(OSType: TT.getOS()); |
772 | |
773 | StringRef CPUString = Hexagon_MC::selectHexagonCPU(CPU: STI.getCPU()); |
774 | return new HexagonAsmBackend(T, TT, OSABI, CPUString); |
775 | } |
776 | |