1 //===-- SparcAsmBackend.cpp - Sparc 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 "MCTargetDesc/SparcFixupKinds.h"
10 #include "MCTargetDesc/SparcMCTargetDesc.h"
11 #include "llvm/MC/MCAsmBackend.h"
12 #include "llvm/MC/MCELFObjectWriter.h"
13 #include "llvm/MC/MCExpr.h"
14 #include "llvm/MC/MCFixupKindInfo.h"
15 #include "llvm/MC/MCObjectWriter.h"
16 #include "llvm/MC/MCSubtargetInfo.h"
17 #include "llvm/MC/MCValue.h"
18 #include "llvm/Support/TargetRegistry.h"
22 static unsigned adjustFixupValue(unsigned Kind
, uint64_t Value
) {
25 llvm_unreachable("Unknown fixup kind!");
32 case Sparc::fixup_sparc_wplt30
:
33 case Sparc::fixup_sparc_call30
:
34 return (Value
>> 2) & 0x3fffffff;
36 case Sparc::fixup_sparc_br22
:
37 return (Value
>> 2) & 0x3fffff;
39 case Sparc::fixup_sparc_br19
:
40 return (Value
>> 2) & 0x7ffff;
42 case Sparc::fixup_sparc_br16_2
:
43 return (Value
>> 2) & 0xc000;
45 case Sparc::fixup_sparc_br16_14
:
46 return (Value
>> 2) & 0x3fff;
48 case Sparc::fixup_sparc_pc22
:
49 case Sparc::fixup_sparc_got22
:
50 case Sparc::fixup_sparc_tls_gd_hi22
:
51 case Sparc::fixup_sparc_tls_ldm_hi22
:
52 case Sparc::fixup_sparc_tls_ie_hi22
:
53 case Sparc::fixup_sparc_hi22
:
54 return (Value
>> 10) & 0x3fffff;
56 case Sparc::fixup_sparc_got13
:
57 case Sparc::fixup_sparc_13
:
58 return Value
& 0x1fff;
60 case Sparc::fixup_sparc_pc10
:
61 case Sparc::fixup_sparc_got10
:
62 case Sparc::fixup_sparc_tls_gd_lo10
:
63 case Sparc::fixup_sparc_tls_ldm_lo10
:
64 case Sparc::fixup_sparc_tls_ie_lo10
:
65 case Sparc::fixup_sparc_lo10
:
68 case Sparc::fixup_sparc_h44
:
69 return (Value
>> 22) & 0x3fffff;
71 case Sparc::fixup_sparc_m44
:
72 return (Value
>> 12) & 0x3ff;
74 case Sparc::fixup_sparc_l44
:
77 case Sparc::fixup_sparc_hh
:
78 return (Value
>> 42) & 0x3fffff;
80 case Sparc::fixup_sparc_hm
:
81 return (Value
>> 32) & 0x3ff;
83 case Sparc::fixup_sparc_tls_ldo_hix22
:
84 case Sparc::fixup_sparc_tls_le_hix22
:
85 case Sparc::fixup_sparc_tls_ldo_lox10
:
86 case Sparc::fixup_sparc_tls_le_lox10
:
87 assert(Value
== 0 && "Sparc TLS relocs expect zero Value");
90 case Sparc::fixup_sparc_tls_gd_add
:
91 case Sparc::fixup_sparc_tls_gd_call
:
92 case Sparc::fixup_sparc_tls_ldm_add
:
93 case Sparc::fixup_sparc_tls_ldm_call
:
94 case Sparc::fixup_sparc_tls_ldo_add
:
95 case Sparc::fixup_sparc_tls_ie_ld
:
96 case Sparc::fixup_sparc_tls_ie_ldx
:
97 case Sparc::fixup_sparc_tls_ie_add
:
102 /// getFixupKindNumBytes - The number of bytes the fixup may change.
103 static unsigned getFixupKindNumBytes(unsigned Kind
) {
117 class SparcAsmBackend
: public MCAsmBackend
{
119 const Target
&TheTarget
;
123 SparcAsmBackend(const Target
&T
)
124 : MCAsmBackend(StringRef(T
.getName()) == "sparcel" ? support::little
126 TheTarget(T
), Is64Bit(StringRef(TheTarget
.getName()) == "sparcv9") {}
128 unsigned getNumFixupKinds() const override
{
129 return Sparc::NumTargetFixupKinds
;
132 const MCFixupKindInfo
&getFixupKindInfo(MCFixupKind Kind
) const override
{
133 const static MCFixupKindInfo InfosBE
[Sparc::NumTargetFixupKinds
] = {
134 // name offset bits flags
135 { "fixup_sparc_call30", 2, 30, MCFixupKindInfo::FKF_IsPCRel
},
136 { "fixup_sparc_br22", 10, 22, MCFixupKindInfo::FKF_IsPCRel
},
137 { "fixup_sparc_br19", 13, 19, MCFixupKindInfo::FKF_IsPCRel
},
138 { "fixup_sparc_br16_2", 10, 2, MCFixupKindInfo::FKF_IsPCRel
},
139 { "fixup_sparc_br16_14", 18, 14, MCFixupKindInfo::FKF_IsPCRel
},
140 { "fixup_sparc_13", 19, 13, 0 },
141 { "fixup_sparc_hi22", 10, 22, 0 },
142 { "fixup_sparc_lo10", 22, 10, 0 },
143 { "fixup_sparc_h44", 10, 22, 0 },
144 { "fixup_sparc_m44", 22, 10, 0 },
145 { "fixup_sparc_l44", 20, 12, 0 },
146 { "fixup_sparc_hh", 10, 22, 0 },
147 { "fixup_sparc_hm", 22, 10, 0 },
148 { "fixup_sparc_pc22", 10, 22, MCFixupKindInfo::FKF_IsPCRel
},
149 { "fixup_sparc_pc10", 22, 10, MCFixupKindInfo::FKF_IsPCRel
},
150 { "fixup_sparc_got22", 10, 22, 0 },
151 { "fixup_sparc_got10", 22, 10, 0 },
152 { "fixup_sparc_got13", 19, 13, 0 },
153 { "fixup_sparc_wplt30", 2, 30, MCFixupKindInfo::FKF_IsPCRel
},
154 { "fixup_sparc_tls_gd_hi22", 10, 22, 0 },
155 { "fixup_sparc_tls_gd_lo10", 22, 10, 0 },
156 { "fixup_sparc_tls_gd_add", 0, 0, 0 },
157 { "fixup_sparc_tls_gd_call", 0, 0, 0 },
158 { "fixup_sparc_tls_ldm_hi22", 10, 22, 0 },
159 { "fixup_sparc_tls_ldm_lo10", 22, 10, 0 },
160 { "fixup_sparc_tls_ldm_add", 0, 0, 0 },
161 { "fixup_sparc_tls_ldm_call", 0, 0, 0 },
162 { "fixup_sparc_tls_ldo_hix22", 10, 22, 0 },
163 { "fixup_sparc_tls_ldo_lox10", 22, 10, 0 },
164 { "fixup_sparc_tls_ldo_add", 0, 0, 0 },
165 { "fixup_sparc_tls_ie_hi22", 10, 22, 0 },
166 { "fixup_sparc_tls_ie_lo10", 22, 10, 0 },
167 { "fixup_sparc_tls_ie_ld", 0, 0, 0 },
168 { "fixup_sparc_tls_ie_ldx", 0, 0, 0 },
169 { "fixup_sparc_tls_ie_add", 0, 0, 0 },
170 { "fixup_sparc_tls_le_hix22", 0, 0, 0 },
171 { "fixup_sparc_tls_le_lox10", 0, 0, 0 }
174 const static MCFixupKindInfo InfosLE
[Sparc::NumTargetFixupKinds
] = {
175 // name offset bits flags
176 { "fixup_sparc_call30", 0, 30, MCFixupKindInfo::FKF_IsPCRel
},
177 { "fixup_sparc_br22", 0, 22, MCFixupKindInfo::FKF_IsPCRel
},
178 { "fixup_sparc_br19", 0, 19, MCFixupKindInfo::FKF_IsPCRel
},
179 { "fixup_sparc_br16_2", 20, 2, MCFixupKindInfo::FKF_IsPCRel
},
180 { "fixup_sparc_br16_14", 0, 14, MCFixupKindInfo::FKF_IsPCRel
},
181 { "fixup_sparc_13", 0, 13, 0 },
182 { "fixup_sparc_hi22", 0, 22, 0 },
183 { "fixup_sparc_lo10", 0, 10, 0 },
184 { "fixup_sparc_h44", 0, 22, 0 },
185 { "fixup_sparc_m44", 0, 10, 0 },
186 { "fixup_sparc_l44", 0, 12, 0 },
187 { "fixup_sparc_hh", 0, 22, 0 },
188 { "fixup_sparc_hm", 0, 10, 0 },
189 { "fixup_sparc_pc22", 0, 22, MCFixupKindInfo::FKF_IsPCRel
},
190 { "fixup_sparc_pc10", 0, 10, MCFixupKindInfo::FKF_IsPCRel
},
191 { "fixup_sparc_got22", 0, 22, 0 },
192 { "fixup_sparc_got10", 0, 10, 0 },
193 { "fixup_sparc_got13", 0, 13, 0 },
194 { "fixup_sparc_wplt30", 0, 30, MCFixupKindInfo::FKF_IsPCRel
},
195 { "fixup_sparc_tls_gd_hi22", 0, 22, 0 },
196 { "fixup_sparc_tls_gd_lo10", 0, 10, 0 },
197 { "fixup_sparc_tls_gd_add", 0, 0, 0 },
198 { "fixup_sparc_tls_gd_call", 0, 0, 0 },
199 { "fixup_sparc_tls_ldm_hi22", 0, 22, 0 },
200 { "fixup_sparc_tls_ldm_lo10", 0, 10, 0 },
201 { "fixup_sparc_tls_ldm_add", 0, 0, 0 },
202 { "fixup_sparc_tls_ldm_call", 0, 0, 0 },
203 { "fixup_sparc_tls_ldo_hix22", 0, 22, 0 },
204 { "fixup_sparc_tls_ldo_lox10", 0, 10, 0 },
205 { "fixup_sparc_tls_ldo_add", 0, 0, 0 },
206 { "fixup_sparc_tls_ie_hi22", 0, 22, 0 },
207 { "fixup_sparc_tls_ie_lo10", 0, 10, 0 },
208 { "fixup_sparc_tls_ie_ld", 0, 0, 0 },
209 { "fixup_sparc_tls_ie_ldx", 0, 0, 0 },
210 { "fixup_sparc_tls_ie_add", 0, 0, 0 },
211 { "fixup_sparc_tls_le_hix22", 0, 0, 0 },
212 { "fixup_sparc_tls_le_lox10", 0, 0, 0 }
215 if (Kind
< FirstTargetFixupKind
)
216 return MCAsmBackend::getFixupKindInfo(Kind
);
218 assert(unsigned(Kind
- FirstTargetFixupKind
) < getNumFixupKinds() &&
220 if (Endian
== support::little
)
221 return InfosLE
[Kind
- FirstTargetFixupKind
];
223 return InfosBE
[Kind
- FirstTargetFixupKind
];
226 bool shouldForceRelocation(const MCAssembler
&Asm
, const MCFixup
&Fixup
,
227 const MCValue
&Target
) override
{
228 switch ((Sparc::Fixups
)Fixup
.getKind()) {
231 case Sparc::fixup_sparc_wplt30
:
232 if (Target
.getSymA()->getSymbol().isTemporary())
235 case Sparc::fixup_sparc_tls_gd_hi22
:
236 case Sparc::fixup_sparc_tls_gd_lo10
:
237 case Sparc::fixup_sparc_tls_gd_add
:
238 case Sparc::fixup_sparc_tls_gd_call
:
239 case Sparc::fixup_sparc_tls_ldm_hi22
:
240 case Sparc::fixup_sparc_tls_ldm_lo10
:
241 case Sparc::fixup_sparc_tls_ldm_add
:
242 case Sparc::fixup_sparc_tls_ldm_call
:
243 case Sparc::fixup_sparc_tls_ldo_hix22
:
244 case Sparc::fixup_sparc_tls_ldo_lox10
:
245 case Sparc::fixup_sparc_tls_ldo_add
:
246 case Sparc::fixup_sparc_tls_ie_hi22
:
247 case Sparc::fixup_sparc_tls_ie_lo10
:
248 case Sparc::fixup_sparc_tls_ie_ld
:
249 case Sparc::fixup_sparc_tls_ie_ldx
:
250 case Sparc::fixup_sparc_tls_ie_add
:
251 case Sparc::fixup_sparc_tls_le_hix22
:
252 case Sparc::fixup_sparc_tls_le_lox10
:
257 bool mayNeedRelaxation(const MCInst
&Inst
,
258 const MCSubtargetInfo
&STI
) const override
{
263 /// fixupNeedsRelaxation - Target specific predicate for whether a given
264 /// fixup requires the associated instruction to be relaxed.
265 bool fixupNeedsRelaxation(const MCFixup
&Fixup
,
267 const MCRelaxableFragment
*DF
,
268 const MCAsmLayout
&Layout
) const override
{
270 llvm_unreachable("fixupNeedsRelaxation() unimplemented");
273 void relaxInstruction(const MCInst
&Inst
, const MCSubtargetInfo
&STI
,
274 MCInst
&Res
) const override
{
276 llvm_unreachable("relaxInstruction() unimplemented");
279 bool writeNopData(raw_ostream
&OS
, uint64_t Count
) const override
{
280 // Cannot emit NOP with size not multiple of 32 bits.
284 uint64_t NumNops
= Count
/ 4;
285 for (uint64_t i
= 0; i
!= NumNops
; ++i
)
286 support::endian::write
<uint32_t>(OS
, 0x01000000, Endian
);
292 class ELFSparcAsmBackend
: public SparcAsmBackend
{
293 Triple::OSType OSType
;
295 ELFSparcAsmBackend(const Target
&T
, Triple::OSType OSType
) :
296 SparcAsmBackend(T
), OSType(OSType
) { }
298 void applyFixup(const MCAssembler
&Asm
, const MCFixup
&Fixup
,
299 const MCValue
&Target
, MutableArrayRef
<char> Data
,
300 uint64_t Value
, bool IsResolved
,
301 const MCSubtargetInfo
*STI
) const override
{
303 Value
= adjustFixupValue(Fixup
.getKind(), Value
);
304 if (!Value
) return; // Doesn't change encoding.
306 unsigned NumBytes
= getFixupKindNumBytes(Fixup
.getKind());
307 unsigned Offset
= Fixup
.getOffset();
308 // For each byte of the fragment that the fixup touches, mask in the bits
309 // from the fixup value. The Value has been "split up" into the
310 // appropriate bitfields above.
311 for (unsigned i
= 0; i
!= NumBytes
; ++i
) {
312 unsigned Idx
= Endian
== support::little
? i
: (NumBytes
- 1) - i
;
313 Data
[Offset
+ Idx
] |= uint8_t((Value
>> (i
* 8)) & 0xff);
317 std::unique_ptr
<MCObjectTargetWriter
>
318 createObjectTargetWriter() const override
{
319 uint8_t OSABI
= MCELFObjectTargetWriter::getOSABI(OSType
);
320 return createSparcELFObjectWriter(Is64Bit
, OSABI
);
324 } // end anonymous namespace
326 MCAsmBackend
*llvm::createSparcAsmBackend(const Target
&T
,
327 const MCSubtargetInfo
&STI
,
328 const MCRegisterInfo
&MRI
,
329 const MCTargetOptions
&Options
) {
330 return new ELFSparcAsmBackend(T
, STI
.getTargetTriple().getOS());