OSDN Git Service

* config/rs6000/x-rs6000: New file.
authordje <dje@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 8 Aug 2007 19:33:24 +0000 (19:33 +0000)
committerdje <dje@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 8 Aug 2007 19:33:24 +0000 (19:33 +0000)
        * config/rs6000/darwin.h (CC1_SPEC): Add cc1_cpu.
        * config/rs6000/rs6000.h (EXTRA_SPECS): Add cc1_cpu.
        (EXTRA_SPEC_FUNCTIONS): Define.
        (HAVE_LOCAL_CPU_DETECT): Define.
        (CC1_CPU_SPEC): Define.
        * config/rs6000/driver-rs6000.c: New file.
        * config/rs6000/aix.h (CC1_SPEC): Define.
        * config/rs6000/sysv4.h (CC1_SPEC): Add cc1_cpu.
        * config.host: Add x-rs6000 to host_xmake_file if host and target
        are rs6000 or powerpc.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@127304 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config.host
gcc/config/rs6000/aix.h
gcc/config/rs6000/darwin.h
gcc/config/rs6000/driver-rs6000.c [new file with mode: 0644]
gcc/config/rs6000/rs6000.h
gcc/config/rs6000/sysv4.h
gcc/config/rs6000/x-rs6000 [new file with mode: 0644]

index 356f904..7d9769a 100644 (file)
@@ -1,3 +1,17 @@
+2007-08-08  David Edelsohn  <edelsohn@gnu.org>
+
+       * config/rs6000/x-rs6000: New file.
+       * config/rs6000/darwin.h (CC1_SPEC): Add cc1_cpu.
+       * config/rs6000/rs6000.h (EXTRA_SPECS): Add cc1_cpu.
+       (EXTRA_SPEC_FUNCTIONS): Define.
+       (HAVE_LOCAL_CPU_DETECT): Define.
+       (CC1_CPU_SPEC): Define.
+       * config/rs6000/driver-rs6000.c: New file.
+       * config/rs6000/aix.h (CC1_SPEC): Define.
+       * config/rs6000/sysv4.h (CC1_SPEC): Add cc1_cpu.
+       * config.host: Add x-rs6000 to host_xmake_file if host and target
+       are rs6000 or powerpc.
+
 2007-08-08  Paolo Bonzini <paolo.bonzini@lu.unisi.ch>
 
        * config/i386/t-crtstuff (CRTSTUFF_T_CFLAGS): Use +=.
index 09a9b9d..93d97f1 100644 (file)
@@ -106,6 +106,19 @@ case ${host} in
     ;;
 esac
 
+case ${host} in
+  rs6000-*-* \
+  | powerpc*-*-* )
+    case ${target} in
+      rs6000-*-* \
+      | powerpc*-*-* )
+        host_extra_gcc_objs="driver-rs6000.o"
+        host_xmake_file="${host_xmake_file} rs6000/x-rs6000"
+        ;;
+    esac
+    ;;
+esac
+
 # Machine-specific settings.
 case ${host} in
   alpha*-dec-*vms*)
index 67f83ae..6f91c57 100644 (file)
 #define CPP_SPEC "%{posix: -D_POSIX_SOURCE}\
    %{ansi: -D_ANSI_C_SOURCE}"
 
+#define CC1_SPEC "%(cc1_cpu)"
+
 #undef ASM_DEFAULT_SPEC
 #define ASM_DEFAULT_SPEC ""
 
index 0380612..6c88757 100644 (file)
@@ -90,6 +90,7 @@
    the kernel or some such.  */
 
 #define CC1_SPEC "\
+  %(cc1_cpu) \
   %{g: %{!fno-eliminate-unused-debug-symbols: -feliminate-unused-debug-symbols }} \
   %{static: %{Zdynamic: %e conflicting code gen style switches are used}}\
   %{!mmacosx-version-min=*:-mmacosx-version-min=%(darwin_minversion)} \
