OSDN Git Service

* config.host (<i[34567]86-*-*, x86_64-*-*>): Set
authormatz <matz@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 9 May 2006 15:40:12 +0000 (15:40 +0000)
committermatz <matz@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 9 May 2006 15:40:12 +0000 (15:40 +0000)
host_extra_gcc_objs and host_xmake_file.
(<*-*-linux*>): Don't overwrite host_xmake_file.
* gcc.c (static_spec_functions): Add EXTRA_SPEC_FUNCTIONS.
* config/i386/i386.h (EXTRA_SPEC_FUNCTIONS): Define.
(host_detect_local_cpu): Declare.
(CC1_CPU_SPEC): Add -march=native and -mtune=native cases.
* config/i386/i386.c (override_options): Handle -mtune=native
as -mtune=generic.
* config/i386/x-i386: New file.
* config/i386/driver-i386.c: New file.
* doc/invoke.texi (<i386 and x86-64 Options>): Describe
cpu-type "native".

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

gcc/ChangeLog
gcc/config.host
gcc/config/i386/driver-i386.c [new file with mode: 0644]
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/config/i386/x-i386 [new file with mode: 0644]
gcc/doc/invoke.texi
gcc/gcc.c

index b7840c4..802de2c 100644 (file)
@@ -1,3 +1,19 @@
+2006-05-09  Michael Matz  <matz@suse.de>
+
+       * config.host (<i[34567]86-*-*, x86_64-*-*>): Set
+       host_extra_gcc_objs and host_xmake_file.
+       (<*-*-linux*>): Don't overwrite host_xmake_file.
+       * gcc.c (static_spec_functions): Add EXTRA_SPEC_FUNCTIONS.
+       * config/i386/i386.h (EXTRA_SPEC_FUNCTIONS): Define.
+       (host_detect_local_cpu): Declare.
+       (CC1_CPU_SPEC): Add -march=native and -mtune=native cases.
+       * config/i386/i386.c (override_options): Handle -mtune=native
+       as -mtune=generic.
+       * config/i386/x-i386: New file.
+       * config/i386/driver-i386.c: New file.
+       * doc/invoke.texi (<i386 and x86-64 Options>): Describe
+       cpu-type "native".
+
 2006-05-09  Dirk Mueller  <dmueller@suse.de>
        Richard Guenther  <rguenther@suse.de>
 
index f9b39e6..b0925a2 100644 (file)
@@ -94,6 +94,17 @@ case ${target} in
     ;;
 esac
 
+case ${host} in
+  i[34567]86-*-* \
+  | x86_64-*-* )
+    # include the support for -march=native only when not cross compiling
+    if test x${host} = x${target} ; then
+      host_extra_gcc_objs="driver-i386.o"
+      host_xmake_file="${host_xmake_file} i386/x-i386"
+    fi
+    ;;
+esac
+
 # Machine-specific settings.
 case ${host} in
   alpha*-dec-*vms*)
@@ -186,7 +197,7 @@ case ${host} in
     ;;
   *-*-linux*)
     out_host_hook_obj=host-linux.o
-    host_xmake_file=x-linux
+    host_xmake_file="${host_xmake_file} x-linux"
     ;;
   ia64-*-hpux*)
     use_long_long_for_widest_fast_int=yes
