mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
Revert "[macho][NFC] Extract all CPU_(SUB_)TYPE logic to libObject"
This reverts commit 726c342ce27ada28efe90cb04ffb69c75065710a. This breaks the windows bots with linker errors.
This commit is contained in:
parent
13b4fc1781
commit
e96a7a4c4c
@ -571,10 +571,6 @@ public:
|
||||
static Triple getArchTriple(uint32_t CPUType, uint32_t CPUSubType,
|
||||
const char **McpuDefault = nullptr,
|
||||
const char **ArchFlag = nullptr);
|
||||
|
||||
static Expected<uint32_t> getCPUTypeFromTriple(const Triple &T);
|
||||
static Expected<uint32_t> getCPUSubTypeFromTriple(const Triple &T);
|
||||
|
||||
static bool isValidArch(StringRef ArchFlag);
|
||||
static ArrayRef<StringRef> getValidArchs();
|
||||
static Triple getHostArch();
|
||||
|
@ -24,7 +24,6 @@
|
||||
#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"
|
||||
@ -2722,94 +2721,6 @@ 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<uint32_t> 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<uint32_t> 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());
|
||||
}
|
||||
|
@ -24,7 +24,6 @@
|
||||
#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;
|
||||
@ -34,7 +33,6 @@ namespace {
|
||||
class AArch64AsmBackend : public MCAsmBackend {
|
||||
static const unsigned PCRelFlagVal =
|
||||
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits | MCFixupKindInfo::FKF_IsPCRel;
|
||||
protected:
|
||||
Triple TheTriple;
|
||||
|
||||
public:
|
||||
@ -546,6 +544,7 @@ 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.
|
||||
@ -556,17 +555,18 @@ class DarwinAArch64AsmBackend : public AArch64AsmBackend {
|
||||
|
||||
public:
|
||||
DarwinAArch64AsmBackend(const Target &T, const Triple &TT,
|
||||
const MCRegisterInfo &MRI)
|
||||
: AArch64AsmBackend(T, TT, /*IsLittleEndian*/ true), MRI(MRI) {}
|
||||
const MCRegisterInfo &MRI, bool IsILP32)
|
||||
: AArch64AsmBackend(T, TT, /*IsLittleEndian*/ true), MRI(MRI),
|
||||
IsILP32(IsILP32) {}
|
||||
|
||||
std::unique_ptr<MCObjectTargetWriter>
|
||||
createObjectTargetWriter() const override {
|
||||
uint32_t CPUType =
|
||||
cantFail(object::MachOObjectFile::getCPUTypeFromTriple(TheTriple));
|
||||
uint32_t CPUSubType =
|
||||
cantFail(object::MachOObjectFile::getCPUSubTypeFromTriple(TheTriple));
|
||||
return createAArch64MachObjectWriter(CPUType, CPUSubType,
|
||||
TheTriple.isArch32Bit());
|
||||
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);
|
||||
}
|
||||
|
||||
/// Generate the compact unwind encoding from the CFI directives.
|
||||
@ -749,7 +749,8 @@ MCAsmBackend *llvm::createAArch64leAsmBackend(const Target &T,
|
||||
const MCTargetOptions &Options) {
|
||||
const Triple &TheTriple = STI.getTargetTriple();
|
||||
if (TheTriple.isOSBinFormatMachO()) {
|
||||
return new DarwinAArch64AsmBackend(T, TheTriple, MRI);
|
||||
const bool IsILP32 = TheTriple.isArch32Bit();
|
||||
return new DarwinAArch64AsmBackend(T, TheTriple, MRI, IsILP32);
|
||||
}
|
||||
|
||||
if (TheTriple.isOSBinFormatCOFF())
|
||||
|
@ -1277,6 +1277,35 @@ 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,
|
||||
@ -1286,8 +1315,10 @@ static MCAsmBackend *createARMAsmBackend(const Target &T,
|
||||
switch (TheTriple.getObjectFormat()) {
|
||||
default:
|
||||
llvm_unreachable("unsupported object format");
|
||||
case Triple::MachO:
|
||||
return new ARMAsmBackendDarwin(T, STI, MRI);
|
||||
case Triple::MachO: {
|
||||
MachO::CPUSubTypeARM CS = getMachOSubTypeFromArch(TheTriple.getArchName());
|
||||
return new ARMAsmBackendDarwin(T, STI, MRI, CS);
|
||||
}
|
||||
case Triple::COFF:
|
||||
assert(TheTriple.isOSWindows() && "non-Windows ARM COFF is not supported");
|
||||
return new ARMAsmBackendWinCOFF(T, STI);
|
||||
|
@ -12,27 +12,20 @@
|
||||
#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)
|
||||
: ARMAsmBackend(T, STI, support::little), MRI(MRI),
|
||||
TT(STI.getTargetTriple()),
|
||||
Subtype((MachO::CPUSubTypeARM)cantFail(
|
||||
object::MachOObjectFile::getCPUSubTypeFromTriple(
|
||||
STI.getTargetTriple()))) {}
|
||||
const MCRegisterInfo &MRI, MachO::CPUSubTypeARM st)
|
||||
: ARMAsmBackend(T, STI, support::little), MRI(MRI), Subtype(st) {}
|
||||
|
||||
std::unique_ptr<MCObjectTargetWriter>
|
||||
createObjectTargetWriter() const override {
|
||||
return createARMMachObjectWriter(
|
||||
/*Is64Bit=*/false,
|
||||
cantFail(object::MachOObjectFile::getCPUTypeFromTriple(TT)), Subtype);
|
||||
return createARMMachObjectWriter(/*Is64Bit=*/false, MachO::CPU_TYPE_ARM,
|
||||
Subtype);
|
||||
}
|
||||
|
||||
uint32_t generateCompactUnwindEncoding(
|
||||
|
@ -20,7 +20,6 @@
|
||||
#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;
|
||||
@ -208,11 +207,11 @@ public:
|
||||
|
||||
std::unique_ptr<MCObjectTargetWriter>
|
||||
createObjectTargetWriter() const override {
|
||||
uint32_t CPUType =
|
||||
cantFail(object::MachOObjectFile::getCPUTypeFromTriple(TT));
|
||||
uint32_t CPUSubType =
|
||||
cantFail(object::MachOObjectFile::getCPUSubTypeFromTriple(TT));
|
||||
return createPPCMachObjectWriter(TT.isArch64Bit(), CPUType, CPUSubType);
|
||||
bool Is64 = TT.isPPC64();
|
||||
return createPPCMachObjectWriter(
|
||||
/*Is64Bit=*/Is64,
|
||||
(Is64 ? MachO::CPU_TYPE_POWERPC64 : MachO::CPU_TYPE_POWERPC),
|
||||
MachO::CPU_SUBTYPE_POWERPC_ALL);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -27,7 +27,6 @@
|
||||
#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"
|
||||
@ -812,7 +811,6 @@ 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.
|
||||
@ -840,142 +838,10 @@ protected:
|
||||
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<MCObjectTargetWriter>
|
||||
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
|
||||
generateCompactUnwindEncoding(ArrayRef<MCCFIInstruction> Instrs) const override {
|
||||
generateCompactUnwindEncodingImpl(ArrayRef<MCCFIInstruction> Instrs) const {
|
||||
if (Instrs.empty()) return 0;
|
||||
|
||||
// Reset the saved registers.
|
||||
@ -1125,6 +991,168 @@ public:
|
||||
|
||||
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<MCObjectTargetWriter>
|
||||
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<MCCFIInstruction> 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<MCObjectTargetWriter>
|
||||
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<MCCFIInstruction> Instrs) const override {
|
||||
return generateCompactUnwindEncodingImpl(Instrs);
|
||||
}
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
@ -1135,7 +1163,7 @@ MCAsmBackend *llvm::createX86_32AsmBackend(const Target &T,
|
||||
const MCTargetOptions &Options) {
|
||||
const Triple &TheTriple = STI.getTargetTriple();
|
||||
if (TheTriple.isOSBinFormatMachO())
|
||||
return new DarwinX86AsmBackend(T, MRI, STI);
|
||||
return new DarwinX86_32AsmBackend(T, MRI, STI);
|
||||
|
||||
if (TheTriple.isOSWindows() && TheTriple.isOSBinFormatCOFF())
|
||||
return new WindowsX86AsmBackend(T, false, STI);
|
||||
@ -1153,8 +1181,13 @@ MCAsmBackend *llvm::createX86_64AsmBackend(const Target &T,
|
||||
const MCRegisterInfo &MRI,
|
||||
const MCTargetOptions &Options) {
|
||||
const Triple &TheTriple = STI.getTargetTriple();
|
||||
if (TheTriple.isOSBinFormatMachO())
|
||||
return new DarwinX86AsmBackend(T, MRI, STI);
|
||||
if (TheTriple.isOSBinFormatMachO()) {
|
||||
MachO::CPUSubTypeX86 CS =
|
||||
StringSwitch<MachO::CPUSubTypeX86>(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.isOSWindows() && TheTriple.isOSBinFormatCOFF())
|
||||
return new WindowsX86AsmBackend(T, true, STI);
|
||||
|
Loading…
Reference in New Issue
Block a user