clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name HexagonAsmBackend.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/lib/Target/Hexagon/MCTargetDesc -resource-dir /usr/lib/llvm-14/lib/clang/14.0.0 -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/lib/Target/Hexagon/MCTargetDesc -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/llvm/lib/Target/Hexagon/MCTargetDesc -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/llvm/lib/Target/Hexagon -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/lib/Target/Hexagon -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/include -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/llvm/include -D NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /usr/lib/llvm-14/lib/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/lib/Target/Hexagon/MCTargetDesc -fdebug-prefix-map=/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e=. -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2021-09-04-040900-46481-1 -x c++ /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp
1 | |
2 | |
3 | |
4 | |
5 | |
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/EndianStream.h" |
26 | #include "llvm/Support/TargetRegistry.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 | raw_svector_ostream VecOS(Code); |
54 | E.encodeInstruction(HMB, VecOS, Fixups, *RF.getSubtargetInfo()); |
55 | |
56 | |
57 | RF.setInst(HMB); |
58 | RF.getContents() = Code; |
59 | RF.getFixups() = Fixups; |
60 | } |
61 | |
62 | public: |
63 | HexagonAsmBackend(const Target &T, const Triple &TT, uint8_t OSABI, |
64 | StringRef CPU) |
65 | : MCAsmBackend(support::little), OSABI(OSABI), CPU(CPU), relaxedCnt(0), |
66 | MCII(T.createMCInstrInfo()), RelaxTarget(new MCInst *), |
67 | Extender(nullptr), MaxPacketSize(HexagonMCInstrInfo::packetSize(CPU)) |
68 | {} |
69 | |
70 | std::unique_ptr<MCObjectTargetWriter> |
71 | createObjectTargetWriter() const override { |
72 | return createHexagonELFObjectWriter(OSABI, CPU); |
73 | } |
74 | |
75 | void setExtender(MCContext &Context) const { |
76 | if (Extender == nullptr) |
77 | const_cast<HexagonAsmBackend *>(this)->Extender = Context.createMCInst(); |
78 | } |
79 | |
80 | MCInst *takeExtender() const { |
81 | assert(Extender != nullptr); |
82 | MCInst * Result = Extender; |
83 | const_cast<HexagonAsmBackend *>(this)->Extender = nullptr; |
84 | return Result; |
85 | } |
86 | |
87 | unsigned getNumFixupKinds() const override { |
88 | return Hexagon::NumTargetFixupKinds; |
89 | } |
90 | |
91 | const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override { |
92 | const static MCFixupKindInfo Infos[Hexagon::NumTargetFixupKinds] = { |
93 | |
94 | |
95 | |
96 | |
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 } |
195 | }; |
196 | |
197 | if (Kind < FirstTargetFixupKind) |
198 | return MCAsmBackend::getFixupKindInfo(Kind); |
199 | |
200 | assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && |
201 | "Invalid kind!"); |
202 | return Infos[Kind - FirstTargetFixupKind]; |
203 | } |
204 | |
205 | bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, |
206 | const MCValue &Target) override { |
207 | switch(Fixup.getTargetKind()) { |
208 | default: |
209 | llvm_unreachable("Unknown Fixup Kind!"); |
210 | |
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 | |
300 | return true; |
301 | |
302 | case fixup_Hexagon_B22_PCREL: |
303 | |
304 | break; |
305 | |
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: |
316 | if (DisableFixup) |
317 | return true; |
318 | break; |
319 | |
320 | case FK_Data_1: |
321 | case FK_Data_2: |
322 | case FK_Data_4: |
323 | case FK_PCRel_4: |
324 | case fixup_Hexagon_32: |
325 | |
326 | return false; |
327 | } |
328 | return false; |
329 | } |
330 | |
331 | |
332 | static unsigned getFixupKindNumBytes(unsigned Kind) { |
333 | switch (Kind) { |
334 | default: |
335 | return 0; |
336 | |
337 | case FK_Data_1: |
338 | return 1; |
339 | case FK_Data_2: |
340 | return 2; |
341 | case FK_Data_4: |
342 | case FK_PCRel_4: |
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: |
357 | return 4; |
358 | } |
359 | } |
360 | |
361 | |
362 | static uint64_t adjustFixupValue(MCFixupKind Kind, uint64_t Value) { |
363 | switch((unsigned)Kind) { |
364 | default: |
365 | break; |
366 | |
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: |
372 | Value >>= 2; |
373 | break; |
374 | |
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: |
380 | Value &= 0x3f; |
381 | break; |
382 | |
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: |
386 | Value >>= 6; |
387 | break; |
388 | } |
389 | return (Value); |
390 | } |
391 | |
392 | void HandleFixupError(const int bits, const int align_bits, |
393 | const int64_t FixupValue, const char *fixupStr) const { |
394 | |
395 | |
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 " << |
400 | FixupValue << |
401 | " out of range: " << |
402 | IntMin.getSExtValue() << |
403 | "-" << |
404 | IntMax.getSExtValue() << |
405 | " when resolving " << |
406 | fixupStr << |
407 | " fixup\n"; |
408 | llvm_unreachable(errStr.str().c_str()); |
409 | } |
410 | |
411 | |
412 | |
413 | |
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 { |
418 | |
419 | |
420 | |
421 | if (!FixupValue) return; |
422 | |
423 | MCFixupKind Kind = Fixup.getKind(); |
424 | uint64_t Value; |
425 | uint32_t InstMask; |
426 | uint32_t Reloc; |
427 | |
428 | |
429 | |
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; |
434 | |
435 | Value = adjustFixupValue(Kind, FixupValue); |
436 | if(!Value) |
437 | return; |
438 | int sValue = (int)Value; |
439 | |
440 | switch((unsigned)Kind) { |
441 | default: |
442 | return; |
443 | |
444 | case fixup_Hexagon_B7_PCREL: |
445 | if (!(isIntN(7, sValue))) |
446 | HandleFixupError(7, 2, (int64_t)FixupValue, "B7_PCREL"); |
447 | LLVM_FALLTHROUGH; |
448 | case fixup_Hexagon_B7_PCREL_X: |
449 | InstMask = 0x00001f18; |
450 | Reloc = (((Value >> 2) & 0x1f) << 8) | |
451 | ((Value & 0x3) << 3); |
452 | break; |
453 | |
454 | case fixup_Hexagon_B9_PCREL: |
455 | if (!(isIntN(9, sValue))) |
456 | HandleFixupError(9, 2, (int64_t)FixupValue, "B9_PCREL"); |
457 | LLVM_FALLTHROUGH; |
458 | case fixup_Hexagon_B9_PCREL_X: |
459 | InstMask = 0x003000fe; |
460 | Reloc = (((Value >> 7) & 0x3) << 20) | |
461 | ((Value & 0x7f) << 1); |
462 | break; |
463 | |
464 | |
465 | |
466 | case fixup_Hexagon_B13_PCREL: |
467 | if (!(isIntN(13, sValue))) |
468 | HandleFixupError(13, 2, (int64_t)FixupValue, "B13_PCREL"); |
469 | LLVM_FALLTHROUGH; |
470 | case fixup_Hexagon_B13_PCREL_X: |
471 | InstMask = 0x00202ffe; |
472 | Reloc = (((Value >> 12) & 0x1) << 21) | |
473 | (((Value >> 11) & 0x1) << 13) | |
474 | ((Value & 0x7ff) << 1); |
475 | break; |
476 | |
477 | case fixup_Hexagon_B15_PCREL: |
478 | if (!(isIntN(15, sValue))) |
479 | HandleFixupError(15, 2, (int64_t)FixupValue, "B15_PCREL"); |
480 | LLVM_FALLTHROUGH; |
481 | case fixup_Hexagon_B15_PCREL_X: |
482 | InstMask = 0x00df20fe; |
483 | Reloc = (((Value >> 13) & 0x3) << 22) | |
484 | (((Value >> 8) & 0x1f) << 16) | |
485 | (((Value >> 7) & 0x1) << 13) | |
486 | ((Value & 0x7f) << 1); |
487 | break; |
488 | |
489 | case fixup_Hexagon_B22_PCREL: |
490 | if (!(isIntN(22, sValue))) |
491 | HandleFixupError(22, 2, (int64_t)FixupValue, "B22_PCREL"); |
492 | LLVM_FALLTHROUGH; |
493 | case fixup_Hexagon_B22_PCREL_X: |
494 | InstMask = 0x01ff3ffe; |
495 | Reloc = (((Value >> 13) & 0x1ff) << 16) | |
496 | ((Value & 0x1fff) << 1); |
497 | break; |
498 | |
499 | case fixup_Hexagon_B32_PCREL_X: |
500 | InstMask = 0x0fff3fff; |
501 | Reloc = (((Value >> 14) & 0xfff) << 16) | |
502 | (Value & 0x3fff); |
503 | break; |
504 | |
505 | case FK_Data_1: |
506 | case FK_Data_2: |
507 | case FK_Data_4: |
508 | case fixup_Hexagon_32: |
509 | InstMask = 0xffffffff; |
510 | Reloc = Value; |
511 | break; |
512 | } |
513 | |
514 | LLVM_DEBUG(dbgs() << "Name=" << getFixupKindInfo(Kind).Name << "(" |
515 | << (unsigned)Kind << ")\n"); |
516 | LLVM_DEBUG( |
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);); |
523 | |
524 | |
525 | |
526 | |
527 | for (unsigned i = 0; i < NumBytes; i++){ |
528 | InstAddr[i] &= uint8_t(~InstMask >> (i * 8)) & 0xff; |
529 | InstAddr[i] |= uint8_t(Reloc >> (i * 8)) & 0xff; |
530 | } |
531 | |
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";); |
536 | } |
537 | |
538 | bool isInstRelaxable(MCInst const &HMI) const { |
539 | const MCInstrDesc &MCID = HexagonMCInstrInfo::getDesc(*MCII, HMI); |
540 | bool Relaxable = false; |
541 | |
542 | if (llvm::HexagonMCInstrInfo::getType(*MCII, HMI) == HexagonII::TypeJ || |
543 | (llvm::HexagonMCInstrInfo::getType(*MCII, HMI) == HexagonII::TypeCJ && |
544 | MCID.isBranch()) || |
545 | (llvm::HexagonMCInstrInfo::getType(*MCII, HMI) == HexagonII::TypeNCJ && |
546 | MCID.isBranch()) || |
547 | (llvm::HexagonMCInstrInfo::getType(*MCII, HMI) == HexagonII::TypeCR && |
548 | HMI.getOpcode() != Hexagon::C4_addipc)) |
549 | if (HexagonMCInstrInfo::isExtendable(*MCII, HMI)) { |
550 | Relaxable = true; |
551 | MCOperand const &Operand = |
552 | HMI.getOperand(HexagonMCInstrInfo::getExtendableOp(*MCII, HMI)); |
553 | if (HexagonMCInstrInfo::mustNotExtend(*Operand.getExpr())) |
554 | Relaxable = false; |
555 | } |
556 | |
557 | return Relaxable; |
558 | } |
559 | |
560 | |
561 | |
562 | |
563 | |
564 | bool mayNeedRelaxation(MCInst const &Inst, |
565 | const MCSubtargetInfo &STI) const override { |
566 | return true; |
567 | } |
568 | |
569 | |
570 | |
571 | bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, bool Resolved, |
572 | uint64_t Value, |
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)); |
578 | |
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) |
584 | return false; |
585 | |
586 | if (!Resolved) { |
587 | switch (Fixup.getTargetKind()) { |
588 | case fixup_Hexagon_B22_PCREL: |
589 | |
590 | LLVM_FALLTHROUGH; |
591 | default: |
592 | return false; |
593 | break; |
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) { |
599 | ++relaxedCnt; |
600 | *RelaxTarget = &MCI; |
601 | setExtender(Layout.getAssembler().getContext()); |
602 | return true; |
603 | } else { |
604 | return false; |
605 | } |
606 | break; |
607 | } |
608 | } |
609 | } |
610 | |
611 | MCFixupKind Kind = Fixup.getKind(); |
612 | int64_t sValue = Value; |
613 | int64_t maxValue; |
614 | |
615 | switch ((unsigned)Kind) { |
616 | case fixup_Hexagon_B7_PCREL: |
617 | maxValue = 1 << 8; |
618 | break; |
619 | case fixup_Hexagon_B9_PCREL: |
620 | maxValue = 1 << 10; |
621 | break; |
622 | case fixup_Hexagon_B15_PCREL: |
623 | maxValue = 1 << 16; |
624 | break; |
625 | case fixup_Hexagon_B22_PCREL: |
626 | maxValue = 1 << 23; |
627 | break; |
628 | default: |
629 | maxValue = INT64_MAX; |
630 | break; |
631 | } |
632 | |
633 | bool isFarAway = -maxValue > sValue || sValue > maxValue - 1; |
634 | |
635 | if (isFarAway) { |
636 | if (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_SIZE) { |
637 | ++relaxedCnt; |
638 | *RelaxTarget = &MCI; |
639 | setExtender(Layout.getAssembler().getContext()); |
640 | return true; |
641 | } |
642 | } |
643 | |
644 | return false; |
645 | } |
646 | |
647 | |
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"); |
652 | } |
653 | |
654 | void relaxInstruction(MCInst &Inst, |
655 | const MCSubtargetInfo &STI) const override { |
656 | assert(HexagonMCInstrInfo::isBundle(Inst) && |
657 | "Hexagon relaxInstruction only works on bundles"); |
658 | |
659 | MCInst Res; |
660 | Res.setOpcode(Hexagon::BUNDLE); |
661 | Res.addOperand(MCOperand::createImm(Inst.getOperand(0).getImm())); |
662 | |
663 | bool Update = false; |
664 | for (auto &I : HexagonMCInstrInfo::bundleInstructions(Inst)) { |
| 1 | Assuming '__begin2' is not equal to '__end2' | |
|
665 | MCInst &CrntHMI = const_cast<MCInst &>(*I.getInst()); |
| 4 | | 'CrntHMI' initialized here | |
|
666 | |
667 | |
668 | if (*RelaxTarget == &CrntHMI) { |
| 2 | | Assuming the condition is true | |
|
| |
| 5 | | Assuming pointer value is null | |
|
| |
669 | Update = true; |
670 | assert((HexagonMCInstrInfo::bundleSize(Res) < HEXAGON_PACKET_SIZE) && |
671 | "No room to insert extender for relaxation"); |
672 | |
673 | MCInst *HMIx = takeExtender(); |
674 | *HMIx = HexagonMCInstrInfo::deriveExtender( |
675 | *MCII, CrntHMI, |
676 | HexagonMCInstrInfo::getExtendableOperand(*MCII, CrntHMI)); |
| 7 | | Forming reference to null pointer |
|
677 | Res.addOperand(MCOperand::createInst(HMIx)); |
678 | *RelaxTarget = nullptr; |
679 | } |
680 | |
681 | Res.addOperand(MCOperand::createInst(I.getInst())); |
682 | } |
683 | |
684 | Inst = std::move(Res); |
685 | (void)Update; |
686 | assert(Update && "Didn't find relaxation target"); |
687 | } |
688 | |
689 | bool writeNopData(raw_ostream &OS, uint64_t Count) const override { |
690 | static const uint32_t Nopcode = 0x7f000000, |
691 | ParseIn = 0x00004000, |
692 | ParseEnd = 0x0000c000; |
693 | |
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"); |
698 | --Count; |
699 | OS << '\0'; |
700 | } |
701 | |
702 | while (Count) { |
703 | Count -= HEXAGON_INSTR_SIZE; |
704 | |
705 | uint32_t ParseBits = (Count % (MaxPacketSize * HEXAGON_INSTR_SIZE)) ? |
706 | ParseIn : ParseEnd; |
707 | support::endian::write<uint32_t>(OS, Nopcode | ParseBits, Endian); |
708 | } |
709 | return true; |
710 | } |
711 | |
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()) { |
718 | default: |
719 | break; |
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;) { |
724 | --K; |
725 | switch (K->getKind()) { |
726 | default: |
727 | break; |
728 | case MCFragment::FT_Align: { |
729 | |
730 | Size = 0; |
731 | break; |
732 | } |
733 | case MCFragment::FT_Relaxable: { |
734 | MCContext &Context = Asm.getContext(); |
735 | auto &RF = cast<MCRelaxableFragment>(*K); |
736 | auto &Inst = const_cast<MCInst &>(RF.getInst()); |
737 | while (Size > 0 && |
738 | HexagonMCInstrInfo::bundleSize(Inst) < MaxPacketSize) { |
739 | MCInst *Nop = Context.createMCInst(); |
740 | Nop->setOpcode(Hexagon::A2_nop); |
741 | Inst.addOperand(MCOperand::createInst(Nop)); |
742 | Size -= 4; |
743 | if (!HexagonMCChecker( |
744 | Context, *MCII, *RF.getSubtargetInfo(), Inst, |
745 | *Context.getRegisterInfo(), false) |
746 | .check()) { |
747 | Inst.erase(Inst.end() - 1); |
748 | Size = 0; |
749 | } |
750 | } |
751 | bool Error = HexagonMCShuffle(Context, true, *MCII, |
752 | *RF.getSubtargetInfo(), Inst); |
753 | |
754 | (void)Error; |
755 | ReplaceInstruction(Asm.getEmitter(), RF, Inst); |
756 | Layout.invalidateFragmentsFrom(&RF); |
757 | Size = 0; |
758 | break; |
759 | } |
760 | } |
761 | } |
762 | } |
763 | } |
764 | } |
765 | } |
766 | } |
767 | }; |
768 | |
769 | } |
770 | |
771 | |
772 | MCAsmBackend *llvm::createHexagonAsmBackend(Target const &T, |
773 | const MCSubtargetInfo &STI, |
774 | MCRegisterInfo const & , |
775 | const MCTargetOptions &Options) { |
776 | const Triple &TT = STI.getTargetTriple(); |
777 | uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS()); |
778 | |
779 | StringRef CPUString = Hexagon_MC::selectHexagonCPU(STI.getCPU()); |
780 | return new HexagonAsmBackend(T, TT, OSABI, CPUString); |
781 | } |