Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 21 additions & 3 deletions clang/lib/Driver/ToolChains/Arch/ARM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,13 +202,25 @@ bool arm::useAAPCSForMachO(const llvm::Triple &T) {
T.getOS() == llvm::Triple::UnknownOS || isARMMProfile(T);
}

// We follow GCC and support when the backend has support for the MRC/MCR
// Check whether the architecture backend has support for the MRC/MCR
// instructions that are used to set the hard thread pointer ("CP15 C13
// Thread id").
// This is not identical to ability to use the instruction, as the ARMV6K
// variants can only use it in Arm mode since they don't support Thumb2
// encoding.
bool arm::isHardTPSupported(const llvm::Triple &Triple) {
int Ver = getARMSubArchVersionNumber(Triple);
llvm::ARM::ArchKind AK = llvm::ARM::parseArch(Triple.getArchName());
return Triple.isARM() || AK == llvm::ARM::ArchKind::ARMV6T2 ||
return AK == llvm::ARM::ArchKind::ARMV6K ||
AK == llvm::ARM::ArchKind::ARMV6KZ ||
(Ver >= 7 && !isARMMProfile(Triple));
}

// Checks whether the architecture is capable of supporting the Thumb2 encoding
static bool supportsThumb2Encoding(const llvm::Triple &Triple) {
int Ver = arm::getARMSubArchVersionNumber(Triple);
llvm::ARM::ArchKind AK = llvm::ARM::parseArch(Triple.getArchName());
return AK == llvm::ARM::ArchKind::ARMV6T2 ||
(Ver >= 7 && AK != llvm::ARM::ArchKind::ARMV8MBaseline);
}

Expand Down Expand Up @@ -240,7 +252,13 @@ arm::ReadTPMode arm::getReadTPMode(const Driver &D, const ArgList &Args,
D.Diag(diag::err_drv_invalid_mtp) << A->getAsString(Args);
return ReadTPMode::Invalid;
}
return (isHardTPSupported(Triple) ? ReadTPMode::TPIDRURO : ReadTPMode::Soft);
// In auto mode we enable HW mode only if both the hardware supports it and
// the thumb2 encoding. For example ARMV6T2 supports thumb2, but not hardware.
// ARMV6K has HW suport, but not thumb2. Otherwise we could enable it for
// ARMV6K in thumb mode.
bool autoUseHWTPMode =
isHardTPSupported(Triple) && supportsThumb2Encoding(Triple);
return autoUseHWTPMode ? ReadTPMode::TPIDRURO : ReadTPMode::Soft;
}

