Add an AVX512 enabled DSCAL function
[platform/upstream/openblas.git] / cpuid_arm64.c
1 /**************************************************************************
2   Copyright (c) 2013, The OpenBLAS Project
3   All rights reserved.
4   Redistribution and use in source and binary forms, with or without
5   modification, are permitted provided that the following conditions are
6   met:
7   1. Redistributions of source code must retain the above copyright
8   notice, this list of conditions and the following disclaimer.
9   2. Redistributions in binary form must reproduce the above copyright
10   notice, this list of conditions and the following disclaimer in
11   the documentation and/or other materials provided with the
12   distribution.
13   3. Neither the name of the OpenBLAS project nor the names of
14   its contributors may be used to endorse or promote products
15   derived from this software without specific prior written permission.
16   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19   ARE DISCLAIMED. IN NO EVENT SHALL THE OPENBLAS PROJECT OR CONTRIBUTORS BE
20   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23   CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
25   USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26   *****************************************************************************/
27
28 #include <string.h>
29
30 #define CPU_UNKNOWN             0
31 #define CPU_ARMV8               1
32 #define CPU_CORTEXA57           2
33 #define CPU_VULCAN              3
34 #define CPU_THUNDERX            4
35 #define CPU_THUNDERX2T99        5
36
37 static char *cpuname[] = {
38   "UNKNOWN",
39   "ARMV8" ,
40   "CORTEXA57",
41   "VULCAN",
42   "THUNDERX",
43   "THUNDERX2T99"
44 };
45
46 static char *cpuname_lower[] = {
47   "unknown",
48   "armv8" ,
49   "cortexa57",
50   "vulcan",
51   "thunderx",
52   "thunderx2t99"
53 };
54
55 int get_feature(char *search)
56 {
57
58 #ifdef linux
59         FILE *infile;
60         char buffer[2048], *p,*t;
61         p = (char *) NULL ;
62
63         infile = fopen("/proc/cpuinfo", "r");
64
65         while (fgets(buffer, sizeof(buffer), infile))
66         {
67
68                 if (!strncmp("Features", buffer, 8))
69                 {
70                         p = strchr(buffer, ':') + 2;
71                         break;
72                 }
73         }
74
75         fclose(infile);
76
77
78         if( p == NULL ) return 0;
79
80         t = strtok(p," ");
81         while( t = strtok(NULL," "))
82         {
83                 if (!strcmp(t, search))   { return(1); }
84         }
85
86 #endif
87         return(0);
88 }
89
90
91 int detect(void)
92 {
93
94 #ifdef linux
95
96         FILE *infile;
97         char buffer[512], *p, *cpu_part = NULL, *cpu_implementer = NULL;
98         p = (char *) NULL ;
99
100         infile = fopen("/proc/cpuinfo", "r");
101         while (fgets(buffer, sizeof(buffer), infile)) {
102                 if ((cpu_part != NULL) && (cpu_implementer != NULL)) {
103                         break;
104                 }
105
106                 if ((cpu_part == NULL) && !strncmp("CPU part", buffer, 8)) {
107                         cpu_part = strchr(buffer, ':') + 2;
108                         cpu_part = strdup(cpu_part);
109                 } else if ((cpu_implementer == NULL) && !strncmp("CPU implementer", buffer, 15)) {
110                         cpu_implementer = strchr(buffer, ':') + 2;
111                         cpu_implementer = strdup(cpu_implementer);
112                 }
113         }
114
115         fclose(infile);
116         if(cpu_part != NULL && cpu_implementer != NULL) {
117                 if (strstr(cpu_implementer, "0x41") && 
118                 (strstr(cpu_part, "0xd07") || strstr(cpu_part,"0xd08") || strstr(cpu_part,"0xd03") ))
119                         return CPU_CORTEXA57; //or compatible A53, A72
120                 else if (strstr(cpu_part, "0x516") && strstr(cpu_implementer, "0x42"))
121                         return CPU_VULCAN;
122                 else if (strstr(cpu_part, "0x0a1") && strstr(cpu_implementer, "0x43"))
123                         return CPU_THUNDERX;
124                 else if (strstr(cpu_part, "0x0af") && strstr(cpu_implementer, "0x43"))
125                         return CPU_THUNDERX2T99;
126         }
127
128         p = (char *) NULL ;
129         infile = fopen("/proc/cpuinfo", "r");
130         while (fgets(buffer, sizeof(buffer), infile))
131         {
132
133                 if ((!strncmp("model name", buffer, 10)) || (!strncmp("Processor", buffer, 9)) ||
134                     (!strncmp("CPU architecture", buffer, 16)))
135                 {
136                         p = strchr(buffer, ':') + 2;
137                         break;
138                 }
139         }
140
141         fclose(infile);
142
143         if(p != NULL)
144         {
145
146                 if ((strstr(p, "AArch64")) || (strstr(p, "8")))
147                 {
148                         return CPU_ARMV8;
149
150                 }
151
152
153         }
154 #endif
155
156         return CPU_UNKNOWN;
157 }
158
159 char *get_corename(void)
160 {
161         return cpuname[detect()];
162 }
163
164 void get_architecture(void)
165 {
166         printf("ARM64");
167 }
168
169 void get_subarchitecture(void)
170 {
171         int d = detect();
172         printf("%s", cpuname[d]);
173 }
174
175 void get_subdirname(void)
176 {
177         printf("arm64");
178 }
179
180 void get_cpuconfig(void)
181 {
182
183         int d = detect();
184         switch (d)
185         {
186
187                 case CPU_ARMV8:
188                         printf("#define ARMV8\n");
189                         printf("#define L1_DATA_SIZE 32768\n");
190                         printf("#define L1_DATA_LINESIZE 64\n");
191                         printf("#define L2_SIZE 262144\n");
192                         printf("#define L2_LINESIZE 64\n");
193                         printf("#define DTB_DEFAULT_ENTRIES 64\n");
194                         printf("#define DTB_SIZE 4096\n");
195                         printf("#define L2_ASSOCIATIVE 4\n");
196                         break;
197
198                 case CPU_VULCAN:
199                         printf("#define VULCAN                        \n");
200                         printf("#define HAVE_VFP                      \n");
201                         printf("#define HAVE_VFPV3                    \n");
202                         printf("#define HAVE_NEON                     \n");
203                         printf("#define HAVE_VFPV4                    \n");
204                         printf("#define L1_CODE_SIZE         32768    \n");
205                         printf("#define L1_CODE_LINESIZE     64       \n");
206                         printf("#define L1_CODE_ASSOCIATIVE  8        \n");
207                         printf("#define L1_DATA_SIZE         32768    \n");
208                         printf("#define L1_DATA_LINESIZE     64       \n");
209                         printf("#define L1_DATA_ASSOCIATIVE  8        \n");
210                         printf("#define L2_SIZE              262144   \n");
211                         printf("#define L2_LINESIZE          64       \n");
212                         printf("#define L2_ASSOCIATIVE       8        \n");
213                         printf("#define L3_SIZE              33554432 \n");
214                         printf("#define L3_LINESIZE          64       \n");
215                         printf("#define L3_ASSOCIATIVE       32       \n");
216                         printf("#define DTB_DEFAULT_ENTRIES  64       \n");
217                         printf("#define DTB_SIZE             4096     \n");
218                         break;
219
220                 case CPU_CORTEXA57:
221                         printf("#define CORTEXA57\n");
222                         printf("#define HAVE_VFP\n");
223                         printf("#define HAVE_VFPV3\n");
224                         printf("#define HAVE_NEON\n");
225                         printf("#define HAVE_VFPV4\n");
226                         printf("#define L1_CODE_SIZE 49152\n");
227                         printf("#define L1_CODE_LINESIZE 64\n");
228                         printf("#define L1_CODE_ASSOCIATIVE 3\n");
229                         printf("#define L1_DATA_SIZE 32768\n");
230                         printf("#define L1_DATA_LINESIZE 64\n");
231                         printf("#define L1_DATA_ASSOCIATIVE 2\n");
232                         printf("#define L2_SIZE 2097152\n");
233                         printf("#define L2_LINESIZE 64\n");
234                         printf("#define L2_ASSOCIATIVE 16\n");
235                         printf("#define DTB_DEFAULT_ENTRIES 64\n");
236                         printf("#define DTB_SIZE 4096\n");
237                         break;
238
239                 case CPU_THUNDERX:
240                         printf("#define ARMV8\n");
241                         printf("#define THUNDERX\n");
242                         printf("#define L1_DATA_SIZE 32768\n");
243                         printf("#define L1_DATA_LINESIZE 128\n");
244                         printf("#define L2_SIZE 16777216\n");
245                         printf("#define L2_LINESIZE 128\n");
246                         printf("#define DTB_DEFAULT_ENTRIES 64\n");
247                         printf("#define DTB_SIZE 4096\n");
248                         printf("#define L2_ASSOCIATIVE 16\n");
249                         break;
250
251                 case CPU_THUNDERX2T99:
252                         printf("#define VULCAN                        \n");
253                         printf("#define HAVE_VFP                      \n");
254                         printf("#define HAVE_VFPV3                    \n");
255                         printf("#define HAVE_NEON                     \n");
256                         printf("#define HAVE_VFPV4                    \n");
257                         printf("#define L1_CODE_SIZE         32768    \n");
258                         printf("#define L1_CODE_LINESIZE     64       \n");
259                         printf("#define L1_CODE_ASSOCIATIVE  8        \n");
260                         printf("#define L1_DATA_SIZE         32768    \n");
261                         printf("#define L1_DATA_LINESIZE     64       \n");
262                         printf("#define L1_DATA_ASSOCIATIVE  8        \n");
263                         printf("#define L2_SIZE              262144   \n");
264                         printf("#define L2_LINESIZE          64       \n");
265                         printf("#define L2_ASSOCIATIVE       8        \n");
266                         printf("#define L3_SIZE              33554432 \n");
267                         printf("#define L3_LINESIZE          64       \n");
268                         printf("#define L3_ASSOCIATIVE       32       \n");
269                         printf("#define DTB_DEFAULT_ENTRIES  64       \n");
270                         printf("#define DTB_SIZE             4096     \n");
271                         break;
272         }
273 }
274
275
276 void get_libname(void)
277 {
278         int d = detect();
279         printf("%s", cpuname_lower[d]);
280 }
281
282 void get_features(void)
283 {
284
285 #ifdef linux
286         FILE *infile;
287         char buffer[2048], *p,*t;
288         p = (char *) NULL ;
289
290         infile = fopen("/proc/cpuinfo", "r");
291
292         while (fgets(buffer, sizeof(buffer), infile))
293         {
294
295                 if (!strncmp("Features", buffer, 8))
296                 {
297                         p = strchr(buffer, ':') + 2;
298                         break;
299                 }
300         }
301
302         fclose(infile);
303
304
305         if( p == NULL ) return;
306
307         t = strtok(p," ");
308         while( t = strtok(NULL," "))
309         {
310         }
311
312 #endif
313         return;
314 }
315
316