1 | //===-- SparcAsmBackend.cpp - Sparc 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 "MCTargetDesc/SparcFixupKinds.h" |
10 | #include "MCTargetDesc/SparcMCTargetDesc.h" |
11 | #include "llvm/ADT/StringSwitch.h" |
12 | #include "llvm/MC/MCAsmBackend.h" |
13 | #include "llvm/MC/MCELFObjectWriter.h" |
14 | #include "llvm/MC/MCExpr.h" |
15 | #include "llvm/MC/MCFixupKindInfo.h" |
16 | #include "llvm/MC/MCObjectWriter.h" |
17 | #include "llvm/MC/MCSubtargetInfo.h" |
18 | #include "llvm/MC/MCValue.h" |
19 | #include "llvm/MC/TargetRegistry.h" |
20 | #include "llvm/Support/EndianStream.h" |
21 | |
22 | using namespace llvm; |
23 | |
24 | static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) { |
25 | switch (Kind) { |
26 | default: |
27 | llvm_unreachable("Unknown fixup kind!" ); |
28 | case FK_Data_1: |
29 | case FK_Data_2: |
30 | case FK_Data_4: |
31 | case FK_Data_8: |
32 | return Value; |
33 | |
34 | case Sparc::fixup_sparc_wplt30: |
35 | case Sparc::fixup_sparc_call30: |
36 | return (Value >> 2) & 0x3fffffff; |
37 | |
38 | case Sparc::fixup_sparc_br22: |
39 | return (Value >> 2) & 0x3fffff; |
40 | |
41 | case Sparc::fixup_sparc_br19: |
42 | return (Value >> 2) & 0x7ffff; |
43 | |
44 | case Sparc::fixup_sparc_br16: { |
45 | // A.3 Branch on Integer Register with Prediction (BPr) |
46 | // Inst{21-20} = d16hi; |
47 | // Inst{13-0} = d16lo; |
48 | unsigned d16hi = (Value >> 16) & 0x3; |
49 | unsigned d16lo = (Value >> 2) & 0x3fff; |
50 | return (d16hi << 20) | d16lo; |
51 | } |
52 | |
53 | case Sparc::fixup_sparc_hix22: |
54 | return (~Value >> 10) & 0x3fffff; |
55 | |
56 | case Sparc::fixup_sparc_pc22: |
57 | case Sparc::fixup_sparc_got22: |
58 | case Sparc::fixup_sparc_tls_gd_hi22: |
59 | case Sparc::fixup_sparc_tls_ldm_hi22: |
60 | case Sparc::fixup_sparc_tls_ie_hi22: |
61 | case Sparc::fixup_sparc_hi22: |
62 | case Sparc::fixup_sparc_lm: |
63 | return (Value >> 10) & 0x3fffff; |
64 | |
65 | case Sparc::fixup_sparc_got13: |
66 | case Sparc::fixup_sparc_13: |
67 | return Value & 0x1fff; |
68 | |
69 | case Sparc::fixup_sparc_lox10: |
70 | return (Value & 0x3ff) | 0x1c00; |
71 | |
72 | case Sparc::fixup_sparc_pc10: |
73 | case Sparc::fixup_sparc_got10: |
74 | case Sparc::fixup_sparc_tls_gd_lo10: |
75 | case Sparc::fixup_sparc_tls_ldm_lo10: |
76 | case Sparc::fixup_sparc_tls_ie_lo10: |
77 | case Sparc::fixup_sparc_lo10: |
78 | return Value & 0x3ff; |
79 | |
80 | case Sparc::fixup_sparc_h44: |
81 | return (Value >> 22) & 0x3fffff; |
82 | |
83 | case Sparc::fixup_sparc_m44: |
84 | return (Value >> 12) & 0x3ff; |
85 | |
86 | case Sparc::fixup_sparc_l44: |
87 | return Value & 0xfff; |
88 | |
89 | case Sparc::fixup_sparc_hh: |
90 | return (Value >> 42) & 0x3fffff; |
91 | |
92 | case Sparc::fixup_sparc_hm: |
93 | return (Value >> 32) & 0x3ff; |
94 | |
95 | case Sparc::fixup_sparc_tls_ldo_hix22: |
96 | case Sparc::fixup_sparc_tls_le_hix22: |
97 | case Sparc::fixup_sparc_tls_ldo_lox10: |
98 | case Sparc::fixup_sparc_tls_le_lox10: |
99 | assert(Value == 0 && "Sparc TLS relocs expect zero Value" ); |
100 | return 0; |
101 | |
102 | case Sparc::fixup_sparc_tls_gd_add: |
103 | case Sparc::fixup_sparc_tls_gd_call: |
104 | case Sparc::fixup_sparc_tls_ldm_add: |
105 | case Sparc::fixup_sparc_tls_ldm_call: |
106 | case Sparc::fixup_sparc_tls_ldo_add: |
107 | case Sparc::fixup_sparc_tls_ie_ld: |
108 | case Sparc::fixup_sparc_tls_ie_ldx: |
109 | case Sparc::fixup_sparc_tls_ie_add: |
110 | case Sparc::fixup_sparc_gotdata_lox10: |
111 | case Sparc::fixup_sparc_gotdata_hix22: |
112 | case Sparc::fixup_sparc_gotdata_op: |
113 | return 0; |
114 | } |
115 | } |
116 | |
117 | /// getFixupKindNumBytes - The number of bytes the fixup may change. |
118 | static unsigned getFixupKindNumBytes(unsigned Kind) { |
119 | switch (Kind) { |
120 | default: |
121 | return 4; |
122 | case FK_Data_1: |
123 | return 1; |
124 | case FK_Data_2: |
125 | return 2; |
126 | case FK_Data_8: |
127 | return 8; |
128 | } |
129 | } |
130 | |
131 | namespace { |
132 | class SparcAsmBackend : public MCAsmBackend { |
133 | protected: |
134 | bool Is64Bit; |
135 | bool HasV9; |
136 | |
137 | public: |
138 | SparcAsmBackend(const MCSubtargetInfo &STI) |
139 | : MCAsmBackend(STI.getTargetTriple().isLittleEndian() |
140 | ? llvm::endianness::little |
141 | : llvm::endianness::big), |
142 | Is64Bit(STI.getTargetTriple().isArch64Bit()), |
143 | HasV9(STI.hasFeature(Feature: Sparc::FeatureV9)) {} |
144 | |
145 | unsigned getNumFixupKinds() const override { |
146 | return Sparc::NumTargetFixupKinds; |
147 | } |
148 | |
149 | std::optional<MCFixupKind> getFixupKind(StringRef Name) const override { |
150 | unsigned Type; |
151 | Type = llvm::StringSwitch<unsigned>(Name) |
152 | #define ELF_RELOC(X, Y) .Case(#X, Y) |
153 | #include "llvm/BinaryFormat/ELFRelocs/Sparc.def" |
154 | #undef ELF_RELOC |
155 | .Case(S: "BFD_RELOC_NONE" , Value: ELF::R_SPARC_NONE) |
156 | .Case(S: "BFD_RELOC_8" , Value: ELF::R_SPARC_8) |
157 | .Case(S: "BFD_RELOC_16" , Value: ELF::R_SPARC_16) |
158 | .Case(S: "BFD_RELOC_32" , Value: ELF::R_SPARC_32) |
159 | .Case(S: "BFD_RELOC_64" , Value: ELF::R_SPARC_64) |
160 | .Default(Value: -1u); |
161 | if (Type == -1u) |
162 | return std::nullopt; |
163 | return static_cast<MCFixupKind>(FirstLiteralRelocationKind + Type); |
164 | } |
165 | |
166 | const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override { |
167 | const static MCFixupKindInfo InfosBE[Sparc::NumTargetFixupKinds] = { |
168 | // name offset bits flags |
169 | { .Name: "fixup_sparc_call30" , .TargetOffset: 2, .TargetSize: 30, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
170 | { .Name: "fixup_sparc_br22" , .TargetOffset: 10, .TargetSize: 22, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
171 | { .Name: "fixup_sparc_br19" , .TargetOffset: 13, .TargetSize: 19, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
172 | { .Name: "fixup_sparc_br16" , .TargetOffset: 0, .TargetSize: 32, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
173 | { .Name: "fixup_sparc_13" , .TargetOffset: 19, .TargetSize: 13, .Flags: 0 }, |
174 | { .Name: "fixup_sparc_hi22" , .TargetOffset: 10, .TargetSize: 22, .Flags: 0 }, |
175 | { .Name: "fixup_sparc_lo10" , .TargetOffset: 22, .TargetSize: 10, .Flags: 0 }, |
176 | { .Name: "fixup_sparc_h44" , .TargetOffset: 10, .TargetSize: 22, .Flags: 0 }, |
177 | { .Name: "fixup_sparc_m44" , .TargetOffset: 22, .TargetSize: 10, .Flags: 0 }, |
178 | { .Name: "fixup_sparc_l44" , .TargetOffset: 20, .TargetSize: 12, .Flags: 0 }, |
179 | { .Name: "fixup_sparc_hh" , .TargetOffset: 10, .TargetSize: 22, .Flags: 0 }, |
180 | { .Name: "fixup_sparc_hm" , .TargetOffset: 22, .TargetSize: 10, .Flags: 0 }, |
181 | { .Name: "fixup_sparc_lm" , .TargetOffset: 10, .TargetSize: 22, .Flags: 0 }, |
182 | { .Name: "fixup_sparc_pc22" , .TargetOffset: 10, .TargetSize: 22, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
183 | { .Name: "fixup_sparc_pc10" , .TargetOffset: 22, .TargetSize: 10, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
184 | { .Name: "fixup_sparc_got22" , .TargetOffset: 10, .TargetSize: 22, .Flags: 0 }, |
185 | { .Name: "fixup_sparc_got10" , .TargetOffset: 22, .TargetSize: 10, .Flags: 0 }, |
186 | { .Name: "fixup_sparc_got13" , .TargetOffset: 19, .TargetSize: 13, .Flags: 0 }, |
187 | { .Name: "fixup_sparc_wplt30" , .TargetOffset: 2, .TargetSize: 30, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
188 | { .Name: "fixup_sparc_tls_gd_hi22" , .TargetOffset: 10, .TargetSize: 22, .Flags: 0 }, |
189 | { .Name: "fixup_sparc_tls_gd_lo10" , .TargetOffset: 22, .TargetSize: 10, .Flags: 0 }, |
190 | { .Name: "fixup_sparc_tls_gd_add" , .TargetOffset: 0, .TargetSize: 0, .Flags: 0 }, |
191 | { .Name: "fixup_sparc_tls_gd_call" , .TargetOffset: 0, .TargetSize: 0, .Flags: 0 }, |
192 | { .Name: "fixup_sparc_tls_ldm_hi22" , .TargetOffset: 10, .TargetSize: 22, .Flags: 0 }, |
193 | { .Name: "fixup_sparc_tls_ldm_lo10" , .TargetOffset: 22, .TargetSize: 10, .Flags: 0 }, |
194 | { .Name: "fixup_sparc_tls_ldm_add" , .TargetOffset: 0, .TargetSize: 0, .Flags: 0 }, |
195 | { .Name: "fixup_sparc_tls_ldm_call" , .TargetOffset: 0, .TargetSize: 0, .Flags: 0 }, |
196 | { .Name: "fixup_sparc_tls_ldo_hix22" , .TargetOffset: 10, .TargetSize: 22, .Flags: 0 }, |
197 | { .Name: "fixup_sparc_tls_ldo_lox10" , .TargetOffset: 22, .TargetSize: 10, .Flags: 0 }, |
198 | { .Name: "fixup_sparc_tls_ldo_add" , .TargetOffset: 0, .TargetSize: 0, .Flags: 0 }, |
199 | { .Name: "fixup_sparc_tls_ie_hi22" , .TargetOffset: 10, .TargetSize: 22, .Flags: 0 }, |
200 | { .Name: "fixup_sparc_tls_ie_lo10" , .TargetOffset: 22, .TargetSize: 10, .Flags: 0 }, |
201 | { .Name: "fixup_sparc_tls_ie_ld" , .TargetOffset: 0, .TargetSize: 0, .Flags: 0 }, |
202 | { .Name: "fixup_sparc_tls_ie_ldx" , .TargetOffset: 0, .TargetSize: 0, .Flags: 0 }, |
203 | { .Name: "fixup_sparc_tls_ie_add" , .TargetOffset: 0, .TargetSize: 0, .Flags: 0 }, |
204 | { .Name: "fixup_sparc_tls_le_hix22" , .TargetOffset: 0, .TargetSize: 0, .Flags: 0 }, |
205 | { .Name: "fixup_sparc_tls_le_lox10" , .TargetOffset: 0, .TargetSize: 0, .Flags: 0 }, |
206 | { .Name: "fixup_sparc_hix22" , .TargetOffset: 10, .TargetSize: 22, .Flags: 0 }, |
207 | { .Name: "fixup_sparc_lox10" , .TargetOffset: 19, .TargetSize: 13, .Flags: 0 }, |
208 | { .Name: "fixup_sparc_gotdata_hix22" , .TargetOffset: 0, .TargetSize: 0, .Flags: 0 }, |
209 | { .Name: "fixup_sparc_gotdata_lox10" , .TargetOffset: 0, .TargetSize: 0, .Flags: 0 }, |
210 | { .Name: "fixup_sparc_gotdata_op" , .TargetOffset: 0, .TargetSize: 0, .Flags: 0 }, |
211 | }; |
212 | |
213 | const static MCFixupKindInfo InfosLE[Sparc::NumTargetFixupKinds] = { |
214 | // name offset bits flags |
215 | { .Name: "fixup_sparc_call30" , .TargetOffset: 0, .TargetSize: 30, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
216 | { .Name: "fixup_sparc_br22" , .TargetOffset: 0, .TargetSize: 22, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
217 | { .Name: "fixup_sparc_br19" , .TargetOffset: 0, .TargetSize: 19, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
218 | { .Name: "fixup_sparc_br16" , .TargetOffset: 32, .TargetSize: 0, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
219 | { .Name: "fixup_sparc_13" , .TargetOffset: 0, .TargetSize: 13, .Flags: 0 }, |
220 | { .Name: "fixup_sparc_hi22" , .TargetOffset: 0, .TargetSize: 22, .Flags: 0 }, |
221 | { .Name: "fixup_sparc_lo10" , .TargetOffset: 0, .TargetSize: 10, .Flags: 0 }, |
222 | { .Name: "fixup_sparc_h44" , .TargetOffset: 0, .TargetSize: 22, .Flags: 0 }, |
223 | { .Name: "fixup_sparc_m44" , .TargetOffset: 0, .TargetSize: 10, .Flags: 0 }, |
224 | { .Name: "fixup_sparc_l44" , .TargetOffset: 0, .TargetSize: 12, .Flags: 0 }, |
225 | { .Name: "fixup_sparc_hh" , .TargetOffset: 0, .TargetSize: 22, .Flags: 0 }, |
226 | { .Name: "fixup_sparc_hm" , .TargetOffset: 0, .TargetSize: 10, .Flags: 0 }, |
227 | { .Name: "fixup_sparc_lm" , .TargetOffset: 0, .TargetSize: 22, .Flags: 0 }, |
228 | { .Name: "fixup_sparc_pc22" , .TargetOffset: 0, .TargetSize: 22, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
229 | { .Name: "fixup_sparc_pc10" , .TargetOffset: 0, .TargetSize: 10, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
230 | { .Name: "fixup_sparc_got22" , .TargetOffset: 0, .TargetSize: 22, .Flags: 0 }, |
231 | { .Name: "fixup_sparc_got10" , .TargetOffset: 0, .TargetSize: 10, .Flags: 0 }, |
232 | { .Name: "fixup_sparc_got13" , .TargetOffset: 0, .TargetSize: 13, .Flags: 0 }, |
233 | { .Name: "fixup_sparc_wplt30" , .TargetOffset: 0, .TargetSize: 30, .Flags: MCFixupKindInfo::FKF_IsPCRel }, |
234 | { .Name: "fixup_sparc_tls_gd_hi22" , .TargetOffset: 0, .TargetSize: 22, .Flags: 0 }, |
235 | { .Name: "fixup_sparc_tls_gd_lo10" , .TargetOffset: 0, .TargetSize: 10, .Flags: 0 }, |
236 | { .Name: "fixup_sparc_tls_gd_add" , .TargetOffset: 0, .TargetSize: 0, .Flags: 0 }, |
237 | { .Name: "fixup_sparc_tls_gd_call" , .TargetOffset: 0, .TargetSize: 0, .Flags: 0 }, |
238 | { .Name: "fixup_sparc_tls_ldm_hi22" , .TargetOffset: 0, .TargetSize: 22, .Flags: 0 }, |
239 | { .Name: "fixup_sparc_tls_ldm_lo10" , .TargetOffset: 0, .TargetSize: 10, .Flags: 0 }, |
240 | { .Name: "fixup_sparc_tls_ldm_add" , .TargetOffset: 0, .TargetSize: 0, .Flags: 0 }, |
241 | { .Name: "fixup_sparc_tls_ldm_call" , .TargetOffset: 0, .TargetSize: 0, .Flags: 0 }, |
242 | { .Name: "fixup_sparc_tls_ldo_hix22" , .TargetOffset: 0, .TargetSize: 22, .Flags: 0 }, |
243 | { .Name: "fixup_sparc_tls_ldo_lox10" , .TargetOffset: 0, .TargetSize: 10, .Flags: 0 }, |
244 | { .Name: "fixup_sparc_tls_ldo_add" , .TargetOffset: 0, .TargetSize: 0, .Flags: 0 }, |
245 | { .Name: "fixup_sparc_tls_ie_hi22" , .TargetOffset: 0, .TargetSize: 22, .Flags: 0 }, |
246 | { .Name: "fixup_sparc_tls_ie_lo10" , .TargetOffset: 0, .TargetSize: 10, .Flags: 0 }, |
247 | { .Name: "fixup_sparc_tls_ie_ld" , .TargetOffset: 0, .TargetSize: 0, .Flags: 0 }, |
248 | { .Name: "fixup_sparc_tls_ie_ldx" , .TargetOffset: 0, .TargetSize: 0, .Flags: 0 }, |
249 | { .Name: "fixup_sparc_tls_ie_add" , .TargetOffset: 0, .TargetSize: 0, .Flags: 0 }, |
250 | { .Name: "fixup_sparc_tls_le_hix22" , .TargetOffset: 0, .TargetSize: 0, .Flags: 0 }, |
251 | { .Name: "fixup_sparc_tls_le_lox10" , .TargetOffset: 0, .TargetSize: 0, .Flags: 0 }, |
252 | { .Name: "fixup_sparc_hix22" , .TargetOffset: 0, .TargetSize: 22, .Flags: 0 }, |
253 | { .Name: "fixup_sparc_lox10" , .TargetOffset: 0, .TargetSize: 13, .Flags: 0 }, |
254 | { .Name: "fixup_sparc_gotdata_hix22" , .TargetOffset: 0, .TargetSize: 0, .Flags: 0 }, |
255 | { .Name: "fixup_sparc_gotdata_lox10" , .TargetOffset: 0, .TargetSize: 0, .Flags: 0 }, |
256 | { .Name: "fixup_sparc_gotdata_op" , .TargetOffset: 0, .TargetSize: 0, .Flags: 0 }, |
257 | }; |
258 | |
259 | // Fixup kinds from .reloc directive are like R_SPARC_NONE. They do |
260 | // not require any extra processing. |
261 | if (Kind >= FirstLiteralRelocationKind) |
262 | return MCAsmBackend::getFixupKindInfo(Kind: FK_NONE); |
263 | |
264 | if (Kind < FirstTargetFixupKind) |
265 | return MCAsmBackend::getFixupKindInfo(Kind); |
266 | |
267 | assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && |
268 | "Invalid kind!" ); |
269 | if (Endian == llvm::endianness::little) |
270 | return InfosLE[Kind - FirstTargetFixupKind]; |
271 | |
272 | return InfosBE[Kind - FirstTargetFixupKind]; |
273 | } |
274 | |
275 | bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, |
276 | const MCValue &Target, |
277 | const MCSubtargetInfo *STI) override { |
278 | if (Fixup.getKind() >= FirstLiteralRelocationKind) |
279 | return true; |
280 | switch ((Sparc::Fixups)Fixup.getKind()) { |
281 | default: |
282 | return false; |
283 | case Sparc::fixup_sparc_wplt30: |
284 | if (Target.getSymA()->getSymbol().isTemporary()) |
285 | return false; |
286 | [[fallthrough]]; |
287 | case Sparc::fixup_sparc_tls_gd_hi22: |
288 | case Sparc::fixup_sparc_tls_gd_lo10: |
289 | case Sparc::fixup_sparc_tls_gd_add: |
290 | case Sparc::fixup_sparc_tls_gd_call: |
291 | case Sparc::fixup_sparc_tls_ldm_hi22: |
292 | case Sparc::fixup_sparc_tls_ldm_lo10: |
293 | case Sparc::fixup_sparc_tls_ldm_add: |
294 | case Sparc::fixup_sparc_tls_ldm_call: |
295 | case Sparc::fixup_sparc_tls_ldo_hix22: |
296 | case Sparc::fixup_sparc_tls_ldo_lox10: |
297 | case Sparc::fixup_sparc_tls_ldo_add: |
298 | case Sparc::fixup_sparc_tls_ie_hi22: |
299 | case Sparc::fixup_sparc_tls_ie_lo10: |
300 | case Sparc::fixup_sparc_tls_ie_ld: |
301 | case Sparc::fixup_sparc_tls_ie_ldx: |
302 | case Sparc::fixup_sparc_tls_ie_add: |
303 | case Sparc::fixup_sparc_tls_le_hix22: |
304 | case Sparc::fixup_sparc_tls_le_lox10: |
305 | return true; |
306 | } |
307 | } |
308 | |
309 | void relaxInstruction(MCInst &Inst, |
310 | const MCSubtargetInfo &STI) const override { |
311 | // FIXME. |
312 | llvm_unreachable("relaxInstruction() unimplemented" ); |
313 | } |
314 | |
315 | bool writeNopData(raw_ostream &OS, uint64_t Count, |
316 | const MCSubtargetInfo *STI) const override { |
317 | |
318 | // If the count is not 4-byte aligned, we must be writing data into the |
319 | // text section (otherwise we have unaligned instructions, and thus have |
320 | // far bigger problems), so just write zeros instead. |
321 | OS.write_zeros(NumZeros: Count % 4); |
322 | |
323 | uint64_t NumNops = Count / 4; |
324 | for (uint64_t i = 0; i != NumNops; ++i) |
325 | support::endian::write<uint32_t>(os&: OS, value: 0x01000000, endian: Endian); |
326 | |
327 | return true; |
328 | } |
329 | }; |
330 | |
331 | class ELFSparcAsmBackend : public SparcAsmBackend { |
332 | Triple::OSType OSType; |
333 | public: |
334 | ELFSparcAsmBackend(const MCSubtargetInfo &STI, Triple::OSType OSType) |
335 | : SparcAsmBackend(STI), OSType(OSType) {} |
336 | |
337 | void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, |
338 | const MCValue &Target, MutableArrayRef<char> Data, |
339 | uint64_t Value, bool IsResolved, |
340 | const MCSubtargetInfo *STI) const override { |
341 | |
342 | if (Fixup.getKind() >= FirstLiteralRelocationKind) |
343 | return; |
344 | Value = adjustFixupValue(Kind: Fixup.getKind(), Value); |
345 | if (!Value) return; // Doesn't change encoding. |
346 | |
347 | unsigned NumBytes = getFixupKindNumBytes(Kind: Fixup.getKind()); |
348 | unsigned Offset = Fixup.getOffset(); |
349 | // For each byte of the fragment that the fixup touches, mask in the bits |
350 | // from the fixup value. The Value has been "split up" into the |
351 | // appropriate bitfields above. |
352 | for (unsigned i = 0; i != NumBytes; ++i) { |
353 | unsigned Idx = |
354 | Endian == llvm::endianness::little ? i : (NumBytes - 1) - i; |
355 | Data[Offset + Idx] |= uint8_t((Value >> (i * 8)) & 0xff); |
356 | } |
357 | } |
358 | |
359 | std::unique_ptr<MCObjectTargetWriter> |
360 | createObjectTargetWriter() const override { |
361 | uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(OSType); |
362 | return createSparcELFObjectWriter(Is64Bit, HasV9, OSABI); |
363 | } |
364 | }; |
365 | |
366 | } // end anonymous namespace |
367 | |
368 | MCAsmBackend *llvm::createSparcAsmBackend(const Target &T, |
369 | const MCSubtargetInfo &STI, |
370 | const MCRegisterInfo &MRI, |
371 | const MCTargetOptions &Options) { |
372 | return new ELFSparcAsmBackend(STI, STI.getTargetTriple().getOS()); |
373 | } |
374 | |