(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.target/
powerpc/
p8vector-int128-2.c
       1  /* { dg-do run } */
       2  /* { dg-skip-if "" { powerpc*-*-darwin* } } */
       3  /* { dg-require-effective-target p8vector_hw } */
       4  /* { dg-require-effective-target int128 } */
       5  /* { dg-options "-mdejagnu-cpu=power8 -O2" } */
       6  
       7  #include <stddef.h>
       8  #include <stdlib.h>
       9  #include <altivec.h>
      10  
      11  #ifdef DEBUG
      12  #include <stdio.h>
      13  #define UNUSED
      14  
      15  #ifdef __LITTLE_ENDIAN__
      16  #define HI_WORD 1
      17  #define LO_WORD 0
      18  #else
      19  #define HI_WORD 0
      20  #define LO_WORD 1
      21  #endif
      22  
      23  #else
      24  #define UNUSED __attribute__((__unused__))
      25  #endif
      26  
      27  #ifndef S_TYPE
      28  #define S_TYPE __uint128_t
      29  #endif
      30  
      31  #ifndef V_TYPE
      32  #define V_TYPE vector S_TYPE
      33  #endif
      34  
      35  static int compare (S_TYPE, V_TYPE, const char *, const char *)
      36    __attribute__((__noinline__));
      37  
      38  static int
      39  compare (S_TYPE scalar,
      40  	 V_TYPE vect,
      41  	 const char *nl    UNUSED,
      42  	 const char *which UNUSED)
      43  {
      44    unsigned long scalar_lo = (unsigned long) scalar;
      45    unsigned long scalar_hi = (unsigned long) (scalar >> 64);
      46    unsigned long vect_lo;
      47    unsigned long vect_hi;
      48    vector long long tmp;
      49    int ret;
      50  
      51    __asm__ ("mfvsrd %0,%x3\n\t"
      52  	   "xxpermdi %x2,%x3,%x3,3\n\t"
      53  	   "mfvsrd %1,%x2"
      54  	   : "=r" (vect_hi),
      55  	     "=r" (vect_lo),
      56  	     "=wa" (tmp)
      57  	   : "wa" (vect));
      58  
      59    ret = (scalar_lo != vect_lo) || (scalar_hi != vect_hi);
      60  
      61  #ifdef DEBUG
      62    printf ("%s%s: 0x%.16lx %.16lx %s 0x%.16lx %.16lx\n",
      63  	  nl, which,
      64  	  scalar_hi, scalar_lo,
      65  	  (ret) ? "!=" : "==",
      66  	  vect_hi, vect_lo);
      67  
      68    fflush (stdout);
      69  #endif
      70  
      71    return ret;
      72  }
      73  
      74  static void convert_via_mem (V_TYPE *, S_TYPE *)
      75    __attribute__((__noinline__));
      76  
      77  static void
      78  convert_via_mem (V_TYPE *v, S_TYPE *s)
      79  {
      80    *v = (V_TYPE) { *s };
      81    __asm__ volatile ("nop"
      82  		    : "+m" (*s), "+m" (*v)
      83  		    :
      84  		    : "memory");
      85  
      86  }
      87  
      88  
      89  /* Check if vadduqm returns the same values as normal 128-bit add.  */
      90  
      91  /* Values to add together.  */
      92  const static struct {
      93    unsigned long hi_1;
      94    unsigned long lo_1;
      95    unsigned long hi_2;
      96    unsigned long lo_2;
      97  } values[] = {
      98    { 0x0000000000000000UL, 0xfffffffffffffffeUL,
      99      0x0000000000000000UL, 0x0000000000000002UL },
     100    { 0x0000000000000000UL, 0x0000000000000002UL,
     101      0x0000000000000000UL, 0xfffffffffffffffeUL },
     102    { 0xffffffffffffffffUL, 0xfffffffffffffffeUL,
     103      0x0000000000000000UL, 0x0000000000000002UL },
     104    { 0xfffffffffffffff2UL, 0xffffffffffffffffUL,
     105      0x0000000000000002UL, 0x0000000000000000UL },
     106    { 0x7fffffffffffffffUL, 0xfffffffffffffffeUL,
     107      0x0000000000000000UL, 0x0000000000000002UL },
     108    { 0x7ffffffffffffff2UL, 0xffffffffffffffffUL,
     109      0x0000000000000002UL, 0x0000000000000000UL },
     110  };
     111  
     112  int
     113  main (void)
     114  {
     115    int reg_errors = 0;
     116    int mem_errors = 0;
     117    size_t i;
     118    const char *nl = "";
     119  
     120    for (i = 0; i < sizeof (values) / sizeof (values[0]); i++)
     121      {
     122        S_TYPE s_reg_res, s_reg_in1, s_reg_in2, s_mem_res, s_mem_in1, s_mem_in2;
     123        V_TYPE v_reg_res, v_reg_in1, v_reg_in2, v_mem_res, v_mem_in1, v_mem_in2;
     124  
     125        s_reg_in1 = ((((S_TYPE)values[i].hi_1 << 64)) + ((S_TYPE)values[i].lo_1));
     126        reg_errors += compare (s_reg_in1, (V_TYPE) { s_reg_in1 }, nl, "reg, in1");
     127  
     128        s_reg_in2 = ((((S_TYPE)values[i].hi_2 << 64)) + ((S_TYPE)values[i].lo_2));
     129        reg_errors += compare (s_reg_in2, (V_TYPE) { s_reg_in2 }, "", "reg, in2");
     130  
     131        s_reg_res = s_reg_in1 + s_reg_in2;
     132  
     133        v_reg_in1 = (V_TYPE) { s_reg_in1 };
     134        v_reg_in2 = (V_TYPE) { s_reg_in2 };
     135        v_reg_res = vec_vadduqm (v_reg_in1, v_reg_in2);
     136        reg_errors += compare (s_reg_res, v_reg_res, "", "reg, res");
     137  
     138        s_mem_in1 = s_reg_in1;
     139        convert_via_mem (&v_mem_in1, &s_mem_in1);
     140        mem_errors += compare (s_mem_in1, (V_TYPE) { s_mem_in1 }, "\n", "mem, in1");
     141  
     142        s_mem_in2 = s_reg_in2;
     143        convert_via_mem (&v_mem_in2, &s_mem_in2);
     144        mem_errors += compare (s_mem_in2, (V_TYPE) { s_mem_in2 }, "", "mem, in2");
     145  
     146        s_mem_res = s_mem_in1 + s_mem_in2;
     147        v_mem_res = vec_vadduqm (v_mem_in1, v_mem_in2);
     148        mem_errors += compare (s_mem_res, v_mem_res, "", "mem, res");
     149  
     150        nl = "\n";
     151      }
     152  
     153  #ifdef DEBUG
     154    putchar ('\n');
     155  
     156    if (!reg_errors)
     157      fputs ("no errors found on register operations\n", stdout);
     158    else
     159      printf ("%d error%s found on register operations\n",
     160  	    reg_errors,
     161  	    (reg_errors == 1) ? "s" : "");
     162  
     163    if (!mem_errors)
     164      fputs ("no errors found on memory operations\n", stdout);
     165    else
     166      printf ("%d error%s found on memory operations\n",
     167  	    mem_errors,
     168  	    (mem_errors == 1) ? "s" : "");
     169  
     170    fflush (stdout);
     171  #endif
     172  
     173    if ((reg_errors + mem_errors) != 0)
     174      abort ();
     175  
     176    return 0;
     177  }