1  /* { dg-do run } */
       2  /* { dg-require-effective-target xop } */
       3  /* { dg-options "-O2 -mxop" } */
       4  
       5  #include "xop-check.h"
       6  
       7  #include <x86intrin.h>
       8  #include <string.h>
       9  
      10  #define NUM 10
      11  
      12  union
      13  {
      14    __m128i x[NUM];
      15    signed char ssi[NUM * 16];
      16    short si[NUM * 8];
      17    int li[NUM * 4];
      18    long long lli[NUM * 2];
      19  } dst, res, src1;
      20  
      21  static void
      22  init_sbyte ()
      23  {
      24    int i;
      25    for (i=0; i < NUM * 16; i++)
      26      src1.ssi[i] = i;
      27  }
      28  
      29  static void
      30  init_sword ()
      31  {
      32    int i;
      33    for (i=0; i < NUM * 8; i++)
      34      src1.si[i] = i;
      35  }
      36  
      37  static void
      38  init_sdword ()
      39  {
      40    int i;
      41    for (i=0; i < NUM * 4; i++)
      42      src1.li[i] = i;
      43  }
      44  
      45  static int 
      46  check_sbyte2word ()
      47  {
      48    int i, j, s, t, check_fails = 0;
      49    for (i = 0; i < NUM * 16; i = i + 16)
      50      {
      51        for (j = 0; j < 8; j++)
      52  	{
      53  	  t = i + (2 * j);
      54  	  s = (i / 2) + j;
      55  	  res.si[s] = src1.ssi[t] - src1.ssi[t + 1] ;
      56  	  if (res.si[s] != dst.si[s]) 
      57  	    check_fails++;	
      58  	}
      59      }
      60    return check_fails;
      61  }
      62  
      63  static int
      64  check_sword2dword ()
      65  {
      66    int i, j, s, t, check_fails = 0;
      67    for (i = 0; i < NUM * 8; i = i + 8)
      68      {
      69        for (j = 0; j < 4; j++)
      70  	{
      71  	  t = i + (2 * j);
      72  	  s = (i / 2) + j;
      73  	  res.li[s] = src1.si[t] - src1.si[t + 1] ;
      74  	  if (res.li[s] != dst.li[s]) 
      75  	    check_fails++;	
      76  	}
      77      }
      78    return check_fails;
      79  }
      80  
      81  static int
      82  check_dword2qword ()
      83  {
      84    int i, j, s, t, check_fails = 0;
      85    for (i = 0; i < NUM * 4; i = i + 4)
      86      {
      87        for (j = 0; j < 2; j++)
      88  	{
      89  	  t = i + (2 * j);
      90  	  s = (i / 2) + j;
      91  	  res.lli[s] = src1.li[t] - src1.li[t + 1] ;
      92  	  if (res.lli[s] != dst.lli[s]) 
      93  	    check_fails++;	
      94  	}
      95      }
      96    return check_fails;
      97  }
      98  
      99  static void
     100  xop_test (void)
     101  {
     102    int i;
     103    
     104    /* Check hsubbw */
     105    init_sbyte ();
     106    
     107    for (i = 0; i < NUM; i++)
     108      dst.x[i] = _mm_hsubw_epi8 (src1.x[i]);
     109    
     110    if (check_sbyte2word())
     111      abort ();
     112  
     113    /* Check hsubwd */
     114    init_sword ();
     115  
     116    for (i = 0; i < NUM; i++)
     117      dst.x[i] = _mm_hsubd_epi16 (src1.x[i]);
     118    
     119    if (check_sword2dword())
     120      abort (); 
     121     
     122     /* Check hsubdq */
     123    init_sdword ();
     124  
     125    for (i = 0; i < NUM; i++)
     126      dst.x[i] = _mm_hsubq_epi32 (src1.x[i]);
     127    
     128    if (check_dword2qword())
     129      abort ();
     130  }