]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lld/ELF/Arch/MipsArchTree.cpp
Import DTS files from Linux 4.18
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lld / ELF / Arch / MipsArchTree.cpp
1 //===- MipsArchTree.cpp --------------------------------------------------===//
2 //
3 //                             The LLVM Linker
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===---------------------------------------------------------------------===//
9 //
10 // This file contains a helper function for the Writer.
11 //
12 //===---------------------------------------------------------------------===//
13
14 #include "InputFiles.h"
15 #include "SymbolTable.h"
16 #include "Writer.h"
17
18 #include "lld/Common/ErrorHandler.h"
19 #include "llvm/BinaryFormat/ELF.h"
20 #include "llvm/Object/ELF.h"
21 #include "llvm/Support/MipsABIFlags.h"
22
23 using namespace llvm;
24 using namespace llvm::object;
25 using namespace llvm::ELF;
26
27 using namespace lld;
28 using namespace lld::elf;
29
30 namespace {
31 struct ArchTreeEdge {
32   uint32_t Child;
33   uint32_t Parent;
34 };
35
36 struct FileFlags {
37   InputFile *File;
38   uint32_t Flags;
39 };
40 } // namespace
41
42 static StringRef getAbiName(uint32_t Flags) {
43   switch (Flags) {
44   case 0:
45     return "n64";
46   case EF_MIPS_ABI2:
47     return "n32";
48   case EF_MIPS_ABI_O32:
49     return "o32";
50   case EF_MIPS_ABI_O64:
51     return "o64";
52   case EF_MIPS_ABI_EABI32:
53     return "eabi32";
54   case EF_MIPS_ABI_EABI64:
55     return "eabi64";
56   default:
57     return "unknown";
58   }
59 }
60
61 static StringRef getNanName(bool IsNan2008) {
62   return IsNan2008 ? "2008" : "legacy";
63 }
64
65 static StringRef getFpName(bool IsFp64) { return IsFp64 ? "64" : "32"; }
66
67 static void checkFlags(ArrayRef<FileFlags> Files) {
68   uint32_t ABI = Files[0].Flags & (EF_MIPS_ABI | EF_MIPS_ABI2);
69   bool Nan = Files[0].Flags & EF_MIPS_NAN2008;
70   bool Fp = Files[0].Flags & EF_MIPS_FP64;
71
72   for (const FileFlags &F : Files.slice(1)) {
73     uint32_t ABI2 = F.Flags & (EF_MIPS_ABI | EF_MIPS_ABI2);
74     if (ABI != ABI2)
75       error("target ABI '" + getAbiName(ABI) + "' is incompatible with '" +
76             getAbiName(ABI2) + "': " + toString(F.File));
77
78     bool Nan2 = F.Flags & EF_MIPS_NAN2008;
79     if (Nan != Nan2)
80       error("target -mnan=" + getNanName(Nan) + " is incompatible with -mnan=" +
81             getNanName(Nan2) + ": " + toString(F.File));
82
83     bool Fp2 = F.Flags & EF_MIPS_FP64;
84     if (Fp != Fp2)
85       error("target -mfp" + getFpName(Fp) + " is incompatible with -mfp" +
86             getFpName(Fp2) + ": " + toString(F.File));
87   }
88 }
89
90 static uint32_t getMiscFlags(ArrayRef<FileFlags> Files) {
91   uint32_t Ret = 0;
92   for (const FileFlags &F : Files)
93     Ret |= F.Flags &
94            (EF_MIPS_ABI | EF_MIPS_ABI2 | EF_MIPS_ARCH_ASE | EF_MIPS_NOREORDER |
95             EF_MIPS_MICROMIPS | EF_MIPS_NAN2008 | EF_MIPS_32BITMODE);
96   return Ret;
97 }
98
99 static uint32_t getPicFlags(ArrayRef<FileFlags> Files) {
100   // Check PIC/non-PIC compatibility.
101   bool IsPic = Files[0].Flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
102   for (const FileFlags &F : Files.slice(1)) {
103     bool IsPic2 = F.Flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
104     if (IsPic && !IsPic2)
105       warn("linking abicalls code " + toString(Files[0].File) +
106            " with non-abicalls file: " + toString(F.File));
107     if (!IsPic && IsPic2)
108       warn("linking non-abicalls code " + toString(Files[0].File) +
109            " with abicalls file: " + toString(F.File));
110   }
111
112   // Compute the result PIC/non-PIC flag.
113   uint32_t Ret = Files[0].Flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
114   for (const FileFlags &F : Files.slice(1))
115     Ret &= F.Flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
116
117   // PIC code is inherently CPIC and may not set CPIC flag explicitly.
118   if (Ret & EF_MIPS_PIC)
119     Ret |= EF_MIPS_CPIC;
120   return Ret;
121 }
122
123 static ArchTreeEdge ArchTree[] = {
124     // MIPS32R6 and MIPS64R6 are not compatible with other extensions
125     // MIPS64R2 extensions.
126     {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON3, EF_MIPS_ARCH_64R2},
127     {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON2, EF_MIPS_ARCH_64R2},
128     {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON, EF_MIPS_ARCH_64R2},
129     {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_LS3A, EF_MIPS_ARCH_64R2},
130     // MIPS64 extensions.
131     {EF_MIPS_ARCH_64 | EF_MIPS_MACH_SB1, EF_MIPS_ARCH_64},
132     {EF_MIPS_ARCH_64 | EF_MIPS_MACH_XLR, EF_MIPS_ARCH_64},
133     {EF_MIPS_ARCH_64R2, EF_MIPS_ARCH_64},
134     // MIPS V extensions.
135     {EF_MIPS_ARCH_64, EF_MIPS_ARCH_5},
136     // R5000 extensions.
137     {EF_MIPS_ARCH_4 | EF_MIPS_MACH_5500, EF_MIPS_ARCH_4 | EF_MIPS_MACH_5400},
138     // MIPS IV extensions.
139     {EF_MIPS_ARCH_4 | EF_MIPS_MACH_5400, EF_MIPS_ARCH_4},
140     {EF_MIPS_ARCH_4 | EF_MIPS_MACH_9000, EF_MIPS_ARCH_4},
141     {EF_MIPS_ARCH_5, EF_MIPS_ARCH_4},
142     // VR4100 extensions.
143     {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4111, EF_MIPS_ARCH_3 | EF_MIPS_MACH_4100},
144     {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4120, EF_MIPS_ARCH_3 | EF_MIPS_MACH_4100},
145     // MIPS III extensions.
146     {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4010, EF_MIPS_ARCH_3},
147     {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4100, EF_MIPS_ARCH_3},
148     {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4650, EF_MIPS_ARCH_3},
149     {EF_MIPS_ARCH_3 | EF_MIPS_MACH_5900, EF_MIPS_ARCH_3},
150     {EF_MIPS_ARCH_3 | EF_MIPS_MACH_LS2E, EF_MIPS_ARCH_3},
151     {EF_MIPS_ARCH_3 | EF_MIPS_MACH_LS2F, EF_MIPS_ARCH_3},
152     {EF_MIPS_ARCH_4, EF_MIPS_ARCH_3},
153     // MIPS32 extensions.
154     {EF_MIPS_ARCH_32R2, EF_MIPS_ARCH_32},
155     // MIPS II extensions.
156     {EF_MIPS_ARCH_3, EF_MIPS_ARCH_2},
157     {EF_MIPS_ARCH_32, EF_MIPS_ARCH_2},
158     // MIPS I extensions.
159     {EF_MIPS_ARCH_1 | EF_MIPS_MACH_3900, EF_MIPS_ARCH_1},
160     {EF_MIPS_ARCH_2, EF_MIPS_ARCH_1},
161 };
162
163 static bool isArchMatched(uint32_t New, uint32_t Res) {
164   if (New == Res)
165     return true;
166   if (New == EF_MIPS_ARCH_32 && isArchMatched(EF_MIPS_ARCH_64, Res))
167     return true;
168   if (New == EF_MIPS_ARCH_32R2 && isArchMatched(EF_MIPS_ARCH_64R2, Res))
169     return true;
170   for (const auto &Edge : ArchTree) {
171     if (Res == Edge.Child) {
172       Res = Edge.Parent;
173       if (Res == New)
174         return true;
175     }
176   }
177   return false;
178 }
179
180 static StringRef getMachName(uint32_t Flags) {
181   switch (Flags & EF_MIPS_MACH) {
182   case EF_MIPS_MACH_NONE:
183     return "";
184   case EF_MIPS_MACH_3900:
185     return "r3900";
186   case EF_MIPS_MACH_4010:
187     return "r4010";
188   case EF_MIPS_MACH_4100:
189     return "r4100";
190   case EF_MIPS_MACH_4650:
191     return "r4650";
192   case EF_MIPS_MACH_4120:
193     return "r4120";
194   case EF_MIPS_MACH_4111:
195     return "r4111";
196   case EF_MIPS_MACH_5400:
197     return "vr5400";
198   case EF_MIPS_MACH_5900:
199     return "vr5900";
200   case EF_MIPS_MACH_5500:
201     return "vr5500";
202   case EF_MIPS_MACH_9000:
203     return "rm9000";
204   case EF_MIPS_MACH_LS2E:
205     return "loongson2e";
206   case EF_MIPS_MACH_LS2F:
207     return "loongson2f";
208   case EF_MIPS_MACH_LS3A:
209     return "loongson3a";
210   case EF_MIPS_MACH_OCTEON:
211     return "octeon";
212   case EF_MIPS_MACH_OCTEON2:
213     return "octeon2";
214   case EF_MIPS_MACH_OCTEON3:
215     return "octeon3";
216   case EF_MIPS_MACH_SB1:
217     return "sb1";
218   case EF_MIPS_MACH_XLR:
219     return "xlr";
220   default:
221     return "unknown machine";
222   }
223 }
224
225 static StringRef getArchName(uint32_t Flags) {
226   switch (Flags & EF_MIPS_ARCH) {
227   case EF_MIPS_ARCH_1:
228     return "mips1";
229   case EF_MIPS_ARCH_2:
230     return "mips2";
231   case EF_MIPS_ARCH_3:
232     return "mips3";
233   case EF_MIPS_ARCH_4:
234     return "mips4";
235   case EF_MIPS_ARCH_5:
236     return "mips5";
237   case EF_MIPS_ARCH_32:
238     return "mips32";
239   case EF_MIPS_ARCH_64:
240     return "mips64";
241   case EF_MIPS_ARCH_32R2:
242     return "mips32r2";
243   case EF_MIPS_ARCH_64R2:
244     return "mips64r2";
245   case EF_MIPS_ARCH_32R6:
246     return "mips32r6";
247   case EF_MIPS_ARCH_64R6:
248     return "mips64r6";
249   default:
250     return "unknown arch";
251   }
252 }
253
254 static std::string getFullArchName(uint32_t Flags) {
255   StringRef Arch = getArchName(Flags);
256   StringRef Mach = getMachName(Flags);
257   if (Mach.empty())
258     return Arch.str();
259   return (Arch + " (" + Mach + ")").str();
260 }
261
262 // There are (arguably too) many MIPS ISAs out there. Their relationships
263 // can be represented as a forest. If all input files have ISAs which
264 // reachable by repeated proceeding from the single child to the parent,
265 // these input files are compatible. In that case we need to return "highest"
266 // ISA. If there are incompatible input files, we show an error.
267 // For example, mips1 is a "parent" of mips2 and such files are compatible.
268 // Output file gets EF_MIPS_ARCH_2 flag. From the other side mips3 and mips32
269 // are incompatible because nor mips3 is a parent for misp32, nor mips32
270 // is a parent for mips3.
271 static uint32_t getArchFlags(ArrayRef<FileFlags> Files) {
272   uint32_t Ret = Files[0].Flags & (EF_MIPS_ARCH | EF_MIPS_MACH);
273
274   for (const FileFlags &F : Files.slice(1)) {
275     uint32_t New = F.Flags & (EF_MIPS_ARCH | EF_MIPS_MACH);
276
277     // Check ISA compatibility.
278     if (isArchMatched(New, Ret))
279       continue;
280     if (!isArchMatched(Ret, New)) {
281       error("incompatible target ISA:\n>>> " + toString(Files[0].File) + ": " +
282             getFullArchName(Ret) + "\n>>> " + toString(F.File) + ": " +
283             getFullArchName(New));
284       return 0;
285     }
286     Ret = New;
287   }
288   return Ret;
289 }
290
291 template <class ELFT> uint32_t elf::calcMipsEFlags() {
292   std::vector<FileFlags> V;
293   for (InputFile *F : ObjectFiles)
294     V.push_back({F, cast<ObjFile<ELFT>>(F)->getObj().getHeader()->e_flags});
295   if (V.empty())
296     return 0;
297   checkFlags(V);
298   return getMiscFlags(V) | getPicFlags(V) | getArchFlags(V);
299 }
300
301 static int compareMipsFpAbi(uint8_t FpA, uint8_t FpB) {
302   if (FpA == FpB)
303     return 0;
304   if (FpB == Mips::Val_GNU_MIPS_ABI_FP_ANY)
305     return 1;
306   if (FpB == Mips::Val_GNU_MIPS_ABI_FP_64A &&
307       FpA == Mips::Val_GNU_MIPS_ABI_FP_64)
308     return 1;
309   if (FpB != Mips::Val_GNU_MIPS_ABI_FP_XX)
310     return -1;
311   if (FpA == Mips::Val_GNU_MIPS_ABI_FP_DOUBLE ||
312       FpA == Mips::Val_GNU_MIPS_ABI_FP_64 ||
313       FpA == Mips::Val_GNU_MIPS_ABI_FP_64A)
314     return 1;
315   return -1;
316 }
317
318 static StringRef getMipsFpAbiName(uint8_t FpAbi) {
319   switch (FpAbi) {
320   case Mips::Val_GNU_MIPS_ABI_FP_ANY:
321     return "any";
322   case Mips::Val_GNU_MIPS_ABI_FP_DOUBLE:
323     return "-mdouble-float";
324   case Mips::Val_GNU_MIPS_ABI_FP_SINGLE:
325     return "-msingle-float";
326   case Mips::Val_GNU_MIPS_ABI_FP_SOFT:
327     return "-msoft-float";
328   case Mips::Val_GNU_MIPS_ABI_FP_OLD_64:
329     return "-mips32r2 -mfp64 (old)";
330   case Mips::Val_GNU_MIPS_ABI_FP_XX:
331     return "-mfpxx";
332   case Mips::Val_GNU_MIPS_ABI_FP_64:
333     return "-mgp32 -mfp64";
334   case Mips::Val_GNU_MIPS_ABI_FP_64A:
335     return "-mgp32 -mfp64 -mno-odd-spreg";
336   default:
337     return "unknown";
338   }
339 }
340
341 uint8_t elf::getMipsFpAbiFlag(uint8_t OldFlag, uint8_t NewFlag,
342                               StringRef FileName) {
343   if (compareMipsFpAbi(NewFlag, OldFlag) >= 0)
344     return NewFlag;
345   if (compareMipsFpAbi(OldFlag, NewFlag) < 0)
346     error("target floating point ABI '" + getMipsFpAbiName(OldFlag) +
347           "' is incompatible with '" + getMipsFpAbiName(NewFlag) +
348           "': " + FileName);
349   return OldFlag;
350 }
351
352 template <class ELFT> static bool isN32Abi(const InputFile *F) {
353   if (auto *EF = dyn_cast<ELFFileBase<ELFT>>(F))
354     return EF->getObj().getHeader()->e_flags & EF_MIPS_ABI2;
355   return false;
356 }
357
358 bool elf::isMipsN32Abi(const InputFile *F) {
359   switch (Config->EKind) {
360   case ELF32LEKind:
361     return isN32Abi<ELF32LE>(F);
362   case ELF32BEKind:
363     return isN32Abi<ELF32BE>(F);
364   case ELF64LEKind:
365     return isN32Abi<ELF64LE>(F);
366   case ELF64BEKind:
367     return isN32Abi<ELF64BE>(F);
368   default:
369     llvm_unreachable("unknown Config->EKind");
370   }
371 }
372
373 bool elf::isMicroMips() { return Config->EFlags & EF_MIPS_MICROMIPS; }
374
375 bool elf::isMipsR6() {
376   uint32_t Arch = Config->EFlags & EF_MIPS_ARCH;
377   return Arch == EF_MIPS_ARCH_32R6 || Arch == EF_MIPS_ARCH_64R6;
378 }
379
380 template uint32_t elf::calcMipsEFlags<ELF32LE>();
381 template uint32_t elf::calcMipsEFlags<ELF32BE>();
382 template uint32_t elf::calcMipsEFlags<ELF64LE>();
383 template uint32_t elf::calcMipsEFlags<ELF64BE>();