1/* { dg-do run } */ 2/* { dg-options "-O2 -mmmx" } */ 3 4#include "mmx-check.h" 5 6#include <mmintrin.h> 7#include <string.h> 8 9#define SHIFT (4) 10 11typedef union { 12 __m64 v; 13 unsigned char c[8]; 14 unsigned short int s[4]; 15 unsigned long long t; 16 unsigned int u[2]; 17}vecInWord; 18 19void mmx_tests (void) __attribute__((noinline)); 20void dump64_16 (char *, char *, vecInWord); 21void dump64_32 (char *, char *, vecInWord); 22void dump64_64 (char *, char *, vecInWord); 23int check (const char *, const char *[]); 24 25char buf[8000]; 26char comparison[8000]; 27static int errors = 0; 28 29vecInWord a64, b64, c64, d64, e64; 30__m64 m64_16, s64, m64_32, m64_64; 31 32const char *reference_mmx[] = { 33 "_mm_srai_pi16 0012 0012 0012 0012 \n", 34 "_mm_sra_pi16 0012 0012 0012 0012 \n", 35 "_mm_srai_pi32 00123456 00123456 \n", 36 "_mm_sra_pi32 00123456 00123456 \n", 37 "_mm_srli_pi16 0012 0012 0012 0012 \n", 38 "_mm_srl_pi16 0012 0012 0012 0012 \n", 39 "_mm_srli_pi32 00123456 00123456 \n", 40 "_mm_srl_pi32 00123456 00123456 \n", 41 "_mm_srli_si64 00123456789abcde\n", 42 "_mm_srl_si64 00123456789abcde\n", 43 "_mm_slli_pi16 1230 1230 1230 1230 \n", 44 "_mm_sll_pi16 1230 1230 1230 1230 \n", 45 "_mm_slli_pi32 12345670 12345670 \n", 46 "_mm_sll_pi32 12345670 12345670 \n", 47 "_mm_slli_si64 123456789abcdef0\n", 48 "_mm_sll_si64 123456789abcdef0\n", 49 "" 50}; 51 52 53static void 54mmx_test (void) 55{ 56 d64.u[0] = 0x01234567; 57 d64.u[1] = 0x01234567; 58 59 m64_32 = d64.v; 60 61 e64.t = 0x0123456789abcdefULL; 62 63 m64_64 = e64.v; 64 65 a64.s[0] = 0x0123; 66 a64.s[1] = 0x0123; 67 a64.s[2] = 0x0123; 68 a64.s[3] = 0x0123; 69 70 m64_16 = a64.v; 71 72 b64.s[0] = SHIFT; 73 b64.s[1] = 0; 74 b64.s[2] = 0; 75 b64.s[3] = 0; 76 77 s64 = b64.v; 78 79 mmx_tests(); 80 check (buf, reference_mmx); 81#ifdef DEBUG 82 printf ("mmx testing:\n"); 83 printf (buf); 84 printf ("\ncomparison:\n"); 85 printf (comparison); 86#endif 87 buf[0] = '\0'; 88 89 if (errors != 0) 90 abort (); 91} 92 93void __attribute__((noinline)) 94mmx_tests (void) 95{ 96 /* psraw */ 97 c64.v = _mm_srai_pi16 (m64_16, SHIFT); 98 dump64_16 (buf, "_mm_srai_pi16", c64); 99 c64.v = _mm_sra_pi16 (m64_16, s64); 100 dump64_16 (buf, "_mm_sra_pi16", c64); 101 102 /* psrad */ 103 c64.v = _mm_srai_pi32 (m64_32, SHIFT); 104 dump64_32 (buf, "_mm_srai_pi32", c64); 105 c64.v = _mm_sra_pi32 (m64_32, s64); 106 dump64_32 (buf, "_mm_sra_pi32", c64); 107 108 /* psrlw */ 109 c64.v = _mm_srli_pi16 (m64_16, SHIFT); 110 dump64_16 (buf, "_mm_srli_pi16", c64); 111 c64.v = _mm_srl_pi16 (m64_16, s64); 112 dump64_16 (buf, "_mm_srl_pi16", c64); 113 114 /* psrld */ 115 c64.v = _mm_srli_pi32 (m64_32, SHIFT); 116 dump64_32 (buf, "_mm_srli_pi32", c64); 117 c64.v = _mm_srl_pi32 (m64_32, s64); 118 dump64_32 (buf, "_mm_srl_pi32", c64); 119 120 /* psrlq */ 121 c64.v = _mm_srli_si64 (m64_64, SHIFT); 122 dump64_64 (buf, "_mm_srli_si64", c64); 123 c64.v = _mm_srl_si64 (m64_64, s64); 124 dump64_64 (buf, "_mm_srl_si64", c64); 125 126 /* psllw */ 127 c64.v = _mm_slli_pi16 (m64_16, SHIFT); 128 dump64_16 (buf, "_mm_slli_pi16", c64); 129 c64.v = _mm_sll_pi16 (m64_16, s64); 130 dump64_16 (buf, "_mm_sll_pi16", c64); 131 132 /* pslld */ 133 c64.v = _mm_slli_pi32 (m64_32, SHIFT); 134 dump64_32 (buf, "_mm_slli_pi32", c64); 135 c64.v = _mm_sll_pi32 (m64_32, s64); 136 dump64_32 (buf, "_mm_sll_pi32", c64); 137 138 /* psllq */ 139 c64.v = _mm_slli_si64 (m64_64, SHIFT); 140 dump64_64 (buf, "_mm_slli_si64", c64); 141 c64.v = _mm_sll_si64 (m64_64, s64); 142 dump64_64 (buf, "_mm_sll_si64", c64); 143} 144 145void 146dump64_16 (char *buf, char *name, vecInWord x) 147{ 148 int i; 149 char *p = buf + strlen (buf); 150 151 sprintf (p, "%s ", name); 152 p += strlen (p); 153 154 for (i=0; i<4; i++) 155 { 156 sprintf (p, "%4.4x ", x.s[i]); 157 p += strlen (p); 158 } 159 strcat (p, "\n"); 160} 161 162void 163dump64_32 (char *buf, char *name, vecInWord x) 164{ 165 int i; 166 char *p = buf + strlen (buf); 167 168 sprintf (p, "%s ", name); 169 p += strlen (p); 170 171 for (i=0; i<2; i++) 172 { 173 sprintf (p, "%8.8x ", x.u[i]); 174 p += strlen (p); 175 } 176 strcat (p, "\n"); 177} 178 179void 180dump64_64 (char *buf, char *name, vecInWord x) 181{ 182 char *p = buf + strlen (buf); 183 184 sprintf (p, "%s ", name); 185 p += strlen (p); 186 187#if defined(_WIN32) && !defined(__CYGWIN__) 188 sprintf (p, "%16.16I64x\n", x.t); 189#else 190 sprintf (p, "%16.16llx\n", x.t); 191#endif 192} 193 194int 195check (const char *input, const char *reference[]) 196{ 197 int broken, i, j, len; 198 const char *p_input; 199 char *p_comparison; 200 int new_errors = 0; 201 202 p_comparison = &comparison[0]; 203 p_input = input; 204 205 for (i = 0; *reference[i] != '\0'; i++) 206 { 207 broken = 0; 208 len = strlen (reference[i]); 209 for (j = 0; j < len; j++) 210 { 211 /* Ignore the terminating NUL characters at the end of every string in 'reference[]'. */ 212 if (!broken && *p_input != reference[i][j]) 213 { 214 *p_comparison = '\0'; 215 strcat (p_comparison, " >>> "); 216 p_comparison += strlen (p_comparison); 217 new_errors++; 218 broken = 1; 219 } 220 *p_comparison = *p_input; 221 p_comparison++; 222 p_input++; 223 } 224 if (broken) 225 { 226 *p_comparison = '\0'; 227 strcat (p_comparison, "expected:\n"); 228 strcat (p_comparison, reference[i]); 229 p_comparison += strlen (p_comparison); 230 } 231 } 232 *p_comparison = '\0'; 233 strcat (p_comparison, new_errors ? "failure\n\n" : "O.K.\n\n") ; 234 errors += new_errors; 235 return 0; 236} 237