//===-- llvm/BinaryFormat/MachO.cpp - The MachO file format -----*- C++/-*-===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "llvm/BinaryFormat/MachO.h"
#include "llvm/TargetParser/ARMTargetParser.h"
#include "llvm/TargetParser/Triple.h"

using namespace llvm;

static MachO::CPUSubTypeX86 getX86SubType(const Triple &T) {
  assert(T.isX86());
  if (T.isArch32Bit())
    return MachO::CPU_SUBTYPE_I386_ALL;

  assert(T.isArch64Bit());
  if (T.getArchName() == "x86_64h")
    return MachO::CPU_SUBTYPE_X86_64_H;
  return MachO::CPU_SUBTYPE_X86_64_ALL;
}

static MachO::CPUSubTypeARM getARMSubType(const Triple &T) {
  assert(T.isARM() || T.isThumb());
  StringRef Arch = T.getArchName();
  ARM::ArchKind AK = ARM::parseArch(Arch);
  switch (AK) {
  default:
    return MachO::CPU_SUBTYPE_ARM_V7;
  case ARM::ArchKind::ARMV4T:
    return MachO::CPU_SUBTYPE_ARM_V4T;
  case ARM::ArchKind::ARMV5T:
  case ARM::ArchKind::ARMV5TE:
  case ARM::ArchKind::ARMV5TEJ:
    return MachO::CPU_SUBTYPE_ARM_V5;
  case ARM::ArchKind::ARMV6:
  case ARM::ArchKind::ARMV6K:
    return MachO::CPU_SUBTYPE_ARM_V6;
  case ARM::ArchKind::ARMV7A:
    return MachO::CPU_SUBTYPE_ARM_V7;
  case ARM::ArchKind::ARMV7S:
    return MachO::CPU_SUBTYPE_ARM_V7S;
  case ARM::ArchKind::ARMV7K:
    return MachO::CPU_SUBTYPE_ARM_V7K;
  case ARM::ArchKind::ARMV6M:
    return MachO::CPU_SUBTYPE_ARM_V6M;
  case ARM::ArchKind::ARMV7M:
    return MachO::CPU_SUBTYPE_ARM_V7M;
  case ARM::ArchKind::ARMV7EM:
    return MachO::CPU_SUBTYPE_ARM_V7EM;
  case ARM::ArchKind::ARMV8MBaseline:
    return MachO::CPU_SUBTYPE_ARM_V8M_BASE;
  case ARM::ArchKind::ARMV8MMainline:
    return MachO::CPU_SUBTYPE_ARM_V8M_MAIN;
  case ARM::ArchKind::ARMV8_1MMainline:
    return MachO::CPU_SUBTYPE_ARM_V8_1M_MAIN;
  }
}

static MachO::CPUSubTypeARM64 getARM64SubType(const Triple &T) {
  assert(T.isAArch64());
  if (T.isArch32Bit())
    return (MachO::CPUSubTypeARM64)MachO::CPU_SUBTYPE_ARM64_32_V8;
  if (T.isArm64e())
    return MachO::CPU_SUBTYPE_ARM64E;

  return MachO::CPU_SUBTYPE_ARM64_ALL;
}

static MachO::CPUSubTypePowerPC getPowerPCSubType(const Triple &T) {
  return MachO::CPU_SUBTYPE_POWERPC_ALL;
}

static Error unsupported(const char *Str, const Triple &T) {
  return createStringError(std::errc::invalid_argument,
                           "Unsupported triple for mach-o cpu %s: %s", Str,
                           T.str().c_str());
}

static MachO::CPUSubTypeRISCV getRISCVSubType(const Triple &T) {
  return MachO::CPU_SUBTYPE_RISCV_ALL;
}

Expected<uint32_t> MachO::getCPUType(const Triple &T) {
  if (!T.isOSBinFormatMachO())
    return unsupported("type", T);
  if (T.isX86() && T.isArch32Bit())
    return MachO::CPU_TYPE_X86;
  if (T.isX86() && T.isArch64Bit())
    return MachO::CPU_TYPE_X86_64;
  if (T.isARM() || T.isThumb())
    return MachO::CPU_TYPE_ARM;
  if (T.isAArch64())
    return T.isArch32Bit() ? MachO::CPU_TYPE_ARM64_32 : MachO::CPU_TYPE_ARM64;
  if (T.getArch() == Triple::ppc)
    return MachO::CPU_TYPE_POWERPC;
  if (T.getArch() == Triple::ppc64)
    return MachO::CPU_TYPE_POWERPC64;
  if (T.getArch() == Triple::riscv32)
    return MachO::CPU_TYPE_RISCV;
  return unsupported("type", T);
}

Expected<uint32_t> MachO::getCPUSubType(const Triple &T) {
  if (!T.isOSBinFormatMachO())
    return unsupported("subtype", T);
  if (T.isX86())
    return getX86SubType(T);
  if (T.isARM() || T.isThumb())
    return getARMSubType(T);
  if (T.isAArch64() || T.getArch() == Triple::aarch64_32)
    return getARM64SubType(T);
  if (T.getArch() == Triple::ppc || T.getArch() == Triple::ppc64)
    return getPowerPCSubType(T);
  if (T.getArch() == Triple::riscv32)
    return getRISCVSubType(T);
  return unsupported("subtype", T);
}

Expected<uint32_t> MachO::getCPUSubType(const Triple &T,
                                        unsigned PtrAuthABIVersion,
                                        bool PtrAuthKernelABIVersion) {
  Expected<uint32_t> Result = MachO::getCPUSubType(T);
  if (!Result)
    return Result.takeError();
  if (*Result != MachO::CPU_SUBTYPE_ARM64E)
    return createStringError(
        std::errc::invalid_argument,
        "ptrauth ABI version is only supported on arm64e.");
  if (PtrAuthABIVersion > 0xF)
    return createStringError(
        std::errc::invalid_argument,
        "The ptrauth ABI version needs to fit within 4 bits.");
  return CPU_SUBTYPE_ARM64E_WITH_PTRAUTH_VERSION(PtrAuthABIVersion,
                                                 PtrAuthKernelABIVersion);
}
