1 //===- MipsArchTree.cpp --------------------------------------------------===//
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 // This file contains a helper function for the Writer.
11 //===---------------------------------------------------------------------===//
13 #include "InputFiles.h"
14 #include "SymbolTable.h"
18 #include "lld/Common/ErrorHandler.h"
19 #include "llvm/BinaryFormat/ELF.h"
20 #include "llvm/Support/MipsABIFlags.h"
23 using namespace llvm::object
;
24 using namespace llvm::ELF
;
27 using namespace lld::elf
;
41 static StringRef
getAbiName(uint32_t flags
) {
51 case EF_MIPS_ABI_EABI32
:
53 case EF_MIPS_ABI_EABI64
:
60 static StringRef
getNanName(bool isNan2008
) {
61 return isNan2008
? "2008" : "legacy";
64 static StringRef
getFpName(bool isFp64
) { return isFp64
? "64" : "32"; }
66 static void checkFlags(Ctx
&ctx
, ArrayRef
<FileFlags
> files
) {
67 assert(!files
.empty() && "expected non-empty file list");
69 uint32_t abi
= files
[0].flags
& (EF_MIPS_ABI
| EF_MIPS_ABI2
);
70 bool nan
= files
[0].flags
& EF_MIPS_NAN2008
;
71 bool fp
= files
[0].flags
& EF_MIPS_FP64
;
73 for (const FileFlags
&f
: files
) {
74 if (ctx
.arg
.is64
&& f
.flags
& EF_MIPS_MICROMIPS
)
75 Err(ctx
) << f
.file
<< ": microMIPS 64-bit is not supported";
77 uint32_t abi2
= f
.flags
& (EF_MIPS_ABI
| EF_MIPS_ABI2
);
79 Err(ctx
) << f
.file
<< ": ABI '" << getAbiName(abi2
)
80 << "' is incompatible with target ABI '" << getAbiName(abi
)
83 bool nan2
= f
.flags
& EF_MIPS_NAN2008
;
85 Err(ctx
) << f
.file
<< ": -mnan=" << getNanName(nan2
)
86 << " is incompatible with target -mnan=" << getNanName(nan
);
88 bool fp2
= f
.flags
& EF_MIPS_FP64
;
90 Err(ctx
) << f
.file
<< ": -mfp" << getFpName(fp2
)
91 << " is incompatible with target -mfp" << getFpName(fp
);
95 static uint32_t getMiscFlags(ArrayRef
<FileFlags
> files
) {
97 for (const FileFlags
&f
: files
)
99 (EF_MIPS_ABI
| EF_MIPS_ABI2
| EF_MIPS_ARCH_ASE
| EF_MIPS_NOREORDER
|
100 EF_MIPS_MICROMIPS
| EF_MIPS_NAN2008
| EF_MIPS_32BITMODE
);
104 static uint32_t getPicFlags(Ctx
&ctx
, ArrayRef
<FileFlags
> files
) {
105 // Check PIC/non-PIC compatibility.
106 bool isPic
= files
[0].flags
& (EF_MIPS_PIC
| EF_MIPS_CPIC
);
107 for (const FileFlags
&f
: files
.slice(1)) {
108 bool isPic2
= f
.flags
& (EF_MIPS_PIC
| EF_MIPS_CPIC
);
109 if (isPic
&& !isPic2
)
110 Warn(ctx
) << f
.file
<< ": linking non-abicalls code with abicalls code "
112 if (!isPic
&& isPic2
)
113 Warn(ctx
) << f
.file
<< ": linking abicalls code with non-abicalls code "
117 // Compute the result PIC/non-PIC flag.
118 uint32_t ret
= files
[0].flags
& (EF_MIPS_PIC
| EF_MIPS_CPIC
);
119 for (const FileFlags
&f
: files
.slice(1))
120 ret
&= f
.flags
& (EF_MIPS_PIC
| EF_MIPS_CPIC
);
122 // PIC code is inherently CPIC and may not set CPIC flag explicitly.
123 if (ret
& EF_MIPS_PIC
)
128 static ArchTreeEdge archTree
[] = {
129 // MIPS32R6 and MIPS64R6 are not compatible with other extensions
130 // MIPS64R2 extensions.
131 {EF_MIPS_ARCH_64R2
| EF_MIPS_MACH_OCTEON3
, EF_MIPS_ARCH_64R2
},
132 {EF_MIPS_ARCH_64R2
| EF_MIPS_MACH_OCTEON2
, EF_MIPS_ARCH_64R2
},
133 {EF_MIPS_ARCH_64R2
| EF_MIPS_MACH_OCTEON
, EF_MIPS_ARCH_64R2
},
134 {EF_MIPS_ARCH_64R2
| EF_MIPS_MACH_LS3A
, EF_MIPS_ARCH_64R2
},
135 // MIPS64 extensions.
136 {EF_MIPS_ARCH_64
| EF_MIPS_MACH_SB1
, EF_MIPS_ARCH_64
},
137 {EF_MIPS_ARCH_64
| EF_MIPS_MACH_XLR
, EF_MIPS_ARCH_64
},
138 {EF_MIPS_ARCH_64R2
, EF_MIPS_ARCH_64
},
139 // MIPS V extensions.
140 {EF_MIPS_ARCH_64
, EF_MIPS_ARCH_5
},
142 {EF_MIPS_ARCH_4
| EF_MIPS_MACH_5500
, EF_MIPS_ARCH_4
| EF_MIPS_MACH_5400
},
143 // MIPS IV extensions.
144 {EF_MIPS_ARCH_4
| EF_MIPS_MACH_5400
, EF_MIPS_ARCH_4
},
145 {EF_MIPS_ARCH_4
| EF_MIPS_MACH_9000
, EF_MIPS_ARCH_4
},
146 {EF_MIPS_ARCH_5
, EF_MIPS_ARCH_4
},
147 // VR4100 extensions.
148 {EF_MIPS_ARCH_3
| EF_MIPS_MACH_4111
, EF_MIPS_ARCH_3
| EF_MIPS_MACH_4100
},
149 {EF_MIPS_ARCH_3
| EF_MIPS_MACH_4120
, EF_MIPS_ARCH_3
| EF_MIPS_MACH_4100
},
150 // MIPS III extensions.
151 {EF_MIPS_ARCH_3
| EF_MIPS_MACH_4010
, EF_MIPS_ARCH_3
},
152 {EF_MIPS_ARCH_3
| EF_MIPS_MACH_4100
, EF_MIPS_ARCH_3
},
153 {EF_MIPS_ARCH_3
| EF_MIPS_MACH_4650
, EF_MIPS_ARCH_3
},
154 {EF_MIPS_ARCH_3
| EF_MIPS_MACH_5900
, EF_MIPS_ARCH_3
},
155 {EF_MIPS_ARCH_3
| EF_MIPS_MACH_LS2E
, EF_MIPS_ARCH_3
},
156 {EF_MIPS_ARCH_3
| EF_MIPS_MACH_LS2F
, EF_MIPS_ARCH_3
},
157 {EF_MIPS_ARCH_4
, EF_MIPS_ARCH_3
},
158 // MIPS32 extensions.
159 {EF_MIPS_ARCH_32R2
, EF_MIPS_ARCH_32
},
160 // MIPS II extensions.
161 {EF_MIPS_ARCH_3
, EF_MIPS_ARCH_2
},
162 {EF_MIPS_ARCH_32
, EF_MIPS_ARCH_2
},
163 // MIPS I extensions.
164 {EF_MIPS_ARCH_1
| EF_MIPS_MACH_3900
, EF_MIPS_ARCH_1
},
165 {EF_MIPS_ARCH_2
, EF_MIPS_ARCH_1
},
168 static bool isArchMatched(uint32_t newFlags
, uint32_t res
) {
171 if (newFlags
== EF_MIPS_ARCH_32
&& isArchMatched(EF_MIPS_ARCH_64
, res
))
173 if (newFlags
== EF_MIPS_ARCH_32R2
&& isArchMatched(EF_MIPS_ARCH_64R2
, res
))
175 for (const auto &edge
: archTree
) {
176 if (res
== edge
.child
) {
185 static StringRef
getMachName(uint32_t flags
) {
186 switch (flags
& EF_MIPS_MACH
) {
187 case EF_MIPS_MACH_NONE
:
189 case EF_MIPS_MACH_3900
:
191 case EF_MIPS_MACH_4010
:
193 case EF_MIPS_MACH_4100
:
195 case EF_MIPS_MACH_4650
:
197 case EF_MIPS_MACH_4120
:
199 case EF_MIPS_MACH_4111
:
201 case EF_MIPS_MACH_5400
:
203 case EF_MIPS_MACH_5900
:
205 case EF_MIPS_MACH_5500
:
207 case EF_MIPS_MACH_9000
:
209 case EF_MIPS_MACH_LS2E
:
211 case EF_MIPS_MACH_LS2F
:
213 case EF_MIPS_MACH_LS3A
:
215 case EF_MIPS_MACH_OCTEON
:
217 case EF_MIPS_MACH_OCTEON2
:
219 case EF_MIPS_MACH_OCTEON3
:
221 case EF_MIPS_MACH_SB1
:
223 case EF_MIPS_MACH_XLR
:
226 return "unknown machine";
230 static StringRef
getArchName(uint32_t flags
) {
231 switch (flags
& EF_MIPS_ARCH
) {
242 case EF_MIPS_ARCH_32
:
244 case EF_MIPS_ARCH_64
:
246 case EF_MIPS_ARCH_32R2
:
248 case EF_MIPS_ARCH_64R2
:
250 case EF_MIPS_ARCH_32R6
:
252 case EF_MIPS_ARCH_64R6
:
255 return "unknown arch";
259 static std::string
getFullArchName(uint32_t flags
) {
260 StringRef arch
= getArchName(flags
);
261 StringRef mach
= getMachName(flags
);
264 return (arch
+ " (" + mach
+ ")").str();
267 // There are (arguably too) many MIPS ISAs out there. Their relationships
268 // can be represented as a forest. If all input files have ISAs which
269 // reachable by repeated proceeding from the single child to the parent,
270 // these input files are compatible. In that case we need to return "highest"
271 // ISA. If there are incompatible input files, we show an error.
272 // For example, mips1 is a "parent" of mips2 and such files are compatible.
273 // Output file gets EF_MIPS_ARCH_2 flag. From the other side mips3 and mips32
274 // are incompatible because nor mips3 is a parent for misp32, nor mips32
275 // is a parent for mips3.
276 static uint32_t getArchFlags(Ctx
&ctx
, ArrayRef
<FileFlags
> files
) {
277 uint32_t ret
= files
[0].flags
& (EF_MIPS_ARCH
| EF_MIPS_MACH
);
279 for (const FileFlags
&f
: files
.slice(1)) {
280 uint32_t newFlags
= f
.flags
& (EF_MIPS_ARCH
| EF_MIPS_MACH
);
282 // Check ISA compatibility.
283 if (isArchMatched(newFlags
, ret
))
285 if (!isArchMatched(ret
, newFlags
)) {
286 Err(ctx
) << "incompatible target ISA:\n>>> " << files
[0].file
<< ": "
287 << getFullArchName(ret
) << "\n>>> " << f
.file
<< ": "
288 << getFullArchName(newFlags
);
296 template <class ELFT
> uint32_t elf::calcMipsEFlags(Ctx
&ctx
) {
297 std::vector
<FileFlags
> v
;
298 for (InputFile
*f
: ctx
.objectFiles
)
299 v
.push_back({f
, cast
<ObjFile
<ELFT
>>(f
)->getObj().getHeader().e_flags
});
301 // If we don't have any input files, we'll have to rely on the information
302 // we can derive from emulation information, since this at least gets us
304 if (ctx
.arg
.emulation
.empty() || ctx
.arg
.is64
)
306 return ctx
.arg
.mipsN32Abi
? EF_MIPS_ABI2
: EF_MIPS_ABI_O32
;
309 return getMiscFlags(v
) | getPicFlags(ctx
, v
) | getArchFlags(ctx
, v
);
312 static int compareMipsFpAbi(uint8_t fpA
, uint8_t fpB
) {
315 if (fpB
== Mips::Val_GNU_MIPS_ABI_FP_ANY
)
317 if (fpB
== Mips::Val_GNU_MIPS_ABI_FP_64A
&&
318 fpA
== Mips::Val_GNU_MIPS_ABI_FP_64
)
320 if (fpB
!= Mips::Val_GNU_MIPS_ABI_FP_XX
)
322 if (fpA
== Mips::Val_GNU_MIPS_ABI_FP_DOUBLE
||
323 fpA
== Mips::Val_GNU_MIPS_ABI_FP_64
||
324 fpA
== Mips::Val_GNU_MIPS_ABI_FP_64A
)
329 static StringRef
getMipsFpAbiName(uint8_t fpAbi
) {
331 case Mips::Val_GNU_MIPS_ABI_FP_ANY
:
333 case Mips::Val_GNU_MIPS_ABI_FP_DOUBLE
:
334 return "-mdouble-float";
335 case Mips::Val_GNU_MIPS_ABI_FP_SINGLE
:
336 return "-msingle-float";
337 case Mips::Val_GNU_MIPS_ABI_FP_SOFT
:
338 return "-msoft-float";
339 case Mips::Val_GNU_MIPS_ABI_FP_OLD_64
:
340 return "-mgp32 -mfp64 (old)";
341 case Mips::Val_GNU_MIPS_ABI_FP_XX
:
343 case Mips::Val_GNU_MIPS_ABI_FP_64
:
344 return "-mgp32 -mfp64";
345 case Mips::Val_GNU_MIPS_ABI_FP_64A
:
346 return "-mgp32 -mfp64 -mno-odd-spreg";
352 uint8_t elf::getMipsFpAbiFlag(Ctx
&ctx
, InputFile
*file
, uint8_t oldFlag
,
354 if (compareMipsFpAbi(newFlag
, oldFlag
) >= 0)
356 if (compareMipsFpAbi(oldFlag
, newFlag
) < 0)
357 Err(ctx
) << file
<< ": floating point ABI '" << getMipsFpAbiName(newFlag
)
358 << "' is incompatible with target floating point ABI '"
359 << getMipsFpAbiName(oldFlag
) << "'";
363 template <class ELFT
> static bool isN32Abi(const InputFile
&f
) {
364 if (auto *ef
= dyn_cast
<ELFFileBase
>(&f
))
365 return ef
->template getObj
<ELFT
>().getHeader().e_flags
& EF_MIPS_ABI2
;
369 bool elf::isMipsN32Abi(Ctx
&ctx
, const InputFile
&f
) {
370 switch (ctx
.arg
.ekind
) {
372 return isN32Abi
<ELF32LE
>(f
);
374 return isN32Abi
<ELF32BE
>(f
);
376 return isN32Abi
<ELF64LE
>(f
);
378 return isN32Abi
<ELF64BE
>(f
);
380 llvm_unreachable("unknown ctx.arg.ekind");
384 bool elf::isMicroMips(Ctx
&ctx
) { return ctx
.arg
.eflags
& EF_MIPS_MICROMIPS
; }
386 bool elf::isMipsR6(Ctx
&ctx
) {
387 uint32_t arch
= ctx
.arg
.eflags
& EF_MIPS_ARCH
;
388 return arch
== EF_MIPS_ARCH_32R6
|| arch
== EF_MIPS_ARCH_64R6
;
391 template uint32_t elf::calcMipsEFlags
<ELF32LE
>(Ctx
&);
392 template uint32_t elf::calcMipsEFlags
<ELF32BE
>(Ctx
&);
393 template uint32_t elf::calcMipsEFlags
<ELF64LE
>(Ctx
&);
394 template uint32_t elf::calcMipsEFlags
<ELF64BE
>(Ctx
&);