i386-cpuid.h (bit_CMOV): Define.

* gcc.dg/i386-cpuid.h (bit_CMOV): Define.
	(i386_cpuid): No need to test if cpuid is available on AMD64.
	Fix assembly, so that it works onboth i386 and AMD64.
	* gcc.dg/i386-sse-6.c: Include stdio.h, stdlib.h and string.h.
	(vecInLong): Fix s[] member type to unsigned int.
	(vecInWord): Remove type.
	(mmx_tests, sse_tests, dump64_16, dump64_32, dump64_64): Remove.
	(a64, b64, c64, d64, e64): Remove.
	(main): Pass if CPU has no MMX, SSE, SSE2 or CMOV support.
	Remove unused variable.  Remove initialization of removed variables.
	Don't call mmx_tests nor sse_tests.
	(reference_mmx, reference_sse): Remove.
	(check): Add return stmt.
	* gcc.dg/i386-sse-7.c: New test.
	* gcc.dg/i386-mmx-4.c: New test.

From-SVN: r77955
This commit is contained in:
Jakub Jelinek 2004-02-17 18:12:20 +01:00 committed by Jakub Jelinek
parent 72b1de442d
commit 3977a4a1ee
5 changed files with 427 additions and 201 deletions

View File

@ -1,3 +1,21 @@
2004-02-17 Jakub Jelinek <jakub@redhat.com>
* gcc.dg/i386-cpuid.h (bit_CMOV): Define.
(i386_cpuid): No need to test if cpuid is available on AMD64.
Fix assembly, so that it works onboth i386 and AMD64.
* gcc.dg/i386-sse-6.c: Include stdio.h, stdlib.h and string.h.
(vecInLong): Fix s[] member type to unsigned int.
(vecInWord): Remove type.
(mmx_tests, sse_tests, dump64_16, dump64_32, dump64_64): Remove.
(a64, b64, c64, d64, e64): Remove.
(main): Pass if CPU has no MMX, SSE, SSE2 or CMOV support.
Remove unused variable. Remove initialization of removed variables.
Don't call mmx_tests nor sse_tests.
(reference_mmx, reference_sse): Remove.
(check): Add return stmt.
* gcc.dg/i386-sse-7.c: New test.
* gcc.dg/i386-mmx-4.c: New test.
2004-02-17 Giovanni Bajo <giovannibajo@gcc.gnu.org>
* g++.dg/tc1/dr176.C: Add missing semicolon (typo).

View File

