1
0
mirror of https://github.com/google/cpu_features.git synced 2025-07-01 05:11:15 +02:00

Adding code. Closes #0.

This commit is contained in:
Guillaume Chatelet
2018-02-01 10:03:09 +01:00
parent 44d56a0a28
commit 439d371594
47 changed files with 4559 additions and 6 deletions

View File

@ -0,0 +1,39 @@
// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_BIT_UTILS_H_
#define THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_BIT_UTILS_H_
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include "cpu_features_macros.h"
START_CPP_NAMESPACE
inline static bool IsBitSet(uint32_t reg, uint32_t bit) {
return (reg >> bit) & 0x1;
}
inline static uint32_t ExtractBitRange(uint32_t reg, uint32_t msb,
uint32_t lsb) {
const uint64_t bits = msb - lsb + 1;
const uint64_t mask = (1ULL << bits) - 1ULL;
assert(msb >= lsb);
return (reg >> lsb) & mask;
}
END_CPP_NAMESPACE
#endif // THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_BIT_UTILS_H_

View File

@ -0,0 +1,37 @@
// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_CPUID_X86_H_
#define THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_CPUID_X86_H_
#include <stdint.h>
#include "cpu_features_macros.h"
START_CPP_NAMESPACE
// A struct to hold the result of a call to cpuid.
typedef struct {
uint32_t eax, ebx, ecx, edx;
} Leaf;
// Retrieves the leaf for a particular cpuid.
Leaf CpuId(uint32_t leaf_id);
// Returns the eax value of the XCR0 register.
uint32_t GetXCR0Eax(void);
END_CPP_NAMESPACE
#endif // THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_CPUID_X86_H_

View File

@ -0,0 +1,38 @@
// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// An interface for the filesystem that allows mocking the filesystem in
// unittests.
#ifndef THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_FILESYSTEM_H_
#define THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_FILESYSTEM_H_
#include <stddef.h>
#include <stdint.h>
#include "cpu_features_macros.h"
START_CPP_NAMESPACE
// Same as linux "open(filename, O_RDONLY)", retries automatically on EINTR.
int OpenFile(const char* filename);
// Same as linux "read(file_descriptor, buffer, buffer_size)", retries
// automatically on EINTR.
int ReadFile(int file_descriptor, void* buffer, size_t buffer_size);
// Same as linux "close(file_descriptor)".
void CloseFile(int file_descriptor);
END_CPP_NAMESPACE
#endif // THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_FILESYSTEM_H_

73
include/internal/hwcaps.h Normal file
View File

@ -0,0 +1,73 @@
// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Interface to retrieve hardware capabilities. It relies on Linux's getauxval
// or `/proc/self/auxval` under the hood.
#ifndef THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_HWCAPS_H_
#define THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_HWCAPS_H_
#include <stdint.h>
#include "cpu_features_macros.h"
START_CPP_NAMESPACE
// To avoid depending on the linux kernel we reproduce the architecture specific
// constants here.
// http://elixir.free-electrons.com/linux/latest/source/arch/arm64/include/uapi/asm/hwcap.h
#define AARCH64_HWCAP_FP (1UL << 0)
#define AARCH64_HWCAP_ASIMD (1UL << 1)
#define AARCH64_HWCAP_AES (1UL << 3)
#define AARCH64_HWCAP_PMULL (1UL << 4)
#define AARCH64_HWCAP_SHA1 (1UL << 5)
#define AARCH64_HWCAP_SHA2 (1UL << 6)
#define AARCH64_HWCAP_CRC32 (1UL << 7)
// http://elixir.free-electrons.com/linux/latest/source/arch/arm/include/uapi/asm/hwcap.h
#define ARM_HWCAP_VFP (1UL << 6)
#define ARM_HWCAP_IWMMXT (1UL << 9)
#define ARM_HWCAP_NEON (1UL << 12)
#define ARM_HWCAP_VFPV3 (1UL << 13)
#define ARM_HWCAP_VFPV3D16 (1UL << 14)
#define ARM_HWCAP_VFPV4 (1UL << 16)
#define ARM_HWCAP_IDIVA (1UL << 17)
#define ARM_HWCAP_IDIVT (1UL << 18)
#define ARM_HWCAP2_AES (1UL << 0)
#define ARM_HWCAP2_PMULL (1UL << 1)
#define ARM_HWCAP2_SHA1 (1UL << 2)
#define ARM_HWCAP2_SHA2 (1UL << 3)
#define ARM_HWCAP2_CRC32 (1UL << 4)
// http://elixir.free-electrons.com/linux/latest/source/arch/mips/include/uapi/asm/hwcap.h
#define MIPS_HWCAP_VZ (1UL << 0)
#define MIPS_HWCAP_EVA (1UL << 1)
#define MIPS_HWCAP_HTW (1UL << 2)
#define MIPS_HWCAP_FPU (1UL << 3)
#define MIPS_HWCAP_MIPS32R2 (1UL << 4)
#define MIPS_HWCAP_MIPS32R5 (1UL << 5)
#define MIPS_HWCAP_MIPS64R6 (1UL << 6)
#define MIPS_HWCAP_DSPR1 (1UL << 7)
#define MIPS_HWCAP_DSPR2 (1UL << 8)
#define MIPS_HWCAP_MSA (1UL << 9)
typedef struct {
uint32_t hwcaps;
uint32_t hwcaps2;
} HardwareCapabilities;
HardwareCapabilities GetHardwareCapabilities(void);
END_CPP_NAMESPACE
#endif // THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_HWCAPS_H_

