Commit b3172cab by Uros Bizjak

cpuid.h: New file.

	* gcc/config/i386/cpuid.h: New file.
	* gcc/config/i386/driver-i386.c: Include cpuid.h.
	(describe_cache): Shrink size and line strings to 100 bytes.
	(detect_caches_amd): Return "" for unsupported max_ext_level.
	Use __cpuid function.
	(detect_caches_intel): Return "" for unsupported max_level.
	Use __cpuid function.
	(host_detect_local_cpu): Change feature flag variables to
	unsigned int.  Initialize only extended feature flag variables.
	Use __get_cpuid_max to determine max supported cpuid level.
	Use __cpuid function to determine supported features.  Fix
	calculation of family id.  Remove is_amd and check signature
	directly.  Check for Geode signature.  Handle family 4 id.
	[PROCESSOR_GENERIC32]: New default for unknown family id. Move
	cpu discovery code to other part of the function.
	[PROCESSOR_PENTIUM, PROCESSOR_K6, PROCESSOR_ATHLON]: Do not tune
	for sub-architecture.
	[PROCESSOR_PENTIUMPRO]: Simplify cpu discovery code.
	[PROCESSOR_K8]: Add k8-sse3 architecture.
	[PROCESSOR_GENERIC64]: Remove.
	* gcc/config/i386/x-i386 (driver-i386.o): Depend on cpuid.h.
	* gcc/config/i386/crtfastmath.c: Include cpuid.h.  Use __get_cpuid
	to check for SSE and FXSAVE support.
	* gcc/config/i386/t-crtfm (crtfastmath.o): Depend on cpuid.h.
	Add -minline-all-stringops.
	* gcc/config.gcc (i[34567]86-*-*): Add cpuid.h to extra_headers.
	(x86_64-*-*): Ditto.

testsuite/ChangeLog:

	* gcc.dg/i386-cpuid.h: Remove.
	* gcc.target/i386/mmx-check.h: Include cpuid.h.  Use __get_cpuid.
	* gcc.target/i386/sse-check.h: Ditto.
	* gcc.target/i386/sse2-check.h: Ditto.
	* gcc.target/i386/sse3-check.h: Ditto.
	* gcc.target/i386/ssse3-check.h: Ditto.
	* gcc.target/i386/sse4_1-check.h: Ditto.
	* gcc.target/i386/sse4_2-check.h: Ditto.
	* gcc.target/i386/sse4a-check.h: Ditto.
	* gcc.dg/torture/pr16104-1.c: Ditto.
	* gcc.target/i386/mmx-4.c: Do not use NOINLINE.
	* gcc.target/i386/sse-6.c: Ditto.
	* gcc.target/i386/sse-7.c: Ditto.
	* g++.dg/other/i386-1.C: Include cpuid.h.
	(main): New function.  Use __get_cpuid to check target fetaures.

libgomp/ChangeLog:

	* testsuite/libgomp.c/atomic-1.c: Include cpuid.h for i386 targets.
	(main): Use __get_cpuid to get i386 target fetaures.
	* testsuite/libgomp.c/atomic-2.c: Include cpuid.h for x86_64 targets.
	(main): Use __get_cpuid to get x86_64 target fetaures.

