#ifndef HIGHWAYHASH_ARCH_SPECIFIC_H_
#define HIGHWAYHASH_ARCH_SPECIFIC_H_
#include "highwayhash/compiler_specific.h"
#include <stdint.h>
#if HH_MSC_VERSION
#include <intrin.h>
#endif
namespace highwayhash {
#if defined(__x86_64__) || defined(_M_X64)
#define HH_ARCH_X64 1
#else
#define HH_ARCH_X64 0
#endif
#ifdef __aarch64__
#define HH_ARCH_AARCH64 1
#else
#define HH_ARCH_AARCH64 0
#endif
#if defined(__powerpc64__) || defined(_M_PPC)
#define HH_ARCH_PPC 1
#else
#define HH_ARCH_PPC 0
#endif
#ifndef HH_TARGET_NAME
#ifdef __AVX2__
#define HH_TARGET_NAME AVX2
#elif defined(__SSE4_1__)
#define HH_TARGET_NAME SSE41
#elif defined(__VSX__)
#define HH_TARGET_NAME VSX
#else
#define HH_TARGET_NAME Portable
#endif
#endif
#define HH_CONCAT(first, second) first##second
#define HH_EXPAND_CONCAT(first, second) HH_CONCAT(first, second)
#define HH_ADD_TARGET_SUFFIX(identifier_prefix) \
HH_EXPAND_CONCAT(identifier_prefix, HH_TARGET_NAME)
#define HH_TARGET HH_ADD_TARGET_SUFFIX(HH_TARGET_)
#define HH_TARGET_PREFERRED HH_TARGET
#define HH_TARGET_Portable 1
#define HH_TARGET_SSE41 2
#define HH_TARGET_AVX2 4
#define HH_TARGET_VSX 8
using TargetBits = unsigned;
namespace HH_TARGET_NAME {
template <class Func> void ForeachTarget(TargetBits bits, const Func &func) {
while (bits != 0) {
const TargetBits lowest = bits & (~bits + 1);
func(lowest);
bits &= ~lowest;
}
}
}
const char *TargetName(const TargetBits target_bit);
double NominalClockRate();
double InvariantTicksPerSecond();
#if HH_ARCH_X64
void Cpuid(const uint32_t level, const uint32_t count,
uint32_t *HH_RESTRICT abcd);
uint32_t ApicId();
#endif
}
#endif