@ -2,6 +2,7 @@
Used by 20020523-2.c and i386-sse-6.c, and possibly others. */
/* Plagarized from 20020523-2.c. */
#define bit_CMOV (1 << 15)
#define bit_MMX (1 << 23)
#define bit_SSE (1 << 25)
#define bit_SSE2 (1 << 26)
@ -17,27 +18,39 @@ i386_cpuid (void)
{
int fl1, fl2;
/* See if we can use cpuid. */
#ifndef __x86_64__
/* 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. */
__asm__ ("push %%ecx ; push %%ebx ; cpuid ; pop %%ebx ; pop %%ecx"
#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 %edx; caller can examine bits to
determine what's supported. */
__asm__ ("push %%ecx ; push %%ebx ; cpuid ; pop %%ebx ; pop %%ecx" : "=d" (fl2) : "a" (1) : "cc");
#ifdef __x86_64__
__asm__ ("pushq %%rcx; pushq %%rbx; cpuid; popq %%rbx; popq %%rcx"
: "=d" (fl2), "=a" (fl1) : "1" (1) : "cc");
#else
__asm__ ("pushl %%ecx; pushl %%ebx; cpuid; popl %%ebx; popl %%ecx"
: "=d" (fl2), "=a" (fl1) : "1" (1) : "cc");
#endif
return fl2;
}

View File

@ -0,0 +1,245 @@
/* { dg-do run { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-O2 -mmmx" } */
#include <mmintrin.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "i386-cpuid.h"
#ifndef NOINLINE
#define NOINLINE __attribute__ ((noinline))
#endif
#define SHIFT (4)
typedef union {
__m64 v;
unsigned char c[8];
unsigned short int s[4];
unsigned long long t;
unsigned int u[2];
}vecInWord;
void mmx_tests (void) NOINLINE;
void dump64_16 (char *, char *, vecInWord);
void dump64_32 (char *, char *, vecInWord);
void dump64_64 (char *, char *, vecInWord);
int check (const char *, const char *[]);
char buf[8000];
char comparison[8000];
static int errors = 0;
vecInWord a64, b64, c64, d64, e64;
__m64 m64_16, s64, m64_32, m64_64;
const char *reference_mmx[] = {
"_mm_srai_pi16 0012 0012 0012 0012 \n",
"_mm_sra_pi16 0012 0012 0012 0012 \n",
"_mm_srai_pi32 00123456 00123456 \n",
"_mm_sra_pi32 00123456 00123456 \n",
"_mm_srli_pi16 0012 0012 0012 0012 \n",
"_mm_srl_pi16 0012 0012 0012 0012 \n",
"_mm_srli_pi32 00123456 00123456 \n",
"_mm_srl_pi32 00123456 00123456 \n",
"_mm_srli_si64 00123456789abcde\n",
"_mm_srl_si64 00123456789abcde\n",
"_mm_slli_pi16 1230 1230 1230 1230 \n",
"_mm_sll_pi16 1230 1230 1230 1230 \n",
"_mm_slli_pi32 12345670 12345670 \n",
"_mm_sll_pi32 12345670 12345670 \n",
"_mm_slli_si64 123456789abcdef0\n",
"_mm_sll_si64 123456789abcdef0\n",
""
};
int main()
{
unsigned long cpu_facilities;
cpu_facilities = i386_cpuid ();
if ((cpu_facilities & bit_MMX) == 0)
exit (0);
d64.u[0] = 0x01234567;
d64.u[1] = 0x01234567;
m64_32 = d64.v;
e64.t = 0x0123456789abcdefULL;
m64_64 = e64.v;
a64.s[0] = 0x0123;
a64.s[1] = 0x0123;
a64.s[2] = 0x0123;
a64.s[3] = 0x0123;
m64_16 = a64.v;
b64.s[0] = SHIFT;
b64.s[1] = 0;
b64.s[2] = 0;
b64.s[3] = 0;
s64 = b64.v;
if (cpu_facilities & bit_MMX)
{
mmx_tests();
check (buf, reference_mmx);
#ifdef DEBUG
printf ("mmx testing:\n");
printf (buf);
printf ("\ncomparison:\n");
printf (comparison);
#endif
buf[0] = '\0';
}
if (errors != 0)
abort ();
exit (0);
}
void NOINLINE
mmx_tests (void)
{
/* psraw */
c64.v = _mm_srai_pi16 (m64_16, SHIFT);
dump64_16 (buf, "_mm_srai_pi16", c64);
c64.v = _mm_sra_pi16 (m64_16, s64);
dump64_16 (buf, "_mm_sra_pi16", c64);
/* psrad */
c64.v = _mm_srai_pi32 (m64_32, SHIFT);
dump64_32 (buf, "_mm_srai_pi32", c64);
c64.v = _mm_sra_pi32 (m64_32, s64);
dump64_32 (buf, "_mm_sra_pi32", c64);
/* psrlw */
c64.v = _mm_srli_pi16 (m64_16, SHIFT);
dump64_16 (buf, "_mm_srli_pi16", c64);
c64.v = _mm_srl_pi16 (m64_16, s64);
dump64_16 (buf, "_mm_srl_pi16", c64);
/* psrld */
c64.v = _mm_srli_pi32 (m64_32, SHIFT);
dump64_32 (buf, "_mm_srli_pi32", c64);
c64.v = _mm_srl_pi32 (m64_32, s64);
dump64_32 (buf, "_mm_srl_pi32", c64);
/* psrlq */
c64.v = _mm_srli_si64 (m64_64, SHIFT);
dump64_64 (buf, "_mm_srli_si64", c64);
c64.v = _mm_srl_si64 (m64_64, s64);
dump64_64 (buf, "_mm_srl_si64", c64);
/* psllw */
c64.v = _mm_slli_pi16 (m64_16, SHIFT);
dump64_16 (buf, "_mm_slli_pi16", c64);
c64.v = _mm_sll_pi16 (m64_16, s64);
dump64_16 (buf, "_mm_sll_pi16", c64);
/* pslld */
c64.v = _mm_slli_pi32 (m64_32, SHIFT);
dump64_32 (buf, "_mm_slli_pi32", c64);
c64.v = _mm_sll_pi32 (m64_32, s64);
dump64_32 (buf, "_mm_sll_pi32", c64);
/* psllq */
c64.v = _mm_slli_si64 (m64_64, SHIFT);
dump64_64 (buf, "_mm_slli_si64", c64);
c64.v = _mm_sll_si64 (m64_64, s64);
dump64_64 (buf, "_mm_sll_si64", c64);
}
void
dump64_16 (char *buf, char *name, vecInWord x)
{
int i;
char *p = buf + strlen (buf);
sprintf (p, "%s ", name);
p += strlen (p);
for (i=0; i<4; i++)
{
sprintf (p, "%4.4x ", x.s[i]);
p += strlen (p);
}
strcat (p, "\n");
}
void
dump64_32 (char *buf, char *name, vecInWord x)
{
int i;
char *p = buf + strlen (buf);
sprintf (p, "%s ", name);
p += strlen (p);
for (i=0; i<2; i++)
{
sprintf (p, "%8.8x ", x.u[i]);
p += strlen (p);
}
strcat (p, "\n");
}
void
dump64_64 (char *buf, char *name, vecInWord x)
{
char *p = buf + strlen (buf);
sprintf (p, "%s ", name);
p += strlen (p);
sprintf (p, "%16.16llx\n", x.t);
}
int
check (const char *input, const char *reference[])
{
int broken, i, j, len;
const char *p_input;
char *p_comparison;
int new_errors = 0;
p_comparison = &comparison[0];
p_input = input;
for (i = 0; *reference[i] != '\0'; i++)
{
broken = 0;
len = strlen (reference[i]);
for (j = 0; j < len; j++)
{
/* Ignore the terminating NUL characters at the end of every string in 'reference[]'. */
if (!broken && *p_input != reference[i][j])
{
*p_comparison = '\0';
strcat (p_comparison, " >>> ");
p_comparison += strlen (p_comparison);
new_errors++;
broken = 1;
}
*p_comparison = *p_input;
p_comparison++;
p_input++;
}
if (broken)
{
*p_comparison = '\0';
strcat (p_comparison, "expected:\n");
strcat (p_comparison, reference[i]);
p_comparison += strlen (p_comparison);
}
}
*p_comparison = '\0';
strcat (p_comparison, new_errors ? "failure\n\n" : "O.K.\n\n") ;
errors += new_errors;
return 0;
}

View File

@ -1,6 +1,9 @@
/* { dg-do run { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-O2 -msse2" } */
#include <xmmintrin.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "i386-cpuid.h"
#ifndef NOINLINE
@ -11,26 +14,13 @@
typedef union {
__m128i v;
unsigned long s[4];
unsigned int s[4];
unsigned short int t[8];
unsigned long long u[2];
unsigned char c[16];
}vecInLong;
typedef union {
__m64 v;
unsigned char c[8];
unsigned short int s[4];
unsigned long long t;
unsigned int u[2];
}vecInWord;
void mmx_tests (void) NOINLINE;
void sse_tests (void) NOINLINE;
void sse2_tests (void) NOINLINE;
void dump64_16 (char *, char *, vecInWord);
void dump64_32 (char *, char *, vecInWord);
void dump64_64 (char *, char *, vecInWord);
void dump128_16 (char *, char *, vecInLong);
void dump128_32 (char *, char *, vecInLong);
void dump128_64 (char *, char *, vecInLong);
@ -42,35 +32,9 @@ char comparison[8000];
static int errors = 0;
vecInLong a128, b128, c128, d128, e128, f128;
vecInWord a64, b64, c64, d64, e64;
__m128i m128_16, m128_32, s128, m128_64, m128_128;
__m64 m64_16, s64, m64_32, m64_64;
const char *reference_mmx[] = {
"_mm_srai_pi16 0012 0012 0012 0012 \n",
"_mm_sra_pi16 0012 0012 0012 0012 \n",
"_mm_srai_pi32 00123456 00123456 \n",
"_mm_sra_pi32 00123456 00123456 \n",
"_mm_srli_pi16 0012 0012 0012 0012 \n",
"_mm_srl_pi16 0012 0012 0012 0012 \n",
"_mm_srli_pi32 00123456 00123456 \n",
"_mm_srl_pi32 00123456 00123456 \n",
"_mm_srli_si64 00123456789abcde\n",
"_mm_srl_si64 00123456789abcde\n",
"_mm_slli_pi16 1230 1230 1230 1230 \n",
"_mm_sll_pi16 1230 1230 1230 1230 \n",
"_mm_slli_pi32 12345670 12345670 \n",
"_mm_sll_pi32 12345670 12345670 \n",
"_mm_slli_si64 123456789abcdef0\n",
"_mm_sll_si64 123456789abcdef0\n",
""
};
const char *reference_sse[] = {
"_mm_shuffle_pi16 0123 4567 89ab cdef \n",
""
};
const char *reference_sse2[] = {
"_mm_srai_epi16 0012 0012 0012 0012 0012 0012 0012 0012 \n",
"_mm_sra_epi16 0012 0012 0012 0012 0012 0012 0012 0012 \n",
@ -98,12 +62,13 @@ const char *reference_sse2[] = {
int main()
{
unsigned long *p;
unsigned long cpu_facilities;
cpu_facilities = i386_cpuid ();
if (!cpu_facilities) /* If host has no vector support, pass. */
if ((cpu_facilities & (bit_MMX | bit_SSE | bit_SSE2 | bit_CMOV))
!= (bit_MMX | bit_SSE | bit_SSE2 | bit_CMOV))
/* If host has no vector support, pass. */
exit (0);
a128.s[0] = 0x01234567;
@ -136,22 +101,6 @@ int main()
m128_128 = e128.v;
d64.u[0] = 0x01234567;
d64.u[1] = 0x01234567;
m64_32 = d64.v;
e64.t = 0x0123456789abcdefULL;
m64_64 = e64.v;
a64.s[0] = 0x0123;
a64.s[1] = 0x0123;
a64.s[2] = 0x0123;
a64.s[3] = 0x0123;
m64_16 = a64.v;
b128.s[0] = SHIFT;
b128.s[1] = 0;
b128.s[2] = 0;
@ -159,39 +108,6 @@ int main()
s128 = b128.v;
b64.s[0] = SHIFT;
b64.s[1] = 0;
b64.s[2] = 0;
b64.s[3] = 0;
s64 = b64.v;
if (cpu_facilities & bit_MMX)
{
mmx_tests();
check (buf, reference_mmx);
#ifdef DEBUG
printf ("mmx testing:\n");
printf (buf);
printf ("\ncomparison:\n");
printf (comparison);
#endif
buf[0] = '\0';
}
if (cpu_facilities & bit_SSE)
{
sse_tests();
check (buf, reference_sse);
#ifdef DEBUG
printf ("sse testing:\n");
printf (buf);
printf ("\ncomparison:\n");
printf (comparison);
#endif
buf[0] = '\0';
}
if (cpu_facilities & bit_SSE2)
{
sse2_tests();
@ -210,66 +126,6 @@ int main()
exit (0);
}
void NOINLINE
mmx_tests (void)
{
/* psraw */
c64.v = _mm_srai_pi16 (m64_16, SHIFT);
dump64_16 (buf, "_mm_srai_pi16", c64);
c64.v = _mm_sra_pi16 (m64_16, s64);
dump64_16 (buf, "_mm_sra_pi16", c64);
/* psrad */
c64.v = _mm_srai_pi32 (m64_32, SHIFT);
dump64_32 (buf, "_mm_srai_pi32", c64);
c64.v = _mm_sra_pi32 (m64_32, s64);
dump64_32 (buf, "_mm_sra_pi32", c64);
/* psrlw */
c64.v = _mm_srli_pi16 (m64_16, SHIFT);
dump64_16 (buf, "_mm_srli_pi16", c64);
c64.v = _mm_srl_pi16 (m64_16, s64);
dump64_16 (buf, "_mm_srl_pi16", c64);
/* psrld */
c64.v = _mm_srli_pi32 (m64_32, SHIFT);
dump64_32 (buf, "_mm_srli_pi32", c64);
c64.v = _mm_srl_pi32 (m64_32, s64);
dump64_32 (buf, "_mm_srl_pi32", c64);
/* psrlq */
c64.v = _mm_srli_si64 (m64_64, SHIFT);
dump64_64 (buf, "_mm_srli_si64", c64);
c64.v = _mm_srl_si64 (m64_64, s64);
dump64_64 (buf, "_mm_srl_si64", c64);
/* psllw */
c64.v = _mm_slli_pi16 (m64_16, SHIFT);
dump64_16 (buf, "_mm_slli_pi16", c64);
c64.v = _mm_sll_pi16 (m64_16, s64);
dump64_16 (buf, "_mm_sll_pi16", c64);
/* pslld */
c64.v = _mm_slli_pi32 (m64_32, SHIFT);
dump64_32 (buf, "_mm_slli_pi32", c64);
c64.v = _mm_sll_pi32 (m64_32, s64);
dump64_32 (buf, "_mm_sll_pi32", c64);
/* psllq */
c64.v = _mm_slli_si64 (m64_64, SHIFT);
dump64_64 (buf, "_mm_slli_si64", c64);
c64.v = _mm_sll_si64 (m64_64, s64);
dump64_64 (buf, "_mm_sll_si64", c64);
}
void NOINLINE
sse_tests (void)
{
/* pshufw */
c64.v = _mm_shuffle_pi16 (m64_64, 0x1b);
dump64_16 (buf, "_mm_shuffle_pi16", c64);
}
void NOINLINE
sse2_tests (void)
{
@ -344,52 +200,6 @@ sse2_tests (void)
dump128_16 (buf, "_mm_shuffehi_epi16", c128);
}
void
dump64_16 (char *buf, char *name, vecInWord x)
{
int i;
char *p = buf + strlen (buf);
sprintf (p, "%s ", name);
p += strlen (p);
for (i=0; i<4; i++)
{
sprintf (p, "%4.4x ", x.s[i]);
p += strlen (p);
}
strcat (p, "\n");
}
void
dump64_32 (char *buf, char *name, vecInWord x)
{
int i;
char *p = buf + strlen (buf);
sprintf (p, "%s ", name);
p += strlen (p);
for (i=0; i<2; i++)
{
sprintf (p, "%8.8x ", x.u[i]);
p += strlen (p);
}
strcat (p, "\n");
}
void
dump64_64 (char *buf, char *name, vecInWord x)
{
int i;
char *p = buf + strlen (buf);
sprintf (p, "%s ", name);
p += strlen (p);
sprintf (p, "%16.16llx\n", x.t);
}
void
dump128_16 (char *buf, char *name, vecInLong x)
{
@ -502,4 +312,5 @@ check (const char *input, const char *reference[])
*p_comparison = '\0';
strcat (p_comparison, new_errors ? "failure\n\n" : "O.K.\n\n") ;
errors += new_errors;
return 0;
}

View File

@ -0,0 +1,139 @@
/* { dg-do run { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-O2 -msse" } */
#include <xmmintrin.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "i386-cpuid.h"
#ifndef NOINLINE
#define NOINLINE __attribute__ ((noinline))
#endif
#define SHIFT (4)
typedef union {
__m64 v;
unsigned char c[8];
unsigned short int s[4];
unsigned long long t;
unsigned int u[2];
}vecInWord;
void sse_tests (void) NOINLINE;
void dump64_16 (char *, char *, vecInWord);
int check (const char *, const char *[]);
char buf[8000];
char comparison[8000];
static int errors = 0;
vecInWord c64, e64;
__m64 m64_64;
const char *reference_sse[] = {
"_mm_shuffle_pi16 0123 4567 89ab cdef \n",
""
};
int main()
{
unsigned long cpu_facilities;
cpu_facilities = i386_cpuid ();
if ((cpu_facilities & (bit_MMX | bit_SSE | bit_CMOV))
!= (bit_MMX | bit_SSE | bit_CMOV))
/* If host has no vector support, pass. */
exit (0);
e64.t = 0x0123456789abcdefULL;
m64_64 = e64.v;
if (cpu_facilities & bit_SSE)
{
sse_tests();
check (buf, reference_sse);
#ifdef DEBUG
printf ("sse testing:\n");
printf (buf);
printf ("\ncomparison:\n");
printf (comparison);
#endif
buf[0] = '\0';
}
if (errors != 0)
abort ();
exit (0);
}
void NOINLINE
sse_tests (void)
{
/* pshufw */
c64.v = _mm_shuffle_pi16 (m64_64, 0x1b);
dump64_16 (buf, "_mm_shuffle_pi16", c64);
}
void
dump64_16 (char *buf, char *name, vecInWord x)
{
int i;
char *p = buf + strlen (buf);
sprintf (p, "%s ", name);
p += strlen (p);
for (i=0; i<4; i++)
{
sprintf (p, "%4.4x ", x.s[i]);
p += strlen (p);
}
strcat (p, "\n");
}
int
check (const char *input, const char *reference[])
{
int broken, i, j, len;
const char *p_input;
char *p_comparison;
int new_errors = 0;
p_comparison = &comparison[0];
p_input = input;
for (i = 0; *reference[i] != '\0'; i++)
{
broken = 0;
len = strlen (reference[i]);
for (j = 0; j < len; j++)
{
/* Ignore the terminating NUL characters at the end of every string in 'reference[]'. */
if (!broken && *p_input != reference[i][j])
{
*p_comparison = '\0';
strcat (p_comparison, " >>> ");
p_comparison += strlen (p_comparison);
new_errors++;
broken = 1;
}
*p_comparison = *p_input;
p_comparison++;
p_input++;
}
if (broken)
{
*p_comparison = '\0';
strcat (p_comparison, "expected:\n");
strcat (p_comparison, reference[i]);
p_comparison += strlen (p_comparison);
}
}
*p_comparison = '\0';
strcat (p_comparison, new_errors ? "failure\n\n" : "O.K.\n\n") ;
errors += new_errors;
return 0;
}