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