Ensure correct output for DAMAX with softfp
[platform/upstream/openblas.git] / cpuid_power.c
1 /*********************************************************************/
2 /* Copyright 2009, 2010 The University of Texas at Austin.           */
3 /* All rights reserved.                                              */
4 /*                                                                   */
5 /* Redistribution and use in source and binary forms, with or        */
6 /* without modification, are permitted provided that the following   */
7 /* conditions are met:                                               */
8 /*                                                                   */
9 /*   1. Redistributions of source code must retain the above         */
10 /*      copyright notice, this list of conditions and the following  */
11 /*      disclaimer.                                                  */
12 /*                                                                   */
13 /*   2. Redistributions in binary form must reproduce the above      */
14 /*      copyright notice, this list of conditions and the following  */
15 /*      disclaimer in the documentation and/or other materials       */
16 /*      provided with the distribution.                              */
17 /*                                                                   */
18 /*    THIS  SOFTWARE IS PROVIDED  BY THE  UNIVERSITY OF  TEXAS AT    */
19 /*    AUSTIN  ``AS IS''  AND ANY  EXPRESS OR  IMPLIED WARRANTIES,    */
20 /*    INCLUDING, BUT  NOT LIMITED  TO, THE IMPLIED  WARRANTIES OF    */
21 /*    MERCHANTABILITY  AND FITNESS FOR  A PARTICULAR  PURPOSE ARE    */
22 /*    DISCLAIMED.  IN  NO EVENT SHALL THE UNIVERSITY  OF TEXAS AT    */
23 /*    AUSTIN OR CONTRIBUTORS BE  LIABLE FOR ANY DIRECT, INDIRECT,    */
24 /*    INCIDENTAL,  SPECIAL, EXEMPLARY,  OR  CONSEQUENTIAL DAMAGES    */
25 /*    (INCLUDING, BUT  NOT LIMITED TO,  PROCUREMENT OF SUBSTITUTE    */
26 /*    GOODS  OR  SERVICES; LOSS  OF  USE,  DATA,  OR PROFITS;  OR    */
27 /*    BUSINESS INTERRUPTION) HOWEVER CAUSED  AND ON ANY THEORY OF    */
28 /*    LIABILITY, WHETHER  IN CONTRACT, STRICT  LIABILITY, OR TORT    */
29 /*    (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY WAY OUT    */
30 /*    OF  THE  USE OF  THIS  SOFTWARE,  EVEN  IF ADVISED  OF  THE    */
31 /*    POSSIBILITY OF SUCH DAMAGE.                                    */
32 /*                                                                   */
33 /* The views and conclusions contained in the software and           */
34 /* documentation are those of the authors and should not be          */
35 /* interpreted as representing official policies, either expressed   */
36 /* or implied, of The University of Texas at Austin.                 */
37 /*********************************************************************/
38
39 #include  <sys/utsname.h>
40 #ifdef _AIX
41 #include <sys/vminfo.h>
42 #endif
43 #ifdef __APPLE__
44 #include <mach/mach.h>
45 #include <mach/mach_host.h>
46 #include <mach/host_info.h>
47 #include <mach/machine.h>
48 #endif
49
50 #define CPUTYPE_UNKNOWN    0
51 #define CPUTYPE_POWER3     1
52 #define CPUTYPE_POWER4     2
53 #define CPUTYPE_PPC970     3
54 #define CPUTYPE_POWER5     4
55 #define CPUTYPE_POWER6     5
56 #define CPUTYPE_CELL       6
57 #define CPUTYPE_PPCG4      7
58 #define CPUTYPE_POWER8     8
59 #define CPUTYPE_POWER9     9
60
61 char *cpuname[] = {
62   "UNKNOWN",
63   "POWER3",
64   "POWER4",
65   "PPC970",
66   "POWER5",
67   "POWER6",
68   "CELL",
69   "PPCG4",
70   "POWER8",
71   "POWER9"
72 };
73
74 char *lowercpuname[] = {
75   "unknown",
76   "power3",
77   "power4",
78   "ppc970",
79   "power5",
80   "power6",
81   "cell",
82   "ppcg4",
83   "power8",
84   "power9"      
85 };
86
87 char *corename[] = {
88   "UNKNOWN",
89   "POWER3",
90   "POWER4",
91   "POWER4",
92   "POWER4",
93   "POWER6",
94   "CELL",
95   "PPCG4",
96   "POWER8",
97   "POWER9"      
98 };
99
100 int detect(void){
101
102 #ifdef linux
103   FILE *infile;
104   char buffer[512], *p;
105
106   p = (char *)NULL;
107   infile = fopen("/proc/cpuinfo", "r");
108   while (fgets(buffer, sizeof(buffer), infile)){
109     if (!strncmp("cpu", buffer, 3)){
110         p = strchr(buffer, ':') + 2;
111 #if 0
112         fprintf(stderr, "%s\n", p);
113 #endif
114         break;
115       }
116   }
117
118   fclose(infile);
119
120   if (!strncasecmp(p, "POWER3", 6)) return CPUTYPE_POWER3;
121   if (!strncasecmp(p, "POWER4", 6)) return CPUTYPE_POWER4;
122   if (!strncasecmp(p, "PPC970", 6)) return CPUTYPE_PPC970;
123   if (!strncasecmp(p, "POWER5", 6)) return CPUTYPE_POWER5;
124   if (!strncasecmp(p, "POWER6", 6)) return CPUTYPE_POWER6;
125   if (!strncasecmp(p, "POWER7", 6)) return CPUTYPE_POWER6;
126   if (!strncasecmp(p, "POWER8", 6)) return CPUTYPE_POWER8;
127   if (!strncasecmp(p, "POWER9", 6)) return CPUTYPE_POWER9;
128   if (!strncasecmp(p, "Cell",   4)) return CPUTYPE_CELL;
129   if (!strncasecmp(p, "7447",   4)) return CPUTYPE_PPCG4;
130
131   return CPUTYPE_UNKNOWN;
132 #endif
133
134 #ifdef _AIX
135   FILE *infile;
136   char buffer[512], *p;
137
138   p = (char *)NULL;
139   infile = popen("prtconf|grep 'Processor Type'", "r");
140   while (fgets(buffer, sizeof(buffer), infile)){
141     if (!strncmp("Pro", buffer, 3)){
142         p = strchr(buffer, ':') + 2;
143 #if 0
144         fprintf(stderr, "%s\n", p);
145 #endif
146         break;
147       }
148   }
149
150   pclose(infile);
151
152   if (!strncasecmp(p, "POWER3", 6)) return CPUTYPE_POWER3;
153   if (!strncasecmp(p, "POWER4", 6)) return CPUTYPE_POWER4;
154   if (!strncasecmp(p, "PPC970", 6)) return CPUTYPE_PPC970;
155   if (!strncasecmp(p, "POWER5", 6)) return CPUTYPE_POWER5;
156   if (!strncasecmp(p, "POWER6", 6)) return CPUTYPE_POWER6;
157   if (!strncasecmp(p, "POWER7", 6)) return CPUTYPE_POWER6;
158   if (!strncasecmp(p, "POWER8", 6)) return CPUTYPE_POWER8;
159   if (!strncasecmp(p, "POWER9", 6)) return CPUTYPE_POWER9;
160   if (!strncasecmp(p, "Cell",   4)) return CPUTYPE_CELL;
161   if (!strncasecmp(p, "7447",   4)) return CPUTYPE_PPCG4;
162   return CPUTYPE_POWER5;
163 #endif
164
165 #ifdef __APPLE__
166   host_basic_info_data_t   hostInfo;
167   mach_msg_type_number_t  infoCount;
168
169   infoCount = HOST_BASIC_INFO_COUNT;
170   host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo, &infoCount);
171
172   if (hostInfo.cpu_subtype == CPU_SUBTYPE_POWERPC_7450) return CPUTYPE_PPCG4;
173   if (hostInfo.cpu_subtype == CPU_SUBTYPE_POWERPC_970)  return CPUTYPE_PPC970;
174
175   return  CPUTYPE_PPC970;
176 #endif
177
178 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
179 int id;
180 __asm __volatile("mfpvr %0" : "=r"(id));
181 switch ( id >> 16 ) {
182   case 0x4e: // POWER9
183     return CPUTYPE_POWER9;
184     break;
185   case 0x4d:
186   case 0x4b: // POWER8/8E 
187     return CPUTYPE_POWER8;
188     break;
189   case 0x4a:
190   case 0x3f:  // POWER7/7E
191     return CPUTYPE_POWER6; 
192     break;
193   case 0x3e:
194     return CPUTYPE_POWER6;
195     break;
196   case 0x3a:
197     return CPUTYPE_POWER5;
198     break;
199   case 0x35:
200   case 0x38: // POWER4 /4+ 
201     return CPUTYPE_POWER4;
202     break;
203   case 0x40:
204   case 0x41: // POWER3 /3+ 
205     return CPUTYPE_POWER3;
206     break;
207   case 0x39:
208   case 0x3c:
209   case 0x44:
210   case 0x45:
211     return CPUTYPE_PPC970;
212     break;
213   case 0x70: 
214     return CPUTYPE_CELL;
215     break;
216   case 0x8003: 
217     return CPUTYPE_PPCG4;
218     break;
219   default:  
220     return  CPUTYPE_UNKNOWN;
221   }
222 #endif
223 }
224
225 void get_architecture(void){
226   printf("POWER");
227 }
228
229 void get_subdirname(void){
230     printf("power");
231 }
232
233
234 void get_subarchitecture(void){
235   printf("%s", cpuname[detect()]);
236 }
237
238 void get_cpuconfig(void){
239 #if 0
240 #ifdef _AIX
241   struct vminfo info;
242 #endif
243 #endif
244
245   printf("#define %s\n", cpuname[detect()]);
246   printf("#define CORE_%s\n", corename[detect()]);
247
248   printf("#define L1_DATA_SIZE 32768\n");
249   printf("#define L1_DATA_LINESIZE 128\n");
250   printf("#define L2_SIZE 524288\n");
251   printf("#define L2_LINESIZE 128 \n");
252   printf("#define DTB_DEFAULT_ENTRIES 128\n");
253   printf("#define DTB_SIZE 4096\n");
254   printf("#define L2_ASSOCIATIVE 8\n");
255
256 #if 0
257 #ifdef _AIX
258   if (vmgetinfo(&info, VMINFO, 0) == 0) {
259     if ((info.lgpg_size >> 20) >= 1024) {
260       printf("#define ALLOC_HUGETLB\n");
261     }
262   }
263 #endif
264 #endif
265
266 }
267
268 void get_libname(void){
269   printf("%s", lowercpuname[detect()]);
270 }
271
272 char *get_corename(void){
273   return cpuname[detect()];
274 }