blob: f91897dc6f9f0a7ba0d528130eb3b8605f85891a [file] [log] [blame]
/* arm_features.c -- ARM processor features detection.
*
* Copyright 2018 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the Chromium source repository LICENSE file.
*/
#include "arm_features.h"
#include "zutil.h"
int ZLIB_INTERNAL arm_cpu_enable_crc32 = 0;
int ZLIB_INTERNAL arm_cpu_enable_pmull = 0;
#if !defined(_MSC_VER)
#include <pthread.h>
#include <stdint.h>
#if defined(ARMV8_OS_ANDROID)
#include <cpu-features.h>
#elif defined(ARMV8_OS_LINUX)
#include <asm/hwcap.h>
#include <sys/auxv.h>
#else
#error arm_features.c ARM feature detection in not defined for your platform
#endif
static pthread_once_t cpu_check_inited_once = PTHREAD_ONCE_INIT;
static void _arm_check_features(void);
void ZLIB_INTERNAL arm_check_features(void)
{
pthread_once(&cpu_check_inited_once, _arm_check_features);
}
/*
* See http://bit.ly/2CcoEsr for run-time detection of ARM features and also
* crbug.com/931275 for android_getCpuFeatures() use in the Android sandbox.
*/
static void _arm_check_features(void)
{
#if defined(ARMV8_OS_ANDROID) && defined(__aarch64__)
uint64_t features = android_getCpuFeatures();
arm_cpu_enable_crc32 = !!(features & ANDROID_CPU_ARM64_FEATURE_CRC32);
arm_cpu_enable_pmull = !!(features & ANDROID_CPU_ARM64_FEATURE_PMULL);
#elif defined(ARMV8_OS_ANDROID) /* aarch32 */
uint64_t features = android_getCpuFeatures();
arm_cpu_enable_crc32 = !!(features & ANDROID_CPU_ARM_FEATURE_CRC32);
arm_cpu_enable_pmull = !!(features & ANDROID_CPU_ARM_FEATURE_PMULL);
#elif defined(ARMV8_OS_LINUX) && defined(__aarch64__)
unsigned long features = getauxval(AT_HWCAP);
arm_cpu_enable_crc32 = !!(features & HWCAP_CRC32);
arm_cpu_enable_pmull = !!(features & HWCAP_PMULL);
#elif defined(ARMV8_OS_LINUX) && (defined(__ARM_NEON) || defined(__ARM_NEON__))
/* Query HWCAP2 for ARMV8-A SoCs running in aarch32 mode */
unsigned long features = getauxval(AT_HWCAP2);
arm_cpu_enable_crc32 = !!(features & HWCAP2_CRC32);
arm_cpu_enable_pmull = !!(features & HWCAP2_PMULL);
#endif
/* TODO(crbug.com/810125): add ARMV8_OS_ZIRCON support for fucshia */
}
#else /* _MSC_VER */
#include <windows.h>
static INIT_ONCE cpu_check_inited_once = INIT_ONCE_STATIC_INIT;
static BOOL CALLBACK _arm_check_features(PINIT_ONCE once,
PVOID param,
PVOID *context);
void ZLIB_INTERNAL arm_check_features(void)
{
InitOnceExecuteOnce(&cpu_check_inited_once, _arm_check_features,
NULL, NULL);
}
static BOOL CALLBACK _arm_check_features(PINIT_ONCE once,
PVOID param,
PVOID *context)
{
if (IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE))
arm_cpu_enable_crc32 = 1;
if (IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE))
arm_cpu_enable_pmull = 1;
return TRUE;
}
#endif /* _MSC_VER */