diff --git a/gcc/config/rs6000/driver-rs6000.c b/gcc/config/rs6000/driver-rs6000.c
new file mode 100644 (file)
index 0000000..5629d6b
--- /dev/null
@@ -0,0 +1,390 @@
+/* Subroutines for the gcc driver.
+   Copyright (C) 2007 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include <stdlib.h>
+
+#ifdef _AIX
+# include <sys/systemcfg.h>
+#endif
+
+#ifdef __linux__
+# include <elf.h>
+#endif
+
+#ifdef __APPLE__
+# include <sys/types.h>
+# include <sys/sysctl.h>
+#endif
+
+const char *host_detect_local_cpu (int argc, const char **argv);
+
+#if GCC_VERSION >= 0
+
+/* Returns parameters that describe L1_ASSOC associative cache of size
+   L1_SIZEKB with lines of size L1_LINE, and L2_SIZEKB.  */
+
+static char *
+describe_cache (unsigned l1_sizekb, unsigned l1_line,
+               unsigned l1_assoc ATTRIBUTE_UNUSED, unsigned l2_sizekb)
+{
+  char l1size[1000], line[1000], l2size[1000];
+
+  /* At the moment, gcc middle-end does not use the information about the
+     associativity of the cache.  */
+
+  sprintf (l1size, "--param l1-cache-size=%u", l1_sizekb);
+  sprintf (line, "--param l1-cache-line-size=%u", l1_line);
+  sprintf (l2size, "--param l2-cache-size=%u", l2_sizekb);
+
+  return concat (l1size, " ", line, " ", l2size, " ", NULL);
+}
+
+#ifdef __APPLE__
+
+/* Returns the description of caches on Darwin.  */
+
+static char *
+detect_caches_darwin (void)
+{
+  unsigned l1_sizekb, l1_line, l1_assoc, l2_sizekb;
+  size_t len = 4;
+  static int l1_size_name[2] = { CTL_HW, HW_L1DCACHESIZE };
+  static int l1_line_name[2] = { CTL_HW, HW_CACHELINE };
+  static int l2_size_name[2] = { CTL_HW, HW_L2CACHESIZE };
+
+  sysctl (l1_size_name, 2, &l1_sizekb, &len, NULL, 0);
+  sysctl (l1_line_name, 2, &l1_line, &len, NULL, 0);
+  sysctl (l2_size_name, 2, &l2_sizekb, &len, NULL, 0);
+  l1_assoc = 0;
+
+  return describe_cache (l1_sizekb / 1024, l1_line, l1_assoc,
+                        l2_sizekb / 1024);
+}
+
+static const char *
+detect_processor_darwin (void)
+{
+  unsigned int proc;
+  size_t len = 4;
+
+  sysctlbyname ("hw.cpusubtype", &proc, &len, NULL, 0);
+
+  if (len > 0)
+    switch (proc)
+      {
+      case 1:
+       return "601";
+      case 2:
+       return "602";
+      case 3:
+       return "603";
+      case 4:
+      case 5:
+       return "603e";
+      case 6:
+       return "604";
+      case 7:
+       return "604e";
+      case 8:
+       return "620";
+      case 9:
+       return "750";
+      case 10:
+       return "7400";
+      case 11:
+       return "7450";
+      case 100:
+       return "970";
+      default:
+       return "powerpc";
+      }
+
+  return "powerpc";
+}
+
+#endif /* __APPLE__ */
+
+#ifdef __linux__
+
+/* Returns AT_PLATFORM if present, otherwise generic PowerPC.  */
+
+static const char *
+elf_platform (void)
+{
+  int fd;
+
+  fd = open ("/proc/self/auxv", O_RDONLY);
+
+  if (fd != -1)
+    {
+      char buf[1024];
+      Elf32_auxv_t *av;
+      ssize_t n;
+
+      n = read (fd, buf, sizeof (buf));
+      close (fd);
+
+      if (n > 0)
+       {
+         for (av = (Elf32_auxv_t *) buf; av->a_type != AT_NULL; ++av)
+           switch (av->a_type)
+             {
+             case AT_PLATFORM:
+               return (const char *) av->a_un.a_val;
+
+             default:
+               break;
+             }
+       }
+    }
+  return NULL;
+}
+
+/* Returns AT_PLATFORM if present, otherwise generic 32.  */
+
+static int
+elf_dcachebsize (void)
+{
+  int fd;
+
+  fd = open ("/proc/self/auxv", O_RDONLY);
+
+  if (fd != -1)
+    {
+      char buf[1024];
+      Elf32_auxv_t *av;
+      ssize_t n;
+
+      n = read (fd, buf, sizeof (buf));
+      close (fd);
+
+      if (n > 0)
+       {
+         for (av = (Elf32_auxv_t *) buf; av->a_type != AT_NULL; ++av)
+           switch (av->a_type)
+             {
+             case AT_DCACHEBSIZE:
+               return av->a_un.a_val;
+
+             default:
+               break;
+             }
+       }
+    }
+  return 32;
+}
+
+/* Returns the description of caches on Linux.  */
+
+static char *
+detect_caches_linux (void)
+{
+  unsigned l1_sizekb, l1_line, l1_assoc, l2_sizekb;
+  const char *platform;
+
+  platform = elf_platform ();
+
+  if (platform != NULL)
+    {
+      l1_line = 128;
+
+      if (platform[5] == '6')
+       /* POWER6 and POWER6x */
+       l1_sizekb = 64;
+      else
+       l1_sizekb = 32;
+    }
+  else
+    {
+      l1_line = elf_dcachebsize ();
+      l1_sizekb = 32;
+    }
+
+  l1_assoc = 0;
+  l2_sizekb = 512;
+
+  return describe_cache (l1_sizekb, l1_line, l1_assoc, l2_sizekb);
+}
+
+static const char *
+detect_processor_linux (void)
+{
+  const char *platform;
+
+  platform = elf_platform ();
+
+  if (platform != NULL)
+    return platform;
+  else
+    return "powerpc";
+}
+
+#endif /* __linux__ */
+
+#ifdef _AIX
+/* Returns the description of caches on AIX.  */
+
+static char *
+detect_caches_aix (void)
+{
+  unsigned l1_sizekb, l1_line, l1_assoc, l2_sizekb;
+
+  l1_sizekb = _system_configuration.dcache_size / 1024;
+  l1_line = _system_configuration.dcache_line;
+  l1_assoc = _system_configuration.dcache_asc;
+  l2_sizekb = _system_configuration.L2_cache_size / 1024;
+
+  return describe_cache (l1_sizekb, l1_line, l1_assoc, l2_sizekb);
+}
+
+
+/* Returns the processor implementation on AIX.  */
+
+static const char *
+detect_processor_aix (void)
+{
+  switch (_system_configuration.implementation)
+    {
+    case 0x0001:
+      return "rios1";
+
+    case 0x0002:
+      return "rsc";
+
+    case 0x0004:
+      return "rios2";
+
+    case 0x0008:
+      return "601";
+
+    case 0x0020:
+      return "603";
+
+    case 0x0010:
+      return "604";
+
+    case 0x0040:
+      return "620";
+
+    case 0x0080:
+      return "630";
+
+    case 0x0100:
+    case 0x0200:
+    case 0x0400:
+      return "rs64";
+
+    case 0x0800:
+      return "power4";
+
+    case 0x2000:
+      if (_system_configuration.version == 0x0F0000)
+       return "power5";
+      else
+       return "power5+";
+
+    case 0x4000:
+      return "power6";
+
+    default:
+      return "powerpc";
+    }
+}
+#endif /* _AIX */
+
+
+/* This will be called by the spec parser in gcc.c when it sees
+   a %:local_cpu_detect(args) construct.  Currently it will be called
+   with either "arch" or "tune" as argument depending on if -march=native
+   or -mtune=native is to be substituted.
+
+   It returns a string containing new command line parameters to be
+   put at the place of the above two options, depending on what CPU
+   this is executed.
+
+   ARGC and ARGV are set depending on the actual arguments given
+   in the spec.  */
+const char
+*host_detect_local_cpu (int argc, const char **argv)
+{
+  const char *cpu = NULL;
+  const char *cache = "";
+  const char *options = "";
+  bool arch;
+
+  if (argc < 1)
+    return NULL;
+
+  arch = strcmp (argv[0], "cpu") == 0;
+  if (!arch && strcmp (argv[0], "tune"))
+    return NULL;
+
+#if defined (_AIX)
+  cache = detect_caches_aix ();
+#elif defined (__APPLE__)
+  cache = detect_caches_darwin ();
+#elif defined (__linux__)
+  cache = detect_caches_linux ();
+  /* PPC Linux does not provide any cache information yet.  */
+  cache = "";
+#else
+  cache = "";
+#endif
+
+#if defined (_AIX)
+  cpu = detect_processor_aix ();
+#elif defined (__APPLE__)
+  cpu = detect_processor_darwin ();
+#elif defined (__linux__)
+  cpu = detect_processor_linux ();
+#else
+  cpu = "powerpc";
+#endif
+
+  return concat (cache, "-m", argv[0], "=", cpu, " ", options, NULL);
+}
+
+#else /* GCC_VERSION */
+
+/* If we aren't compiling with GCC we just provide a minimal
+   default value.  */
+const char *host_detect_local_cpu (int argc, const char **argv)
+{
+  const char *cpu;
+  bool arch;
+
+  if (argc < 1)
+    return NULL;
+
+  arch = strcmp (argv[0], "cpu") == 0;
+  if (!arch && strcmp (argv[0], "tune"))
+    return NULL;
+  
+  if (arch)
+    cpu = "powerpc";
+
+  return concat ("-m", argv[0], "=", cpu, NULL);
+}
+
+#endif /* GCC_VERSION */
+
index 35c5112..fae5ea2 100644 (file)
   { "cpp_default",             CPP_DEFAULT_SPEC },                     \
   { "asm_cpu",                 ASM_CPU_SPEC },                         \
   { "asm_default",             ASM_DEFAULT_SPEC },                     \
