]> AND Private Git Repository - Cipher_code.git/blob - IDA_new/gf-complete/src/gf_cpu.c
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
Merge branch 'master' of ssh://info.iut-bm.univ-fcomte.fr/Cipher_code
[Cipher_code.git] / IDA_new / gf-complete / src / gf_cpu.c
1 /*
2  * GF-Complete: A Comprehensive Open Source Library for Galois Field Arithmetic
3  * James S. Plank, Ethan L. Miller, Kevin M. Greenan,
4  * Benjamin A. Arnold, John A. Burnum, Adam W. Disney, Allen C. McBride.
5  *
6  * gf_cpu.h
7  *
8  * Identifies whether the CPU supports SIMD instructions at runtime.
9  */
10
11 #include <stdio.h>
12 #include <stdlib.h>
13
14 int gf_cpu_identified = 0;
15
16 int gf_cpu_supports_intel_pclmul = 0;
17 int gf_cpu_supports_intel_sse4 = 0;
18 int gf_cpu_supports_intel_ssse3 = 0;
19 int gf_cpu_supports_intel_sse3 = 0;
20 int gf_cpu_supports_intel_sse2 = 0;
21 int gf_cpu_supports_arm_neon = 0;
22
23 #if defined(__x86_64__)
24
25 /* CPUID Feature Bits */
26
27 /* ECX */
28 #define GF_CPU_SSE3     (1 << 0)
29 #define GF_CPU_PCLMUL   (1 << 1)
30 #define GF_CPU_SSSE3    (1 << 9)
31 #define GF_CPU_SSE41    (1 << 19)
32 #define GF_CPU_SSE42    (1 << 20)
33
34 /* EDX */
35 #define GF_CPU_SSE2     (1 << 26)
36
37 #if defined(_MSC_VER)
38
39 #define cpuid(info, x)    __cpuidex(info, x, 0)
40
41 #elif defined(__GNUC__)
42
43 #include <cpuid.h>
44 void cpuid(int info[4], int InfoType){
45     __cpuid_count(InfoType, 0, info[0], info[1], info[2], info[3]);
46 }
47
48 #else
49
50 #error please add a way to detect CPU SIMD support at runtime 
51
52 #endif
53
54 void gf_cpu_identify(void)
55 {
56   if (gf_cpu_identified) {
57       return;
58   }
59
60   int reg[4];
61
62   cpuid(reg, 1);
63
64 #if defined(INTEL_SSE4_PCLMUL)
65   if ((reg[2] & GF_CPU_PCLMUL) != 0 && !getenv("GF_COMPLETE_DISABLE_SSE4_PCLMUL")) {
66       gf_cpu_supports_intel_pclmul = 1;
67 #ifdef DEBUG_CPU_DETECTION
68       printf("#gf_cpu_supports_intel_pclmul\n");
69 #endif
70   }
71 #endif
72
73 #if defined(INTEL_SSE4)
74   if (((reg[2] & GF_CPU_SSE42) != 0 || (reg[2] & GF_CPU_SSE41) != 0) && !getenv("GF_COMPLETE_DISABLE_SSE4")) {
75       gf_cpu_supports_intel_sse4 = 1;
76 #ifdef DEBUG_CPU_DETECTION
77       printf("#gf_cpu_supports_intel_sse4\n");
78 #endif
79   }
80 #endif
81
82 #if defined(INTEL_SSSE3)
83   if ((reg[2] & GF_CPU_SSSE3) != 0 && !getenv("GF_COMPLETE_DISABLE_SSSE3")) {
84       gf_cpu_supports_intel_ssse3 = 1;
85 #ifdef DEBUG_CPU_DETECTION
86       printf("#gf_cpu_supports_intel_ssse3\n");
87 #endif
88   }
89 #endif
90
91 #if defined(INTEL_SSE3)
92   if ((reg[2] & GF_CPU_SSE3) != 0 && !getenv("GF_COMPLETE_DISABLE_SSE3")) {
93       gf_cpu_supports_intel_sse3 = 1;
94 #ifdef DEBUG_CPU_DETECTION
95       printf("#gf_cpu_supports_intel_sse3\n");
96 #endif
97   }
98 #endif
99
100 #if defined(INTEL_SSE2)
101   if ((reg[3] & GF_CPU_SSE2) != 0 && !getenv("GF_COMPLETE_DISABLE_SSE2")) {
102       gf_cpu_supports_intel_sse2 = 1;
103 #ifdef DEBUG_CPU_DETECTION
104       printf("#gf_cpu_supports_intel_sse2\n");
105 #endif
106   }
107 #endif
108
109   gf_cpu_identified = 1;
110 }
111
112 #elif defined(__arm__) || defined(__aarch64__)
113
114 #ifdef __linux__
115
116 #include <stdio.h>
117 #include <unistd.h>
118 #include <elf.h>
119 #include <linux/auxvec.h>
120 #include <asm/hwcap.h>
121 #include <fcntl.h>
122
123 unsigned long get_hwcap(unsigned long type) {
124     unsigned long hwcap = 0; 
125     int fd = open("/proc/self/auxv", O_RDONLY);
126     if (fd > 0) {
127         Elf32_auxv_t auxv;
128         while (read(fd, &auxv, sizeof(Elf32_auxv_t))) {
129             if (auxv.a_type == type) {
130                 hwcap = auxv.a_un.a_val;
131                 break;
132             }
133         }
134         close(fd);
135     }
136
137     return hwcap;
138 }
139
140 #endif // linux
141
142 void gf_cpu_identify(void)
143 {
144   if (gf_cpu_identified) {
145       return;
146   }
147
148 #if defined(ARM_NEON)
149   if (!getenv("GF_COMPLETE_DISABLE_NEON")) {
150 #if __linux__ && __arm__
151           gf_cpu_supports_arm_neon = (get_hwcap(AT_HWCAP) & HWCAP_NEON) > 0;
152 #elif __aarch64__
153     // ASIMD is supported on all aarch64 architectures
154           gf_cpu_supports_arm_neon = 1;
155 #else
156     // we assume that NEON is supported if the compiler supports
157     // NEON and we dont have a reliable way to detect runtime support.
158           gf_cpu_supports_arm_neon = 1;
159 #endif
160
161 #ifdef DEBUG_CPU_DETECTION
162     if (gf_cpu_supports_arm_neon) {
163       printf("#gf_cpu_supports_arm_neon\n");
164     }
165 #endif
166   }
167 #endif // defined(ARM_NEON)
168
169   gf_cpu_identified = 1;
170 }
171
172 #else // defined(__arm__) || defined(__aarch64__)
173
174 int gf_cpu_identify(void)
175 {
176     gf_cpu_identified = 1;
177     return 0;
178 }
179
180 #endif