1 //   Copyright Naoki Shibata and contributors 2010 - 2020.
2 // Distributed under the Boost Software License, Version 1.0.
3 //    (See accompanying file LICENSE.txt or copy at
4 //          http://www.boost.org/LICENSE_1_0.txt)
5 
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <stdint.h>
9 #include <assert.h>
10 
11 #include "misc.h"
12 
13 #if defined(__MINGW32__) || defined(__MINGW64__) || defined(_MSC_VER)
14 #include <sys/timeb.h>
15 
Sleef_malloc(size_t z)16 EXPORT void *Sleef_malloc(size_t z) { return _aligned_malloc(z, 256); }
Sleef_free(void * ptr)17 EXPORT void Sleef_free(void *ptr) { _aligned_free(ptr); }
18 
Sleef_currentTimeMicros()19 EXPORT uint64_t Sleef_currentTimeMicros() {
20   struct __timeb64 t;
21   _ftime64(&t);
22   return t.time * 1000000LL + t.millitm*1000;
23 }
24 #elif defined(__APPLE__)
25 #include <sys/time.h>
26 
Sleef_malloc(size_t z)27 EXPORT void *Sleef_malloc(size_t z) { void *ptr = NULL; posix_memalign(&ptr, 256, z); return ptr; }
Sleef_free(void * ptr)28 EXPORT void Sleef_free(void *ptr) { free(ptr); }
29 
Sleef_currentTimeMicros()30 EXPORT uint64_t Sleef_currentTimeMicros() {
31   struct timeval time;
32   gettimeofday(&time, NULL);
33   return (uint64_t)((time.tv_sec * 1000000LL) + time.tv_usec);
34 }
35 #else // #if defined(__MINGW32__) || defined(__MINGW64__) || defined(_MSC_VER)
36 #include <time.h>
37 #include <unistd.h>
38 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
39 #include <stdlib.h>
40 #else
41 #include <malloc.h>
42 #endif
43 
Sleef_malloc(size_t z)44 EXPORT void *Sleef_malloc(size_t z) { void *ptr = NULL; posix_memalign(&ptr, 4096, z); return ptr; }
Sleef_free(void * ptr)45 EXPORT void Sleef_free(void *ptr) { free(ptr); }
46 
Sleef_currentTimeMicros()47 EXPORT uint64_t Sleef_currentTimeMicros() {
48   struct timespec tp;
49   clock_gettime(CLOCK_MONOTONIC, &tp);
50   return (uint64_t)tp.tv_sec * 1000000LL + ((uint64_t)tp.tv_nsec/1000);
51 }
52 #endif // #if defined(__MINGW32__) || defined(__MINGW64__) || defined(_MSC_VER)
53 
54 #ifdef _MSC_VER
55 #include <intrin.h>
Sleef_x86CpuID(int32_t out[4],uint32_t eax,uint32_t ecx)56 EXPORT void Sleef_x86CpuID(int32_t out[4], uint32_t eax, uint32_t ecx) {
57   __cpuidex(out, eax, ecx);
58 }
59 #else
60 #if defined(__x86_64__) || defined(__i386__)
Sleef_x86CpuID(int32_t out[4],uint32_t eax,uint32_t ecx)61 EXPORT void Sleef_x86CpuID(int32_t out[4], uint32_t eax, uint32_t ecx) {
62   uint32_t a, b, c, d;
63   __asm__ __volatile__ ("cpuid" : "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "a" (eax), "c"(ecx));
64   out[0] = a; out[1] = b; out[2] = c; out[3] = d;
65 }
66 #endif
67 #endif
68 
69 #if defined(__i386__) || defined(__x86_64__) || defined(_MSC_VER)
70 static char x86BrandString[256];
71 
Sleef_getCpuIdString()72 EXPORT char *Sleef_getCpuIdString() {
73   union {
74     int32_t info[4];
75     uint8_t str[16];
76   } u;
77   int i,j;
78   char *p;
79 
80   p = x86BrandString;
81 
82   for(i=0;i<3;i++) {
83     Sleef_x86CpuID(u.info, i + 0x80000002, 0);
84 
85     for(j=0;j<16;j++) {
86       *p++ = u.str[j];
87     }
88   }
89 
90   *p++ = '\n';
91 
92   return x86BrandString;
93 }
94 #else
Sleef_getCpuIdString()95 EXPORT char *Sleef_getCpuIdString() {
96   return "Unknown architecture";
97 }
98 #endif
99