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"
17 #include "lld/Common/ErrorHandler.h"
18 #include "llvm/BinaryFormat/ELF.h"
19 #include "llvm/Support/MipsABIFlags.h"
22 using namespace llvm::object
;
23 using namespace llvm::ELF
;
26 using namespace lld::elf
;
40 static StringRef
getAbiName(uint32_t flags
) {
50 case EF_MIPS_ABI_EABI32
:
52 case EF_MIPS_ABI_EABI64
:
59 static StringRef
getNanName(bool isNan2008
) {
60 return isNan2008
? "2008" : "legacy";
63 static StringRef
getFpName(bool isFp64
) { return isFp64
? "64" : "32"; }
65 static void checkFlags(ArrayRef
<FileFlags
> files
) {
66 assert(!files
.empty() && "expected non-empty file list");
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
) {
73 if (config
->is64
&& f
.flags
& EF_MIPS_MICROMIPS
)
74 error(toString(f
.file
) + ": microMIPS 64-bit is not supported");
76 uint32_t abi2
= f
.flags
& (EF_MIPS_ABI
| EF_MIPS_ABI2
);
78 error(toString(f
.file
) + ": ABI '" + getAbiName(abi2
) +
79 "' is incompatible with target ABI '" + getAbiName(abi
) + "'");
81 bool nan2
= f
.flags
& EF_MIPS_NAN2008
;
83 error(toString(f
.file
) + ": -mnan=" + getNanName(nan2
) +
84 " is incompatible with target -mnan=" + getNanName(nan
));
86 bool fp2
= f
.flags
& EF_MIPS_FP64
;
88 error(toString(f
.file
) + ": -mfp" + getFpName(fp2
) +
89 " is incompatible with target -mfp" + getFpName(fp
));
93 static uint32_t getMiscFlags(ArrayRef
<FileFlags
> files
) {
95 for (const FileFlags
&f
: files
)
97 (EF_MIPS_ABI
| EF_MIPS_ABI2
| EF_MIPS_ARCH_ASE
| EF_MIPS_NOREORDER
|
98 EF_MIPS_MICROMIPS
| EF_MIPS_NAN2008
| EF_MIPS_32BITMODE
);
102 static uint32_t getPicFlags(ArrayRef
<FileFlags
> files
) {
103 // Check PIC/non-PIC compatibility.
104 bool isPic
= files
[0].flags
& (EF_MIPS_PIC
| EF_MIPS_CPIC
);
105 for (const FileFlags
&f
: files
.slice(1)) {
106 bool isPic2
= f
.flags
& (EF_MIPS_PIC
| EF_MIPS_CPIC
);
107 if (isPic
&& !isPic2
)
108 warn(toString(f
.file
) +
109 ": linking non-abicalls code with abicalls code " +
110 toString(files
[0].file
));
111 if (!isPic
&& isPic2
)
112 warn(toString(f
.file
) +
113 ": linking abicalls code with non-abicalls code " +
114 toString(files
[0].file
));
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(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 error("incompatible target ISA:\n>>> " + toString(files
[0].file
) + ": " +
287 getFullArchName(ret
) + "\n>>> " + toString(f
.file
) + ": " +
288 getFullArchName(newFlags
));
296 template <class ELFT
> uint32_t elf::calcMipsEFlags() {
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 (config
->emulation
.empty() || config
->is64
)
306 return config
->mipsN32Abi
? EF_MIPS_ABI2
: EF_MIPS_ABI_O32
;
309 return getMiscFlags(v
) | getPicFlags(v
) | getArchFlags(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(uint8_t oldFlag
, uint8_t newFlag
,
353 StringRef fileName
) {
354 if (compareMipsFpAbi(newFlag
, oldFlag
) >= 0)
356 if (compareMipsFpAbi(oldFlag
, newFlag
) < 0)
357 error(fileName
+ ": 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(const InputFile
*f
) {
370 switch (config
->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 Config->EKind");
384 bool elf::isMicroMips() { return config
->eflags
& EF_MIPS_MICROMIPS
; }
386 bool elf::isMipsR6() {
387 uint32_t arch
= config
->eflags
& EF_MIPS_ARCH
;
388 return arch
== EF_MIPS_ARCH_32R6
|| arch
== EF_MIPS_ARCH_64R6
;
391 template uint32_t elf::calcMipsEFlags
<ELF32LE
>();
392 template uint32_t elf::calcMipsEFlags
<ELF32BE
>();
393 template uint32_t elf::calcMipsEFlags
<ELF64LE
>();
394 template uint32_t elf::calcMipsEFlags
<ELF64BE
>();