summaryrefslogtreecommitdiffstats
path: root/contrib/libottery/ottery_cpuinfo.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/libottery/ottery_cpuinfo.c')
-rw-r--r--contrib/libottery/ottery_cpuinfo.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/contrib/libottery/ottery_cpuinfo.c b/contrib/libottery/ottery_cpuinfo.c
new file mode 100644
index 0000000..2e8bdaa
--- /dev/null
+++ b/contrib/libottery/ottery_cpuinfo.c
@@ -0,0 +1,88 @@
+/* Libottery by Nick Mathewson.
+
+ This software has been dedicated to the public domain under the CC0
+ public domain dedication.
+
+ To the extent possible under law, the person who associated CC0 with
+ libottery has waived all copyright and related or neighboring rights
+ to libottery.
+
+ You should have received a copy of the CC0 legalcode along with this
+ work in doc/cc0.txt. If not, see
+ <http://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+#include "ottery-internal.h"
+#include <stdint.h>
+
+#if defined(i386) || \
+ defined(__i386) || \
+ defined(__M_IX86) || \
+ defined(_M_IX86)
+#define X86
+#elif defined(__x86_64) || \
+ defined(_M_AMD64)
+#define X86
+#define X86_64
+#endif
+
+#if defined(__arm__) || \
+ defined(_M_ARM)
+#define ARM
+#endif
+
+#if defined(X86)
+#ifdef _MSC_VER
+#include <intrin.h>
+#define cpuid(a,b) __cpuid((b), (a))
+#else
+static void
+cpuid(int index, int regs[4])
+{
+ unsigned int eax, ebx, ecx, edx;
+#ifdef X86_64
+ __asm("cpuid" : "=a"(eax), "=b" (ebx), "=c"(ecx), "=d"(edx)
+ : "0"(index));
+#else
+ __asm volatile(
+ "xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1"
+ : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx)
+ : "0" (index)
+ : "cc" );
+#endif
+
+ regs[0] = eax;
+ regs[1] = ebx;
+ regs[2] = ecx;
+ regs[3] = edx;
+}
+#endif
+#endif
+
+static uint32_t disabled_cpu_capabilities = 0;
+
+void
+ottery_disable_cpu_capabilities_(uint32_t disable)
+{
+ disabled_cpu_capabilities |= disable;
+}
+
+uint32_t
+ottery_get_cpu_capabilities_(void)
+{
+#ifdef X86
+ uint32_t cap = 0;
+ int res[4];
+ cpuid(1, res);
+ if (res[3] & (1<<26))
+ cap |= OTTERY_CPUCAP_SIMD;
+ if (res[2] & (1<<9))
+ cap |= OTTERY_CPUCAP_SSSE3;
+ if (res[2] & (1<<25))
+ cap |= OTTERY_CPUCAP_AES;
+ if (res[2] & (1<<30))
+ cap |= OTTERY_CPUCAP_RAND;
+#else
+ uint32_t cap = OTTERY_CPUCAP_SIMD;
+#endif
+ return cap & ~disabled_cpu_capabilities;
+}