diff --git a/llvm/include/llvm/Object/MachO.h b/llvm/include/llvm/Object/MachO.h index 380e3908d9da2..05836a0866bcf 100644 --- a/llvm/include/llvm/Object/MachO.h +++ b/llvm/include/llvm/Object/MachO.h @@ -571,6 +571,10 @@ class MachOObjectFile : public ObjectFile { static Triple getArchTriple(uint32_t CPUType, uint32_t CPUSubType, const char **McpuDefault = nullptr, const char **ArchFlag = nullptr); + + static Expected getCPUTypeFromTriple(const Triple &T); + static Expected getCPUSubTypeFromTriple(const Triple &T); + static bool isValidArch(StringRef ArchFlag); static ArrayRef getValidArchs(); static Triple getHostArch(); diff --git a/llvm/lib/Object/MachOObjectFile.cpp b/llvm/lib/Object/MachOObjectFile.cpp index 8540b7ab03cdf..b74e27e1bfca0 100644 --- a/llvm/lib/Object/MachOObjectFile.cpp +++ b/llvm/lib/Object/MachOObjectFile.cpp @@ -24,6 +24,7 @@ #include "llvm/Object/MachO.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Object/SymbolicFile.h" +#include "llvm/Support/ARMTargetParser.h" #include "llvm/Support/DataExtractor.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Error.h" @@ -2721,6 +2722,94 @@ Triple MachOObjectFile::getArchTriple(uint32_t CPUType, uint32_t CPUSubType, } } +static MachO::CPUSubTypeX86 getX86SubTypeFromTriple(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 getARMSubTypeFromTriple(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; + } +} + +static MachO::CPUSubTypeARM64 getARM64SubTypeFromTriple(const Triple &T) { + assert(T.isAArch64() || T.getArch() == Triple::aarch64_32); + if (T.isArch32Bit()) + return (MachO::CPUSubTypeARM64)MachO::CPU_SUBTYPE_ARM64_32_V8; + if (T.getArchName() == "arm64e") + return MachO::CPU_SUBTYPE_ARM64E; + + return MachO::CPU_SUBTYPE_ARM64_ALL; +} + +static MachO::CPUSubTypePowerPC getPowerPCSubTypeFromTriple(const Triple &T) { + return MachO::CPU_SUBTYPE_POWERPC_ALL; +} + +Expected MachOObjectFile::getCPUTypeFromTriple(const Triple &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 MachO::CPU_TYPE_ARM64; + if (T.getArch() == Triple::aarch64_32) + return MachO::CPU_TYPE_ARM64_32; + if (T.getArch() == Triple::ppc) + return MachO::CPU_TYPE_POWERPC; + if (T.getArch() == Triple::ppc64) + return MachO::CPU_TYPE_POWERPC64; + return createStringError(std::errc::invalid_argument, + "Unsupported triple for mach-o cpu type."); +} + +Expected MachOObjectFile::getCPUSubTypeFromTriple(const Triple &T) { + if (T.isX86()) + return getX86SubTypeFromTriple(T); + if (T.isARM() || T.isThumb()) + return getARMSubTypeFromTriple(T); + if (T.isAArch64() || T.getArch() == Triple::aarch64_32) + return getARM64SubTypeFromTriple(T); + if (T.getArch() == Triple::ppc || T.getArch() == Triple::ppc64) + return getPowerPCSubTypeFromTriple(T); + return createStringError(std::errc::invalid_argument, + "Unsupported triple for mach-o cpu subtype."); +} + Triple MachOObjectFile::getHostArch() { return Triple(sys::getDefaultTargetTriple()); } diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp index 9db746733aa35..d1ca47837dd55 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp @@ -24,6 +24,7 @@ #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCTargetOptions.h" #include "llvm/MC/MCValue.h" +#include "llvm/Object/MachO.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/TargetRegistry.h" using namespace llvm; @@ -33,6 +34,7 @@ namespace { class AArch64AsmBackend : public MCAsmBackend { static const unsigned PCRelFlagVal = MCFixupKindInfo::FKF_IsAlignedDownTo32Bits | MCFixupKindInfo::FKF_IsPCRel; +protected: Triple TheTriple; public: @@ -544,7 +546,6 @@ enum CompactUnwindEncodings { // FIXME: This should be in a separate file. class DarwinAArch64AsmBackend : public AArch64AsmBackend { const MCRegisterInfo &MRI; - bool IsILP32; /// Encode compact unwind stack adjustment for frameless functions. /// See UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK in compact_unwind_encoding.h. @@ -555,18 +556,17 @@ class DarwinAArch64AsmBackend : public AArch64AsmBackend { public: DarwinAArch64AsmBackend(const Target &T, const Triple &TT, - const MCRegisterInfo &MRI, bool IsILP32) - : AArch64AsmBackend(T, TT, /*IsLittleEndian*/ true), MRI(MRI), - IsILP32(IsILP32) {} + const MCRegisterInfo &MRI) + : AArch64AsmBackend(T, TT, /*IsLittleEndian*/ true), MRI(MRI) {} std::unique_ptr createObjectTargetWriter() const override { - if (IsILP32) - return createAArch64MachObjectWriter( - MachO::CPU_TYPE_ARM64_32, MachO::CPU_SUBTYPE_ARM64_32_V8, true); - else - return createAArch64MachObjectWriter(MachO::CPU_TYPE_ARM64, - MachO::CPU_SUBTYPE_ARM64_ALL, false); + uint32_t CPUType = + cantFail(object::MachOObjectFile::getCPUTypeFromTriple(TheTriple)); + uint32_t CPUSubType = + cantFail(object::MachOObjectFile::getCPUSubTypeFromTriple(TheTriple)); + return createAArch64MachObjectWriter(CPUType, CPUSubType, + TheTriple.isArch32Bit()); } /// Generate the compact unwind encoding from the CFI directives. @@ -749,8 +749,7 @@ MCAsmBackend *llvm::createAArch64leAsmBackend(const Target &T, const MCTargetOptions &Options) { const Triple &TheTriple = STI.getTargetTriple(); if (TheTriple.isOSBinFormatMachO()) { - const bool IsILP32 = TheTriple.isArch32Bit(); - return new DarwinAArch64AsmBackend(T, TheTriple, MRI, IsILP32); + return new DarwinAArch64AsmBackend(T, TheTriple, MRI); } if (TheTriple.isOSBinFormatCOFF()) diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp index fc04d37eb3623..06957c396e482 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp @@ -407,5 +407,5 @@ std::unique_ptr llvm::createAArch64MachObjectWriter(uint32_t CPUType, uint32_t CPUSubtype, bool IsILP32) { return std::make_unique(CPUType, CPUSubtype, - IsILP32); + IsILP32); } diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp index 6196881a9b8f8..0480a0d414d5b 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp @@ -1277,35 +1277,6 @@ uint32_t ARMAsmBackendDarwin::generateCompactUnwindEncoding( return CompactUnwindEncoding | ((FloatRegCount - 1) << 8); } -static MachO::CPUSubTypeARM getMachOSubTypeFromArch(StringRef Arch) { - 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; - } -} - static MCAsmBackend *createARMAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, @@ -1315,10 +1286,8 @@ static MCAsmBackend *createARMAsmBackend(const Target &T, switch (TheTriple.getObjectFormat()) { default: llvm_unreachable("unsupported object format"); - case Triple::MachO: { - MachO::CPUSubTypeARM CS = getMachOSubTypeFromArch(TheTriple.getArchName()); - return new ARMAsmBackendDarwin(T, STI, MRI, CS); - } + case Triple::MachO: + return new ARMAsmBackendDarwin(T, STI, MRI); case Triple::COFF: assert(TheTriple.isOSWindows() && "non-Windows ARM COFF is not supported"); return new ARMAsmBackendWinCOFF(T, STI); diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h index 87e56940f46db..b4a33dd97f510 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h @@ -12,20 +12,27 @@ #include "ARMAsmBackend.h" #include "llvm/BinaryFormat/MachO.h" #include "llvm/MC/MCObjectWriter.h" +#include "llvm/Object/MachO.h" namespace llvm { class ARMAsmBackendDarwin : public ARMAsmBackend { const MCRegisterInfo &MRI; + Triple TT; public: const MachO::CPUSubTypeARM Subtype; ARMAsmBackendDarwin(const Target &T, const MCSubtargetInfo &STI, - const MCRegisterInfo &MRI, MachO::CPUSubTypeARM st) - : ARMAsmBackend(T, STI, support::little), MRI(MRI), Subtype(st) {} + const MCRegisterInfo &MRI) + : ARMAsmBackend(T, STI, support::little), MRI(MRI), + TT(STI.getTargetTriple()), + Subtype((MachO::CPUSubTypeARM)cantFail( + object::MachOObjectFile::getCPUSubTypeFromTriple( + STI.getTargetTriple()))) {} std::unique_ptr createObjectTargetWriter() const override { - return createARMMachObjectWriter(/*Is64Bit=*/false, MachO::CPU_TYPE_ARM, - Subtype); + return createARMMachObjectWriter( + /*Is64Bit=*/false, + cantFail(object::MachOObjectFile::getCPUTypeFromTriple(TT)), Subtype); } uint32_t generateCompactUnwindEncoding( diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp index 8778e916f7e4d..ea596a34075f7 100644 --- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp @@ -20,6 +20,7 @@ #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCSymbolELF.h" #include "llvm/MC/MCValue.h" +#include "llvm/Object/MachO.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/TargetRegistry.h" using namespace llvm; @@ -207,11 +208,11 @@ class DarwinPPCAsmBackend : public PPCAsmBackend { std::unique_ptr createObjectTargetWriter() const override { - bool Is64 = TT.isPPC64(); - return createPPCMachObjectWriter( - /*Is64Bit=*/Is64, - (Is64 ? MachO::CPU_TYPE_POWERPC64 : MachO::CPU_TYPE_POWERPC), - MachO::CPU_SUBTYPE_POWERPC_ALL); + uint32_t CPUType = + cantFail(object::MachOObjectFile::getCPUTypeFromTriple(TT)); + uint32_t CPUSubType = + cantFail(object::MachOObjectFile::getCPUSubTypeFromTriple(TT)); + return createPPCMachObjectWriter(TT.isArch64Bit(), CPUType, CPUSubType); } }; diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp index dd0cf37056870..def5f446f082d 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp @@ -27,6 +27,7 @@ #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCValue.h" +#include "llvm/Object/MachO.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/TargetRegistry.h" @@ -811,6 +812,7 @@ class DarwinX86AsmBackend : public X86AsmBackend { enum { CU_NUM_SAVED_REGS = 6 }; mutable unsigned SavedRegs[CU_NUM_SAVED_REGS]; + Triple TT; bool Is64Bit; unsigned OffsetSize; ///< Offset of a "push" instruction. @@ -838,10 +840,142 @@ class DarwinX86AsmBackend : public X86AsmBackend { return 1; } +private: + /// Get the compact unwind number for a given register. The number + /// corresponds to the enum lists in compact_unwind_encoding.h. + int getCompactUnwindRegNum(unsigned Reg) const { + static const MCPhysReg CU32BitRegs[7] = { + X86::EBX, X86::ECX, X86::EDX, X86::EDI, X86::ESI, X86::EBP, 0 + }; + static const MCPhysReg CU64BitRegs[] = { + X86::RBX, X86::R12, X86::R13, X86::R14, X86::R15, X86::RBP, 0 + }; + const MCPhysReg *CURegs = Is64Bit ? CU64BitRegs : CU32BitRegs; + for (int Idx = 1; *CURegs; ++CURegs, ++Idx) + if (*CURegs == Reg) + return Idx; + + return -1; + } + + /// Return the registers encoded for a compact encoding with a frame + /// pointer. + uint32_t encodeCompactUnwindRegistersWithFrame() const { + // Encode the registers in the order they were saved --- 3-bits per + // register. The list of saved registers is assumed to be in reverse + // order. The registers are numbered from 1 to CU_NUM_SAVED_REGS. + uint32_t RegEnc = 0; + for (int i = 0, Idx = 0; i != CU_NUM_SAVED_REGS; ++i) { + unsigned Reg = SavedRegs[i]; + if (Reg == 0) break; + + int CURegNum = getCompactUnwindRegNum(Reg); + if (CURegNum == -1) return ~0U; + + // Encode the 3-bit register number in order, skipping over 3-bits for + // each register. + RegEnc |= (CURegNum & 0x7) << (Idx++ * 3); + } + + assert((RegEnc & 0x3FFFF) == RegEnc && + "Invalid compact register encoding!"); + return RegEnc; + } + + /// Create the permutation encoding used with frameless stacks. It is + /// passed the number of registers to be saved and an array of the registers + /// saved. + uint32_t encodeCompactUnwindRegistersWithoutFrame(unsigned RegCount) const { + // The saved registers are numbered from 1 to 6. In order to encode the + // order in which they were saved, we re-number them according to their + // place in the register order. The re-numbering is relative to the last + // re-numbered register. E.g., if we have registers {6, 2, 4, 5} saved in + // that order: + // + // Orig Re-Num + // ---- ------ + // 6 6 + // 2 2 + // 4 3 + // 5 3 + // + for (unsigned i = 0; i < RegCount; ++i) { + int CUReg = getCompactUnwindRegNum(SavedRegs[i]); + if (CUReg == -1) return ~0U; + SavedRegs[i] = CUReg; + } + + // Reverse the list. + std::reverse(&SavedRegs[0], &SavedRegs[CU_NUM_SAVED_REGS]); + + uint32_t RenumRegs[CU_NUM_SAVED_REGS]; + for (unsigned i = CU_NUM_SAVED_REGS - RegCount; i < CU_NUM_SAVED_REGS; ++i){ + unsigned Countless = 0; + for (unsigned j = CU_NUM_SAVED_REGS - RegCount; j < i; ++j) + if (SavedRegs[j] < SavedRegs[i]) + ++Countless; + + RenumRegs[i] = SavedRegs[i] - Countless - 1; + } + + // Take the renumbered values and encode them into a 10-bit number. + uint32_t permutationEncoding = 0; + switch (RegCount) { + case 6: + permutationEncoding |= 120 * RenumRegs[0] + 24 * RenumRegs[1] + + 6 * RenumRegs[2] + 2 * RenumRegs[3] + + RenumRegs[4]; + break; + case 5: + permutationEncoding |= 120 * RenumRegs[1] + 24 * RenumRegs[2] + + 6 * RenumRegs[3] + 2 * RenumRegs[4] + + RenumRegs[5]; + break; + case 4: + permutationEncoding |= 60 * RenumRegs[2] + 12 * RenumRegs[3] + + 3 * RenumRegs[4] + RenumRegs[5]; + break; + case 3: + permutationEncoding |= 20 * RenumRegs[3] + 4 * RenumRegs[4] + + RenumRegs[5]; + break; + case 2: + permutationEncoding |= 5 * RenumRegs[4] + RenumRegs[5]; + break; + case 1: + permutationEncoding |= RenumRegs[5]; + break; + } + + assert((permutationEncoding & 0x3FF) == permutationEncoding && + "Invalid compact register encoding!"); + return permutationEncoding; + } + +public: + DarwinX86AsmBackend(const Target &T, const MCRegisterInfo &MRI, + const MCSubtargetInfo &STI) + : X86AsmBackend(T, STI), MRI(MRI), TT(STI.getTargetTriple()), + Is64Bit(TT.isArch64Bit()) { + memset(SavedRegs, 0, sizeof(SavedRegs)); + OffsetSize = Is64Bit ? 8 : 4; + MoveInstrSize = Is64Bit ? 3 : 2; + StackDivide = Is64Bit ? 8 : 4; + } + + std::unique_ptr + createObjectTargetWriter() const override { + uint32_t CPUType = + cantFail(object::MachOObjectFile::getCPUTypeFromTriple(TT)); + uint32_t CPUSubType = + cantFail(object::MachOObjectFile::getCPUSubTypeFromTriple(TT)); + return createX86MachObjectWriter(Is64Bit, CPUType, CPUSubType); + } + /// Implementation of algorithm to generate the compact unwind encoding /// for the CFI instructions. uint32_t - generateCompactUnwindEncodingImpl(ArrayRef Instrs) const { + generateCompactUnwindEncoding(ArrayRef Instrs) const override { if (Instrs.empty()) return 0; // Reset the saved registers. @@ -991,168 +1125,6 @@ class DarwinX86AsmBackend : public X86AsmBackend { return CompactUnwindEncoding; } - -private: - /// Get the compact unwind number for a given register. The number - /// corresponds to the enum lists in compact_unwind_encoding.h. - int getCompactUnwindRegNum(unsigned Reg) const { - static const MCPhysReg CU32BitRegs[7] = { - X86::EBX, X86::ECX, X86::EDX, X86::EDI, X86::ESI, X86::EBP, 0 - }; - static const MCPhysReg CU64BitRegs[] = { - X86::RBX, X86::R12, X86::R13, X86::R14, X86::R15, X86::RBP, 0 - }; - const MCPhysReg *CURegs = Is64Bit ? CU64BitRegs : CU32BitRegs; - for (int Idx = 1; *CURegs; ++CURegs, ++Idx) - if (*CURegs == Reg) - return Idx; - - return -1; - } - - /// Return the registers encoded for a compact encoding with a frame - /// pointer. - uint32_t encodeCompactUnwindRegistersWithFrame() const { - // Encode the registers in the order they were saved --- 3-bits per - // register. The list of saved registers is assumed to be in reverse - // order. The registers are numbered from 1 to CU_NUM_SAVED_REGS. - uint32_t RegEnc = 0; - for (int i = 0, Idx = 0; i != CU_NUM_SAVED_REGS; ++i) { - unsigned Reg = SavedRegs[i]; - if (Reg == 0) break; - - int CURegNum = getCompactUnwindRegNum(Reg); - if (CURegNum == -1) return ~0U; - - // Encode the 3-bit register number in order, skipping over 3-bits for - // each register. - RegEnc |= (CURegNum & 0x7) << (Idx++ * 3); - } - - assert((RegEnc & 0x3FFFF) == RegEnc && - "Invalid compact register encoding!"); - return RegEnc; - } - - /// Create the permutation encoding used with frameless stacks. It is - /// passed the number of registers to be saved and an array of the registers - /// saved. - uint32_t encodeCompactUnwindRegistersWithoutFrame(unsigned RegCount) const { - // The saved registers are numbered from 1 to 6. In order to encode the - // order in which they were saved, we re-number them according to their - // place in the register order. The re-numbering is relative to the last - // re-numbered register. E.g., if we have registers {6, 2, 4, 5} saved in - // that order: - // - // Orig Re-Num - // ---- ------ - // 6 6 - // 2 2 - // 4 3 - // 5 3 - // - for (unsigned i = 0; i < RegCount; ++i) { - int CUReg = getCompactUnwindRegNum(SavedRegs[i]); - if (CUReg == -1) return ~0U; - SavedRegs[i] = CUReg; - } - - // Reverse the list. - std::reverse(&SavedRegs[0], &SavedRegs[CU_NUM_SAVED_REGS]); - - uint32_t RenumRegs[CU_NUM_SAVED_REGS]; - for (unsigned i = CU_NUM_SAVED_REGS - RegCount; i < CU_NUM_SAVED_REGS; ++i){ - unsigned Countless = 0; - for (unsigned j = CU_NUM_SAVED_REGS - RegCount; j < i; ++j) - if (SavedRegs[j] < SavedRegs[i]) - ++Countless; - - RenumRegs[i] = SavedRegs[i] - Countless - 1; - } - - // Take the renumbered values and encode them into a 10-bit number. - uint32_t permutationEncoding = 0; - switch (RegCount) { - case 6: - permutationEncoding |= 120 * RenumRegs[0] + 24 * RenumRegs[1] - + 6 * RenumRegs[2] + 2 * RenumRegs[3] - + RenumRegs[4]; - break; - case 5: - permutationEncoding |= 120 * RenumRegs[1] + 24 * RenumRegs[2] - + 6 * RenumRegs[3] + 2 * RenumRegs[4] - + RenumRegs[5]; - break; - case 4: - permutationEncoding |= 60 * RenumRegs[2] + 12 * RenumRegs[3] - + 3 * RenumRegs[4] + RenumRegs[5]; - break; - case 3: - permutationEncoding |= 20 * RenumRegs[3] + 4 * RenumRegs[4] - + RenumRegs[5]; - break; - case 2: - permutationEncoding |= 5 * RenumRegs[4] + RenumRegs[5]; - break; - case 1: - permutationEncoding |= RenumRegs[5]; - break; - } - - assert((permutationEncoding & 0x3FF) == permutationEncoding && - "Invalid compact register encoding!"); - return permutationEncoding; - } - -public: - DarwinX86AsmBackend(const Target &T, const MCRegisterInfo &MRI, - const MCSubtargetInfo &STI, bool Is64Bit) - : X86AsmBackend(T, STI), MRI(MRI), Is64Bit(Is64Bit) { - memset(SavedRegs, 0, sizeof(SavedRegs)); - OffsetSize = Is64Bit ? 8 : 4; - MoveInstrSize = Is64Bit ? 3 : 2; - StackDivide = Is64Bit ? 8 : 4; - } -}; - -class DarwinX86_32AsmBackend : public DarwinX86AsmBackend { -public: - DarwinX86_32AsmBackend(const Target &T, const MCRegisterInfo &MRI, - const MCSubtargetInfo &STI) - : DarwinX86AsmBackend(T, MRI, STI, false) {} - - std::unique_ptr - createObjectTargetWriter() const override { - return createX86MachObjectWriter(/*Is64Bit=*/false, - MachO::CPU_TYPE_I386, - MachO::CPU_SUBTYPE_I386_ALL); - } - - /// Generate the compact unwind encoding for the CFI instructions. - uint32_t generateCompactUnwindEncoding( - ArrayRef Instrs) const override { - return generateCompactUnwindEncodingImpl(Instrs); - } -}; - -class DarwinX86_64AsmBackend : public DarwinX86AsmBackend { - const MachO::CPUSubTypeX86 Subtype; -public: - DarwinX86_64AsmBackend(const Target &T, const MCRegisterInfo &MRI, - const MCSubtargetInfo &STI, MachO::CPUSubTypeX86 st) - : DarwinX86AsmBackend(T, MRI, STI, true), Subtype(st) {} - - std::unique_ptr - createObjectTargetWriter() const override { - return createX86MachObjectWriter(/*Is64Bit=*/true, MachO::CPU_TYPE_X86_64, - Subtype); - } - - /// Generate the compact unwind encoding for the CFI instructions. - uint32_t generateCompactUnwindEncoding( - ArrayRef Instrs) const override { - return generateCompactUnwindEncodingImpl(Instrs); - } }; } // end anonymous namespace @@ -1163,7 +1135,7 @@ MCAsmBackend *llvm::createX86_32AsmBackend(const Target &T, const MCTargetOptions &Options) { const Triple &TheTriple = STI.getTargetTriple(); if (TheTriple.isOSBinFormatMachO()) - return new DarwinX86_32AsmBackend(T, MRI, STI); + return new DarwinX86AsmBackend(T, MRI, STI); if (TheTriple.isOSWindows() && TheTriple.isOSBinFormatCOFF()) return new WindowsX86AsmBackend(T, false, STI); @@ -1181,13 +1153,8 @@ MCAsmBackend *llvm::createX86_64AsmBackend(const Target &T, const MCRegisterInfo &MRI, const MCTargetOptions &Options) { const Triple &TheTriple = STI.getTargetTriple(); - if (TheTriple.isOSBinFormatMachO()) { - MachO::CPUSubTypeX86 CS = - StringSwitch(TheTriple.getArchName()) - .Case("x86_64h", MachO::CPU_SUBTYPE_X86_64_H) - .Default(MachO::CPU_SUBTYPE_X86_64_ALL); - return new DarwinX86_64AsmBackend(T, MRI, STI, CS); - } + if (TheTriple.isOSBinFormatMachO()) + return new DarwinX86AsmBackend(T, MRI, STI); if (TheTriple.isOSWindows() && TheTriple.isOSBinFormatCOFF()) return new WindowsX86AsmBackend(T, true, STI);