+  { "cc1_cpu",                 CC1_CPU_SPEC },                         \
   SUBTARGET_EXTRA_SPECS
 
+/* -mcpu=native handling only makes sense with compiler running on
+   an PowerPC chip.  If changing this condition, also change
+   the condition in driver-rs6000.c.  */
+#if defined(__powerpc__) || defined(__POWERPC__) || defined(_AIX)
+/* In driver-rs6000.c.  */
+extern const char *host_detect_local_cpu (int argc, const char **argv);
+#define EXTRA_SPEC_FUNCTIONS \
+  { "local_cpu_detect", host_detect_local_cpu },
+#define HAVE_LOCAL_CPU_DETECT
+#endif
+
+#if !defined (CC1_CPU_SPEC) && defined (HAVE_LOCAL_CPU_DETECT)
+#define CC1_CPU_SPEC \
+"%{mcpu=native:%<mcpu=native %:local_cpu_detect(cpu)} \
+ %{mtune=native:%<mtune=native %:local_cpu_detect(tune)}"
+#endif
+
 /* Architecture type.  */
 
 /* Define TARGET_MFCRF if the target assembler does not support the
index 967f32e..6e04bee 100644 (file)
@@ -607,7 +607,7 @@ extern int fixuplabelno;
 #endif
 
 /* Pass -G xxx to the compiler and set correct endian mode.  */
-#define        CC1_SPEC "%{G*} \
+#define        CC1_SPEC "%{G*} %(cc1_cpu) \
 %{mlittle|mlittle-endian: %(cc1_endian_little);           \
   mbig   |mbig-endian   : %(cc1_endian_big);              \
   mcall-aixdesc |                                        \
diff --git a/gcc/config/rs6000/x-rs6000 b/gcc/config/rs6000/x-rs6000
new file mode 100644 (file)
index 0000000..8246c37
--- /dev/null
@@ -0,0 +1,3 @@
+driver-rs6000.o : $(srcdir)/config/rs6000/driver-rs6000.c \
+  $(CONFIG_H) $(SYSTEM_H) $(TM_H) coretypes.h
+       $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<