diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2020-01-16 13:09:45 -0500 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2020-01-16 13:09:45 -0500 |
| commit | ba4cc03b4f0d71ac3e0147aa3dde449299ce8cd5 (patch) | |
| tree | 88e0c274db5c1c943944c565833bea103692a556 /deps/lld/ELF/Arch/MipsArchTree.cpp | |
| parent | fbe6af81fdb1b964bb0c28f51de2458800b8274c (diff) | |
| download | zig-ba4cc03b4f0d71ac3e0147aa3dde449299ce8cd5.tar.gz zig-ba4cc03b4f0d71ac3e0147aa3dde449299ce8cd5.zip | |
remove embedded LLD
we no longer have any patches against upstream LLD
Diffstat (limited to 'deps/lld/ELF/Arch/MipsArchTree.cpp')
| -rw-r--r-- | deps/lld/ELF/Arch/MipsArchTree.cpp | 389 |
1 files changed, 0 insertions, 389 deletions
diff --git a/deps/lld/ELF/Arch/MipsArchTree.cpp b/deps/lld/ELF/Arch/MipsArchTree.cpp deleted file mode 100644 index f64d037564..0000000000 --- a/deps/lld/ELF/Arch/MipsArchTree.cpp +++ /dev/null @@ -1,389 +0,0 @@ -//===- MipsArchTree.cpp --------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===---------------------------------------------------------------------===// -// -// This file contains a helper function for the Writer. -// -//===---------------------------------------------------------------------===// - -#include "InputFiles.h" -#include "SymbolTable.h" -#include "Writer.h" - -#include "lld/Common/ErrorHandler.h" -#include "llvm/BinaryFormat/ELF.h" -#include "llvm/Object/ELF.h" -#include "llvm/Support/MipsABIFlags.h" - -using namespace llvm; -using namespace llvm::object; -using namespace llvm::ELF; - -using namespace lld; -using namespace lld::elf; - -namespace { -struct ArchTreeEdge { - uint32_t child; - uint32_t parent; -}; - -struct FileFlags { - InputFile *file; - uint32_t flags; -}; -} // namespace - -static StringRef getAbiName(uint32_t flags) { - switch (flags) { - case 0: - return "n64"; - case EF_MIPS_ABI2: - return "n32"; - case EF_MIPS_ABI_O32: - return "o32"; - case EF_MIPS_ABI_O64: - return "o64"; - case EF_MIPS_ABI_EABI32: - return "eabi32"; - case EF_MIPS_ABI_EABI64: - return "eabi64"; - default: - return "unknown"; - } -} - -static StringRef getNanName(bool isNan2008) { - return isNan2008 ? "2008" : "legacy"; -} - -static StringRef getFpName(bool isFp64) { return isFp64 ? "64" : "32"; } - -static void checkFlags(ArrayRef<FileFlags> files) { - assert(!files.empty() && "expected non-empty file list"); - - uint32_t abi = files[0].flags & (EF_MIPS_ABI | EF_MIPS_ABI2); - bool nan = files[0].flags & EF_MIPS_NAN2008; - bool fp = files[0].flags & EF_MIPS_FP64; - - for (const FileFlags &f : files) { - if (config->is64 && f.flags & EF_MIPS_MICROMIPS) - error(toString(f.file) + ": microMIPS 64-bit is not supported"); - - uint32_t abi2 = f.flags & (EF_MIPS_ABI | EF_MIPS_ABI2); - if (abi != abi2) - error(toString(f.file) + ": ABI '" + getAbiName(abi2) + - "' is incompatible with target ABI '" + getAbiName(abi) + "'"); - - bool nan2 = f.flags & EF_MIPS_NAN2008; - if (nan != nan2) - error(toString(f.file) + ": -mnan=" + getNanName(nan2) + - " is incompatible with target -mnan=" + getNanName(nan)); - - bool fp2 = f.flags & EF_MIPS_FP64; - if (fp != fp2) - error(toString(f.file) + ": -mfp" + getFpName(fp2) + - " is incompatible with target -mfp" + getFpName(fp)); - } -} - -static uint32_t getMiscFlags(ArrayRef<FileFlags> files) { - uint32_t ret = 0; - for (const FileFlags &f : files) - ret |= f.flags & - (EF_MIPS_ABI | EF_MIPS_ABI2 | EF_MIPS_ARCH_ASE | EF_MIPS_NOREORDER | - EF_MIPS_MICROMIPS | EF_MIPS_NAN2008 | EF_MIPS_32BITMODE); - return ret; -} - -static uint32_t getPicFlags(ArrayRef<FileFlags> files) { - // Check PIC/non-PIC compatibility. - bool isPic = files[0].flags & (EF_MIPS_PIC | EF_MIPS_CPIC); - for (const FileFlags &f : files.slice(1)) { - bool isPic2 = f.flags & (EF_MIPS_PIC | EF_MIPS_CPIC); - if (isPic && !isPic2) - warn(toString(f.file) + - ": linking non-abicalls code with abicalls code " + - toString(files[0].file)); - if (!isPic && isPic2) - warn(toString(f.file) + - ": linking abicalls code with non-abicalls code " + - toString(files[0].file)); - } - - // Compute the result PIC/non-PIC flag. - uint32_t ret = files[0].flags & (EF_MIPS_PIC | EF_MIPS_CPIC); - for (const FileFlags &f : files.slice(1)) - ret &= f.flags & (EF_MIPS_PIC | EF_MIPS_CPIC); - - // PIC code is inherently CPIC and may not set CPIC flag explicitly. - if (ret & EF_MIPS_PIC) - ret |= EF_MIPS_CPIC; - return ret; -} - -static ArchTreeEdge archTree[] = { - // MIPS32R6 and MIPS64R6 are not compatible with other extensions - // MIPS64R2 extensions. - {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON3, EF_MIPS_ARCH_64R2}, - {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON2, EF_MIPS_ARCH_64R2}, - {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON, EF_MIPS_ARCH_64R2}, - {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_LS3A, EF_MIPS_ARCH_64R2}, - // MIPS64 extensions. - {EF_MIPS_ARCH_64 | EF_MIPS_MACH_SB1, EF_MIPS_ARCH_64}, - {EF_MIPS_ARCH_64 | EF_MIPS_MACH_XLR, EF_MIPS_ARCH_64}, - {EF_MIPS_ARCH_64R2, EF_MIPS_ARCH_64}, - // MIPS V extensions. - {EF_MIPS_ARCH_64, EF_MIPS_ARCH_5}, - // R5000 extensions. - {EF_MIPS_ARCH_4 | EF_MIPS_MACH_5500, EF_MIPS_ARCH_4 | EF_MIPS_MACH_5400}, - // MIPS IV extensions. - {EF_MIPS_ARCH_4 | EF_MIPS_MACH_5400, EF_MIPS_ARCH_4}, - {EF_MIPS_ARCH_4 | EF_MIPS_MACH_9000, EF_MIPS_ARCH_4}, - {EF_MIPS_ARCH_5, EF_MIPS_ARCH_4}, - // VR4100 extensions. - {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4111, EF_MIPS_ARCH_3 | EF_MIPS_MACH_4100}, - {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4120, EF_MIPS_ARCH_3 | EF_MIPS_MACH_4100}, - // MIPS III extensions. - {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4010, EF_MIPS_ARCH_3}, - {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4100, EF_MIPS_ARCH_3}, - {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4650, EF_MIPS_ARCH_3}, - {EF_MIPS_ARCH_3 | EF_MIPS_MACH_5900, EF_MIPS_ARCH_3}, - {EF_MIPS_ARCH_3 | EF_MIPS_MACH_LS2E, EF_MIPS_ARCH_3}, - {EF_MIPS_ARCH_3 | EF_MIPS_MACH_LS2F, EF_MIPS_ARCH_3}, - {EF_MIPS_ARCH_4, EF_MIPS_ARCH_3}, - // MIPS32 extensions. - {EF_MIPS_ARCH_32R2, EF_MIPS_ARCH_32}, - // MIPS II extensions. - {EF_MIPS_ARCH_3, EF_MIPS_ARCH_2}, - {EF_MIPS_ARCH_32, EF_MIPS_ARCH_2}, - // MIPS I extensions. - {EF_MIPS_ARCH_1 | EF_MIPS_MACH_3900, EF_MIPS_ARCH_1}, - {EF_MIPS_ARCH_2, EF_MIPS_ARCH_1}, -}; - -static bool isArchMatched(uint32_t New, uint32_t res) { - if (New == res) - return true; - if (New == EF_MIPS_ARCH_32 && isArchMatched(EF_MIPS_ARCH_64, res)) - return true; - if (New == EF_MIPS_ARCH_32R2 && isArchMatched(EF_MIPS_ARCH_64R2, res)) - return true; - for (const auto &edge : archTree) { - if (res == edge.child) { - res = edge.parent; - if (res == New) - return true; - } - } - return false; -} - -static StringRef getMachName(uint32_t flags) { - switch (flags & EF_MIPS_MACH) { - case EF_MIPS_MACH_NONE: - return ""; - case EF_MIPS_MACH_3900: - return "r3900"; - case EF_MIPS_MACH_4010: - return "r4010"; - case EF_MIPS_MACH_4100: - return "r4100"; - case EF_MIPS_MACH_4650: - return "r4650"; - case EF_MIPS_MACH_4120: - return "r4120"; - case EF_MIPS_MACH_4111: - return "r4111"; - case EF_MIPS_MACH_5400: - return "vr5400"; - case EF_MIPS_MACH_5900: - return "vr5900"; - case EF_MIPS_MACH_5500: - return "vr5500"; - case EF_MIPS_MACH_9000: - return "rm9000"; - case EF_MIPS_MACH_LS2E: - return "loongson2e"; - case EF_MIPS_MACH_LS2F: - return "loongson2f"; - case EF_MIPS_MACH_LS3A: - return "loongson3a"; - case EF_MIPS_MACH_OCTEON: - return "octeon"; - case EF_MIPS_MACH_OCTEON2: - return "octeon2"; - case EF_MIPS_MACH_OCTEON3: - return "octeon3"; - case EF_MIPS_MACH_SB1: - return "sb1"; - case EF_MIPS_MACH_XLR: - return "xlr"; - default: - return "unknown machine"; - } -} - -static StringRef getArchName(uint32_t flags) { - switch (flags & EF_MIPS_ARCH) { - case EF_MIPS_ARCH_1: - return "mips1"; - case EF_MIPS_ARCH_2: - return "mips2"; - case EF_MIPS_ARCH_3: - return "mips3"; - case EF_MIPS_ARCH_4: - return "mips4"; - case EF_MIPS_ARCH_5: - return "mips5"; - case EF_MIPS_ARCH_32: - return "mips32"; - case EF_MIPS_ARCH_64: - return "mips64"; - case EF_MIPS_ARCH_32R2: - return "mips32r2"; - case EF_MIPS_ARCH_64R2: - return "mips64r2"; - case EF_MIPS_ARCH_32R6: - return "mips32r6"; - case EF_MIPS_ARCH_64R6: - return "mips64r6"; - default: - return "unknown arch"; - } -} - -static std::string getFullArchName(uint32_t flags) { - StringRef arch = getArchName(flags); - StringRef mach = getMachName(flags); - if (mach.empty()) - return arch.str(); - return (arch + " (" + mach + ")").str(); -} - -// There are (arguably too) many MIPS ISAs out there. Their relationships -// can be represented as a forest. If all input files have ISAs which -// reachable by repeated proceeding from the single child to the parent, -// these input files are compatible. In that case we need to return "highest" -// ISA. If there are incompatible input files, we show an error. -// For example, mips1 is a "parent" of mips2 and such files are compatible. -// Output file gets EF_MIPS_ARCH_2 flag. From the other side mips3 and mips32 -// are incompatible because nor mips3 is a parent for misp32, nor mips32 -// is a parent for mips3. -static uint32_t getArchFlags(ArrayRef<FileFlags> files) { - uint32_t ret = files[0].flags & (EF_MIPS_ARCH | EF_MIPS_MACH); - - for (const FileFlags &f : files.slice(1)) { - uint32_t New = f.flags & (EF_MIPS_ARCH | EF_MIPS_MACH); - - // Check ISA compatibility. - if (isArchMatched(New, ret)) - continue; - if (!isArchMatched(ret, New)) { - error("incompatible target ISA:\n>>> " + toString(files[0].file) + ": " + - getFullArchName(ret) + "\n>>> " + toString(f.file) + ": " + - getFullArchName(New)); - return 0; - } - ret = New; - } - return ret; -} - -template <class ELFT> uint32_t elf::calcMipsEFlags() { - std::vector<FileFlags> v; - for (InputFile *f : objectFiles) - v.push_back({f, cast<ObjFile<ELFT>>(f)->getObj().getHeader()->e_flags}); - if (v.empty()) - return 0; - checkFlags(v); - return getMiscFlags(v) | getPicFlags(v) | getArchFlags(v); -} - -static int compareMipsFpAbi(uint8_t fpA, uint8_t fpB) { - if (fpA == fpB) - return 0; - if (fpB == Mips::Val_GNU_MIPS_ABI_FP_ANY) - return 1; - if (fpB == Mips::Val_GNU_MIPS_ABI_FP_64A && - fpA == Mips::Val_GNU_MIPS_ABI_FP_64) - return 1; - if (fpB != Mips::Val_GNU_MIPS_ABI_FP_XX) - return -1; - if (fpA == Mips::Val_GNU_MIPS_ABI_FP_DOUBLE || - fpA == Mips::Val_GNU_MIPS_ABI_FP_64 || - fpA == Mips::Val_GNU_MIPS_ABI_FP_64A) - return 1; - return -1; -} - -static StringRef getMipsFpAbiName(uint8_t fpAbi) { - switch (fpAbi) { - case Mips::Val_GNU_MIPS_ABI_FP_ANY: - return "any"; - case Mips::Val_GNU_MIPS_ABI_FP_DOUBLE: - return "-mdouble-float"; - case Mips::Val_GNU_MIPS_ABI_FP_SINGLE: - return "-msingle-float"; - case Mips::Val_GNU_MIPS_ABI_FP_SOFT: - return "-msoft-float"; - case Mips::Val_GNU_MIPS_ABI_FP_OLD_64: - return "-mgp32 -mfp64 (old)"; - case Mips::Val_GNU_MIPS_ABI_FP_XX: - return "-mfpxx"; - case Mips::Val_GNU_MIPS_ABI_FP_64: - return "-mgp32 -mfp64"; - case Mips::Val_GNU_MIPS_ABI_FP_64A: - return "-mgp32 -mfp64 -mno-odd-spreg"; - default: - return "unknown"; - } -} - -uint8_t elf::getMipsFpAbiFlag(uint8_t oldFlag, uint8_t newFlag, - StringRef fileName) { - if (compareMipsFpAbi(newFlag, oldFlag) >= 0) - return newFlag; - if (compareMipsFpAbi(oldFlag, newFlag) < 0) - error(fileName + ": floating point ABI '" + getMipsFpAbiName(newFlag) + - "' is incompatible with target floating point ABI '" + - getMipsFpAbiName(oldFlag) + "'"); - return oldFlag; -} - -template <class ELFT> static bool isN32Abi(const InputFile *f) { - if (auto *ef = dyn_cast<ELFFileBase>(f)) - return ef->template getObj<ELFT>().getHeader()->e_flags & EF_MIPS_ABI2; - return false; -} - -bool elf::isMipsN32Abi(const InputFile *f) { - switch (config->ekind) { - case ELF32LEKind: - return isN32Abi<ELF32LE>(f); - case ELF32BEKind: - return isN32Abi<ELF32BE>(f); - case ELF64LEKind: - return isN32Abi<ELF64LE>(f); - case ELF64BEKind: - return isN32Abi<ELF64BE>(f); - default: - llvm_unreachable("unknown Config->EKind"); - } -} - -bool elf::isMicroMips() { return config->eflags & EF_MIPS_MICROMIPS; } - -bool elf::isMipsR6() { - uint32_t arch = config->eflags & EF_MIPS_ARCH; - return arch == EF_MIPS_ARCH_32R6 || arch == EF_MIPS_ARCH_64R6; -} - -template uint32_t elf::calcMipsEFlags<ELF32LE>(); -template uint32_t elf::calcMipsEFlags<ELF32BE>(); -template uint32_t elf::calcMipsEFlags<ELF64LE>(); -template uint32_t elf::calcMipsEFlags<ELF64BE>(); |
