config.host (<i[34567]86-*-*, [...]): Set host_extra_gcc_objs and host_xmake_file.

* 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".

From-SVN: r113655
This commit is contained in:
Michael Matz 2006-05-09 15:40:12 +00:00 committed by Michael Matz
parent f9c3744b7f
commit fa959ce486
8 changed files with 237 additions and 3 deletions

View 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>

View 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

View File

@ -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

View 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";

View 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
/* Target CPU builtins. */

3
gcc/config/i386/x-i386 Normal file
View File

@ -0,0 +1,3 @@
driver-i386.o : $(srcdir)/config/i386/driver-i386.c \
$(CONFIG_H) $(SYSTEM_H)
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<

View 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

View File

@ -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 }
};