diff --git a/src/external/cpuid/CMakeLists.txt b/src/external/cpuid/CMakeLists.txt new file mode 100644 index 00000000..d4e779be --- /dev/null +++ b/src/external/cpuid/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required (VERSION 3.5) +project(sfizz-cpuid) + +add_library(sfizz-cpuid STATIC src/cpuid/cpuinfo.cpp src/cpuid/version.cpp) +set_property(TARGET sfizz-cpuid PROPERTY CXX_STANDARD 11) +target_include_directories(sfizz-cpuid PUBLIC src PRIVATE platform/src) diff --git a/src/external/cpuid/LICENSE.rst b/src/external/cpuid/LICENSE.rst new file mode 100644 index 00000000..9bfdb29a --- /dev/null +++ b/src/external/cpuid/LICENSE.rst @@ -0,0 +1,31 @@ +cpuid license +------------- +cpuid is provided under the "BSD (3-clause) License":: + + Copyright (c) 2014, Steinwurf ApS + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of Steinwurf ApS nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL Steinwurf ApS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/external/cpuid/platform/LICENSE.rst b/src/external/cpuid/platform/LICENSE.rst new file mode 100644 index 00000000..6f26a40f --- /dev/null +++ b/src/external/cpuid/platform/LICENSE.rst @@ -0,0 +1,31 @@ +platform license +---------------- +platform is provided under the "BSD (3-clause) License":: + + Copyright (c) 2014, Steinwurf ApS + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of Steinwurf ApS nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL Steinwurf ApS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/external/cpuid/platform/src/platform/config.hpp b/src/external/cpuid/platform/src/platform/config.hpp new file mode 100644 index 00000000..570fda76 --- /dev/null +++ b/src/external/cpuid/platform/src/platform/config.hpp @@ -0,0 +1,159 @@ +// Copyright (c) 2014 Steinwurf ApS +// All Rights Reserved +// +// Distributed under the "BSD License". See the accompanying LICENSE.rst file. + +#pragma once + +// Here we create a number of defines to make it easy to choose between +// different compilers, operatings systems and CPU architectures. +// Some information about the defines used can be found here: +// http://sourceforge.net/p/predef/wiki/Architectures/ + +// Detect operating systems +#if defined(__linux__) + #define PLATFORM_LINUX 1 + #if defined(__ANDROID__) + #define PLATFORM_ANDROID 1 + #endif +#elif defined(_WIN32) + #define PLATFORM_WINDOWS 1 + #if defined(WINAPI_FAMILY) + #include + #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) + #define PLATFORM_WINDOWS_PHONE 1 + #endif + #endif +#elif defined(__APPLE__) + // Detect iOS before MacOSX (__MACH__ is also defined for iOS) + #if defined(IPHONE) + #define PLATFORM_IOS 1 + #elif defined(__MACH__) + #define PLATFORM_MAC 1 + #endif +#elif defined(__EMSCRIPTEN__) + #define PLATFORM_EMSCRIPTEN 1 +#else + #error "Unable to determine operating system" +#endif + +// Detect compilers and CPU architectures +// Note: clang also defines __GNUC__ since it aims to be compatible with GCC. +// Therefore we need to check for __clang__ or __llvm__ first. +#if defined(__clang__) || defined(__llvm__) + #define PLATFORM_CLANG 1 + #define PLATFORM_GCC_COMPATIBLE 1 + #if defined(__i386__) || defined(__x86_64__) + #define PLATFORM_X86 1 + #define PLATFORM_CLANG_X86 1 + #define PLATFORM_GCC_COMPATIBLE_X86 1 + #elif defined(__arm__) || defined (__arm64__) || defined (__aarch64__) + #define PLATFORM_ARM 1 + #define PLATFORM_CLANG_ARM 1 + #define PLATFORM_GCC_COMPATIBLE_ARM 1 + #elif defined(__mips__) + #define PLATFORM_MIPS 1 + #define PLATFORM_CLANG_MIPS 1 + #define PLATFORM_GCC_COMPATIBLE_MIPS 1 + #elif defined(__asmjs__) + #define PLATFORM_ASMJS 1 + #define PLATFORM_CLANG_ASMJS 1 + #define PLATFORM_GCC_COMPATIBLE_ASMJS 1 + #endif +#elif defined(__GNUC__) + #define PLATFORM_GCC 1 + #define PLATFORM_GCC_COMPATIBLE 1 + #if defined(__i386__) || defined(__x86_64__) + #define PLATFORM_X86 1 + #define PLATFORM_GCC_X86 1 + #define PLATFORM_GCC_COMPATIBLE_X86 1 + #elif defined(__arm__) || defined (__arm64__) || defined (__aarch64__) + #define PLATFORM_ARM 1 + #define PLATFORM_GCC_ARM 1 + #define PLATFORM_GCC_COMPATIBLE_ARM 1 + #elif defined(__mips__) + #define PLATFORM_MIPS 1 + #define PLATFORM_GCC_MIPS 1 + #define PLATFORM_GCC_COMPATIBLE_MIPS 1 + #endif +#elif defined(_MSC_VER) + #define PLATFORM_MSVC 1 + #if defined(_M_IX86) || defined(_M_X64) + #define PLATFORM_X86 1 + #define PLATFORM_MSVC_X86 1 + #elif defined(_M_ARM) || defined(_M_ARMT) + #define PLATFORM_ARM 1 + #define PLATFORM_MSVC_ARM 1 + #endif +#else + #error "Unable to determine compiler" +#endif + +// Define macros for supported CPU instruction sets +#if defined(PLATFORM_GCC_COMPATIBLE) + #if defined(__MMX__) + #define PLATFORM_MMX 1 + #endif + #if defined(__SSE__) + #define PLATFORM_SSE 1 + #endif + #if defined(__SSE2__) + #define PLATFORM_SSE2 1 + #endif + #if defined(__SSE3__) + #define PLATFORM_SSE3 1 + #endif + #if defined(__SSSE3__) + #define PLATFORM_SSSE3 1 + #endif + #if defined(__SSE4_1__) + #define PLATFORM_SSE41 1 + #endif + #if defined(__SSE4_2__) + #define PLATFORM_SSE42 1 + #endif + #if defined(__PCLMUL__) + #define PLATFORM_PCLMUL 1 + #endif + #if defined(__AVX__) + #define PLATFORM_AVX 1 + #endif + #if defined(__AVX2__) + #define PLATFORM_AVX2 1 + #endif + #if defined(__ARM_NEON__) || defined (__ARM_NEON) + #define PLATFORM_NEON 1 + #endif + // First, check the PLATFORM_WINDOWS_PHONE define, because + // the X86 instructions sets are not supported on the Windows Phone emulator +#elif defined(PLATFORM_WINDOWS_PHONE) + #if defined(PLATFORM_MSVC_ARM) + // NEON introduced in VS2012 + #if (_MSC_VER >= 1700) + #define PLATFORM_NEON 1 + #endif + #endif +#elif defined(PLATFORM_MSVC_X86) + // MMX, SSE and SSE2 introduced in VS2003 + #if (_MSC_VER >= 1310) + #define PLATFORM_MMX 1 + #define PLATFORM_SSE 1 + #define PLATFORM_SSE2 1 + #endif + // SSE3 introduced in VS2005 + #if (_MSC_VER >= 1400) + #define PLATFORM_SSE3 1 + #endif + // SSSE3, SSE4.1, SSE4.2, PCLMUL introduced in VS2008 + #if (_MSC_VER >= 1500) + #define PLATFORM_SSSE3 1 + #define PLATFORM_SSE41 1 + #define PLATFORM_SSE42 1 + #define PLATFORM_PCLMUL 1 + #endif + // AVX and AVX2 introduced in VS2012 + #if (_MSC_VER >= 1700) + #define PLATFORM_AVX 1 + #define PLATFORM_AVX2 1 + #endif +#endif diff --git a/src/external/cpuid/src/cpuid/cpuinfo.cpp b/src/external/cpuid/src/cpuid/cpuinfo.cpp new file mode 100644 index 00000000..93569229 --- /dev/null +++ b/src/external/cpuid/src/cpuid/cpuinfo.cpp @@ -0,0 +1,103 @@ +// Copyright (c) 2013 Steinwurf ApS +// All Rights Reserved +// +// Distributed under the "BSD License". See the accompanying LICENSE.rst file. + +#include + +#include "cpuinfo.hpp" +#include "detail/cpuinfo_impl.hpp" + +#if defined(PLATFORM_GCC_COMPATIBLE_X86) + #include "detail/init_gcc_x86.hpp" +#elif defined(PLATFORM_MSVC_X86) && !defined(PLATFORM_WINDOWS_PHONE) + #include "detail/init_msvc_x86.hpp" +#elif defined(PLATFORM_MSVC_ARM) + #include "detail/init_msvc_arm.hpp" +#elif defined(PLATFORM_CLANG_ARM) && defined(PLATFORM_IOS) + #include "detail/init_ios_clang_arm.hpp" +#elif defined(PLATFORM_GCC_COMPATIBLE_ARM) && defined(PLATFORM_LINUX) + #include "detail/init_linux_gcc_arm.hpp" +#else + #include "detail/init_unknown.hpp" +#endif + +namespace cpuid +{ + +inline namespace STEINWURF_CPUID_VERSION +{ + +cpuinfo::cpuinfo() : + m_impl(new impl) +{ + init_cpuinfo(*m_impl); +} + +cpuinfo::~cpuinfo() +{ +} + +// x86 member functions +bool cpuinfo::has_fpu() const +{ + return m_impl->m_has_fpu; +} + +bool cpuinfo::has_mmx() const +{ + return m_impl->m_has_mmx; +} + +bool cpuinfo::has_sse() const +{ + return m_impl->m_has_sse; +} + +bool cpuinfo::has_sse2() const +{ + return m_impl->m_has_sse2; +} + +bool cpuinfo::has_sse3() const +{ + return m_impl->m_has_sse3; +} + +bool cpuinfo::has_ssse3() const +{ + return m_impl->m_has_ssse3; +} + +bool cpuinfo::has_sse4_1() const +{ + return m_impl->m_has_sse4_1; +} + +bool cpuinfo::has_sse4_2() const +{ + return m_impl->m_has_sse4_2; +} + +bool cpuinfo::has_pclmulqdq() const +{ + return m_impl->m_has_pclmulqdq; +} + +bool cpuinfo::has_avx() const +{ + return m_impl->m_has_avx; +} + +bool cpuinfo::has_avx2() const +{ + return m_impl->m_has_avx2; +} + +// ARM functions +bool cpuinfo::has_neon() const +{ + return m_impl->m_has_neon; +} +} +} diff --git a/src/external/cpuid/src/cpuid/cpuinfo.hpp b/src/external/cpuid/src/cpuid/cpuinfo.hpp new file mode 100644 index 00000000..60979c1e --- /dev/null +++ b/src/external/cpuid/src/cpuid/cpuinfo.hpp @@ -0,0 +1,72 @@ +// Copyright (c) 2013 Steinwurf ApS +// All Rights Reserved +// +// Distributed under the "BSD License". See the accompanying LICENSE.rst file. + +#pragma once + +#include + +#include "version.hpp" + +namespace cpuid +{ +inline namespace STEINWURF_CPUID_VERSION +{ +/// The cpuinfo object extract information about which, if any, additional +/// instructiions are supported by the CPU. +class cpuinfo +{ +public: + /// Constructor for feature detection with default values + cpuinfo(); + + /// Destructor + ~cpuinfo(); + + /// Has X87 FPU + bool has_fpu() const; + + /// Return true if the CPU supports MMX + bool has_mmx() const; + + /// Return true if the CPU supports SSE + bool has_sse() const; + + /// Return true if the CPU supports SSE2 + bool has_sse2() const; + + /// Return true if the CPU supports SSE3 + bool has_sse3() const; + + /// Return true if the CPU supports SSSE3 + bool has_ssse3() const; + + /// Return true if the CPU supports SSE 4.1 + bool has_sse4_1() const; + + /// Return true if the CPU supports SSE 4.2 + bool has_sse4_2() const; + + /// Return true if the CPU supports pclmulqdq + bool has_pclmulqdq() const; + + /// Return true if the CPU supports AVX + bool has_avx() const; + + /// Return true if the CPU supports AVX2 + bool has_avx2() const; + + /// ARM member functions + bool has_neon() const; + +public: + /// Private implementation + struct impl; + +private: + /// Pimpl pointer + std::unique_ptr m_impl; +}; +} +} diff --git a/src/external/cpuid/src/cpuid/detail/cpuinfo_impl.hpp b/src/external/cpuid/src/cpuid/detail/cpuinfo_impl.hpp new file mode 100644 index 00000000..9eee303a --- /dev/null +++ b/src/external/cpuid/src/cpuid/detail/cpuinfo_impl.hpp @@ -0,0 +1,39 @@ +// Copyright (c) 2013 Steinwurf ApS +// All Rights Reserved +// +// Distributed under the "BSD License". See the accompanying LICENSE.rst file. + +#pragma once + +#include "../cpuinfo.hpp" + +namespace cpuid +{ +inline namespace STEINWURF_CPUID_VERSION +{ + +struct cpuinfo::impl +{ + impl() : + m_has_fpu(false), m_has_mmx(false), m_has_sse(false), m_has_sse2(false), + m_has_sse3(false), m_has_ssse3(false), m_has_sse4_1(false), + m_has_sse4_2(false), m_has_pclmulqdq(false), m_has_avx(false), + m_has_avx2(false), m_has_neon(false) + { + } + + bool m_has_fpu; + bool m_has_mmx; + bool m_has_sse; + bool m_has_sse2; + bool m_has_sse3; + bool m_has_ssse3; + bool m_has_sse4_1; + bool m_has_sse4_2; + bool m_has_pclmulqdq; + bool m_has_avx; + bool m_has_avx2; + bool m_has_neon; +}; +} +} diff --git a/src/external/cpuid/src/cpuid/detail/extract_x86_flags.hpp b/src/external/cpuid/src/cpuid/detail/extract_x86_flags.hpp new file mode 100644 index 00000000..eee98190 --- /dev/null +++ b/src/external/cpuid/src/cpuid/detail/extract_x86_flags.hpp @@ -0,0 +1,39 @@ +// Copyright (c) 2013 Steinwurf ApS +// All Rights Reserved +// +// Distributed under the "BSD License". See the accompanying LICENSE.rst file. + +#pragma once + +#include + +#include "cpuinfo_impl.hpp" + +namespace cpuid +{ +inline namespace STEINWURF_CPUID_VERSION +{ +void extract_x86_flags(cpuinfo::impl& info, uint32_t ecx, uint32_t edx) +{ + // Instruction set flags + + info.m_has_fpu = (edx & (1 << 0)) != 0; + info.m_has_mmx = (edx & (1 << 23)) != 0; + info.m_has_sse = (edx & (1 << 25)) != 0; + info.m_has_sse2 = (edx & (1 << 26)) != 0; + info.m_has_sse3 = (ecx & (1 << 0)) != 0; + info.m_has_ssse3 = (ecx & (1 << 9)) != 0; + info.m_has_sse4_1 = (ecx & (1 << 19)) != 0; + info.m_has_sse4_2 = (ecx & (1 << 20)) != 0; + info.m_has_pclmulqdq = (ecx & (1 << 1)) != 0; + info.m_has_avx = (ecx & (1 << 28)) != 0; +} + +void extract_x86_extended_flags(cpuinfo::impl& info, uint32_t ebx) +{ + // Extended instruction set flags + + info.m_has_avx2 = (ebx & (1 << 5)) != 0; +} +} +} diff --git a/src/external/cpuid/src/cpuid/detail/init_gcc_x86.hpp b/src/external/cpuid/src/cpuid/detail/init_gcc_x86.hpp new file mode 100644 index 00000000..916175b5 --- /dev/null +++ b/src/external/cpuid/src/cpuid/detail/init_gcc_x86.hpp @@ -0,0 +1,73 @@ +// Copyright (c) 2013 Steinwurf ApS +// All Rights Reserved +// +// Distributed under the "BSD License". See the accompanying LICENSE.rst file. + +#pragma once + +#include + +#include "cpuinfo_impl.hpp" +#include "extract_x86_flags.hpp" + +namespace cpuid +{ +inline namespace STEINWURF_CPUID_VERSION +{ +// Reference for this code is Intel's recommendation for detecting AVX2 +// on Haswell located here: http://goo.gl/c6IkGX +void run_cpuid(uint32_t eax, uint32_t ecx, uint32_t* abcd) +{ + uint32_t ebx = 0, edx = 0; + +#if defined(__i386__) && defined(__PIC__) + // If PIC used under 32-bit, EBX cannot be clobbered + // EBX is saved to EDI and later restored + __asm__("movl %%ebx, %%edi;" + "cpuid;" + "xchgl %%ebx, %%edi;" + : "=D"(ebx), "+a"(eax), "+c"(ecx), "=d"(edx)); +#else + __asm__("cpuid;" : "+b"(ebx), "+a"(eax), "+c"(ecx), "=d"(edx)); +#endif + + abcd[0] = eax; + abcd[1] = ebx; + abcd[2] = ecx; + abcd[3] = edx; +} + +/// @todo Document +void init_cpuinfo(cpuinfo::impl& info) +{ + // Note: We need to capture these 4 registers, otherwise we get + // a segmentation fault on 32-bit Linux + uint32_t output[4]; + + // The register information per input can be extracted from here: + // http://en.wikipedia.org/wiki/CPUID + + // CPUID should be called with EAX=0 first, as this will return the + // maximum supported EAX input value for future calls + run_cpuid(0, 0, output); + uint32_t maximum_index = output[0]; + + // Set registers for basic flag extraction + // All CPUs should support index=1 + if (maximum_index >= 1U) + { + run_cpuid(1, 0, output); + extract_x86_flags(info, output[2], output[3]); + } + + // Set registers for extended flags extraction using index=7 + // This operation is not supported on older CPUs, so it should be skipped + // to avoid incorrect results + if (maximum_index >= 7U) + { + run_cpuid(7, 0, output); + extract_x86_extended_flags(info, output[1]); + } +} +} +} diff --git a/src/external/cpuid/src/cpuid/detail/init_ios_clang_arm.hpp b/src/external/cpuid/src/cpuid/detail/init_ios_clang_arm.hpp new file mode 100644 index 00000000..5eae039f --- /dev/null +++ b/src/external/cpuid/src/cpuid/detail/init_ios_clang_arm.hpp @@ -0,0 +1,30 @@ +// Copyright (c) 2013 Steinwurf ApS +// All Rights Reserved +// +// Distributed under the "BSD License". See the accompanying LICENSE.rst file. + +#pragma once + +#include "cpuinfo_impl.hpp" + +namespace cpuid +{ +inline namespace STEINWURF_CPUID_VERSION +{ +/// @todo docs +void init_cpuinfo(cpuinfo::impl& info) +{ + // The __ARM_NEON__ macro will be defined by the Apple Clang compiler + // when targeting ARMv7 processors that have NEON. + // The compiler guarantees this capability, so there is no benefit + // in doing a runtime check. More info in this SO answer: + // http://stackoverflow.com/a/1601234 + +#if defined __ARM_NEON__ + info.m_has_neon = true; +#else + info.m_has_neon = false; +#endif +} +} +} diff --git a/src/external/cpuid/src/cpuid/detail/init_linux_gcc_arm.hpp b/src/external/cpuid/src/cpuid/detail/init_linux_gcc_arm.hpp new file mode 100644 index 00000000..2895ac4b --- /dev/null +++ b/src/external/cpuid/src/cpuid/detail/init_linux_gcc_arm.hpp @@ -0,0 +1,64 @@ +// Copyright (c) 2013 Steinwurf ApS +// All Rights Reserved +// +// Distributed under the "BSD License". See the accompanying LICENSE.rst file. + +#pragma once + +#include +#include +#include + +#include +#include +#include +#include + +#include "cpuinfo_impl.hpp" + +namespace cpuid +{ +inline namespace STEINWURF_CPUID_VERSION +{ +/// @todo docs +void init_cpuinfo(cpuinfo::impl& info) +{ +#if defined(__aarch64__) + // The Advanced SIMD (NEON) instruction set is required on AArch64 + // (64-bit ARM). Note that /proc/cpuinfo will display "asimd" instead of + // "neon" in the Features list on a 64-bit ARM CPU. + info.m_has_neon = true; +#else + // Runtime detection of NEON is necessary on 32-bit ARM CPUs + // + // Follow recommendation from Cortex-A Series Programmer's guide + // in Section 20.1.7 Detecting NEON. The guide is available at + // Steinwurf's Google drive: steinwurf/technical/experimental/cpuid + + auto cpufile = open("/proc/self/auxv", O_RDONLY); + assert(cpufile); + + Elf32_auxv_t auxv; + + if (cpufile >= 0) + { + const auto size_auxv_t = sizeof(Elf32_auxv_t); + while (read(cpufile, &auxv, size_auxv_t) == size_auxv_t) + { + if (auxv.a_type == AT_HWCAP) + { + info.m_has_neon = (auxv.a_un.a_val & 4096) != 0; + break; + } + } + + close(cpufile); + } + else + { + info.m_has_neon = false; + } +#endif +} +} +} diff --git a/src/external/cpuid/src/cpuid/detail/init_msvc_arm.hpp b/src/external/cpuid/src/cpuid/detail/init_msvc_arm.hpp new file mode 100644 index 00000000..60cbf3f7 --- /dev/null +++ b/src/external/cpuid/src/cpuid/detail/init_msvc_arm.hpp @@ -0,0 +1,26 @@ +// Copyright (c) 2013 Steinwurf ApS +// All Rights Reserved +// +// Distributed under the "BSD License". See the accompanying LICENSE.rst file. + +#pragma once + +#include "cpuinfo_impl.hpp" + +namespace cpuid +{ +inline namespace STEINWURF_CPUID_VERSION +{ +void init_cpuinfo(cpuinfo::impl& info) +{ + // Visual Studio 2012 (and above) guarantees the NEON capability when + // compiling for Windows Phone 8 (and above) + +#if defined(PLATFORM_WINDOWS_PHONE) + info.m_has_neon = true; +#else + info.m_has_neon = false; +#endif +} +} +} diff --git a/src/external/cpuid/src/cpuid/detail/init_msvc_x86.hpp b/src/external/cpuid/src/cpuid/detail/init_msvc_x86.hpp new file mode 100644 index 00000000..7ce670a9 --- /dev/null +++ b/src/external/cpuid/src/cpuid/detail/init_msvc_x86.hpp @@ -0,0 +1,52 @@ +// Copyright (c) 2013 Steinwurf ApS +// All Rights Reserved +// +// Distributed under the "BSD License". See the accompanying LICENSE.rst file. + +#pragma once + +#include + +#include "cpuinfo_impl.hpp" +#include "extract_x86_flags.hpp" + +namespace cpuid +{ +inline namespace STEINWURF_CPUID_VERSION +{ +/// @todo docs +void init_cpuinfo(cpuinfo::impl& info) +{ + int registers[4]; + + /// According to the msvc docs eax, ebx, ecx and edx are + /// stored (in that order) in the array passed to the __cpuid + /// function. + + // The register information per input can be extracted from here: + // http://en.wikipedia.org/wiki/CPUID + + // CPUID should be called with EAX=0 first, as this will return the + // maximum supported EAX input value for future calls + __cpuid(registers, 0); + uint32_t maximum_eax = registers[0]; + + // Set registers for basic flag extraction, eax=1 + // All CPUs should support index=1 + if (maximum_eax >= 1U) + { + __cpuid(registers, 1); + extract_x86_flags(info, registers[2], registers[3]); + } + + // Set registers for extended flags extraction, eax=7 and ecx=0 + // This operation is not supported on older CPUs, so it should be skipped + // to avoid incorrect results + if (maximum_eax >= 7U) + { + __cpuidex(registers, 7, 0); + extract_x86_extended_flags(info, registers[1]); + } +} +} +} diff --git a/src/external/cpuid/src/cpuid/detail/init_unknown.hpp b/src/external/cpuid/src/cpuid/detail/init_unknown.hpp new file mode 100644 index 00000000..ff876f9f --- /dev/null +++ b/src/external/cpuid/src/cpuid/detail/init_unknown.hpp @@ -0,0 +1,20 @@ +// Copyright (c) 2013 Steinwurf ApS +// All Rights Reserved +// +// Distributed under the "BSD License". See the accompanying LICENSE.rst file. + +#pragma once + +#include "cpuinfo_impl.hpp" + +namespace cpuid +{ +inline namespace STEINWURF_CPUID_VERSION +{ +/// @todo docs +void init_cpuinfo(cpuinfo::impl& info) +{ + (void)info; +} +} +} diff --git a/src/external/cpuid/src/cpuid/version.cpp b/src/external/cpuid/src/cpuid/version.cpp new file mode 100644 index 00000000..8b35150a --- /dev/null +++ b/src/external/cpuid/src/cpuid/version.cpp @@ -0,0 +1,18 @@ +// Copyright (c) 2013 Steinwurf ApS +// All Rights Reserved +// +// Distributed under the "BSD License". See the accompanying LICENSE.rst file. + +#include "version.hpp" + +namespace cpuid +{ + +inline namespace STEINWURF_CPUID_VERSION +{ +std::string version() +{ + return "6.3.1"; +} +} +} diff --git a/src/external/cpuid/src/cpuid/version.hpp b/src/external/cpuid/src/cpuid/version.hpp new file mode 100644 index 00000000..9bb4fb87 --- /dev/null +++ b/src/external/cpuid/src/cpuid/version.hpp @@ -0,0 +1,21 @@ +// Copyright (c) 2013 Steinwurf ApS +// All Rights Reserved +// +// Distributed under the "BSD License". See the accompanying LICENSE.rst file. + +#pragma once + +#include + +namespace cpuid +{ +/// Here we define the STEINWURF_CPUID_VERSION this should be updated on each +/// release +#define STEINWURF_CPUID_VERSION v6_3_1 + +inline namespace STEINWURF_CPUID_VERSION +{ +/// @return The version of the library as string +std::string version(); +} +}