diff --git a/gcc/config/i386/driver-i386.c b/gcc/config/i386/driver-i386.c
new file mode 100644 (file)
index 0000000..f13abd1
--- /dev/null
@@ -0,0 +1,174 @@
+/* Subroutines for the gcc driver.
+   Copyright (C) 2006 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 2, 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 COPYING.  If not, write to
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
+
+#include "config.h"
+#include "system.h"
+#include <stdlib.h>
+
+#ifndef CROSS_COMPILE
+/* This file shouldn't even be included in a cross compiler, but
+   let's be sure.  */
+extern const char *host_detect_local_cpu (int argc, const char **argv);
+
+#ifdef GCC_VERSION
+#define cpuid(num,a,b,c,d) \
+  asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" \
+               : "=a" (a), "=r" (b), "=c" (c), "=d" (d)  \
+               : "0" (num))
+
+#define bit_CMPXCHG8B (1 << 8)
+#define bit_CMOV (1 << 15)
+#define bit_MMX (1 << 23)
+#define bit_SSE (1 << 25)
+#define bit_SSE2 (1 << 26)
+
+#define bit_SSE3 (1 << 0)
+#define bit_CMPXCHG16B (1 << 13)
+
+#define bit_3DNOW (1 << 31)
+#define bit_3DNOWP (1 << 30)
+#define bit_LM (1 << 29)
+
+/* 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.  E.g. "-march=k8" on an AMD64 machine
+   for -march=native.
+
+   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 = "i386";
+  unsigned int eax, ebx, ecx, edx;
+  unsigned int max_level;
+  unsigned int vendor;
+  unsigned int ext_level;
+  unsigned char has_mmx = 0, has_3dnow = 0, has_3dnowp = 0, has_sse = 0;
+  unsigned char has_sse2 = 0, has_sse3 = 0, has_cmov = 0;
+  unsigned char has_longmode = 0;
+  unsigned char is_amd = 0;
+  unsigned int family = 0;
+  if (argc < 1
+      || (strcmp (argv[0], "arch")
+         && strcmp (argv[0], "tune")))
+    return NULL;
+
+#ifndef __x86_64__
+  /* See if we can use cpuid.  */
+  asm volatile ("pushfl; pushfl; popl %0; movl %0,%1; xorl %2,%0;"
+               "pushl %0; popfl; pushfl; popl %0; popfl"
+               : "=&r" (eax), "=&r" (ebx)
+               : "i" (0x00200000));
+
+  if (((eax ^ ebx) & 0x00200000) == 0)
+    goto done;
+#endif
+
+  cpu = "i586";
+
+  /* Check the highest input value for eax.  */
+  cpuid (0, eax, ebx, ecx, edx);
+  max_level = eax;
+  /* We only look at the first four characters.  */
+  vendor = ebx;
+  if (max_level == 0)
+    goto done;
+
+  cpuid (1, eax, ebx, ecx, edx);
+  has_cmov = !!(edx & bit_CMOV);
+  has_mmx = !!(edx & bit_MMX);
+  has_sse = !!(edx & bit_SSE);
+  has_sse2 = !!(edx & bit_SSE2);
+  has_sse3 = !!(ecx & bit_SSE3);
+  /* We don't care for extended family.  */
+  family = (eax >> 8) & ~(1 << 4);
+
+  cpuid (0x80000000, eax, ebx, ecx, edx);
+  ext_level = eax;
+  if (ext_level >= 0x80000000)
+    {
+      cpuid (0x80000001, eax, ebx, ecx, edx);
+      has_3dnow = !!(edx & bit_3DNOW);
+      has_3dnowp = !!(edx & bit_3DNOWP);
+      has_longmode = !!(edx & bit_LM);
+    }
+
+  is_amd = vendor == *(unsigned int*)"Auth";
+
+  if (is_amd)
+    {
+      if (has_mmx)
+        cpu = "k6";
+      if (has_3dnow)
+        cpu = "k6-3";
+      if (has_3dnowp)
+        cpu = "athlon";
+      if (has_sse)
+       cpu = "athlon-4";
+      if (has_sse2 || has_longmode)
+        cpu = "k8";
+    }
+  else
+    {
+      if (family == 5)
+        {
+          if (has_mmx)
+            cpu = "pentium-mmx";
+       }
+      else if (has_mmx)
+        cpu = "pentium2";
+      if (has_sse)
+        cpu = "pentium3";
+      if (has_sse2)
+       {
+         if (family == 6)
+           /* It's a pentiumpro with sse2 --> pentium-m */
+            cpu = "pentium-m";
+         else
+           /* Would have to look at extended family, but it's at least
+              an pentium4 core.  */
+           cpu = "pentium4";
+       }
+      if (has_sse3)
+        {
+         if (has_longmode)
+           cpu = "nocona";
+         else 
+            cpu = "prescott";
+       }
+    }
+
+done:
+  return concat ("-m", argv[0], "=", cpu, NULL);
+}
+#else
+/* 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)
+{
+  return concat ("-m", argv[0], "=i386", NULL);
+}
+#endif
+#endif
index df5a4e6..c81dee8 100644 (file)
@@ -1565,7 +1565,11 @@ override_options (void)
   if (ix86_tune_string)
     {
       if (!strcmp (ix86_tune_string, "generic")
-         || !strcmp (ix86_tune_string, "i686"))
+         || !strcmp (ix86_tune_string, "i686")
+         /* As special support for cross compilers we read -mtune=native
+            as -mtune=generic.  With native compilers we won't see the
+            -mtune=native, as it was changed by the driver.  */
+         || !strcmp (ix86_tune_string, "native"))
        {
          if (TARGET_64BIT)
            ix86_tune_string = "generic64";
index b783913..a3a1129 100644 (file)
@@ -273,6 +273,14 @@ extern int x86_prefetch_sse;
 #define OPTIMIZATION_OPTIONS(LEVEL, SIZE) \
   optimization_options ((LEVEL), (SIZE))
 
+/* -march=native handling only makes sense with a native compiler.  */
+#ifndef CROSS_COMPILE
+/* In driver-i386.c.  */
+extern const char *host_detect_local_cpu (int argc, const char **argv);
+#define EXTRA_SPEC_FUNCTIONS \
+  { "local_cpu_detect", host_detect_local_cpu },
+#endif
+
 /* Support for configure-time defaults of some command line options.  */
 #define OPTION_DEFAULT_SPECS \
   {"arch", "%{!march=*:-march=%(VALUE)}"}, \
@@ -282,7 +290,7 @@ extern int x86_prefetch_sse;
 /* Specs for the compiler proper */
 
 #ifndef CC1_CPU_SPEC
-#define CC1_CPU_SPEC "\
+#define CC1_CPU_SPEC_1 "\
 %{!mtune*: \
 %{m386:mtune=i386 \
 %n`-m386' is deprecated. Use `-march=i386' or `-mtune=i386' instead.\n} \
@@ -299,6 +307,14 @@ extern int x86_prefetch_sse;
 %n`-mintel-syntax' is deprecated. Use `-masm=intel' instead.\n} \
 %{mno-intel-syntax:-masm=att \
 %n`-mno-intel-syntax' is deprecated. Use `-masm=att' instead.\n}"
+
+#ifdef CROSS_COMPILE
+#define CC1_CPU_SPEC CC1_CPU_SPEC_1
+#else
+#define CC1_CPU_SPEC CC1_CPU_SPEC_1 \
+"%{march=native:%<march=native %:local_cpu_detect(arch)} \
+%{mtune=native:%<mtune=native %:local_cpu_detect(tune)}"
+#endif
 #endif
 \f
 /* Target CPU builtins.  */
diff --git a/gcc/config/i386/x-i386 b/gcc/config/i386/x-i386
new file mode 100644 (file)
index 0000000..2c35e5b
--- /dev/null
@@ -0,0 +1,3 @@
+driver-i386.o : $(srcdir)/config/i386/driver-i386.c \
+  $(CONFIG_H) $(SYSTEM_H)
+       $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
index 71c6925..bf1fe7c 100644 (file)
@@ -9176,6 +9176,13 @@ indicates the instruction set the compiler can use, and there is no
 generic instruction set applicable to all processors.  In contrast,
 @option{-mtune} indicates the processor (or, in this case, collection of
 processors) for which the code is optimized.
+@item native
+This selects the CPU to tune for at compilation time by determining
+the processor type of the compiling machine.  Using @option{-mtune=native}
+will produce code optimized for the local machine under the constraints
+of the selected instruction set.  Using @option{-march=native} will
+enable all instruction subsets supported by the local machine (hence
+the result might not run on different machines).
 @item i386
 Original Intel's i386 CPU@.
 @item i486
index 4b628ef..7e5733c 100644 (file)
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -1601,6 +1601,9 @@ static const struct spec_function static_spec_functions[] =
   { "replace-outfile",         replace_outfile_spec_function },
   { "version-compare",         version_compare_spec_function },
   { "include",                 include_spec_function },
+#ifdef EXTRA_SPEC_FUNCTIONS
+  EXTRA_SPEC_FUNCTIONS
+#endif
   { 0, 0 }
 };