11874dee5SFrancis Visoiu Mistrih //===-- llvm/BinaryFormat/MachO.cpp - The MachO file format -----*- C++/-*-===//
21874dee5SFrancis Visoiu Mistrih //
31874dee5SFrancis Visoiu Mistrih // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
41874dee5SFrancis Visoiu Mistrih // See https://llvm.org/LICENSE.txt for license information.
51874dee5SFrancis Visoiu Mistrih // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
61874dee5SFrancis Visoiu Mistrih //
71874dee5SFrancis Visoiu Mistrih //===----------------------------------------------------------------------===//
81874dee5SFrancis Visoiu Mistrih
91874dee5SFrancis Visoiu Mistrih #include "llvm/BinaryFormat/MachO.h"
101874dee5SFrancis Visoiu Mistrih #include "llvm/ADT/Triple.h"
111874dee5SFrancis Visoiu Mistrih #include "llvm/Support/ARMTargetParser.h"
121874dee5SFrancis Visoiu Mistrih
131874dee5SFrancis Visoiu Mistrih using namespace llvm;
141874dee5SFrancis Visoiu Mistrih
getX86SubType(const Triple & T)151874dee5SFrancis Visoiu Mistrih static MachO::CPUSubTypeX86 getX86SubType(const Triple &T) {
161874dee5SFrancis Visoiu Mistrih assert(T.isX86());
171874dee5SFrancis Visoiu Mistrih if (T.isArch32Bit())
181874dee5SFrancis Visoiu Mistrih return MachO::CPU_SUBTYPE_I386_ALL;
191874dee5SFrancis Visoiu Mistrih
201874dee5SFrancis Visoiu Mistrih assert(T.isArch64Bit());
211874dee5SFrancis Visoiu Mistrih if (T.getArchName() == "x86_64h")
221874dee5SFrancis Visoiu Mistrih return MachO::CPU_SUBTYPE_X86_64_H;
231874dee5SFrancis Visoiu Mistrih return MachO::CPU_SUBTYPE_X86_64_ALL;
241874dee5SFrancis Visoiu Mistrih }
251874dee5SFrancis Visoiu Mistrih
getARMSubType(const Triple & T)261874dee5SFrancis Visoiu Mistrih static MachO::CPUSubTypeARM getARMSubType(const Triple &T) {
271874dee5SFrancis Visoiu Mistrih assert(T.isARM() || T.isThumb());
281874dee5SFrancis Visoiu Mistrih StringRef Arch = T.getArchName();
291874dee5SFrancis Visoiu Mistrih ARM::ArchKind AK = ARM::parseArch(Arch);
301874dee5SFrancis Visoiu Mistrih switch (AK) {
311874dee5SFrancis Visoiu Mistrih default:
321874dee5SFrancis Visoiu Mistrih return MachO::CPU_SUBTYPE_ARM_V7;
331874dee5SFrancis Visoiu Mistrih case ARM::ArchKind::ARMV4T:
341874dee5SFrancis Visoiu Mistrih return MachO::CPU_SUBTYPE_ARM_V4T;
351874dee5SFrancis Visoiu Mistrih case ARM::ArchKind::ARMV5T:
361874dee5SFrancis Visoiu Mistrih case ARM::ArchKind::ARMV5TE:
371874dee5SFrancis Visoiu Mistrih case ARM::ArchKind::ARMV5TEJ:
381874dee5SFrancis Visoiu Mistrih return MachO::CPU_SUBTYPE_ARM_V5;
391874dee5SFrancis Visoiu Mistrih case ARM::ArchKind::ARMV6:
401874dee5SFrancis Visoiu Mistrih case ARM::ArchKind::ARMV6K:
411874dee5SFrancis Visoiu Mistrih return MachO::CPU_SUBTYPE_ARM_V6;
421874dee5SFrancis Visoiu Mistrih case ARM::ArchKind::ARMV7A:
431874dee5SFrancis Visoiu Mistrih return MachO::CPU_SUBTYPE_ARM_V7;
441874dee5SFrancis Visoiu Mistrih case ARM::ArchKind::ARMV7S:
451874dee5SFrancis Visoiu Mistrih return MachO::CPU_SUBTYPE_ARM_V7S;
461874dee5SFrancis Visoiu Mistrih case ARM::ArchKind::ARMV7K:
471874dee5SFrancis Visoiu Mistrih return MachO::CPU_SUBTYPE_ARM_V7K;
481874dee5SFrancis Visoiu Mistrih case ARM::ArchKind::ARMV6M:
491874dee5SFrancis Visoiu Mistrih return MachO::CPU_SUBTYPE_ARM_V6M;
501874dee5SFrancis Visoiu Mistrih case ARM::ArchKind::ARMV7M:
511874dee5SFrancis Visoiu Mistrih return MachO::CPU_SUBTYPE_ARM_V7M;
521874dee5SFrancis Visoiu Mistrih case ARM::ArchKind::ARMV7EM:
531874dee5SFrancis Visoiu Mistrih return MachO::CPU_SUBTYPE_ARM_V7EM;
541874dee5SFrancis Visoiu Mistrih }
551874dee5SFrancis Visoiu Mistrih }
561874dee5SFrancis Visoiu Mistrih
getARM64SubType(const Triple & T)571874dee5SFrancis Visoiu Mistrih static MachO::CPUSubTypeARM64 getARM64SubType(const Triple &T) {
58152df3adSTim Northover assert(T.isAArch64());
591874dee5SFrancis Visoiu Mistrih if (T.isArch32Bit())
601874dee5SFrancis Visoiu Mistrih return (MachO::CPUSubTypeARM64)MachO::CPU_SUBTYPE_ARM64_32_V8;
61*f77c948dSAhmed Bougacha if (T.isArm64e())
621874dee5SFrancis Visoiu Mistrih return MachO::CPU_SUBTYPE_ARM64E;
631874dee5SFrancis Visoiu Mistrih
641874dee5SFrancis Visoiu Mistrih return MachO::CPU_SUBTYPE_ARM64_ALL;
651874dee5SFrancis Visoiu Mistrih }
661874dee5SFrancis Visoiu Mistrih
getPowerPCSubType(const Triple & T)671874dee5SFrancis Visoiu Mistrih static MachO::CPUSubTypePowerPC getPowerPCSubType(const Triple &T) {
681874dee5SFrancis Visoiu Mistrih return MachO::CPU_SUBTYPE_POWERPC_ALL;
691874dee5SFrancis Visoiu Mistrih }
701874dee5SFrancis Visoiu Mistrih
unsupported(const char * Str,const Triple & T)717b0a5683SFrancis Visoiu Mistrih static Error unsupported(const char *Str, const Triple &T) {
727b0a5683SFrancis Visoiu Mistrih return createStringError(std::errc::invalid_argument,
737b0a5683SFrancis Visoiu Mistrih "Unsupported triple for mach-o cpu %s: %s", Str,
747b0a5683SFrancis Visoiu Mistrih T.str().c_str());
757b0a5683SFrancis Visoiu Mistrih }
767b0a5683SFrancis Visoiu Mistrih
getCPUType(const Triple & T)771874dee5SFrancis Visoiu Mistrih Expected<uint32_t> MachO::getCPUType(const Triple &T) {
787b0a5683SFrancis Visoiu Mistrih if (!T.isOSBinFormatMachO())
797b0a5683SFrancis Visoiu Mistrih return unsupported("type", T);
801874dee5SFrancis Visoiu Mistrih if (T.isX86() && T.isArch32Bit())
811874dee5SFrancis Visoiu Mistrih return MachO::CPU_TYPE_X86;
821874dee5SFrancis Visoiu Mistrih if (T.isX86() && T.isArch64Bit())
831874dee5SFrancis Visoiu Mistrih return MachO::CPU_TYPE_X86_64;
841874dee5SFrancis Visoiu Mistrih if (T.isARM() || T.isThumb())
851874dee5SFrancis Visoiu Mistrih return MachO::CPU_TYPE_ARM;
861874dee5SFrancis Visoiu Mistrih if (T.isAArch64())
87152df3adSTim Northover return T.isArch32Bit() ? MachO::CPU_TYPE_ARM64_32 : MachO::CPU_TYPE_ARM64;
881874dee5SFrancis Visoiu Mistrih if (T.getArch() == Triple::ppc)
891874dee5SFrancis Visoiu Mistrih return MachO::CPU_TYPE_POWERPC;
901874dee5SFrancis Visoiu Mistrih if (T.getArch() == Triple::ppc64)
911874dee5SFrancis Visoiu Mistrih return MachO::CPU_TYPE_POWERPC64;
927b0a5683SFrancis Visoiu Mistrih return unsupported("type", T);
931874dee5SFrancis Visoiu Mistrih }
941874dee5SFrancis Visoiu Mistrih
getCPUSubType(const Triple & T)951874dee5SFrancis Visoiu Mistrih Expected<uint32_t> MachO::getCPUSubType(const Triple &T) {
967b0a5683SFrancis Visoiu Mistrih if (!T.isOSBinFormatMachO())
977b0a5683SFrancis Visoiu Mistrih return unsupported("subtype", T);
981874dee5SFrancis Visoiu Mistrih if (T.isX86())
991874dee5SFrancis Visoiu Mistrih return getX86SubType(T);
1001874dee5SFrancis Visoiu Mistrih if (T.isARM() || T.isThumb())
1011874dee5SFrancis Visoiu Mistrih return getARMSubType(T);
1021874dee5SFrancis Visoiu Mistrih if (T.isAArch64() || T.getArch() == Triple::aarch64_32)
1031874dee5SFrancis Visoiu Mistrih return getARM64SubType(T);
1041874dee5SFrancis Visoiu Mistrih if (T.getArch() == Triple::ppc || T.getArch() == Triple::ppc64)
1051874dee5SFrancis Visoiu Mistrih return getPowerPCSubType(T);
1067b0a5683SFrancis Visoiu Mistrih return unsupported("subtype", T);
1071874dee5SFrancis Visoiu Mistrih }
108