1 //===-- MipsAsmBackend.cpp - Mips Asm 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 // This file implements the MipsAsmBackend class.
10 //
11 //===----------------------------------------------------------------------===//
12 //
13
14 #include "MCTargetDesc/MipsAsmBackend.h"
15 #include "MCTargetDesc/MipsABIInfo.h"
16 #include "MCTargetDesc/MipsFixupKinds.h"
17 #include "MCTargetDesc/MipsMCExpr.h"
18 #include "MCTargetDesc/MipsMCTargetDesc.h"
19 #include "MipsTargetStreamer.h"
20 #include "llvm/ADT/STLExtras.h"
21 #include "llvm/MC/MCAsmBackend.h"
22 #include "llvm/MC/MCAssembler.h"
23 #include "llvm/MC/MCContext.h"
24 #include "llvm/MC/MCDirectives.h"
25 #include "llvm/MC/MCELFObjectWriter.h"
26 #include "llvm/MC/MCFixupKindInfo.h"
27 #include "llvm/MC/MCObjectWriter.h"
28 #include "llvm/MC/MCSubtargetInfo.h"
29 #include "llvm/MC/MCTargetOptions.h"
30 #include "llvm/MC/MCValue.h"
31 #include "llvm/Support/ErrorHandling.h"
32 #include "llvm/Support/Format.h"
33 #include "llvm/Support/MathExtras.h"
34 #include "llvm/Support/raw_ostream.h"
35
36 using namespace llvm;
37
38 // Prepare value for the target space for it
adjustFixupValue(const MCFixup & Fixup,uint64_t Value,MCContext & Ctx)39 static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
40 MCContext &Ctx) {
41
42 unsigned Kind = Fixup.getKind();
43
44 // Add/subtract and shift
45 switch (Kind) {
46 default:
47 return 0;
48 case Mips::fixup_CHERI_CAPABILITY:
49 // This should never change anything, it is just a marker for the linker
50 return 0;
51 case FK_Data_2:
52 case Mips::fixup_Mips_LO16:
53 case Mips::fixup_Mips_GPREL16:
54 case Mips::fixup_Mips_GPOFF_HI:
55 case Mips::fixup_Mips_GPOFF_LO:
56 case Mips::fixup_Mips_CAPTABLEREL16:
57 case Mips::fixup_Mips_CAPTABLEOFF_HI:
58 case Mips::fixup_Mips_CAPTABLEOFF_LO:
59 case Mips::fixup_Mips_GOT_PAGE:
60 case Mips::fixup_Mips_GOT_OFST:
61 case Mips::fixup_Mips_GOT_DISP:
62 case Mips::fixup_Mips_GOT_LO16:
63 case Mips::fixup_Mips_CALL_LO16:
64 case Mips::fixup_MICROMIPS_GPOFF_HI:
65 case Mips::fixup_MICROMIPS_GPOFF_LO:
66 case Mips::fixup_MICROMIPS_LO16:
67 case Mips::fixup_MICROMIPS_GOT_PAGE:
68 case Mips::fixup_MICROMIPS_GOT_OFST:
69 case Mips::fixup_MICROMIPS_GOT_DISP:
70 case Mips::fixup_MIPS_PCLO16:
71 case Mips::fixup_CHERI_CAPTABLE_LO16:
72 case Mips::fixup_CHERI_CAPCALL_LO16:
73 Value &= 0xffff;
74 break;
75 case FK_DTPRel_4:
76 case FK_DTPRel_8:
77 case FK_TPRel_4:
78 case FK_TPRel_8:
79 case FK_GPRel_4:
80 case FK_Data_4:
81 case FK_Data_8:
82 case Mips::fixup_Mips_SUB:
83 case Mips::fixup_MICROMIPS_SUB:
84 break;
85 case Mips::fixup_Mips_PC16:
86 // The displacement is then divided by 4 to give us an 18 bit
87 // address range. Forcing a signed division because Value can be negative.
88 Value = (int64_t)Value / 4;
89 // We now check if Value can be encoded as a 16-bit signed immediate.
90 if (!isInt<16>(Value)) {
91 Ctx.reportError(Fixup.getLoc(), "out of range PC16 fixup");
92 return 0;
93 }
94 break;
95 case Mips::fixup_MIPS_PC19_S2:
96 case Mips::fixup_MICROMIPS_PC19_S2:
97 // Forcing a signed division because Value can be negative.
98 Value = (int64_t)Value / 4;
99 // We now check if Value can be encoded as a 19-bit signed immediate.
100 if (!isInt<19>(Value)) {
101 Ctx.reportError(Fixup.getLoc(), "out of range PC19 fixup");
102 return 0;
103 }
104 break;
105 case Mips::fixup_Mips_26:
106 // So far we are only using this type for jumps.
107 // The displacement is then divided by 4 to give us an 28 bit
108 // address range.
109 Value >>= 2;
110 break;
111 case Mips::fixup_Mips_HI16:
112 case Mips::fixup_Mips_GOT:
113 case Mips::fixup_MICROMIPS_GOT16:
114 case Mips::fixup_Mips_GOT_HI16:
115 case Mips::fixup_Mips_CALL_HI16:
116 case Mips::fixup_MICROMIPS_HI16:
117 case Mips::fixup_MIPS_PCHI16:
118 case Mips::fixup_CHERI_CAPTABLE_HI16:
119 case Mips::fixup_CHERI_CAPCALL_HI16:
120 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1.
121 Value = ((Value + 0x8000) >> 16) & 0xffff;
122 break;
123 case Mips::fixup_Mips_HIGHER:
124 case Mips::fixup_MICROMIPS_HIGHER:
125 // Get the 3rd 16-bits.
126 Value = ((Value + 0x80008000LL) >> 32) & 0xffff;
127 break;
128 case Mips::fixup_Mips_HIGHEST:
129 case Mips::fixup_MICROMIPS_HIGHEST:
130 // Get the 4th 16-bits.
131 Value = ((Value + 0x800080008000LL) >> 48) & 0xffff;
132 break;
133 case Mips::fixup_MICROMIPS_26_S1:
134 Value >>= 1;
135 break;
136 case Mips::fixup_MICROMIPS_PC7_S1:
137 Value -= 4;
138 // Forcing a signed division because Value can be negative.
139 Value = (int64_t) Value / 2;
140 // We now check if Value can be encoded as a 7-bit signed immediate.
141 if (!isInt<7>(Value)) {
142 Ctx.reportError(Fixup.getLoc(), "out of range PC7 fixup");
143 return 0;
144 }
145 break;
146 case Mips::fixup_MICROMIPS_PC10_S1:
147 Value -= 2;
148 // Forcing a signed division because Value can be negative.
149 Value = (int64_t) Value / 2;
150 // We now check if Value can be encoded as a 10-bit signed immediate.
151 if (!isInt<10>(Value)) {
152 Ctx.reportError(Fixup.getLoc(), "out of range PC10 fixup");
153 return 0;
154 }
155 break;
156 case Mips::fixup_MICROMIPS_PC16_S1:
157 Value -= 4;
158 // Forcing a signed division because Value can be negative.
159 Value = (int64_t)Value / 2;
160 // We now check if Value can be encoded as a 16-bit signed immediate.
161 if (!isInt<16>(Value)) {
162 Ctx.reportError(Fixup.getLoc(), "out of range PC16 fixup");
163 return 0;
164 }
165 break;
166 case Mips::fixup_MIPS_PC18_S3:
167 // Forcing a signed division because Value can be negative.
168 Value = (int64_t)Value / 8;
169 // We now check if Value can be encoded as a 18-bit signed immediate.
170 if (!isInt<18>(Value)) {
171 Ctx.reportError(Fixup.getLoc(), "out of range PC18 fixup");
172 return 0;
173 }
174 break;
175 case Mips::fixup_MICROMIPS_PC18_S3:
176 // Check alignment.
177 if ((Value & 7)) {
178 Ctx.reportError(Fixup.getLoc(), "out of range PC18 fixup");
179 }
180 // Forcing a signed division because Value can be negative.
181 Value = (int64_t)Value / 8;
182 // We now check if Value can be encoded as a 18-bit signed immediate.
183 if (!isInt<18>(Value)) {
184 Ctx.reportError(Fixup.getLoc(), "out of range PC18 fixup");
185 return 0;
186 }
187 break;
188 case Mips::fixup_MIPS_PC21_S2:
189 // Forcing a signed division because Value can be negative.
190 Value = (int64_t) Value / 4;
191 // We now check if Value can be encoded as a 21-bit signed immediate.
192 if (!isInt<21>(Value)) {
193 Ctx.reportError(Fixup.getLoc(), "out of range PC21 fixup");
194 return 0;
195 }
196 break;
197 case Mips::fixup_MIPS_PC26_S2:
198 // Forcing a signed division because Value can be negative.
199 Value = (int64_t) Value / 4;
200 // We now check if Value can be encoded as a 26-bit signed immediate.
201 if (!isInt<26>(Value)) {
202 Ctx.reportError(Fixup.getLoc(), "out of range PC26 fixup");
203 return 0;
204 }
205 break;
206 case Mips::fixup_MICROMIPS_PC26_S1:
207 // Forcing a signed division because Value can be negative.
208 Value = (int64_t)Value / 2;
209 // We now check if Value can be encoded as a 26-bit signed immediate.
210 if (!isInt<26>(Value)) {
211 Ctx.reportFatalError(Fixup.getLoc(), "out of range PC26 fixup");
212 return 0;
213 }
214 break;
215 case Mips::fixup_MICROMIPS_PC21_S1:
216 // Forcing a signed division because Value can be negative.
217 Value = (int64_t)Value / 2;
218 // We now check if Value can be encoded as a 21-bit signed immediate.
219 if (!isInt<21>(Value)) {
220 Ctx.reportError(Fixup.getLoc(), "out of range PC21 fixup");
221 return 0;
222 }
223 break;
224 case Mips::fixup_CHERI_CAPTABLE11:
225 case Mips::fixup_CHERI_CAPCALL11:
226 // Forcing a signed division because Value can be negative.
227 Value = (int64_t)Value / 16;
228 // We now check if Value can be encoded as a 11-bit signed immediate.
229 if (!isInt<11>(Value)) {
230 StringRef type = Kind == Mips::fixup_CHERI_CAPTABLE11 ?
231 "CAPTABLE11" : "CAPCALL11";
232 Ctx.reportError(Fixup.getLoc(), "out of range " + type + " fixup");
233 return 0;
234 }
235 break;
236 case Mips::fixup_CHERI_CAPTABLE20:
237 case Mips::fixup_CHERI_CAPCALL20:
238 // Forcing a signed division because Value can be negative.
239 Value = (int64_t)Value / 16;
240 // We now check if Value can be encoded as a 16-bit signed immediate.
241 if (!isInt<16>(Value)) {
242 StringRef type = Kind == Mips::fixup_CHERI_CAPTABLE20 ?
243 "CAPTABLE20" : "CAPCALL20";
244 Ctx.reportError(Fixup.getLoc(), "out of range " + type + " fixup");
245 return 0;
246 }
247 break;
248 }
249
250 return Value;
251 }
252
253 std::unique_ptr<MCObjectTargetWriter>
createObjectTargetWriter() const254 MipsAsmBackend::createObjectTargetWriter() const {
255 return createMipsELFObjectWriter(TheTriple, IsN32);
256 }
257
258 // Little-endian fixup data byte ordering:
259 // mips32r2: a | b | x | x
260 // microMIPS: x | x | a | b
261
needsMMLEByteOrder(unsigned Kind)262 static bool needsMMLEByteOrder(unsigned Kind) {
263 return Kind != Mips::fixup_MICROMIPS_PC10_S1 &&
264 Kind >= Mips::fixup_MICROMIPS_26_S1 &&
265 Kind < Mips::LastTargetFixupKind;
266 }
267
268 // Calculate index for microMIPS specific little endian byte order
calculateMMLEIndex(unsigned i)269 static unsigned calculateMMLEIndex(unsigned i) {
270 assert(i <= 3 && "Index out of range!");
271
272 return (1 - i / 2) * 2 + i % 2;
273 }
274
275 /// ApplyFixup - Apply the \p Value for given \p Fixup into the provided
276 /// data fragment, at the offset specified by the fixup and following the
277 /// fixup kind as appropriate.
applyFixup(const MCAssembler & Asm,const MCFixup & Fixup,const MCValue & Target,MutableArrayRef<char> Data,uint64_t Value,bool IsResolved,const MCSubtargetInfo * STI) const278 void MipsAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
279 const MCValue &Target,
280 MutableArrayRef<char> Data, uint64_t Value,
281 bool IsResolved,
282 const MCSubtargetInfo *STI) const {
283 MCFixupKind Kind = Fixup.getKind();
284 MCContext &Ctx = Asm.getContext();
285 Value = adjustFixupValue(Fixup, Value, Ctx);
286
287 if (!Value)
288 return; // Doesn't change encoding.
289
290 // Where do we start in the object
291 unsigned Offset = Fixup.getOffset();
292 // Number of bytes we need to fixup
293 unsigned NumBytes = (getFixupKindInfo(Kind).TargetSize + 7) / 8;
294 // Used to point to big endian bytes
295 unsigned FullSize;
296
297 switch ((unsigned)Kind) {
298 case FK_Data_2:
299 case Mips::fixup_Mips_16:
300 case Mips::fixup_MICROMIPS_PC10_S1:
301 FullSize = 2;
302 break;
303 case FK_Data_8:
304 case Mips::fixup_Mips_64:
305 FullSize = 8;
306 break;
307 case Mips::fixup_CHERI_CAPABILITY:
308 llvm_unreachable("fixup_CHERI_CAPABILITY shouldn't happen here!");
309 break;
310 case FK_Data_4:
311 default:
312 FullSize = 4;
313 break;
314 }
315
316 // Grab current value, if any, from bits.
317 uint64_t CurVal = 0;
318
319 bool microMipsLEByteOrder = needsMMLEByteOrder((unsigned) Kind);
320
321 for (unsigned i = 0; i != NumBytes; ++i) {
322 unsigned Idx = Endian == support::little
323 ? (microMipsLEByteOrder ? calculateMMLEIndex(i) : i)
324 : (FullSize - 1 - i);
325 CurVal |= (uint64_t)((uint8_t)Data[Offset + Idx]) << (i*8);
326 }
327
328 uint64_t Mask = ((uint64_t)(-1) >>
329 (64 - getFixupKindInfo(Kind).TargetSize));
330 CurVal |= Value & Mask;
331
332 // Write out the fixed up bytes back to the code/data bits.
333 for (unsigned i = 0; i != NumBytes; ++i) {
334 unsigned Idx = Endian == support::little
335 ? (microMipsLEByteOrder ? calculateMMLEIndex(i) : i)
336 : (FullSize - 1 - i);
337 Data[Offset + Idx] = (uint8_t)((CurVal >> (i*8)) & 0xff);
338 }
339 }
340
getFixupKind(StringRef Name) const341 Optional<MCFixupKind> MipsAsmBackend::getFixupKind(StringRef Name) const {
342 return StringSwitch<Optional<MCFixupKind>>(Name)
343 .Case("R_MIPS_NONE", FK_NONE)
344 .Case("R_MIPS_32", FK_Data_4)
345 .Case("R_MIPS_CALL_HI16", (MCFixupKind)Mips::fixup_Mips_CALL_HI16)
346 .Case("R_MIPS_CALL_LO16", (MCFixupKind)Mips::fixup_Mips_CALL_LO16)
347 .Case("R_MIPS_CALL16", (MCFixupKind)Mips::fixup_Mips_CALL16)
348 .Case("R_MIPS_GOT16", (MCFixupKind)Mips::fixup_Mips_GOT)
349 .Case("R_MIPS_GOT_PAGE", (MCFixupKind)Mips::fixup_Mips_GOT_PAGE)
350 .Case("R_MIPS_GOT_OFST", (MCFixupKind)Mips::fixup_Mips_GOT_OFST)
351 .Case("R_MIPS_GOT_DISP", (MCFixupKind)Mips::fixup_Mips_GOT_DISP)
352 .Case("R_MIPS_GOT_HI16", (MCFixupKind)Mips::fixup_Mips_GOT_HI16)
353 .Case("R_MIPS_GOT_LO16", (MCFixupKind)Mips::fixup_Mips_GOT_LO16)
354 .Case("R_MIPS_TLS_GOTTPREL", (MCFixupKind)Mips::fixup_Mips_GOTTPREL)
355 .Case("R_MIPS_TLS_DTPREL_HI16", (MCFixupKind)Mips::fixup_Mips_DTPREL_HI)
356 .Case("R_MIPS_TLS_DTPREL_LO16", (MCFixupKind)Mips::fixup_Mips_DTPREL_LO)
357 .Case("R_MIPS_TLS_GD", (MCFixupKind)Mips::fixup_Mips_TLSGD)
358 .Case("R_MIPS_TLS_LDM", (MCFixupKind)Mips::fixup_Mips_TLSLDM)
359 .Case("R_MIPS_TLS_TPREL_HI16", (MCFixupKind)Mips::fixup_Mips_TPREL_HI)
360 .Case("R_MIPS_TLS_TPREL_LO16", (MCFixupKind)Mips::fixup_Mips_TPREL_LO)
361 .Case("R_MICROMIPS_CALL16", (MCFixupKind)Mips::fixup_MICROMIPS_CALL16)
362 .Case("R_MICROMIPS_GOT_DISP", (MCFixupKind)Mips::fixup_MICROMIPS_GOT_DISP)
363 .Case("R_MICROMIPS_GOT_PAGE", (MCFixupKind)Mips::fixup_MICROMIPS_GOT_PAGE)
364 .Case("R_MICROMIPS_GOT_OFST", (MCFixupKind)Mips::fixup_MICROMIPS_GOT_OFST)
365 .Case("R_MICROMIPS_GOT16", (MCFixupKind)Mips::fixup_MICROMIPS_GOT16)
366 .Case("R_MICROMIPS_TLS_GOTTPREL",
367 (MCFixupKind)Mips::fixup_MICROMIPS_GOTTPREL)
368 .Case("R_MICROMIPS_TLS_DTPREL_HI16",
369 (MCFixupKind)Mips::fixup_MICROMIPS_TLS_DTPREL_HI16)
370 .Case("R_MICROMIPS_TLS_DTPREL_LO16",
371 (MCFixupKind)Mips::fixup_MICROMIPS_TLS_DTPREL_LO16)
372 .Case("R_MICROMIPS_TLS_GD", (MCFixupKind)Mips::fixup_MICROMIPS_TLS_GD)
373 .Case("R_MICROMIPS_TLS_LDM", (MCFixupKind)Mips::fixup_MICROMIPS_TLS_LDM)
374 .Case("R_MICROMIPS_TLS_TPREL_HI16",
375 (MCFixupKind)Mips::fixup_MICROMIPS_TLS_TPREL_HI16)
376 .Case("R_MICROMIPS_TLS_TPREL_LO16",
377 (MCFixupKind)Mips::fixup_MICROMIPS_TLS_TPREL_LO16)
378 .Case("R_MIPS_JALR", (MCFixupKind)Mips::fixup_Mips_JALR)
379 .Case("R_MICROMIPS_JALR", (MCFixupKind)Mips::fixup_MICROMIPS_JALR)
380
381 .Case("R_MIPS_CHERI_CAPABILITY", (MCFixupKind)Mips::fixup_CHERI_CAPABILITY)
382 .Case("R_MIPS_CHERI_CAPCALL11", (MCFixupKind)Mips::fixup_CHERI_CAPCALL11)
383 .Case("R_MIPS_CHERI_CAPCALL20", (MCFixupKind)Mips::fixup_CHERI_CAPCALL20)
384 .Case("R_MIPS_CHERI_CAPCALL_HI16", (MCFixupKind)Mips::fixup_CHERI_CAPCALL_HI16)
385 .Case("R_MIPS_CHERI_CAPCALL_LO16", (MCFixupKind)Mips::fixup_CHERI_CAPCALL_LO16)
386 .Case("R_MIPS_CHERI_CAPTABLE11", (MCFixupKind)Mips::fixup_CHERI_CAPTABLE11)
387 .Case("R_MIPS_CHERI_CAPTABLE20", (MCFixupKind)Mips::fixup_CHERI_CAPTABLE20)
388 .Case("R_MIPS_CHERI_CAPTABLE_HI16", (MCFixupKind)Mips::fixup_CHERI_CAPTABLE_HI16)
389 .Case("R_MIPS_CHERI_CAPTABLE_LO16", (MCFixupKind)Mips::fixup_CHERI_CAPTABLE_LO16)
390 // CHERI TLS:
391 .Case("R_MIPS_CHERI_CAPTAB_TLSGD_HI16", (MCFixupKind)Mips::fixup_CHERI_CAPTAB_TLSGD_HI16)
392 .Case("R_MIPS_CHERI_CAPTAB_TLSGD_LO16", (MCFixupKind)Mips::fixup_CHERI_CAPTAB_TLSGD_LO16)
393 .Case("R_MIPS_CHERI_CAPTAB_TLSDM_HI16", (MCFixupKind)Mips::fixup_CHERI_CAPTAB_TLSLDM_HI16)
394 .Case("R_MIPS_CHERI_CAPTAB_TLSDM_LO16", (MCFixupKind)Mips::fixup_CHERI_CAPTAB_TLSLDM_LO16)
395 .Case("R_MIPS_CHERI_CAPTAB_TPREL_HI16", (MCFixupKind)Mips::fixup_CHERI_CAPTAB_TPREL_HI16)
396 .Case("R_MIPS_CHERI_CAPTAB_TPREL_LO16", (MCFixupKind)Mips::fixup_CHERI_CAPTAB_TPREL_LO16)
397
398
399 .Default(MCAsmBackend::getFixupKind(Name));
400 }
401
402 const MCFixupKindInfo &MipsAsmBackend::
getFixupKindInfo(MCFixupKind Kind) const403 getFixupKindInfo(MCFixupKind Kind) const {
404 const static MCFixupKindInfo LittleEndianInfos[] = {
405 // This table *must* be in same the order of fixup_* kinds in
406 // MipsFixupKinds.h.
407 //
408 // name offset bits flags
409 { "fixup_Mips_16", 0, 16, 0 },
410 { "fixup_Mips_32", 0, 32, 0 },
411 { "fixup_Mips_REL32", 0, 32, 0 },
412 { "fixup_Mips_26", 0, 26, 0 },
413 { "fixup_Mips_HI16", 0, 16, 0 },
414 { "fixup_Mips_LO16", 0, 16, 0 },
415 { "fixup_Mips_GPREL16", 0, 16, 0 },
416 { "fixup_Mips_LITERAL", 0, 16, 0 },
417 { "fixup_Mips_GOT", 0, 16, 0 },
418 { "fixup_Mips_PC16", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
419 { "fixup_Mips_CALL16", 0, 16, 0 },
420 { "fixup_Mips_GPREL32", 0, 32, 0 },
421 { "fixup_Mips_SHIFT5", 6, 5, 0 },
422 { "fixup_Mips_SHIFT6", 6, 5, 0 },
423 { "fixup_Mips_64", 0, 64, 0 },
424 { "fixup_Mips_TLSGD", 0, 16, 0 },
425 { "fixup_Mips_GOTTPREL", 0, 16, 0 },
426 { "fixup_Mips_TPREL_HI", 0, 16, 0 },
427 { "fixup_Mips_TPREL_LO", 0, 16, 0 },
428 { "fixup_Mips_TLSLDM", 0, 16, 0 },
429 { "fixup_Mips_DTPREL_HI", 0, 16, 0 },
430 { "fixup_Mips_DTPREL_LO", 0, 16, 0 },
431 { "fixup_Mips_Branch_PCRel", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
432 { "fixup_Mips_GPOFF_HI", 0, 16, 0 },
433 { "fixup_MICROMIPS_GPOFF_HI",0, 16, 0 },
434 { "fixup_Mips_GPOFF_LO", 0, 16, 0 },
435 { "fixup_MICROMIPS_GPOFF_LO",0, 16, 0 },
436 { "fixup_Mips_GOT_PAGE", 0, 16, 0 },
437 { "fixup_Mips_GOT_OFST", 0, 16, 0 },
438 { "fixup_Mips_GOT_DISP", 0, 16, 0 },
439 { "fixup_Mips_HIGHER", 0, 16, 0 },
440 { "fixup_MICROMIPS_HIGHER", 0, 16, 0 },
441 { "fixup_Mips_HIGHEST", 0, 16, 0 },
442 { "fixup_MICROMIPS_HIGHEST", 0, 16, 0 },
443 { "fixup_Mips_GOT_HI16", 0, 16, 0 },
444 { "fixup_Mips_GOT_LO16", 0, 16, 0 },
445 { "fixup_Mips_CALL_HI16", 0, 16, 0 },
446 { "fixup_Mips_CALL_LO16", 0, 16, 0 },
447 { "fixup_Mips_PC18_S3", 0, 18, MCFixupKindInfo::FKF_IsPCRel },
448 { "fixup_MIPS_PC19_S2", 0, 19, MCFixupKindInfo::FKF_IsPCRel },
449 { "fixup_MIPS_PC21_S2", 0, 21, MCFixupKindInfo::FKF_IsPCRel },
450 { "fixup_MIPS_PC26_S2", 0, 26, MCFixupKindInfo::FKF_IsPCRel },
451 { "fixup_MIPS_PCHI16", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
452 { "fixup_MIPS_PCLO16", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
453 { "fixup_MICROMIPS_26_S1", 0, 26, 0 },
454 { "fixup_MICROMIPS_HI16", 0, 16, 0 },
455 { "fixup_MICROMIPS_LO16", 0, 16, 0 },
456 { "fixup_MICROMIPS_GOT16", 0, 16, 0 },
457 { "fixup_MICROMIPS_PC7_S1", 0, 7, MCFixupKindInfo::FKF_IsPCRel },
458 { "fixup_MICROMIPS_PC10_S1", 0, 10, MCFixupKindInfo::FKF_IsPCRel },
459 { "fixup_MICROMIPS_PC16_S1", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
460 { "fixup_MICROMIPS_PC26_S1", 0, 26, MCFixupKindInfo::FKF_IsPCRel },
461 { "fixup_MICROMIPS_PC19_S2", 0, 19, MCFixupKindInfo::FKF_IsPCRel },
462 { "fixup_MICROMIPS_PC18_S3", 0, 18, MCFixupKindInfo::FKF_IsPCRel },
463 { "fixup_MICROMIPS_PC21_S1", 0, 21, MCFixupKindInfo::FKF_IsPCRel },
464 { "fixup_MICROMIPS_CALL16", 0, 16, 0 },
465 { "fixup_MICROMIPS_GOT_DISP", 0, 16, 0 },
466 { "fixup_MICROMIPS_GOT_PAGE", 0, 16, 0 },
467 { "fixup_MICROMIPS_GOT_OFST", 0, 16, 0 },
468 { "fixup_MICROMIPS_TLS_GD", 0, 16, 0 },
469 { "fixup_MICROMIPS_TLS_LDM", 0, 16, 0 },
470 { "fixup_MICROMIPS_TLS_DTPREL_HI16", 0, 16, 0 },
471 { "fixup_MICROMIPS_TLS_DTPREL_LO16", 0, 16, 0 },
472 { "fixup_MICROMIPS_GOTTPREL", 0, 16, 0 },
473 { "fixup_MICROMIPS_TLS_TPREL_HI16", 0, 16, 0 },
474 { "fixup_MICROMIPS_TLS_TPREL_LO16", 0, 16, 0 },
475 { "fixup_Mips_SUB", 0, 64, 0 },
476 { "fixup_MICROMIPS_SUB", 0, 64, 0 },
477 { "fixup_Mips_JALR", 0, 32, 0 },
478 { "fixup_MICROMIPS_JALR", 0, 32, 0 },
479
480 { "fixup_CHERI_CAPTABLE11", 0, 11, 0 },
481 { "fixup_CHERI_CAPTABLE20", 0, 16, 0 },
482 { "fixup_CHERI_CAPTABLE_HI16", 0, 16, 0 },
483 { "fixup_CHERI_CAPTABLE_LO16", 0, 16, 0 },
484 { "fixup_CHERI_CAPCALL11", 0, 11, 0 },
485 { "fixup_CHERI_CAPCALL20", 0, 16, 0 },
486 { "fixup_CHERI_CAPCALL_HI16", 0, 16, 0 },
487 { "fixup_CHERI_CAPCALL_LO16", 0, 16, 0 },
488 { "fixup_CHERI_CAPABILITY", 0, 0xdead, 0 },
489
490 { "fixup_Mips_CAPTABLEREL16", 0, 16, 0 }, // like GPREL16
491 { "fixup_Mips_CAPTABLEREL_HI", 0, 16, 0 }, // like GPOFF_HI
492 { "fixup_Mips_CAPTABLEREL_LO", 0, 16, 0 }, // like GPOFF_LO
493
494 { "fixup_CHERI_CAPTAB_TLSGD_HI16", 0, 16, 0 },
495 { "fixup_CHERI_CAPTAB_TLSGD_LO16", 0, 16, 0 },
496 { "fixup_CHERI_CAPTAB_TLSLDM_HI16", 0, 16, 0 },
497 { "fixup_CHERI_CAPTAB_TLSLDM_LO16", 0, 16, 0 },
498 { "fixup_CHERI_CAPTAB_TPREL_HI16", 0, 16, 0 },
499 { "fixup_CHERI_CAPTAB_TPREL_LO16", 0, 16, 0 },
500
501 };
502 static_assert(array_lengthof(LittleEndianInfos) == Mips::NumTargetFixupKinds,
503 "Not all MIPS little endian fixup kinds added!");
504
505 const static MCFixupKindInfo BigEndianInfos[] = {
506 // This table *must* be in same the order of fixup_* kinds in
507 // MipsFixupKinds.h.
508 //
509 // name offset bits flags
510 { "fixup_Mips_16", 16, 16, 0 },
511 { "fixup_Mips_32", 0, 32, 0 },
512 { "fixup_Mips_REL32", 0, 32, 0 },
513 { "fixup_Mips_26", 6, 26, 0 },
514 { "fixup_Mips_HI16", 16, 16, 0 },
515 { "fixup_Mips_LO16", 16, 16, 0 },
516 { "fixup_Mips_GPREL16", 16, 16, 0 },
517 { "fixup_Mips_LITERAL", 16, 16, 0 },
518 { "fixup_Mips_GOT", 16, 16, 0 },
519 { "fixup_Mips_PC16", 16, 16, MCFixupKindInfo::FKF_IsPCRel },
520 { "fixup_Mips_CALL16", 16, 16, 0 },
521 { "fixup_Mips_GPREL32", 0, 32, 0 },
522 { "fixup_Mips_SHIFT5", 21, 5, 0 },
523 { "fixup_Mips_SHIFT6", 21, 5, 0 },
524 { "fixup_Mips_64", 0, 64, 0 },
525 { "fixup_Mips_TLSGD", 16, 16, 0 },
526 { "fixup_Mips_GOTTPREL", 16, 16, 0 },
527 { "fixup_Mips_TPREL_HI", 16, 16, 0 },
528 { "fixup_Mips_TPREL_LO", 16, 16, 0 },
529 { "fixup_Mips_TLSLDM", 16, 16, 0 },
530 { "fixup_Mips_DTPREL_HI", 16, 16, 0 },
531 { "fixup_Mips_DTPREL_LO", 16, 16, 0 },
532 { "fixup_Mips_Branch_PCRel",16, 16, MCFixupKindInfo::FKF_IsPCRel },
533 { "fixup_Mips_GPOFF_HI", 16, 16, 0 },
534 { "fixup_MICROMIPS_GPOFF_HI", 16, 16, 0 },
535 { "fixup_Mips_GPOFF_LO", 16, 16, 0 },
536 { "fixup_MICROMIPS_GPOFF_LO", 16, 16, 0 },
537 { "fixup_Mips_GOT_PAGE", 16, 16, 0 },
538 { "fixup_Mips_GOT_OFST", 16, 16, 0 },
539 { "fixup_Mips_GOT_DISP", 16, 16, 0 },
540 { "fixup_Mips_HIGHER", 16, 16, 0 },
541 { "fixup_MICROMIPS_HIGHER", 16, 16, 0 },
542 { "fixup_Mips_HIGHEST", 16, 16, 0 },
543 { "fixup_MICROMIPS_HIGHEST",16, 16, 0 },
544 { "fixup_Mips_GOT_HI16", 16, 16, 0 },
545 { "fixup_Mips_GOT_LO16", 16, 16, 0 },
546 { "fixup_Mips_CALL_HI16", 16, 16, 0 },
547 { "fixup_Mips_CALL_LO16", 16, 16, 0 },
548 { "fixup_Mips_PC18_S3", 14, 18, MCFixupKindInfo::FKF_IsPCRel },
549 { "fixup_MIPS_PC19_S2", 13, 19, MCFixupKindInfo::FKF_IsPCRel },
550 { "fixup_MIPS_PC21_S2", 11, 21, MCFixupKindInfo::FKF_IsPCRel },
551 { "fixup_MIPS_PC26_S2", 6, 26, MCFixupKindInfo::FKF_IsPCRel },
552 { "fixup_MIPS_PCHI16", 16, 16, MCFixupKindInfo::FKF_IsPCRel },
553 { "fixup_MIPS_PCLO16", 16, 16, MCFixupKindInfo::FKF_IsPCRel },
554 { "fixup_MICROMIPS_26_S1", 6, 26, 0 },
555 { "fixup_MICROMIPS_HI16", 16, 16, 0 },
556 { "fixup_MICROMIPS_LO16", 16, 16, 0 },
557 { "fixup_MICROMIPS_GOT16", 16, 16, 0 },
558 { "fixup_MICROMIPS_PC7_S1", 9, 7, MCFixupKindInfo::FKF_IsPCRel },
559 { "fixup_MICROMIPS_PC10_S1", 6, 10, MCFixupKindInfo::FKF_IsPCRel },
560 { "fixup_MICROMIPS_PC16_S1",16, 16, MCFixupKindInfo::FKF_IsPCRel },
561 { "fixup_MICROMIPS_PC26_S1", 6, 26, MCFixupKindInfo::FKF_IsPCRel },
562 { "fixup_MICROMIPS_PC19_S2",13, 19, MCFixupKindInfo::FKF_IsPCRel },
563 { "fixup_MICROMIPS_PC18_S3",14, 18, MCFixupKindInfo::FKF_IsPCRel },
564 { "fixup_MICROMIPS_PC21_S1",11, 21, MCFixupKindInfo::FKF_IsPCRel },
565 { "fixup_MICROMIPS_CALL16", 16, 16, 0 },
566 { "fixup_MICROMIPS_GOT_DISP", 16, 16, 0 },
567 { "fixup_MICROMIPS_GOT_PAGE", 16, 16, 0 },
568 { "fixup_MICROMIPS_GOT_OFST", 16, 16, 0 },
569 { "fixup_MICROMIPS_TLS_GD", 16, 16, 0 },
570 { "fixup_MICROMIPS_TLS_LDM", 16, 16, 0 },
571 { "fixup_MICROMIPS_TLS_DTPREL_HI16", 16, 16, 0 },
572 { "fixup_MICROMIPS_TLS_DTPREL_LO16", 16, 16, 0 },
573 { "fixup_MICROMIPS_GOTTPREL", 16, 16, 0 },
574 { "fixup_MICROMIPS_TLS_TPREL_HI16", 16, 16, 0 },
575 { "fixup_MICROMIPS_TLS_TPREL_LO16", 16, 16, 0 },
576 { "fixup_Mips_SUB", 0, 64, 0 },
577 { "fixup_MICROMIPS_SUB", 0, 64, 0 },
578 { "fixup_Mips_JALR", 0, 32, 0 },
579 { "fixup_MICROMIPS_JALR", 0, 32, 0 },
580
581 { "fixup_CHERI_CAPTABLE11", 21, 11, 0 },
582 { "fixup_CHERI_CAPTABLE20", 16, 16, 0 },
583 { "fixup_CHERI_CAPTABLE_HI16", 16, 16, 0 },
584 { "fixup_CHERI_CAPTABLE_LO16", 16, 16, 0 },
585 { "fixup_CHERI_CAPCALL11", 21, 11, 0 },
586 { "fixup_CHERI_CAPCALL20", 16, 16, 0 },
587 { "fixup_CHERI_CAPCALL_HI16", 16, 16, 0 },
588 { "fixup_CHERI_CAPCALL_LO16", 16, 16, 0 },
589 { "fixup_CHERI_CAPABILITY", 0,0xdead, 0 },
590
591 { "fixup_Mips_CAPTABLEREL16", 16, 16, 0 }, // like GPREL16
592 { "fixup_Mips_CAPTABLEREL_HI", 16, 16, 0 }, // like GPOFF_HI
593 { "fixup_Mips_CAPTABLEREL_LO", 16, 16, 0 }, // like GPOFF_LO
594
595 { "fixup_CHERI_CAPTAB_TLSGD_HI16", 16, 16, 0 },
596 { "fixup_CHERI_CAPTAB_TLSGD_LO16", 16, 16, 0 },
597 { "fixup_CHERI_CAPTAB_TLSLDM_HI16", 16, 16, 0 },
598 { "fixup_CHERI_CAPTAB_TLSLDM_LO16", 16, 16, 0 },
599 { "fixup_CHERI_CAPTAB_TPREL_HI16", 16, 16, 0 },
600 { "fixup_CHERI_CAPTAB_TPREL_LO16", 16, 16, 0 },
601
602 };
603 static_assert(array_lengthof(BigEndianInfos) == Mips::NumTargetFixupKinds,
604 "Not all MIPS big endian fixup kinds added!");
605
606 if (Kind < FirstTargetFixupKind)
607 return MCAsmBackend::getFixupKindInfo(Kind);
608
609 assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
610 "Invalid kind!");
611
612 assert(Kind - FirstTargetFixupKind != Mips::fixup_CHERI_CAPABILITY);
613
614 if (Endian == support::little)
615 return LittleEndianInfos[Kind - FirstTargetFixupKind];
616 return BigEndianInfos[Kind - FirstTargetFixupKind];
617 }
618
619 /// WriteNopData - Write an (optimal) nop sequence of Count bytes
620 /// to the given output. If the target cannot generate such a sequence,
621 /// it should return an error.
622 ///
623 /// \return - True on success.
writeNopData(raw_ostream & OS,uint64_t Count) const624 bool MipsAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const {
625 // Check for a less than instruction size number of bytes
626 // FIXME: 16 bit instructions are not handled yet here.
627 // We shouldn't be using a hard coded number for instruction size.
628
629 // If the count is not 4-byte aligned, we must be writing data into the text
630 // section (otherwise we have unaligned instructions, and thus have far
631 // bigger problems), so just write zeros instead.
632 OS.write_zeros(Count);
633 return true;
634 }
635
shouldForceRelocation(const MCAssembler & Asm,const MCFixup & Fixup,const MCValue & Target)636 bool MipsAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
637 const MCFixup &Fixup,
638 const MCValue &Target) {
639 const unsigned FixupKind = Fixup.getKind();
640 switch (FixupKind) {
641 default:
642 return false;
643 // All these relocations require special processing
644 // at linking time. Delegate this work to a linker.
645 case Mips::fixup_Mips_CALL_HI16:
646 case Mips::fixup_Mips_CALL_LO16:
647 case Mips::fixup_Mips_CALL16:
648 case Mips::fixup_Mips_GOT:
649 case Mips::fixup_Mips_GOT_PAGE:
650 case Mips::fixup_Mips_GOT_OFST:
651 case Mips::fixup_Mips_GOT_DISP:
652 case Mips::fixup_Mips_GOT_HI16:
653 case Mips::fixup_Mips_GOT_LO16:
654 case Mips::fixup_Mips_GOTTPREL:
655 case Mips::fixup_Mips_DTPREL_HI:
656 case Mips::fixup_Mips_DTPREL_LO:
657 case Mips::fixup_Mips_TLSGD:
658 case Mips::fixup_Mips_TLSLDM:
659 case Mips::fixup_Mips_TPREL_HI:
660 case Mips::fixup_Mips_TPREL_LO:
661 case Mips::fixup_Mips_JALR:
662 case Mips::fixup_MICROMIPS_CALL16:
663 case Mips::fixup_MICROMIPS_GOT_DISP:
664 case Mips::fixup_MICROMIPS_GOT_PAGE:
665 case Mips::fixup_MICROMIPS_GOT_OFST:
666 case Mips::fixup_MICROMIPS_GOT16:
667 case Mips::fixup_MICROMIPS_GOTTPREL:
668 case Mips::fixup_MICROMIPS_TLS_DTPREL_HI16:
669 case Mips::fixup_MICROMIPS_TLS_DTPREL_LO16:
670 case Mips::fixup_MICROMIPS_TLS_GD:
671 case Mips::fixup_MICROMIPS_TLS_LDM:
672 case Mips::fixup_MICROMIPS_TLS_TPREL_HI16:
673 case Mips::fixup_MICROMIPS_TLS_TPREL_LO16:
674 case Mips::fixup_MICROMIPS_JALR:
675 case Mips::fixup_CHERI_CAPTAB_TLSGD_HI16:
676 case Mips::fixup_CHERI_CAPTAB_TLSGD_LO16:
677 case Mips::fixup_CHERI_CAPTAB_TLSLDM_HI16:
678 case Mips::fixup_CHERI_CAPTAB_TLSLDM_LO16:
679 case Mips::fixup_CHERI_CAPTAB_TPREL_HI16:
680 case Mips::fixup_CHERI_CAPTAB_TPREL_LO16:
681 return true;
682 }
683 }
684
isMicroMips(const MCSymbol * Sym) const685 bool MipsAsmBackend::isMicroMips(const MCSymbol *Sym) const {
686 if (const auto *ElfSym = dyn_cast<const MCSymbolELF>(Sym)) {
687 if (ElfSym->getOther() & ELF::STO_MIPS_MICROMIPS)
688 return true;
689 }
690 return false;
691 }
692
createMipsAsmBackend(const Target & T,const MCSubtargetInfo & STI,const MCRegisterInfo & MRI,const MCTargetOptions & Options)693 MCAsmBackend *llvm::createMipsAsmBackend(const Target &T,
694 const MCSubtargetInfo &STI,
695 const MCRegisterInfo &MRI,
696 const MCTargetOptions &Options) {
697 MipsABIInfo ABI = MipsABIInfo::computeTargetABI(STI.getTargetTriple(),
698 STI.getCPU(), Options);
699 return new MipsAsmBackend(T, MRI, STI.getTargetTriple(), STI.getCPU(),
700 ABI.IsN32());
701 }
702