1/* { dg-do run { target i?86-*-* x86_64-*-* } } */ 2/* { dg-options "-O2 -msse" } */ 3#include <xmmintrin.h> 4#include <stdio.h> 5#include <stdlib.h> 6#include <string.h> 7#include "../../gcc.dg/i386-cpuid.h" 8 9#ifndef NOINLINE 10#define NOINLINE __attribute__ ((noinline)) 11#endif 12 13#define SHIFT (4) 14 15typedef union { 16 __m64 v; 17 unsigned char c[8]; 18 unsigned short int s[4]; 19 unsigned long long t; 20 unsigned int u[2]; 21}vecInWord; 22 23void sse_tests (void) NOINLINE; 24void dump64_16 (char *, char *, vecInWord); 25int check (const char *, const char *[]); 26 27char buf[8000]; 28char comparison[8000]; 29static int errors = 0; 30 31vecInWord c64, e64; 32__m64 m64_64; 33 34const char *reference_sse[] = { 35 "_mm_shuffle_pi16 0123 4567 89ab cdef \n", 36 "" 37}; 38 39int main() 40{ 41 unsigned long cpu_facilities; 42 43 cpu_facilities = i386_cpuid (); 44 45 if ((cpu_facilities & (bit_MMX | bit_SSE | bit_CMOV)) 46 != (bit_MMX | bit_SSE | bit_CMOV)) 47 /* If host has no vector support, pass. */ 48 exit (0); 49 50 e64.t = 0x0123456789abcdefULL; 51 52 m64_64 = e64.v; 53 54 if (cpu_facilities & bit_SSE) 55 { 56 sse_tests(); 57 check (buf, reference_sse); 58#ifdef DEBUG 59 printf ("sse testing:\n"); 60 printf (buf); 61 printf ("\ncomparison:\n"); 62 printf (comparison); 63#endif 64 buf[0] = '\0'; 65 } 66 67 if (errors != 0) 68 abort (); 69 exit (0); 70} 71 72void NOINLINE 73sse_tests (void) 74{ 75 /* pshufw */ 76 c64.v = _mm_shuffle_pi16 (m64_64, 0x1b); 77 dump64_16 (buf, "_mm_shuffle_pi16", c64); 78} 79 80void 81dump64_16 (char *buf, char *name, vecInWord x) 82{ 83 int i; 84 char *p = buf + strlen (buf); 85 86 sprintf (p, "%s ", name); 87 p += strlen (p); 88 89 for (i=0; i<4; i++) 90 { 91 sprintf (p, "%4.4x ", x.s[i]); 92 p += strlen (p); 93 } 94 strcat (p, "\n"); 95} 96 97int 98check (const char *input, const char *reference[]) 99{ 100 int broken, i, j, len; 101 const char *p_input; 102 char *p_comparison; 103 int new_errors = 0; 104 105 p_comparison = &comparison[0]; 106 p_input = input; 107 108 for (i = 0; *reference[i] != '\0'; i++) 109 { 110 broken = 0; 111 len = strlen (reference[i]); 112 for (j = 0; j < len; j++) 113 { 114 /* Ignore the terminating NUL characters at the end of every string in 'reference[]'. */ 115 if (!broken && *p_input != reference[i][j]) 116 { 117 *p_comparison = '\0'; 118 strcat (p_comparison, " >>> "); 119 p_comparison += strlen (p_comparison); 120 new_errors++; 121 broken = 1; 122 } 123 *p_comparison = *p_input; 124 p_comparison++; 125 p_input++; 126 } 127 if (broken) 128 { 129 *p_comparison = '\0'; 130 strcat (p_comparison, "expected:\n"); 131 strcat (p_comparison, reference[i]); 132 p_comparison += strlen (p_comparison); 133 } 134 } 135 *p_comparison = '\0'; 136 strcat (p_comparison, new_errors ? "failure\n\n" : "O.K.\n\n") ; 137 errors += new_errors; 138 return 0; 139} 140