OSDN Git Service

gcc/
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / driver-i386.c
1 /* Subroutines for the gcc driver.
2    Copyright (C) 2006, 2007 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING.  If not, write to
18 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.  */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include <stdlib.h>
26
27 const char *host_detect_local_cpu (int argc, const char **argv);
28
29 #ifdef GCC_VERSION
30 #define cpuid(num,a,b,c,d) \
31   asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" \
32                 : "=a" (a), "=r" (b), "=c" (c), "=d" (d)  \
33                 : "0" (num))
34
35 #define bit_CMPXCHG8B (1 << 8)
36 #define bit_CMOV (1 << 15)
37 #define bit_MMX (1 << 23)
38 #define bit_SSE (1 << 25)
39 #define bit_SSE2 (1 << 26)
40
41 #define bit_SSE3 (1 << 0)
42 #define bit_SSSE3 (1 << 9)
43 #define bit_SSE4a (1 << 6)
44 #define bit_CMPXCHG16B (1 << 13)
45
46 #define bit_LAHF_LM (1 << 0)
47 #define bit_3DNOW (1 << 31)
48 #define bit_3DNOWP (1 << 30)
49 #define bit_LM (1 << 29)
50
51 /* Returns parameters that describe L1_ASSOC associative cache of size
52    L1_SIZEKB with lines of size L1_LINE.  */
53
54 static char *
55 describe_cache (unsigned l1_sizekb, unsigned l1_line,
56                 unsigned l1_assoc ATTRIBUTE_UNUSED)
57 {
58   char size[1000], line[1000];
59   unsigned size_in_lines;
60
61   /* At the moment, gcc middle-end does not use the information about the
62      associativity of the cache.  */
63
64   size_in_lines = (l1_sizekb * 1024) / l1_line;
65
66   sprintf (size, "--param l1-cache-size=%u", size_in_lines);
67   sprintf (line, "--param l1-cache-line-size=%u", l1_line);
68
69   return concat (size, " ", line, " ", NULL);
70 }
71
72 /* Returns the description of caches for an AMD processor.  */
73
74 static char *
75 detect_caches_amd (unsigned max_ext_level)
76 {
77   unsigned eax, ebx, ecx, edx;
78   unsigned l1_sizekb, l1_line, l1_assoc;
79
80   if (max_ext_level < 0x80000005)
81     return NULL;
82
83   cpuid (0x80000005, eax, ebx, ecx, edx);
84
85   l1_line = ecx & 0xff;
86   l1_sizekb = (ecx >> 24) & 0xff;
87   l1_assoc = (ecx >> 16) & 0xff;
88
89   return describe_cache (l1_sizekb, l1_line, l1_assoc);
90 }
91
92 /* Stores the size of the L1 cache and cache line, and the associativity
93    of the cache according to REG to L1_SIZEKB, L1_LINE and L1_ASSOC.  */
94
95 static void
96 decode_caches_intel (unsigned reg, unsigned *l1_sizekb, unsigned *l1_line,
97                      unsigned *l1_assoc)
98 {
99   unsigned i, val;
100
101   if (((reg >> 31) & 1) != 0)
102     return;
103
104   for (i = 0; i < 4; i++)
105     {
106       val = reg & 0xff;
107       reg >>= 8;
108
109       switch (val)
110         {
111         case 0xa:
112           *l1_sizekb = 8;
113           *l1_line = 32;
114           *l1_assoc = 2;
115           break;
116         case 0xc:
117           *l1_sizekb = 16;
118           *l1_line = 32;
119           *l1_assoc = 4;
120           break;
121         case 0x2c:
122           *l1_sizekb = 32;
123           *l1_line = 64;
124           *l1_assoc = 8;
125           break;
126         case 0x60:
127           *l1_sizekb = 16;
128           *l1_line = 64;
129           *l1_assoc = 8;
130           break;
131         case 0x66:
132           *l1_sizekb = 8;
133           *l1_line = 64;
134           *l1_assoc = 4;
135           break;
136         case 0x67:
137           *l1_sizekb = 16;
138           *l1_line = 64;
139           *l1_assoc = 4;
140           break;
141         case 0x68:
142           *l1_sizekb = 32;
143           *l1_line = 64;
144           *l1_assoc = 4;
145           break;
146
147         default:
148           break;
149         }
150     }
151 }
152
153 /* Returns the description of caches for an intel processor.  */
154
155 static char *
156 detect_caches_intel (unsigned max_level)
157 {
158   unsigned eax, ebx, ecx, edx;
159   unsigned l1_sizekb = 0, l1_line = 0, assoc = 0;
160
161   if (max_level < 2)
162     return NULL;
163
164   cpuid (2, eax, ebx, ecx, edx);
165
166   decode_caches_intel (eax, &l1_sizekb, &l1_line, &assoc);
167   decode_caches_intel (ebx, &l1_sizekb, &l1_line, &assoc);
168   decode_caches_intel (ecx, &l1_sizekb, &l1_line, &assoc);
169   decode_caches_intel (edx, &l1_sizekb, &l1_line, &assoc);
170   if (!l1_sizekb)
171     return (char *) "";
172
173   return describe_cache (l1_sizekb, l1_line, assoc);
174 }
175
176 /* This will be called by the spec parser in gcc.c when it sees
177    a %:local_cpu_detect(args) construct.  Currently it will be called
178    with either "arch" or "tune" as argument depending on if -march=native
179    or -mtune=native is to be substituted.
180
181    It returns a string containing new command line parameters to be
182    put at the place of the above two options, depending on what CPU
183    this is executed.  E.g. "-march=k8" on an AMD64 machine
184    for -march=native.
185
186    ARGC and ARGV are set depending on the actual arguments given
187    in the spec.  */
188 const char *host_detect_local_cpu (int argc, const char **argv)
189 {
190   const char *cpu = NULL;
191   const char *cache = "";
192   const char *options = "";
193   enum processor_type processor = PROCESSOR_I386;
194   unsigned int eax, ebx, ecx, edx;
195   unsigned int max_level;
196   unsigned int vendor;
197   unsigned int ext_level;
198   unsigned char has_mmx = 0, has_3dnow = 0, has_3dnowp = 0, has_sse = 0;
199   unsigned char has_sse2 = 0, has_sse3 = 0, has_ssse3 = 0, has_cmov = 0;
200   unsigned char has_cmpxchg16b = 0, has_lahf_lm = 0;
201   unsigned char has_longmode = 0, has_cmpxchg8b = 0, has_sse4a = 0;
202   unsigned char is_amd = 0;
203   unsigned int family = 0;
204   bool arch;
205
206   if (argc < 1)
207     return NULL;
208
209   arch = strcmp (argv[0], "arch") == 0;
210   if (!arch && strcmp (argv[0], "tune"))
211     return NULL;
212
213 #ifndef __x86_64__
214   /* See if we can use cpuid.  */
215   asm volatile ("pushfl; pushfl; popl %0; movl %0,%1; xorl %2,%0;"
216                 "pushl %0; popfl; pushfl; popl %0; popfl"
217                 : "=&r" (eax), "=&r" (ebx)
218                 : "i" (0x00200000));
219
220   if (((eax ^ ebx) & 0x00200000) == 0)
221     goto done;
222 #endif
223
224   processor = PROCESSOR_PENTIUM;
225
226   /* Check the highest input value for eax.  */
227   cpuid (0, eax, ebx, ecx, edx);
228   max_level = eax;
229   /* We only look at the first four characters.  */
230   vendor = ebx;
231   if (max_level == 0)
232     goto done;
233
234   cpuid (1, eax, ebx, ecx, edx);
235   has_cmpxchg8b = !!(edx & bit_CMPXCHG8B);
236   has_cmov = !!(edx & bit_CMOV);
237   has_mmx = !!(edx & bit_MMX);
238   has_sse = !!(edx & bit_SSE);
239   has_sse2 = !!(edx & bit_SSE2);
240   has_sse3 = !!(ecx & bit_SSE3);
241   has_ssse3 = !!(ecx & bit_SSSE3);
242   has_cmpxchg16b = !!(ecx & bit_CMPXCHG16B);
243   /* We don't care for extended family.  */
244   family = (eax >> 8) & ~(1 << 4);
245
246   cpuid (0x80000000, eax, ebx, ecx, edx);
247   ext_level = eax;
248   if (ext_level >= 0x80000000)
249     {
250       cpuid (0x80000001, eax, ebx, ecx, edx);
251       has_lahf_lm = !!(ecx & bit_LAHF_LM);
252       has_3dnow = !!(edx & bit_3DNOW);
253       has_3dnowp = !!(edx & bit_3DNOWP);
254       has_longmode = !!(edx & bit_LM);
255       has_sse4a = !!(ecx & bit_SSE4a);
256     }
257
258   is_amd = vendor == *(unsigned int*)"Auth";
259
260   if (!arch)
261     {
262       if (is_amd)
263         cache = detect_caches_amd (ext_level);
264       else if (vendor == *(unsigned int*)"Genu")
265         cache = detect_caches_intel (max_level);
266     }
267
268   if (is_amd)
269     {
270       if (has_mmx)
271         processor = PROCESSOR_K6;
272       if (has_3dnowp)
273         processor = PROCESSOR_ATHLON;
274       if (has_sse2 || has_longmode)
275         processor = PROCESSOR_K8;
276       if (has_sse4a)
277         processor = PROCESSOR_AMDFAM10;
278     }
279   else
280     {
281       switch (family)
282         {
283         case 5:
284           /* Default is PROCESSOR_PENTIUM.  */
285           break;
286         case 6:
287           processor = PROCESSOR_PENTIUMPRO;
288           break;
289         case 15:
290           processor = PROCESSOR_PENTIUM4;
291           break;
292         default:
293           /* We have no idea.  Use something reasonable.  */
294           if (arch)
295             {
296               if (has_ssse3)
297                 cpu = "core2";
298               else if (has_sse3)
299                 {
300                   if (has_longmode)
301                     cpu = "nocona";
302                   else
303                     cpu = "prescott";
304                 }
305               else if (has_sse2)
306                 cpu = "pentium4";
307               else if (has_cmov)
308                 cpu = "pentiumpro";
309               else if (has_mmx)
310                 cpu = "pentium-mmx";
311               else if (has_cmpxchg8b)
312                 cpu = "pentium";
313               else
314                 cpu = "i386";
315             }
316           else
317             cpu = "generic";
318           goto done;
319           break;
320         }
321     }
322
323   switch (processor)
324     {
325     case PROCESSOR_I386:
326       cpu = "i386";
327       break;
328     case PROCESSOR_I486:
329       cpu = "i486";
330       break;
331     case PROCESSOR_PENTIUM:
332       if (has_mmx)
333         cpu = "pentium-mmx";
334       else
335         cpu = "pentium";
336       break;
337     case PROCESSOR_PENTIUMPRO:
338       if (has_longmode)
339         {
340           /* It is Core 2 Duo.  */
341           cpu = "core2";
342         }
343       else
344         {
345           if (arch)
346             {
347               if (has_sse3)
348                 {
349                   /* It is Core Duo.  */
350                   cpu = "prescott";
351                 }
352               else if (has_sse2)
353                 {
354                   /* It is Pentium M.  */
355                   cpu = "pentium4";
356                 }
357               else if (has_sse)
358                 {
359                   /* It is Pentium III.  */
360                   cpu = "pentium3";
361                 }
362               else if (has_mmx)
363                 {
364                   /* It is Pentium II.  */
365                   cpu = "pentium2";
366                 }
367               else
368                 {
369                   /* Default to Pentium Pro.  */
370                   cpu = "pentiumpro";
371                 }
372             }
373           else
374             {
375               /* For -mtune, we default to -mtune=generic.  */
376               cpu = "generic";
377             }
378         }
379       break;
380     case PROCESSOR_GEODE:
381       cpu = "geode";
382       break;
383     case PROCESSOR_K6:
384       if (has_3dnow)
385         cpu = "k6-3";
386       else
387         cpu = "k6";
388       break;
389     case PROCESSOR_ATHLON:
390       if (has_sse)
391         cpu = "athlon-4";
392       else
393         cpu = "athlon";
394       break;
395     case PROCESSOR_PENTIUM4:
396       if (has_sse3)
397         {
398           if (has_longmode)
399             cpu = "nocona";
400           else
401             cpu = "prescott";
402         }
403       else
404         cpu = "pentium4";
405       break;
406     case PROCESSOR_K8:
407       cpu = "k8";
408       break;
409     case PROCESSOR_NOCONA:
410       cpu = "nocona";
411       break;
412     case PROCESSOR_AMDFAM10:
413       cpu = "amdfam10";
414       break;
415     case PROCESSOR_GENERIC32:
416     case PROCESSOR_GENERIC64:
417       cpu = "generic";
418       break;
419     default:
420       abort ();
421       break;
422     }
423
424   if (arch)
425     {
426       if (has_cmpxchg16b)
427         options = concat (options, "-mcx16 ", NULL);
428       if (has_lahf_lm)
429         options = concat (options, "-msahf ", NULL);
430     }
431
432 done:
433   return concat (cache, "-m", argv[0], "=", cpu, " ", options, NULL);
434 }
435 #else
436 /* If we aren't compiling with GCC we just provide a minimal
437    default value.  */
438 const char *host_detect_local_cpu (int argc, const char **argv)
439 {
440   const char *cpu;
441   bool arch;
442
443   if (argc < 1)
444     return NULL;
445
446   arch = strcmp (argv[0], "arch") == 0;
447   if (!arch && strcmp (argv[0], "tune"))
448     return NULL;
449   
450   if (arch)
451     {
452       /* FIXME: i386 is wrong for 64bit compiler.  How can we tell if
453          we are generating 64bit or 32bit code?  */
454       cpu = "i386";
455     }
456   else
457     cpu = "generic";
458
459   return concat ("-m", argv[0], "=", cpu, NULL);
460 }
461 #endif /* GCC_VERSION */