aboutsummaryrefslogtreecommitdiff
path: root/compiler-rt/lib/builtins/cpu_model.c
diff options
context:
space:
mode:
Diffstat (limited to 'compiler-rt/lib/builtins/cpu_model.c')
-rw-r--r--compiler-rt/lib/builtins/cpu_model.c65
1 files changed, 52 insertions, 13 deletions
diff --git a/compiler-rt/lib/builtins/cpu_model.c b/compiler-rt/lib/builtins/cpu_model.c
index 8346bb62dcfb..51bedd98c3d3 100644
--- a/compiler-rt/lib/builtins/cpu_model.c
+++ b/compiler-rt/lib/builtins/cpu_model.c
@@ -8,10 +8,21 @@
//
// This file is based on LLVM's lib/Support/Host.cpp.
// It implements the operating system Host concept and builtin
-// __cpu_model for the compiler_rt library, for x86 only.
+// __cpu_model for the compiler_rt library for x86 and
+// __aarch64_have_lse_atomics for AArch64.
//
//===----------------------------------------------------------------------===//
+#if defined(HAVE_INIT_PRIORITY)
+#define CONSTRUCTOR_ATTRIBUTE __attribute__((__constructor__ 101))
+#elif __has_attribute(__constructor__)
+#define CONSTRUCTOR_ATTRIBUTE __attribute__((__constructor__))
+#else
+// FIXME: For MSVC, we should make a function pointer global in .CRT$X?? so that
+// this runs during initialization.
+#define CONSTRUCTOR_ATTRIBUTE
+#endif
+
#if (defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || \
defined(_M_X64)) && \
(defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER))
@@ -57,6 +68,7 @@ enum ProcessorTypes {
INTEL_GOLDMONT,
INTEL_GOLDMONT_PLUS,
INTEL_TREMONT,
+ AMDFAM19H,
CPU_TYPE_MAX
};
@@ -84,6 +96,9 @@ enum ProcessorSubtypes {
INTEL_COREI7_CASCADELAKE,
INTEL_COREI7_TIGERLAKE,
INTEL_COREI7_COOPERLAKE,
+ INTEL_COREI7_SAPPHIRERAPIDS,
+ INTEL_COREI7_ALDERLAKE,
+ AMDFAM19H_ZNVER3,
CPU_SUBTYPE_MAX
};
@@ -277,7 +292,7 @@ getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model,
const unsigned *Features,
unsigned *Type, unsigned *Subtype) {
#define testFeature(F) \
- (Features[F / 32] & (F % 32)) != 0
+ (Features[F / 32] & (1 << (F % 32))) != 0
// We select CPU strings to match the code in Host.cpp, but we don't use them
// in compiler-rt.
@@ -407,6 +422,13 @@ getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model,
*Subtype = INTEL_COREI7_ICELAKE_SERVER;
break;
+ // Sapphire Rapids:
+ case 0x8f:
+ CPU = "sapphirerapids";
+ *Type = INTEL_COREI7;
+ *Subtype = INTEL_COREI7_SAPPHIRERAPIDS;
+ break;
+
case 0x1c: // Most 45 nm Intel Atom processors
case 0x26: // 45 nm Atom Lincroft
case 0x27: // 32 nm Atom Medfield
@@ -530,6 +552,14 @@ getAMDProcessorTypeAndSubtype(unsigned Family, unsigned Model,
break; // 00h-0Fh: Zen1
}
break;
+ case 25:
+ CPU = "znver3";
+ *Type = AMDFAM19H;
+ if (Model <= 0x0f) {
+ *Subtype = AMDFAM19H_ZNVER3;
+ break; // 00h-0Fh: Zen3
+ }
+ break;
default:
break; // Unknown AMD CPU.
}
@@ -656,16 +686,6 @@ static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf,
#undef setFeature
}
-#if defined(HAVE_INIT_PRIORITY)
-#define CONSTRUCTOR_ATTRIBUTE __attribute__((__constructor__ 101))
-#elif __has_attribute(__constructor__)
-#define CONSTRUCTOR_ATTRIBUTE __attribute__((__constructor__))
-#else
-// FIXME: For MSVC, we should make a function pointer global in .CRT$X?? so that
-// this runs during initialization.
-#define CONSTRUCTOR_ATTRIBUTE
-#endif
-
#ifndef _WIN32
__attribute__((visibility("hidden")))
#endif
@@ -740,5 +760,24 @@ int CONSTRUCTOR_ATTRIBUTE __cpu_indicator_init(void) {
return 0;
}
-
+#elif defined(__aarch64__)
+// LSE support detection for out-of-line atomics
+// using HWCAP and Auxiliary vector
+_Bool __aarch64_have_lse_atomics
+ __attribute__((visibility("hidden"), nocommon));
+#if defined(__has_include)
+#if __has_include(<sys/auxv.h>)
+#include <sys/auxv.h>
+#ifndef AT_HWCAP
+#define AT_HWCAP 16
+#endif
+#ifndef HWCAP_ATOMICS
+#define HWCAP_ATOMICS (1 << 8)
#endif
+static void CONSTRUCTOR_ATTRIBUTE init_have_lse_atomics(void) {
+ unsigned long hwcap = getauxval(AT_HWCAP);
+ __aarch64_have_lse_atomics = (hwcap & HWCAP_ATOMICS) != 0;
+}
+#endif // defined(__has_include)
+#endif // __has_include(<sys/auxv.h>)
+#endif // defined(__aarch64__)