1258945Sroberto/* { dg-do run { target i?86-*-* x86_64-*-* } } */ 2258945Sroberto/* { dg-options "-O2 -mmmx" } */ 3258945Sroberto#include <mmintrin.h> 4258945Sroberto#include <stdio.h> 5258945Sroberto#include <stdlib.h> 6258945Sroberto#include <string.h> 7258945Sroberto#include "../../gcc.dg/i386-cpuid.h" 8258945Sroberto 9258945Sroberto#ifndef NOINLINE 10258945Sroberto#define NOINLINE __attribute__ ((noinline)) 11258945Sroberto#endif 12258945Sroberto 13258945Sroberto#define SHIFT (4) 14258945Sroberto 15258945Srobertotypedef union { 16258945Sroberto __m64 v; 17258945Sroberto unsigned char c[8]; 18258945Sroberto unsigned short int s[4]; 19258945Sroberto unsigned long long t; 20258945Sroberto unsigned int u[2]; 21258945Sroberto}vecInWord; 22258945Sroberto 23258945Srobertovoid mmx_tests (void) NOINLINE; 24258945Srobertovoid dump64_16 (char *, char *, vecInWord); 25258945Srobertovoid dump64_32 (char *, char *, vecInWord); 26258945Srobertovoid dump64_64 (char *, char *, vecInWord); 27258945Srobertoint check (const char *, const char *[]); 28258945Sroberto 29258945Srobertochar buf[8000]; 30258945Srobertochar comparison[8000]; 31258945Srobertostatic int errors = 0; 32258945Sroberto 33258945SrobertovecInWord a64, b64, c64, d64, e64; 34258945Sroberto__m64 m64_16, s64, m64_32, m64_64; 35258945Sroberto 36258945Srobertoconst char *reference_mmx[] = { 37258945Sroberto "_mm_srai_pi16 0012 0012 0012 0012 \n", 38258945Sroberto "_mm_sra_pi16 0012 0012 0012 0012 \n", 39258945Sroberto "_mm_srai_pi32 00123456 00123456 \n", 40258945Sroberto "_mm_sra_pi32 00123456 00123456 \n", 41258945Sroberto "_mm_srli_pi16 0012 0012 0012 0012 \n", 42258945Sroberto "_mm_srl_pi16 0012 0012 0012 0012 \n", 43258945Sroberto "_mm_srli_pi32 00123456 00123456 \n", 44258945Sroberto "_mm_srl_pi32 00123456 00123456 \n", 45258945Sroberto "_mm_srli_si64 00123456789abcde\n", 46258945Sroberto "_mm_srl_si64 00123456789abcde\n", 47258945Sroberto "_mm_slli_pi16 1230 1230 1230 1230 \n", 48258945Sroberto "_mm_sll_pi16 1230 1230 1230 1230 \n", 49258945Sroberto "_mm_slli_pi32 12345670 12345670 \n", 50258945Sroberto "_mm_sll_pi32 12345670 12345670 \n", 51258945Sroberto "_mm_slli_si64 123456789abcdef0\n", 52258945Sroberto "_mm_sll_si64 123456789abcdef0\n", 53258945Sroberto "" 54258945Sroberto}; 55258945Sroberto 56258945Srobertoint main() 57258945Sroberto{ 58258945Sroberto unsigned long cpu_facilities; 59258945Sroberto 60258945Sroberto cpu_facilities = i386_cpuid (); 61258945Sroberto 62258945Sroberto if ((cpu_facilities & bit_MMX) == 0) 63258945Sroberto exit (0); 64258945Sroberto 65258945Sroberto d64.u[0] = 0x01234567; 66258945Sroberto d64.u[1] = 0x01234567; 67258945Sroberto 68258945Sroberto m64_32 = d64.v; 69258945Sroberto 70258945Sroberto e64.t = 0x0123456789abcdefULL; 71258945Sroberto 72258945Sroberto m64_64 = e64.v; 73258945Sroberto 74258945Sroberto a64.s[0] = 0x0123; 75258945Sroberto a64.s[1] = 0x0123; 76258945Sroberto a64.s[2] = 0x0123; 77258945Sroberto a64.s[3] = 0x0123; 78258945Sroberto 79258945Sroberto m64_16 = a64.v; 80258945Sroberto 81258945Sroberto b64.s[0] = SHIFT; 82258945Sroberto b64.s[1] = 0; 83258945Sroberto b64.s[2] = 0; 84258945Sroberto b64.s[3] = 0; 85258945Sroberto 86258945Sroberto s64 = b64.v; 87258945Sroberto 88258945Sroberto if (cpu_facilities & bit_MMX) 89258945Sroberto { 90258945Sroberto mmx_tests(); 91258945Sroberto check (buf, reference_mmx); 92258945Sroberto#ifdef DEBUG 93258945Sroberto printf ("mmx testing:\n"); 94258945Sroberto printf (buf); 95258945Sroberto printf ("\ncomparison:\n"); 96258945Sroberto printf (comparison); 97258945Sroberto#endif 98258945Sroberto buf[0] = '\0'; 99258945Sroberto } 100258945Sroberto 101258945Sroberto if (errors != 0) 102258945Sroberto abort (); 103258945Sroberto exit (0); 104258945Sroberto} 105258945Sroberto 106258945Srobertovoid NOINLINE 107258945Srobertommx_tests (void) 108258945Sroberto{ 109258945Sroberto /* psraw */ 110258945Sroberto c64.v = _mm_srai_pi16 (m64_16, SHIFT); 111258945Sroberto dump64_16 (buf, "_mm_srai_pi16", c64); 112258945Sroberto c64.v = _mm_sra_pi16 (m64_16, s64); 113258945Sroberto dump64_16 (buf, "_mm_sra_pi16", c64); 114258945Sroberto 115258945Sroberto /* psrad */ 116258945Sroberto c64.v = _mm_srai_pi32 (m64_32, SHIFT); 117258945Sroberto dump64_32 (buf, "_mm_srai_pi32", c64); 118258945Sroberto c64.v = _mm_sra_pi32 (m64_32, s64); 119258945Sroberto dump64_32 (buf, "_mm_sra_pi32", c64); 120258945Sroberto 121258945Sroberto /* psrlw */ 122258945Sroberto c64.v = _mm_srli_pi16 (m64_16, SHIFT); 123258945Sroberto dump64_16 (buf, "_mm_srli_pi16", c64); 124258945Sroberto c64.v = _mm_srl_pi16 (m64_16, s64); 125258945Sroberto dump64_16 (buf, "_mm_srl_pi16", c64); 126258945Sroberto 127258945Sroberto /* psrld */ 128258945Sroberto c64.v = _mm_srli_pi32 (m64_32, SHIFT); 129258945Sroberto dump64_32 (buf, "_mm_srli_pi32", c64); 130258945Sroberto c64.v = _mm_srl_pi32 (m64_32, s64); 131258945Sroberto dump64_32 (buf, "_mm_srl_pi32", c64); 132258945Sroberto 133258945Sroberto /* psrlq */ 134258945Sroberto c64.v = _mm_srli_si64 (m64_64, SHIFT); 135258945Sroberto dump64_64 (buf, "_mm_srli_si64", c64); 136258945Sroberto c64.v = _mm_srl_si64 (m64_64, s64); 137258945Sroberto dump64_64 (buf, "_mm_srl_si64", c64); 138258945Sroberto 139258945Sroberto /* psllw */ 140258945Sroberto c64.v = _mm_slli_pi16 (m64_16, SHIFT); 141258945Sroberto dump64_16 (buf, "_mm_slli_pi16", c64); 142258945Sroberto c64.v = _mm_sll_pi16 (m64_16, s64); 143258945Sroberto dump64_16 (buf, "_mm_sll_pi16", c64); 144258945Sroberto 145258945Sroberto /* pslld */ 146258945Sroberto c64.v = _mm_slli_pi32 (m64_32, SHIFT); 147258945Sroberto dump64_32 (buf, "_mm_slli_pi32", c64); 148258945Sroberto c64.v = _mm_sll_pi32 (m64_32, s64); 149258945Sroberto dump64_32 (buf, "_mm_sll_pi32", c64); 150258945Sroberto 151258945Sroberto /* psllq */ 152258945Sroberto c64.v = _mm_slli_si64 (m64_64, SHIFT); 153258945Sroberto dump64_64 (buf, "_mm_slli_si64", c64); 154258945Sroberto c64.v = _mm_sll_si64 (m64_64, s64); 155258945Sroberto dump64_64 (buf, "_mm_sll_si64", c64); 156258945Sroberto} 157258945Sroberto 158258945Srobertovoid 159258945Srobertodump64_16 (char *buf, char *name, vecInWord x) 160258945Sroberto{ 161258945Sroberto int i; 162258945Sroberto char *p = buf + strlen (buf); 163258945Sroberto 164258945Sroberto sprintf (p, "%s ", name); 165258945Sroberto p += strlen (p); 166258945Sroberto 167258945Sroberto for (i=0; i<4; i++) 168258945Sroberto { 169258945Sroberto sprintf (p, "%4.4x ", x.s[i]); 170258945Sroberto p += strlen (p); 171258945Sroberto } 172258945Sroberto strcat (p, "\n"); 173258945Sroberto} 174258945Sroberto 175258945Srobertovoid 176258945Srobertodump64_32 (char *buf, char *name, vecInWord x) 177258945Sroberto{ 178258945Sroberto int i; 179258945Sroberto char *p = buf + strlen (buf); 180258945Sroberto 181258945Sroberto sprintf (p, "%s ", name); 182258945Sroberto p += strlen (p); 183258945Sroberto 184258945Sroberto for (i=0; i<2; i++) 185258945Sroberto { 186258945Sroberto sprintf (p, "%8.8x ", x.u[i]); 187258945Sroberto p += strlen (p); 188258945Sroberto } 189258945Sroberto strcat (p, "\n"); 190258945Sroberto} 191258945Sroberto 192258945Srobertovoid 193258945Srobertodump64_64 (char *buf, char *name, vecInWord x) 194258945Sroberto{ 195258945Sroberto char *p = buf + strlen (buf); 196258945Sroberto 197258945Sroberto sprintf (p, "%s ", name); 198258945Sroberto p += strlen (p); 199258945Sroberto 200258945Sroberto sprintf (p, "%16.16llx\n", x.t); 201258945Sroberto} 202258945Sroberto 203258945Srobertoint 204258945Srobertocheck (const char *input, const char *reference[]) 205258945Sroberto{ 206258945Sroberto int broken, i, j, len; 207258945Sroberto const char *p_input; 208258945Sroberto char *p_comparison; 209258945Sroberto int new_errors = 0; 210258945Sroberto 211258945Sroberto p_comparison = &comparison[0]; 212258945Sroberto p_input = input; 213258945Sroberto 214258945Sroberto for (i = 0; *reference[i] != '\0'; i++) 215258945Sroberto { 216258945Sroberto broken = 0; 217258945Sroberto len = strlen (reference[i]); 218258945Sroberto for (j = 0; j < len; j++) 219258945Sroberto { 220258945Sroberto /* Ignore the terminating NUL characters at the end of every string in 'reference[]'. */ 221258945Sroberto if (!broken && *p_input != reference[i][j]) 222258945Sroberto { 223258945Sroberto *p_comparison = '\0'; 224258945Sroberto strcat (p_comparison, " >>> "); 225258945Sroberto p_comparison += strlen (p_comparison); 226258945Sroberto new_errors++; 227258945Sroberto broken = 1; 228258945Sroberto } 229258945Sroberto *p_comparison = *p_input; 230258945Sroberto p_comparison++; 231258945Sroberto p_input++; 232258945Sroberto } 233258945Sroberto if (broken) 234258945Sroberto { 235258945Sroberto *p_comparison = '\0'; 236258945Sroberto strcat (p_comparison, "expected:\n"); 237258945Sroberto strcat (p_comparison, reference[i]); 238258945Sroberto p_comparison += strlen (p_comparison); 239258945Sroberto } 240258945Sroberto } 241258945Sroberto *p_comparison = '\0'; 242258945Sroberto strcat (p_comparison, new_errors ? "failure\n\n" : "O.K.\n\n") ; 243258945Sroberto errors += new_errors; 244258945Sroberto return 0; 245258945Sroberto} 246258945Sroberto