mmx-4.c

来自「linux下编程用 编译软件」· C语言 代码 · 共 246 行

C
246
字号
/* { 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 "../../gcc.dg/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 NOINLINEmmx_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);}voiddump64_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");}voiddump64_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");}voiddump64_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);}intcheck (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;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?