From-SVN: r128141
parent 57df7359
2007-09-06 Jie Zhang <jie.zhang@analog.com> 2007-09-05 Uros Bizjak <ubizjak@gmail.com>
* gcc/config/i386/cpuid.h: New file.
* gcc/config/i386/driver-i386.c: Include cpuid.h.
(describe_cache): Shrink size and line strings to 100 bytes.
(detect_caches_amd): Return "" for unsupported max_ext_level.
Use __cpuid function.
(detect_caches_intel): Return "" for unsupported max_level.
Use __cpuid function.
(host_detect_local_cpu): Change feature flag variables to
unsigned int. Initialize only extended feature flag variables.
Use __get_cpuid_max to determine max supported cpuid level.
Use __cpuid function to determine supported features. Fix
calculation of family id. Remove is_amd and check signature
directly. Check for Geode signature. Handle family 4 id.
[PROCESSOR_GENERIC32]: New default for unknown family id. Move
cpu discovery code to lower part of the function.
[PROCESSOR_PENTIUM, PROCESSOR_K6, PROCESSOR_ATHLON]: Do not tune
for sub-architecture.
[PROCESSOR_PENTIUMPRO]: Simplify cpu discovery code.
[PROCESSOR_K8]: Add k8-sse3 architecture.
[PROCESSOR_NOCONA]: Remove.
[PROCESSOR_GENERIC64]: Ditto.
* gcc/config/i386/x-i386 (driver-i386.o): Depend on cpuid.h.
* gcc/config/i386/crtfastmath.c: Include cpuid.h. Use __get_cpuid
to check for SSE and FXSAVE support.
* gcc/config/i386/t-crtfm (crtfastmath.o): Depend on cpuid.h.
Add -minline-all-stringops.
* gcc/config.gcc (i[34567]86-*-*): Add cpuid.h to extra_headers.
(x86_64-*-*): Ditto.
2007-09-05 Jie Zhang <jie.zhang@analog.com>
* config/bfin/linux-unwind.h: New file. * config/bfin/linux-unwind.h: New file.
* config/bfin/linux.h (MD_UNWIND_SUPPORT): Define. * config/bfin/linux.h (MD_UNWIND_SUPPORT): Define.
......
...@@ -278,13 +278,13 @@ xscale-*-*) ...@@ -278,13 +278,13 @@ xscale-*-*)
;; ;;
i[34567]86-*-*) i[34567]86-*-*)
cpu_type=i386 cpu_type=i386
extra_headers="mmintrin.h mm3dnow.h xmmintrin.h emmintrin.h extra_headers="cpuid.h mmintrin.h mm3dnow.h xmmintrin.h emmintrin.h
pmmintrin.h tmmintrin.h ammintrin.h smmintrin.h pmmintrin.h tmmintrin.h ammintrin.h smmintrin.h
nmmintrin.h" nmmintrin.h"
;; ;;
x86_64-*-*) x86_64-*-*)
cpu_type=i386 cpu_type=i386
extra_headers="mmintrin.h mm3dnow.h xmmintrin.h emmintrin.h extra_headers="cpuid.h mmintrin.h mm3dnow.h xmmintrin.h emmintrin.h
pmmintrin.h tmmintrin.h ammintrin.h smmintrin.h pmmintrin.h tmmintrin.h ammintrin.h smmintrin.h
nmmintrin.h" nmmintrin.h"
need_64bit_hwint=yes need_64bit_hwint=yes
......
/*
* Copyright (C) 2007 Free Software Foundation, Inc.
*
* This file 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.
*
* In addition to the permissions in the GNU General Public License, the
* Free Software Foundation gives you unlimited permission to link the
* compiled version of this file with other programs, and to distribute
* those programs without any restriction coming from the use of this
* file. (The General Public License restrictions do apply in other
* respects; for example, they cover modification of the file, and
* distribution when not linked into another program.)
*
* This file 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 this program; see the file COPYING. If not, write to
* the Free Software Foundation, 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*
* As a special exception, if you link this library with files
* compiled with GCC to produce an executable, this does not cause
* the resulting executable to be covered by the GNU General Public License.
* This exception does not however invalidate any other reasons why
* the executable file might be covered by the GNU General Public License.
*/
/* %ecx */
#define bit_SSE3 (1 << 0)
#define bit_SSSE3 (1 << 9)
#define bit_CMPXCHG16B (1 << 13)
#define bit_SSE4_1 (1 << 19)
#define bit_SSE4_2 (1 << 20)
#define bit_POPCNT (1 << 23)
/* %edx */
#define bit_CMPXCHG8B (1 << 8)
#define bit_CMOV (1 << 15)
#define bit_MMX (1 << 23)
#define bit_FXSAVE (1 << 24)
#define bit_SSE (1 << 25)
#define bit_SSE2 (1 << 26)
/* Extended Features */
/* %ecx */
#define bit_LAHF_LM (1 << 0)
#define bit_SSE4a (1 << 6)
/* %edx */
#define bit_LM (1 << 29)
#define bit_3DNOWP (1 << 30)
#define bit_3DNOW (1 << 31)
#if defined(__i386__) && defined(__PIC__)
/* %ebx may be the PIC register. */
#define __cpuid(level, a, b, c, d) \
__asm__ ("xchgl\t%%ebx, %1\n\t" \
"cpuid\n\t" \
"xchgl\t%%ebx, %1\n\t" \
: "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
: "0" (level))
#else
#define __cpuid(level, a, b, c, d) \
__asm__ ("cpuid\n\t" \
: "=a" (a), "=b" (b), "=c" (c), "=d" (d) \
: "0" (level))
#endif
/* Return highest supported input value for cpuid instruction. ext can
be either 0x0 or 0x8000000 to return highest supported value for
basic or extended cpuid information. Function returns 0 if cpuid
is not supported or whatever cpuid returns in eax register. If sig
pointer is non-null, then first four bytes of the signature
(as found in ebx register) are returned in location pointed by sig. */
static __inline unsigned int
__get_cpuid_max (unsigned int __ext, unsigned int *__sig)
{
unsigned int __eax, __ebx, __ecx, __edx;
#ifndef __x86_64__
/* See if we can use cpuid. On AMD64 we always can. */
__asm__ ("pushfl\n\t"
"pushfl\n\t"
"popl\t%0\n\t"
"movl\t%0, %1\n\t"
"xorl\t%2, %0\n\t"
"pushl\t%0\n\t"
"popfl\n\t"
"pushfl\n\t"
"popl\t%0\n\t"
"popfl\n\t"
: "=&r" (__eax), "=&r" (__ebx)
: "i" (0x00200000));
if (!((__eax ^ __ebx) & 0x00200000))
return 0;
#endif
/* Host supports cpuid. Return highest supported cpuid input value. */
__cpuid (__ext, __eax, __ebx, __ecx, __edx);
if (__sig)
*__sig = __ebx;
return __eax;
}
/* Return cpuid data for requested cpuid level, as found in returned
eax, ebx, ecx and edx registers. The function checks if cpuid is
supported and returns 1 for valid cpuid information or 0 for
unsupported cpuid level. All pointers are requred to be non-null. */
static __inline int
__get_cpuid (unsigned int __level,
unsigned int *__eax, unsigned int *__ebx,
unsigned int *__ecx, unsigned int *__edx)
{
unsigned int __ext = __level & 0x80000000;
if (__get_cpuid_max (__ext, 0) < __level)
return 0;
__cpuid (__level, *__eax, *__ebx, *__ecx, *__edx);
return 1;
}
/* /*
* Copyright (C) 2005 Free Software Foundation, Inc. * Copyright (C) 2005, 2007 Free Software Foundation, Inc.
* *
* This file is free software; you can redistribute it and/or modify it * This file is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the * under the terms of the GNU General Public License as published by the
...@@ -34,8 +34,11 @@ ...@@ -34,8 +34,11 @@
#define MXCSR_DAZ (1 << 6) /* Enable denormals are zero mode */ #define MXCSR_DAZ (1 << 6) /* Enable denormals are zero mode */
#define MXCSR_FTZ (1 << 15) /* Enable flush to zero mode */ #define MXCSR_FTZ (1 << 15) /* Enable flush to zero mode */
#define FXSAVE (1 << 24) #ifndef __x86_64__
#define SSE (1 << 25) /* All 64-bit targets have SSE and DAZ;
only check them explicitly for 32-bit ones. */
#include "cpuid.h"
#endif
static void __attribute__((constructor)) static void __attribute__((constructor))
#ifndef __x86_64__ #ifndef __x86_64__
...@@ -47,38 +50,18 @@ __attribute__ ((force_align_arg_pointer)) ...@@ -47,38 +50,18 @@ __attribute__ ((force_align_arg_pointer))
set_fast_math (void) set_fast_math (void)
{ {
#ifndef __x86_64__ #ifndef __x86_64__
/* All 64-bit targets have SSE and DAZ; only check them explicitly
for 32-bit ones. */
unsigned int eax, ebx, ecx, edx; unsigned int eax, ebx, ecx, edx;
/* See if we can use cpuid. */ if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
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)
return; return;
/* Check the highest input value for eax. */ if (edx & bit_SSE)
asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1"
: "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx)
: "0" (0));
if (eax == 0)
return;
asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1"
: "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx)
: "0" (1));
if (edx & SSE)
{ {
unsigned int mxcsr = __builtin_ia32_stmxcsr (); unsigned int mxcsr = __builtin_ia32_stmxcsr ();
mxcsr |= MXCSR_FTZ; mxcsr |= MXCSR_FTZ;
if (edx & FXSAVE) if (edx & bit_FXSAVE)
{ {
/* Check if DAZ is available. */ /* Check if DAZ is available. */
struct struct
......
EXTRA_PARTS += crtfastmath.o EXTRA_PARTS += crtfastmath.o
$(T)crtfastmath.o: $(srcdir)/config/i386/crtfastmath.c $(GCC_PASSES) $(T)crtfastmath.o: $(srcdir)/config/i386/crtfastmath.c \
$(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -msse -c \ $(srcdir)/config/i386/cpuid.h $(GCC_PASSES)
$(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -msse -minline-all-stringops -c \
$(srcdir)/config/i386/crtfastmath.c \ $(srcdir)/config/i386/crtfastmath.c \
-o $(T)crtfastmath$(objext) -o $(T)crtfastmath$(objext)
driver-i386.o : $(srcdir)/config/i386/driver-i386.c \ driver-i386.o : $(srcdir)/config/i386/driver-i386.c \
$(srcdir)/config/i386/cpuid.h \
$(CONFIG_H) $(SYSTEM_H) $(TM_H) coretypes.h $(CONFIG_H) $(SYSTEM_H) $(TM_H) coretypes.h
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
2007-09-05 Uros Bizjak <ubizjak@gmail.com>
* gcc.dg/i386-cpuid.h: Remove.
* gcc.target/i386/mmx-check.h: Include cpuid.h.
(main): Use __get_cpuid to get target features.
* gcc.target/i386/sse-check.h: Ditto.
* gcc.target/i386/sse2-check.h: Ditto.
* gcc.target/i386/sse3-check.h: Ditto.
* gcc.target/i386/ssse3-check.h: Ditto.
* gcc.target/i386/sse4_1-check.h: Ditto.
* gcc.target/i386/sse4_2-check.h: Ditto.
* gcc.target/i386/sse4a-check.h: Ditto.
* gcc.dg/torture/pr16104-1.c: Ditto.
(do_test): Change to void.
* gcc.target/i386/mmx-4.c: Do not use NOINLINE.
* gcc.target/i386/sse-6.c: Ditto.
* gcc.target/i386/sse-7.c: Ditto.
* g++.dg/other/i386-1.C: Include cpuid.h.
(main): New function. Use __get_cpuid to get target fetaures.
2007-09-05 Sandra Loosemore <sandra@codesourcery.com> 2007-09-05 Sandra Loosemore <sandra@codesourcery.com>
David Ung <davidu@mips.com> David Ung <davidu@mips.com>
Nigel Stephens <nigel@mips.com> Nigel Stephens <nigel@mips.com>
...@@ -225,7 +245,8 @@ ...@@ -225,7 +245,8 @@
* gcc.dg/vect/vect-intfloat-conversion-4a.c: Mark functions noinline. * gcc.dg/vect/vect-intfloat-conversion-4a.c: Mark functions noinline.
* gcc.dg/vect/vect-109.c: Mark functions noinline. * gcc.dg/vect/vect-109.c: Mark functions noinline.
* gcc.dg/vect/no-scevccp-outer-22.c: Mark functions noinline. * gcc.dg/vect/no-scevccp-outer-22.c: Mark functions noinline.
* gcc.dg/vect/no-section-anchors-vect-outer-4h.c: Mark functions noinline. * gcc.dg/vect/no-section-anchors-vect-outer-4h.c: Mark functions
noinline.
* gcc.dg/vect/vect-iv-3.c: Mark functions noinline. * gcc.dg/vect/vect-iv-3.c: Mark functions noinline.
* gcc.dg/vect/vect-reduc-pattern-2b.c: Mark functions noinline. * gcc.dg/vect/vect-reduc-pattern-2b.c: Mark functions noinline.
* gcc.dg/vect/vect-reduc-dot-s8a.c: Mark functions noinline. * gcc.dg/vect/vect-reduc-dot-s8a.c: Mark functions noinline.
...@@ -361,15 +382,15 @@ ...@@ -361,15 +382,15 @@
2007-09-04 Uros Bizjak <ubizjak@gmail.com> 2007-09-04 Uros Bizjak <ubizjak@gmail.com>
* gcc.target/i386/sse4a-check.h: New file. * gcc.target/i386/sse4a-check.h: New file.
* gcc.target/i386/sse4a-extract.c: Include sse4a-check.h. Remove main. * gcc.target/i386/sse4a-extract.c: Include sse4a-check.h. Remove main.
* gcc.target/i386/sse4a-insert.c: Ditto. * gcc.target/i386/sse4a-insert.c: Ditto.
* gcc.target/i386/sse4a-montsd.c: Ditto. * gcc.target/i386/sse4a-montsd.c: Ditto.
* gcc.target/i386/sse4a-montss.c: Ditto. * gcc.target/i386/sse4a-montss.c: Ditto.
* gcc.target/i386/mmx-check.h: New file. * gcc.target/i386/mmx-check.h: New file.
* gcc.target/i386/mmx-4.c: Include mmx-check.h. Remove main. * gcc.target/i386/mmx-4.c: Include mmx-check.h. Remove main.
* gcc.target/i386/builtin-apply-mmx.c: Ditto. * gcc.target/i386/builtin-apply-mmx.c: Ditto.
* gcc.target/i386/sse-check.h: New file. * gcc.target/i386/sse-check.h: New file.
* gcc.target/i386/pr13685: Include sse-check.h. Remove main. * gcc.target/i386/pr13685: Include sse-check.h. Remove main.
* gcc.target/i386/sse-3.c: Ditto. * gcc.target/i386/sse-3.c: Ditto.
* gcc.target/i386/sse-7.c: Ditto. * gcc.target/i386/sse-7.c: Ditto.
* gcc.target/i386/sse-9.c: Ditto. * gcc.target/i386/sse-9.c: Ditto.
...@@ -378,7 +399,7 @@ ...@@ -378,7 +399,7 @@
* gcc.target/i386/sse-recip-vec.c: Ditto. * gcc.target/i386/sse-recip-vec.c: Ditto.
* gcc.target/i386/20020523.c: Ditto. Rename from 20020523-2.c. * gcc.target/i386/20020523.c: Ditto. Rename from 20020523-2.c.
* gcc.target/i386/20020523-1.c: Remove. * gcc.target/i386/20020523-1.c: Remove.
* gcc.target/i386/sse2-lrint-vec.c: Include sse2-check.h. Remove main. * gcc.target/i386/sse2-lrint-vec.c: Include sse2-check.h. Remove main.
* gcc.target/i386/sse2-lrintf-vec.c: Ditto. * gcc.target/i386/sse2-lrintf-vec.c: Ditto.
* gcc.target/i386/ssefn-4.c: Ditto. * gcc.target/i386/ssefn-4.c: Ditto.
* gcc.target/i386/sse-6.c: Ditto. * gcc.target/i386/sse-6.c: Ditto.
...@@ -406,14 +427,11 @@ ...@@ -406,14 +427,11 @@
2007-09-03 H.J. Lu <hongjiu.lu@intel.com> 2007-09-03 H.J. Lu <hongjiu.lu@intel.com>
* gcc.dg/vect/no-tree-scev-cprop-vect-iv-1.c: Restored. Moved * gcc.dg/vect/no-tree-scev-cprop-vect-iv-1.c: Restored. Moved to ...
to ...
* gcc.dg/vect/no-scevccp-vect-iv-1.c: New test. * gcc.dg/vect/no-scevccp-vect-iv-1.c: New test.
* gcc.dg/vect/no-tree-scev-cprop-vect-iv-2.c: Restored. Moved * gcc.dg/vect/no-tree-scev-cprop-vect-iv-2.c: Restored. Moved to ...
to ...
* gcc.dg/vect/no-scevccp-vect-iv-2.c: New test. * gcc.dg/vect/no-scevccp-vect-iv-2.c: New test.
* gcc.dg/vect/no-tree-scev-cprop-vect-iv-3.c: Restored. Moved * gcc.dg/vect/no-tree-scev-cprop-vect-iv-3.c: Restored. Moved to ...
to ...
* gcc.dg/vect/no-scevccp-vect-iv-3.c: New test. * gcc.dg/vect/no-scevccp-vect-iv-3.c: New test.
2007-09-03 Jesper Nilsson <jesper.nilsson@axis.com> 2007-09-03 Jesper Nilsson <jesper.nilsson@axis.com>
/* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-msse2" } */ /* { dg-options "-msse2" } */
#include "../../gcc.target/i386/sse2-check.h"
#include <xmmintrin.h> #include <xmmintrin.h>
#include "cpuid.h"
static void static void
sse2_test (void) sse2_test (void)
{ {
...@@ -20,3 +20,18 @@ sse2_test (void) ...@@ -20,3 +20,18 @@ sse2_test (void)
if (r != 3.0f) if (r != 3.0f)
abort (); abort ();
} }
int
main ()
{
unsigned int eax, ebx, ecx, edx;
if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
return 0;
/* Run SSE2 test only if host has SSE2 support. */
if (edx & bit_SSE2)
sse2_test ();
return 0;
}
/* Helper file for i386 platform. Runtime check for MMX/SSE/SSE2 support.
Used by 20020523-2.c and i386-sse-6.c, and possibly others. */
/* Plagarized from 20020523-2.c. */
/* %ecx */
#define bit_SSE3 (1 << 0)
#define bit_SSSE3 (1 << 9)
#define bit_SSE4_1 (1 << 19)
#define bit_SSE4_2 (1 << 20)
#define bit_POPCNT (1 << 23)
/* %edx */
#define bit_CMOV (1 << 15)
#define bit_MMX (1 << 23)
#define bit_SSE (1 << 25)
#define bit_SSE2 (1 << 26)
/* Extended Features */
/* %ecx */
#define bit_SSE4a (1 << 6)
#ifndef NOINLINE
#define NOINLINE __attribute__ ((noinline))
#endif
static inline unsigned int
i386_get_cpuid (unsigned int *ecx, unsigned int *edx)
{
int fl1;
#ifndef __x86_64__
int fl2;
/* See if we can use cpuid. On AMD64 we always can. */
__asm__ ("pushfl; pushfl; popl %0; movl %0,%1; xorl %2,%0;"
"pushl %0; popfl; pushfl; popl %0; popfl"
: "=&r" (fl1), "=&r" (fl2)
: "i" (0x00200000));
if (((fl1 ^ fl2) & 0x00200000) == 0)
return (0);
#endif
/* Host supports cpuid. See if cpuid gives capabilities, try
CPUID(0). Preserve %ebx and %ecx; cpuid insn clobbers these, we
don't need their CPUID values here, and %ebx may be the PIC
register. */
#ifdef __x86_64__
__asm__ ("pushq %%rcx; pushq %%rbx; cpuid; popq %%rbx; popq %%rcx"
: "=a" (fl1) : "0" (0) : "rdx", "cc");
#else
__asm__ ("pushl %%ecx; pushl %%ebx; cpuid; popl %%ebx; popl %%ecx"
: "=a" (fl1) : "0" (0) : "edx", "cc");
#endif
if (fl1 == 0)
return (0);
/* Invoke CPUID(1), return %ecx and %edx; caller can examine bits to
determine what's supported. */
#ifdef __x86_64__
__asm__ ("pushq %%rbx; cpuid; popq %%rbx"
: "=c" (*ecx), "=d" (*edx), "=a" (fl1) : "2" (1) : "cc");
#else
__asm__ ("pushl %%ebx; cpuid; popl %%ebx"
: "=c" (*ecx), "=d" (*edx), "=a" (fl1) : "2" (1) : "cc");
#endif
return 1;
}
static inline unsigned int
i386_get_extended_cpuid (unsigned int *ecx, unsigned int *edx)
{
int fl1;
if (!(i386_get_cpuid (ecx, edx)))
return 0;
/* Invoke CPUID(0x80000000) to get the highest supported extended function
number */
#ifdef __x86_64__
__asm__ ("cpuid"
: "=a" (fl1) : "0" (0x80000000) : "edx", "ecx", "ebx");
#else
__asm__ ("pushl %%ebx; cpuid; popl %%ebx"
: "=a" (fl1) : "0" (0x80000000) : "edx", "ecx");
#endif
/* Check if highest supported extended function used below are supported */
if (fl1 < 0x80000001)
return 0;
/* Invoke CPUID(0x80000001), return %ecx and %edx; caller can examine bits to
determine what's supported. */
#ifdef __x86_64__
__asm__ ("cpuid"
: "=c" (*ecx), "=d" (*edx), "=a" (fl1) : "2" (0x80000001) : "ebx");
#else
__asm__ ("pushl %%ebx; cpuid; popl %%ebx"
: "=c" (*ecx), "=d" (*edx), "=a" (fl1) : "2" (0x80000001));
#endif
return 1;
}
unsigned int i386_cpuid_ecx (void) NOINLINE;
unsigned int i386_cpuid_edx (void) NOINLINE;
unsigned int i386_extended_cpuid_ecx (void) NOINLINE;
unsigned int i386_extended_cpuid_edx (void) NOINLINE;
unsigned int NOINLINE
i386_cpuid_ecx (void)
{
unsigned int ecx, edx;
if (i386_get_cpuid (&ecx, &edx))
return ecx;
else
return 0;
}
unsigned int NOINLINE
i386_cpuid_edx (void)
{
unsigned int ecx, edx;
if (i386_get_cpuid (&ecx, &edx))
return edx;
else
return 0;
}
unsigned int NOINLINE
i386_extended_cpuid_ecx (void)
{
unsigned int ecx, edx;
if (i386_get_extended_cpuid (&ecx, &edx))
return ecx;
else
return 0;
}
unsigned int NOINLINE
i386_extended_cpuid_edx (void)
{
unsigned int ecx, edx;
if (i386_get_extended_cpuid (&ecx, &edx))
return edx;
else
return 0;
}
static inline unsigned int
i386_cpuid (void)
{
return i386_cpuid_edx ();
}
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
/* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-msse2" } */ /* { dg-options "-msse2" } */
#include "../i386-cpuid.h" #include "cpuid.h"
extern void abort (void); extern void abort (void);
...@@ -41,12 +41,12 @@ test5 (V2USI x) ...@@ -41,12 +41,12 @@ test5 (V2USI x)
return (V2SI) x; return (V2SI) x;
} }
int void
__attribute__ ((noinline)) __attribute__ ((noinline))
do_test (void) do_test (void)
{ {
if (sizeof (short) != 2 || sizeof (int) != 4 || sizeof (long long) != 8) if (sizeof (short) != 2 || sizeof (int) != 4 || sizeof (long long) != 8)
return 0; return;
if (test1 () != 0) if (test1 () != 0)
abort (); abort ();
...@@ -70,19 +70,19 @@ do_test (void) ...@@ -70,19 +70,19 @@ do_test (void)
u.x = test5 (z); u.x = test5 (z);
if (u.y[0] != 6 || u.y[1] != 6) if (u.y[0] != 6 || u.y[1] != 6)
abort (); abort ();
return 0;
} }
int int
main (void) main (void)
{ {
unsigned long cpu_facilities; unsigned int eax, ebx, ecx, edx;
cpu_facilities = i386_cpuid (); if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
if ((cpu_facilities & (bit_MMX | bit_SSE | bit_CMOV | bit_SSE2))
!= (bit_MMX | bit_SSE | bit_CMOV | bit_SSE2))
return 0; return 0;
return do_test (); /* Run SSE2 test only if host has SSE2 support. */
if (edx & bit_SSE2)
do_test ();
return 0;
} }
...@@ -16,7 +16,7 @@ typedef union { ...@@ -16,7 +16,7 @@ typedef union {
unsigned int u[2]; unsigned int u[2];
}vecInWord; }vecInWord;
void mmx_tests (void) NOINLINE; void mmx_tests (void) __attribute__((noinline));
void dump64_16 (char *, char *, vecInWord); void dump64_16 (char *, char *, vecInWord);
void dump64_32 (char *, char *, vecInWord); void dump64_32 (char *, char *, vecInWord);
void dump64_64 (char *, char *, vecInWord); void dump64_64 (char *, char *, vecInWord);
...@@ -90,7 +90,7 @@ mmx_test (void) ...@@ -90,7 +90,7 @@ mmx_test (void)
abort (); abort ();
} }
void NOINLINE void __attribute__((noinline))
mmx_tests (void) mmx_tests (void)
{ {
/* psraw */ /* psraw */
......
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "../../gcc.dg/i386-cpuid.h" #include "cpuid.h"
static void mmx_test (void); static void mmx_test (void);
int int
main () main ()
{ {
unsigned long cpu_facilities; unsigned int eax, ebx, ecx, edx;
cpu_facilities = i386_cpuid_edx (); if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
return 0;
/* Run MMX test only if host has MMX support. */ /* Run MMX test only if host has MMX support. */
if ((cpu_facilities & bit_MMX)) if (edx & bit_MMX)
mmx_test (); mmx_test ();
exit (0); return 0;
} }
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
typedef _Complex double complex_16; typedef _Complex double complex_16;
void NOINLINE void __attribute__((noinline))
test (complex_16 a[5][5]) test (complex_16 a[5][5])
{ {
int i, j, k; int i, j, k;
......
...@@ -16,7 +16,7 @@ typedef union { ...@@ -16,7 +16,7 @@ typedef union {
unsigned char c[16]; unsigned char c[16];
}vecInLong; }vecInLong;
void sse2_tests (void) NOINLINE; void sse2_tests (void) __attribute__((noinline));
void dump128_16 (char *, char *, vecInLong); void dump128_16 (char *, char *, vecInLong);
void dump128_32 (char *, char *, vecInLong); void dump128_32 (char *, char *, vecInLong);
void dump128_64 (char *, char *, vecInLong); void dump128_64 (char *, char *, vecInLong);
...@@ -110,7 +110,7 @@ sse2_test (void) ...@@ -110,7 +110,7 @@ sse2_test (void)
abort (); abort ();
} }
void NOINLINE void __attribute__((noinline))
sse2_tests (void) sse2_tests (void)
{ {
/* psraw */ /* psraw */
......
...@@ -16,7 +16,7 @@ typedef union { ...@@ -16,7 +16,7 @@ typedef union {
unsigned int u[2]; unsigned int u[2];
}vecInWord; }vecInWord;
void sse_tests (void) NOINLINE; void sse_tests (void) __attribute__((noinline));
void dump64_16 (char *, char *, vecInWord); void dump64_16 (char *, char *, vecInWord);
int check (const char *, const char *[]); int check (const char *, const char *[]);
...@@ -53,7 +53,7 @@ sse_test (void) ...@@ -53,7 +53,7 @@ sse_test (void)
abort (); abort ();
} }
void NOINLINE void __attribute__((noinline))
sse_tests (void) sse_tests (void)
{ {
/* pshufw */ /* pshufw */
......
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "../../gcc.dg/i386-cpuid.h" #include "cpuid.h"
static void sse_test (void); static void sse_test (void);
int int
main () main ()
{ {
unsigned long cpu_facilities; unsigned int eax, ebx, ecx, edx;
cpu_facilities = i386_cpuid_edx (); if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
return 0;
/* Run SSE test only if host has SSE support. */ /* Run SSE test only if host has SSE support. */
if ((cpu_facilities & bit_SSE)) if (edx & bit_SSE)
sse_test (); sse_test ();
exit (0); return 0;
} }
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "../../gcc.dg/i386-cpuid.h" #include "cpuid.h"
static void sse2_test (void); static void sse2_test (void);
int int
main () main ()
{ {
unsigned long cpu_facilities; unsigned int eax, ebx, ecx, edx;
cpu_facilities = i386_cpuid_edx (); if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
return 0;
/* Run SSE2 test only if host has SSE2 support. */ /* Run SSE2 test only if host has SSE2 support. */
if ((cpu_facilities & bit_SSE2)) if (edx & bit_SSE2)
sse2_test (); sse2_test ();
exit (0); return 0;
} }
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "../../gcc.dg/i386-cpuid.h" #include "cpuid.h"
static void sse3_test (void); static void sse3_test (void);
int int
main () main ()
{ {
unsigned long cpu_facilities; unsigned int eax, ebx, ecx, edx;
if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
return 0;
cpu_facilities = i386_cpuid_ecx ();
/* Run SSE3 test only if host has SSE3 support. */ /* Run SSE3 test only if host has SSE3 support. */
if ((cpu_facilities & bit_SSE3)) if (ecx & bit_SSE3)
sse3_test (); sse3_test ();
exit (0); return 0;
} }
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "../../gcc.dg/i386-cpuid.h" #include "cpuid.h"
static void sse4_1_test (void); static void sse4_1_test (void);
...@@ -9,13 +10,14 @@ static void sse4_1_test (void); ...@@ -9,13 +10,14 @@ static void sse4_1_test (void);
int int
main () main ()
{ {
unsigned long cpu_facilities; unsigned int eax, ebx, ecx, edx;
cpu_facilities = i386_cpuid_ecx (); if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
return 0;
/* Run SSE4.1 test only if host has SSE4.1 support. */ /* Run SSE4.1 test only if host has SSE4.1 support. */
if ((cpu_facilities & bit_SSE4_1)) if (ecx & bit_SSE4_1)
sse4_1_test (); sse4_1_test ();
exit (0); return 0;
} }
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "../../gcc.dg/i386-cpuid.h" #include "cpuid.h"
static void sse4_2_test (void); static void sse4_2_test (void);
int int
main () main ()
{ {
unsigned long cpu_facilities; unsigned int eax, ebx, ecx, edx;
cpu_facilities = i386_cpuid_ecx (); if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
return 0;
/* Run SSE4.2 test only if host has SSE4.2 support. */ /* Run SSE4.2 test only if host has SSE4.2 support. */
if ((cpu_facilities & bit_SSE4_2)) if (ecx & bit_SSE4_2)
sse4_2_test (); sse4_2_test ();
exit (0); return 0;
} }
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "../../gcc.dg/i386-cpuid.h" #include "cpuid.h"
static void sse4a_test (void); static void sse4a_test (void);
int int
main () main ()
{ {
unsigned long cpu_facilities; unsigned int eax, ebx, ecx, edx;
cpu_facilities = i386_extended_cpuid_ecx (); if (!__get_cpuid (0x80000001, &eax, &ebx, &ecx, &edx))
return 0;
/* Run SSE4a test only if host has SSE4a support. */ /* Run SSE4a test only if host has SSE4a support. */
if ((cpu_facilities & bit_SSE4a)) if (ecx & bit_SSE4a)
sse4a_test (); sse4a_test ();
exit (0); return 0;
} }
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "../../gcc.dg/i386-cpuid.h" #include "cpuid.h"
static void ssse3_test (void); static void ssse3_test (void);
int int
main () main ()
{ {
unsigned long cpu_facilities; unsigned int eax, ebx, ecx, edx;
cpu_facilities = i386_cpuid_ecx (); if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
return 0;
/* Run SSSE3 test only if host has SSSE3 support. */ /* Run SSSE3 test only if host has SSSE3 support. */
if ((cpu_facilities & bit_SSSE3)) if (ecx & bit_SSSE3)
ssse3_test (); ssse3_test ();
exit (0); return 0;
} }
2007-09-05 Uros Bizjak <ubizjak@gmail.com>
* testsuite/libgomp.c/atomic-1.c: Include cpuid.h for i386 targets.
(main): Use __get_cpuid to get i386 target fetaures.
* testsuite/libgomp.c/atomic-2.c: Include cpuid.h for x86_64 targets.
(main): Use __get_cpuid to get x86_64 target fetaures.
2007-08-15 Jack Howarth <howarth@bromo.med.uc.edu> 2007-08-15 Jack Howarth <howarth@bromo.med.uc.edu>
PR target/32765 PR target/32765
......
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
/* { dg-options "-O2 -march=pentium" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */ /* { dg-options "-O2 -march=pentium" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
#ifdef __i386__ #ifdef __i386__
#include "../../../gcc/testsuite/gcc.dg/i386-cpuid.h" #include "cpuid.h"
#define bit_CX8 (1 << 8)
#endif #endif
extern void abort (void); extern void abort (void);
...@@ -41,11 +40,12 @@ int ...@@ -41,11 +40,12 @@ int
main (void) main (void)
{ {
#ifdef __i386__ #ifdef __i386__
unsigned long cpu_facilities; unsigned int eax, ebx, ecx, edx;
cpu_facilities = i386_cpuid (); if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
return 0;
if (!(cpu_facilities & bit_CX8)) if (!(edx & bit_CMPXCHG8B))
return 0; return 0;
#endif #endif
......
/* { dg-do run } */ /* { dg-do run } */
/* { dg-options "-O2 -mcx16" { target { { i?86-*-* x86_64-*-* } && lp64 } } } */ /* { dg-options "-O2 -mcx16" { target { { i?86-*-* x86_64-*-* } && lp64 } } } */
#ifdef __x86_64__
#include "cpuid.h"
#endif
double d = 1.5; double d = 1.5;
long double ld = 3; long double ld = 3;
extern void abort (void); extern void abort (void);
...@@ -20,11 +24,12 @@ int ...@@ -20,11 +24,12 @@ int
main (void) main (void)
{ {
#ifdef __x86_64__ #ifdef __x86_64__
# define bit_CX16 (1 << 13) unsigned int eax, ebx, ecx, edx;
unsigned int ax, bx, cx, dx;
__asm__ ("cpuid" : "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx) if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
: "0" (1) : "cc"); return 0;
if (!(cx & bit_CX16))
if (!(ecx & bit_CMPXCHG16B))
return 0; return 0;
#endif #endif
test (); test ();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment