1 /* Subroutines for the gcc driver.
2 Copyright (C) 2007 Free Software Foundation, Inc.
4 This file is part of GCC.
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 3, or (at your option)
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.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
22 #include "coretypes.h"
27 # include <sys/systemcfg.h>
35 # include <sys/types.h>
36 # include <sys/sysctl.h>
39 const char *host_detect_local_cpu (int argc, const char **argv);
43 /* Returns parameters that describe L1_ASSOC associative cache of size
44 L1_SIZEKB with lines of size L1_LINE, and L2_SIZEKB. */
47 describe_cache (unsigned l1_sizekb, unsigned l1_line,
48 unsigned l1_assoc ATTRIBUTE_UNUSED, unsigned l2_sizekb)
50 char l1size[1000], line[1000], l2size[1000];
52 /* At the moment, gcc middle-end does not use the information about the
53 associativity of the cache. */
55 sprintf (l1size, "--param l1-cache-size=%u", l1_sizekb);
56 sprintf (line, "--param l1-cache-line-size=%u", l1_line);
57 sprintf (l2size, "--param l2-cache-size=%u", l2_sizekb);
59 return concat (l1size, " ", line, " ", l2size, " ", NULL);
64 /* Returns the description of caches on Darwin. */
67 detect_caches_darwin (void)
69 unsigned l1_sizekb, l1_line, l1_assoc, l2_sizekb;
71 static int l1_size_name[2] = { CTL_HW, HW_L1DCACHESIZE };
72 static int l1_line_name[2] = { CTL_HW, HW_CACHELINE };
73 static int l2_size_name[2] = { CTL_HW, HW_L2CACHESIZE };
75 sysctl (l1_size_name, 2, &l1_sizekb, &len, NULL, 0);
76 sysctl (l1_line_name, 2, &l1_line, &len, NULL, 0);
77 sysctl (l2_size_name, 2, &l2_sizekb, &len, NULL, 0);
80 return describe_cache (l1_sizekb / 1024, l1_line, l1_assoc,
85 detect_processor_darwin (void)
90 sysctlbyname ("hw.cpusubtype", &proc, &len, NULL, 0);
125 #endif /* __APPLE__ */
129 /* Returns AT_PLATFORM if present, otherwise generic PowerPC. */
136 fd = open ("/proc/self/auxv", O_RDONLY);
144 n = read (fd, buf, sizeof (buf));
149 for (av = (ElfW(auxv_t) *) buf; av->a_type != AT_NULL; ++av)
153 return (const char *) av->a_un.a_val;
163 /* Returns AT_PLATFORM if present, otherwise generic 32. */
166 elf_dcachebsize (void)
170 fd = open ("/proc/self/auxv", O_RDONLY);
178 n = read (fd, buf, sizeof (buf));
183 for (av = (ElfW(auxv_t) *) buf; av->a_type != AT_NULL; ++av)
187 return av->a_un.a_val;
197 /* Returns the description of caches on Linux. */
200 detect_caches_linux (void)
202 unsigned l1_sizekb, l1_line, l1_assoc, l2_sizekb;
203 const char *platform;
205 platform = elf_platform ();
207 if (platform != NULL)
211 if (platform[5] == '6')
212 /* POWER6 and POWER6x */
219 l1_line = elf_dcachebsize ();
226 return describe_cache (l1_sizekb, l1_line, l1_assoc, l2_sizekb);
230 detect_processor_linux (void)
232 const char *platform;
234 platform = elf_platform ();
236 if (platform != NULL)
242 #endif /* __linux__ */
245 /* Returns the description of caches on AIX. */
248 detect_caches_aix (void)
250 unsigned l1_sizekb, l1_line, l1_assoc, l2_sizekb;
252 l1_sizekb = _system_configuration.dcache_size / 1024;
253 l1_line = _system_configuration.dcache_line;
254 l1_assoc = _system_configuration.dcache_asc;
255 l2_sizekb = _system_configuration.L2_cache_size / 1024;
257 return describe_cache (l1_sizekb, l1_line, l1_assoc, l2_sizekb);
261 /* Returns the processor implementation on AIX. */
264 detect_processor_aix (void)
266 switch (_system_configuration.implementation)
301 if (_system_configuration.version == 0x0F0000)
316 /* This will be called by the spec parser in gcc.c when it sees
317 a %:local_cpu_detect(args) construct. Currently it will be called
318 with either "arch" or "tune" as argument depending on if -march=native
319 or -mtune=native is to be substituted.
321 It returns a string containing new command line parameters to be
322 put at the place of the above two options, depending on what CPU
325 ARGC and ARGV are set depending on the actual arguments given
328 *host_detect_local_cpu (int argc, const char **argv)
330 const char *cpu = NULL;
331 const char *cache = "";
332 const char *options = "";
338 arch = strcmp (argv[0], "cpu") == 0;
339 if (!arch && strcmp (argv[0], "tune"))
343 cache = detect_caches_aix ();
344 #elif defined (__APPLE__)
345 cache = detect_caches_darwin ();
346 #elif defined (__linux__)
347 cache = detect_caches_linux ();
348 /* PPC Linux does not provide any cache information yet. */
355 cpu = detect_processor_aix ();
356 #elif defined (__APPLE__)
357 cpu = detect_processor_darwin ();
358 #elif defined (__linux__)
359 cpu = detect_processor_linux ();
364 return concat (cache, "-m", argv[0], "=", cpu, " ", options, NULL);
367 #else /* GCC_VERSION */
369 /* If we aren't compiling with GCC we just provide a minimal
371 const char *host_detect_local_cpu (int argc, const char **argv)
379 arch = strcmp (argv[0], "cpu") == 0;
380 if (!arch && strcmp (argv[0], "tune"))
386 return concat ("-m", argv[0], "=", cpu, NULL);
389 #endif /* GCC_VERSION */