1 // Copyright 2017 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "cpu_features_macros.h"
16
17 #ifdef CPU_FEATURES_ARCH_X86
18 #ifdef CPU_FEATURES_OS_MACOS
19
20 #include "impl_x86__base_implementation.inl"
21
22 #if !defined(HAVE_SYSCTLBYNAME)
23 #error "Darwin needs support for sysctlbyname"
24 #endif
25 #include <sys/sysctl.h>
26
27 #if defined(CPU_FEATURES_MOCK_CPUID_X86)
28 extern bool GetDarwinSysCtlByName(const char*);
29 #else // CPU_FEATURES_MOCK_CPUID_X86
GetDarwinSysCtlByName(const char * name)30 static bool GetDarwinSysCtlByName(const char* name) {
31 int enabled;
32 size_t enabled_len = sizeof(enabled);
33 const int failure = sysctlbyname(name, &enabled, &enabled_len, NULL, 0);
34 return failure ? false : enabled;
35 }
36 #endif
37
OverrideOsPreserves(OsPreserves * os_preserves)38 static void OverrideOsPreserves(OsPreserves* os_preserves) {
39 // On Darwin AVX512 support is On-demand.
40 // We have to query the OS instead of querying the Zmm save/restore state.
41 // https://github.com/apple/darwin-xnu/blob/8f02f2a044b9bb1ad951987ef5bab20ec9486310/osfmk/i386/fpu.c#L173-L199
42 os_preserves->avx512_registers = GetDarwinSysCtlByName("hw.optional.avx512f");
43 }
44
DetectFeaturesFromOs(X86Info * info,X86Features * features)45 static void DetectFeaturesFromOs(X86Info* info, X86Features* features) {
46 (void)info;
47 // Handling Darwin platform through sysctlbyname.
48 features->sse = GetDarwinSysCtlByName("hw.optional.sse");
49 features->sse2 = GetDarwinSysCtlByName("hw.optional.sse2");
50 features->sse3 = GetDarwinSysCtlByName("hw.optional.sse3");
51 features->ssse3 = GetDarwinSysCtlByName("hw.optional.supplementalsse3");
52 features->sse4_1 = GetDarwinSysCtlByName("hw.optional.sse4_1");
53 features->sse4_2 = GetDarwinSysCtlByName("hw.optional.sse4_2");
54 }
55
56 #endif // CPU_FEATURES_OS_MACOS
57 #endif // CPU_FEATURES_ARCH_X86
58