1 //===- MipsArchTree.cpp --------------------------------------------------===//
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===---------------------------------------------------------------------===//
10 // This file contains a helper function for the Writer.
12 //===---------------------------------------------------------------------===//
14 #include "InputFiles.h"
15 #include "SymbolTable.h"
18 #include "lld/Common/ErrorHandler.h"
19 #include "llvm/BinaryFormat/ELF.h"
20 #include "llvm/Object/ELF.h"
21 #include "llvm/Support/MipsABIFlags.h"
24 using namespace llvm::object;
25 using namespace llvm::ELF;
28 using namespace lld::elf;
42 static StringRef getAbiName(uint32_t Flags) {
52 case EF_MIPS_ABI_EABI32:
54 case EF_MIPS_ABI_EABI64:
61 static StringRef getNanName(bool IsNan2008) {
62 return IsNan2008 ? "2008" : "legacy";
65 static StringRef getFpName(bool IsFp64) { return IsFp64 ? "64" : "32"; }
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;
72 for (const FileFlags &F : Files.slice(1)) {
73 uint32_t ABI2 = F.Flags & (EF_MIPS_ABI | EF_MIPS_ABI2);
75 error("target ABI '" + getAbiName(ABI) + "' is incompatible with '" +
76 getAbiName(ABI2) + "': " + toString(F.File));
78 bool Nan2 = F.Flags & EF_MIPS_NAN2008;
80 error("target -mnan=" + getNanName(Nan) + " is incompatible with -mnan=" +
81 getNanName(Nan2) + ": " + toString(F.File));
83 bool Fp2 = F.Flags & EF_MIPS_FP64;
85 error("target -mfp" + getFpName(Fp) + " is incompatible with -mfp" +
86 getFpName(Fp2) + ": " + toString(F.File));
90 static uint32_t getMiscFlags(ArrayRef<FileFlags> Files) {
92 for (const FileFlags &F : Files)
94 (EF_MIPS_ABI | EF_MIPS_ABI2 | EF_MIPS_ARCH_ASE | EF_MIPS_NOREORDER |
95 EF_MIPS_MICROMIPS | EF_MIPS_NAN2008 | EF_MIPS_32BITMODE);
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));
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);
117 // PIC code is inherently CPIC and may not set CPIC flag explicitly.
118 if (Ret & EF_MIPS_PIC)
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},
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},
163 static bool isArchMatched(uint32_t New, uint32_t Res) {
166 if (New == EF_MIPS_ARCH_32 && isArchMatched(EF_MIPS_ARCH_64, Res))
168 if (New == EF_MIPS_ARCH_32R2 && isArchMatched(EF_MIPS_ARCH_64R2, Res))
170 for (const auto &Edge : ArchTree) {
171 if (Res == Edge.Child) {
180 static StringRef getMachName(uint32_t Flags) {
181 switch (Flags & EF_MIPS_MACH) {
182 case EF_MIPS_MACH_NONE:
184 case EF_MIPS_MACH_3900:
186 case EF_MIPS_MACH_4010:
188 case EF_MIPS_MACH_4100:
190 case EF_MIPS_MACH_4650:
192 case EF_MIPS_MACH_4120:
194 case EF_MIPS_MACH_4111:
196 case EF_MIPS_MACH_5400:
198 case EF_MIPS_MACH_5900:
200 case EF_MIPS_MACH_5500:
202 case EF_MIPS_MACH_9000:
204 case EF_MIPS_MACH_LS2E:
206 case EF_MIPS_MACH_LS2F:
208 case EF_MIPS_MACH_LS3A:
210 case EF_MIPS_MACH_OCTEON:
212 case EF_MIPS_MACH_OCTEON2:
214 case EF_MIPS_MACH_OCTEON3:
216 case EF_MIPS_MACH_SB1:
218 case EF_MIPS_MACH_XLR:
221 return "unknown machine";
225 static StringRef getArchName(uint32_t Flags) {
226 switch (Flags & EF_MIPS_ARCH) {
237 case EF_MIPS_ARCH_32:
239 case EF_MIPS_ARCH_64:
241 case EF_MIPS_ARCH_32R2:
243 case EF_MIPS_ARCH_64R2:
245 case EF_MIPS_ARCH_32R6:
247 case EF_MIPS_ARCH_64R6:
250 return "unknown arch";
254 static std::string getFullArchName(uint32_t Flags) {
255 StringRef Arch = getArchName(Flags);
256 StringRef Mach = getMachName(Flags);
259 return (Arch + " (" + Mach + ")").str();
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);
274 for (const FileFlags &F : Files.slice(1)) {
275 uint32_t New = F.Flags & (EF_MIPS_ARCH | EF_MIPS_MACH);
277 // Check ISA compatibility.
278 if (isArchMatched(New, Ret))
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));
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});
298 return getMiscFlags(V) | getPicFlags(V) | getArchFlags(V);
301 static int compareMipsFpAbi(uint8_t FpA, uint8_t FpB) {
304 if (FpB == Mips::Val_GNU_MIPS_ABI_FP_ANY)
306 if (FpB == Mips::Val_GNU_MIPS_ABI_FP_64A &&
307 FpA == Mips::Val_GNU_MIPS_ABI_FP_64)
309 if (FpB != Mips::Val_GNU_MIPS_ABI_FP_XX)
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)
318 static StringRef getMipsFpAbiName(uint8_t FpAbi) {
320 case Mips::Val_GNU_MIPS_ABI_FP_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:
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";
341 uint8_t elf::getMipsFpAbiFlag(uint8_t OldFlag, uint8_t NewFlag,
342 StringRef FileName) {
343 if (compareMipsFpAbi(NewFlag, OldFlag) >= 0)
345 if (compareMipsFpAbi(OldFlag, NewFlag) < 0)
346 error("target floating point ABI '" + getMipsFpAbiName(OldFlag) +
347 "' is incompatible with '" + getMipsFpAbiName(NewFlag) +
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;
358 bool elf::isMipsN32Abi(const InputFile *F) {
359 switch (Config->EKind) {
361 return isN32Abi<ELF32LE>(F);
363 return isN32Abi<ELF32BE>(F);
365 return isN32Abi<ELF64LE>(F);
367 return isN32Abi<ELF64BE>(F);
369 llvm_unreachable("unknown Config->EKind");
373 bool elf::isMicroMips() { return Config->EFlags & EF_MIPS_MICROMIPS; }
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;
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>();