void arm::setArchNameInTriple(const Driver &D, const ArgList &Args,
Expand Down
60 changes: 52 additions & 8 deletions clang/test/Driver/arm-thread-pointer.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,26 @@
// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER-TPIDRPRW %s
// ARMv7_THREAD_POINTER-TPIDRPRW: "-target-feature" "+read-tp-tpidrprw"

// RUN: %clang --target=armv6t2-linux -mtp=cp15 -### -S %s 2>&1 | \
// RUN: FileCheck -check-prefix=ARM_THREAD_POINTER-HARD %s
// RUN: %clang --target=thumbv6t2-linux -mtp=cp15 -### -S %s 2>&1 | \
// RUN: FileCheck -check-prefix=ARM_THREAD_POINTER-HARD %s
// RUN: %clang --target=armv6k-linux -mtp=cp15 -### -S %s 2>&1 | \
// RUN: FileCheck -check-prefix=ARM_THREAD_POINTER-HARD %s
// RUN: %clang --target=armv6-linux -mtp=cp15 -### -S %s 2>&1 | \
// RUN: FileCheck -check-prefix=ARM_THREAD_POINTER-HARD %s
// RUN: %clang --target=armv5t-linux -mtp=cp15 -### -S %s 2>&1 | \
// RUN: FileCheck -check-prefix=ARM_THREAD_POINTER-HARD %s
// ARM_THREAD_POINTER-HARD: "-target-feature" "+read-tp-tpidruro"

// RUN: %clang --target=armv6k-linux -mtp=auto -### -S %s 2>&1 | \
// RUN: FileCheck -check-prefix=ARM_THREAD_POINTER_AUTO %s
// ARM_THREAD_POINTER_AUTO-NOT: "-target-feature" "+read-tp-tpidruro"

// RUN: %clang --target=thumbv6k-apple-darwin -### -S %s 2>&1 | \
// RUN: FileCheck -check-prefix=THUMBv6_THREAD_POINTER_NO_AUTO %s
// THUMBv6_THREAD_POINTER_NO_AUTO-NOT: "-target-feature" "+read-tp-tpidruro"

// RUN: not %clang --target=thumbv6k-apple-darwin -mtp=cp15 -### -S %s 2>&1 | \
// RUN: FileCheck -check-prefix=THUMBv6_THREAD_POINTER_NO_HARD %s
// THUMBv6_THREAD_POINTER_NO_HARD: unsupported option '-mtp=' for target 'thumbv6k-apple-darwin'

// RUN: not %clang --target=thumbv6t2-linux -mtp=cp15 -### -S %s 2>&1 | \
// RUN: FileCheck -check-prefix=ARM_THREAD_POINTER_NO_HARD %s
// ARM_THREAD_POINTER_NO_HARD: hardware TLS register is not supported for the armv6t2 sub-architecture

// RUN: %clang --target=armv5t-linux -mtp=cp15 -x assembler -### %s 2>&1 | \
// RUN: FileCheck -check-prefix=ARMv5_THREAD_POINTER_ASSEMBLER %s
// ARMv5_THREAD_POINTER_ASSEMBLER-NOT: hardware TLS register is not supported for the armv5 sub-architecture
Expand All @@ -47,3 +55,39 @@
// RUN: %clang --target=armv7-linux -mtp=auto -### -S %s 2>&1 | \
// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER_Auto %s
// ARMv7_THREAD_POINTER_Auto: "-target-feature" "+read-tp-tpidruro"

// RUN: %clang --target=armv7-linux -mtp=cp15 -### -S %s 2>&1 | \
// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER_HARD %s
// ARMv7_THREAD_POINTER_HARD: "-target-feature" "+read-tp-tpidruro"

// RUN: %clang --target=armv7m-linux -mtp=auto -### -S %s 2>&1 | \
// RUN: FileCheck -check-prefix=ARMv7m_THREAD_POINTER_Auto %s
// ARMv7m_THREAD_POINTER_Auto-NOT: "-target-feature" "+read-tp-tpidruro"

// RUN: not %clang --target=armv7m-linux -mtp=cp15 -### -S %s 2>&1 | \
// RUN: FileCheck -check-prefix=ARMv7m_THREAD_POINTER_HARD %s
// ARMv7m_THREAD_POINTER_HARD: hardware TLS register is not supported for the thumbv7m sub-architecture

// RUN: %clang --target=armv5t-linux -mtp=auto -### -S %s 2>&1 | \
// RUN: FileCheck -check-prefix=ARMv5t_THREAD_POINTER_Auto %s
// ARMv5t_THREAD_POINTER_Auto-NOT: "-target-feature" "+read-tp-tpidruro"

// RUN: %clang --target=armv6k-linux -mtp=cp15 -### -S %s 2>&1 | \
// RUN: FileCheck -check-prefix=ARMv6k_THREAD_POINTER_Auto %s
// ARMv6k_THREAD_POINTER_Auto: "-target-feature" "+read-tp-tpidruro"

// RUN: not %clang --target=armv6t2-linux -mtp=cp15 -### -S %s 2>&1 | \
// RUN: FileCheck -check-prefix=ARMv6t2_THREAD_POINTER_HARD %s
// ARMv6t2_THREAD_POINTER_HARD: hardware TLS register is not supported for the armv6t2 sub-architecture

// RUN: %clang --target=armv6t2-linux -mtp=auto -### -S %s 2>&1 | \
// RUN: FileCheck -check-prefix=ARMV6t2_THREAD_POINTER_AUTO %s
// ARMV6t2_THREAD_POINTER_AUTO-NOT: "-target-feature" "+read-tp-tpidruro"

// RUN: %clang --target=armv6kz-linux -mtp=cp15 -### -S %s 2>&1 | \
// RUN: FileCheck -check-prefix=ARMv6kz_THREAD_POINTER_HARD %s
// ARMv6kz_THREAD_POINTER_HARD: "-target-feature" "+read-tp-tpidruro"

// RUN: %clang --target=armv6kz-linux -mtp=auto -### -S %s 2>&1 | \
// RUN: FileCheck -check-prefix=ARMV6KZ_THREAD_POINTER_AUTO %s
// ARMV6KZ_THREAD_POINTER_AUTO-NOT: "-target-feature" "+read-tp-tpidruro"