View File

@ -0,0 +1,58 @@
// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// CapabilityConfig provides a way to map cpu features to hardware caps and
// /proc/cpuinfo flags. We then provide functions to update capabilities from
// either source.
#ifndef THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_LINUX_FEATURES_AGGREGATOR_H_
#define THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_LINUX_FEATURES_AGGREGATOR_H_
#include <ctype.h>
#include <stdint.h>
#include "cpu_features_macros.h"
#include "internal/hwcaps.h"
#include "internal/string_view.h"
START_CPP_NAMESPACE
// Use the following macro to declare setter functions to be used in
// CapabilityConfig.
#define DECLARE_SETTER(FeatureType, FeatureName) \
static void set_##FeatureName(void* const features, bool value) { \
((FeatureType*)features)->FeatureName = value; \
}
// Describes the relationship between hardware caps and /proc/cpuinfo flags.
typedef struct {
const HardwareCapabilities hwcaps_mask;
const char* const proc_cpuinfo_flag;
void (*set_bit)(void* const, bool); // setter for the corresponding bit.
} CapabilityConfig;
// For every config, looks into flags_line for the presence of the
// corresponding proc_cpuinfo_flag, calls `set_bit` accordingly.
// Note: features is a pointer to the underlying Feature struct.
void SetFromFlags(const size_t configs_size, const CapabilityConfig* configs,
const StringView flags_line, void* const features);
// For every config, looks into hwcaps for the presence of the feature. Calls
// `set_bit` with true if the hardware capability is found.
// Note: features is a pointer to the underlying Feature struct.
void OverrideFromHwCaps(const size_t configs_size,
const CapabilityConfig* configs,
const HardwareCapabilities hwcaps,
void* const features);
END_CPP_NAMESPACE
#endif // THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_LINUX_FEATURES_AGGREGATOR_H_

View File

@ -0,0 +1,49 @@
// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Reads a file line by line and stores the data on the stack. This allows
// parsing files in one go without allocating.
#ifndef THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_STACK_LINE_READER_H_
#define THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_STACK_LINE_READER_H_
#include <stdbool.h>
#include "cpu_features_macros.h"
#include "internal/string_view.h"
START_CPP_NAMESPACE
typedef struct {
char buffer[STACK_LINE_READER_BUFFER_SIZE];
StringView view;
int fd;
bool skip_mode;
} StackLineReader;
// Initializes a StackLineReader.
void StackLineReader_Initialize(StackLineReader* reader, int fd);
typedef struct {
StringView line; // A view of the line.
bool eof; // Nothing more to read, we reached EOF.
bool full_line; // If false the line was truncated to
// STACK_LINE_READER_BUFFER_SIZE.
} LineResult;
// Reads the file pointed to by fd and tries to read a full line.
LineResult StackLineReader_NextLine(StackLineReader* reader);
END_CPP_NAMESPACE
#endif // THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_STACK_LINE_READER_H_

View File

@ -0,0 +1,101 @@
// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// A view over a piece of string. The view is not 0 terminated.
#ifndef THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_STRING_VIEW_H_
#define THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_STRING_VIEW_H_
#include <stdbool.h>
#include <stddef.h>
#include <string.h>
#include "cpu_features_macros.h"
START_CPP_NAMESPACE
typedef struct {
const char* ptr;
size_t size;
} StringView;
#ifdef __cplusplus
static const StringView kEmptyStringView = {NULL, 0};
#else
static const StringView kEmptyStringView;
#endif
// Returns a StringView from the provided string.
// Passing NULL is valid only if size is 0.
static inline StringView view(const char* str, const size_t size) {
StringView view;
view.ptr = str;
view.size = size;
return view;
}
static inline StringView str(const char* str) { return view(str, strlen(str)); }
// Returns the index of the first occurrence of c in view or -1 if not found.
int IndexOfChar(const StringView view, char c);
// Returns the index of the first occurrence of sub_view in view or -1 if not
// found.
int IndexOf(const StringView view, const StringView sub_view);
// Returns whether a is equal to b (same content).
bool IsEquals(const StringView a, const StringView b);
// Returns whether a starts with b.
bool StartsWith(const StringView a, const StringView b);
// Removes count characters from the beginning of view or kEmptyStringView if
// count if greater than view.size.
StringView PopFront(const StringView view, size_t count);
// Removes count characters from the end of view or kEmptyStringView if count if
// greater than view.size.
StringView PopBack(const StringView str_view, size_t count);
// Keeps the count first characters of view or view if count if greater than
// view.size.
StringView KeepFront(const StringView view, size_t count);
// Retrieves the first character of view. If view is empty the behavior is
// undefined.
char Front(const StringView view);
// Retrieves the last character of view. If view is empty the behavior is
// undefined.
char Back(const StringView view);
// Removes leading and tailing space characters.
StringView TrimWhitespace(StringView view);
// Convert StringView to positive integer. e.g. "42", "0x2a".
// Returns -1 on error.
int ParsePositiveNumber(const StringView view);
// Copies src StringView to dst buffer.
void CopyString(const StringView src, char* dst, size_t dst_size);
// Checks if line contains the specified whitespace separated word.
bool HasWord(const StringView line, const char* const word);
// Get key/value from line. key and value are separated by ": ".
// key and value are cleaned up from leading and trailing whitespaces.
bool GetAttributeKeyValue(const StringView line, StringView* key,
StringView* value);
END_CPP_NAMESPACE
#endif // THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_STRING_VIEW_H_