(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.target/
powerpc/
check-builtin-vec_rlnm-runnable.c
       1  /* { dg-do run } */
       2  /* { dg-require-effective-target p9vector_hw } */
       3  /* { dg-options "-O2 -mdejagnu-cpu=power9 -save-temps" } */
       4  
       5  /* Verify the vec_rlm and vec_rlmi builtins works correctly.  */
       6  /* { dg-final { scan-assembler-times {\mvrldmi\M} 1 } } */
       7  
       8  #include <altivec.h>
       9  
      10  #ifdef DEBUG
      11  #include <stdio.h>
      12  #include <stdlib.h>
      13  #endif
      14  
      15  void abort (void);
      16  
      17  int main ()
      18  {
      19    int i;
      20  
      21    vector unsigned int vec_arg1_int, vec_arg2_int, vec_arg3_int;
      22    vector unsigned int vec_result_int, vec_expected_result_int;
      23    
      24    vector unsigned long long int vec_arg1_di, vec_arg2_di, vec_arg3_di;
      25    vector unsigned long long int vec_result_di, vec_expected_result_di;
      26  
      27    unsigned int mask_begin, mask_end, shift;
      28    unsigned long long int mask;
      29  
      30  /* Check vec int version of vec_rlmi builtin */
      31    mask = 0;
      32    mask_begin = 0;
      33    mask_end   = 4;
      34    shift = 16;
      35  
      36    for (i = 0; i < 31; i++)
      37      if ((i >= mask_begin) && (i <= mask_end))
      38        mask |= 0x80000000ULL >> i;
      39  
      40    for (i = 0; i < 4; i++) {
      41      vec_arg1_int[i] = 0x12345678 + i*0x11111111;
      42      vec_arg2_int[i] = 0xA1B1CDEF;
      43      vec_arg3_int[i] = mask_begin << 16 | mask_end << 8 | shift;
      44  
      45      /* do rotate */
      46      vec_expected_result_int[i] =  ( vec_arg2_int[i] & ~mask) 
      47        | ((vec_arg1_int[i] << shift) | (vec_arg1_int[i] >> (32-shift))) & mask;
      48        
      49    }
      50  
      51    /* vec_rlmi(arg1, arg2, arg3)
      52       result - rotate each element of arg2 left and inserts it into arg1 
      53       element based on the mask specified in arg3.  The shift, mask
      54       start and end is specified in arg3.  */
      55    vec_result_int = vec_rlmi (vec_arg1_int, vec_arg2_int, vec_arg3_int);
      56  
      57    for (i = 0; i < 4; i++) {
      58      if (vec_result_int[i] != vec_expected_result_int[i])
      59  #ifdef DEBUG
      60        printf("ERROR: i = %d, vec_rlmi int result 0x%x, does not match "
      61  	     "expected result 0x%x\n", i, vec_result_int[i],
      62  	     vec_expected_result_int[i]);
      63  #else
      64        abort();
      65  #endif
      66      }
      67  
      68  /* Check vec long long int version of vec_rlmi builtin */
      69    mask = 0;
      70    mask_begin = 0;
      71    mask_end   = 4;
      72    shift = 16;
      73  
      74    for (i = 0; i < 31; i++)
      75      if ((i >= mask_begin) && (i <= mask_end))
      76        mask |= 0x8000000000000000ULL >> i;
      77  
      78    for (i = 0; i < 2; i++) {
      79      vec_arg1_di[i] = 0x1234567800000000 + i*0x11111111;
      80      vec_arg2_di[i] = 0xA1B1C1D1E1F12345;
      81      vec_arg3_di[i] = mask_begin << 16 | mask_end << 8 | shift;
      82  
      83      /* do rotate */
      84      vec_expected_result_di[i] =  ( vec_arg2_di[i] & ~mask) 
      85        | ((vec_arg1_di[i] << shift) | (vec_arg1_di[i] >> (64-shift))) & mask;
      86    }
      87  
      88    /* vec_rlmi(arg1, arg2, arg3)
      89       result - rotate each element of arg1 left and inserts it into arg2 
      90       element based on the mask specified in arg3.  The shift, mask, start
      91       and end is specified in arg3.  */
      92    vec_result_di = vec_rlmi (vec_arg1_di, vec_arg2_di, vec_arg3_di);
      93  
      94    for (i = 0; i < 2; i++) {
      95      if (vec_result_di[i] != vec_expected_result_di[i])
      96  #ifdef DEBUG
      97        printf("ERROR: i = %d, vec_rlmi int long long result 0x%llx, does not match "
      98  	     "expected result 0x%llx\n", i, vec_result_di[i],
      99  	     vec_expected_result_di[i]);
     100  #else
     101        abort();
     102  #endif
     103      }
     104  
     105    /* Check vec int version of vec_rlnm builtin */
     106    mask = 0;
     107    mask_begin = 0;
     108    mask_end   = 4;
     109    shift = 16;
     110  
     111    for (i = 0; i < 31; i++)
     112      if ((i >= mask_begin) && (i <= mask_end))
     113        mask |= 0x80000000ULL >> i;
     114  
     115    for (i = 0; i < 4; i++) {
     116      vec_arg1_int[i] = 0x12345678 + i*0x11111111;
     117      vec_arg2_int[i] = shift;
     118      vec_arg3_int[i] = mask_begin << 8 | mask_end;
     119      vec_expected_result_int[i] = (vec_arg1_int[i] << shift) & mask;
     120    }
     121  
     122    /* vec_rlnm(arg1, arg2, arg3)
     123       result - rotate each element of arg1 left by shift in element of arg2.
     124         Then AND with mask whose  start/stop bits are specified in element of
     125         arg3.  */
     126    vec_result_int = vec_rlnm (vec_arg1_int, vec_arg2_int, vec_arg3_int);
     127    for (i = 0; i < 4; i++) {
     128      if (vec_result_int[i] != vec_expected_result_int[i])
     129  #ifdef DEBUG
     130        printf("ERROR: vec_rlnm, i = %d, int result 0x%x does not match "
     131  	     "expected result 0x%x\n", i, vec_result_int[i],
     132  	     vec_expected_result_int[i]);
     133  #else
     134        abort();
     135  #endif
     136      }
     137  
     138  /* Check vec long int version of builtin */
     139    mask = 0;
     140    mask_begin = 0;
     141    mask_end   = 4;
     142    shift = 20;
     143  
     144    for (i = 0; i < 63; i++)
     145      if ((i >= mask_begin) && (i <= mask_end))
     146        mask |= 0x8000000000000000ULL >> i;
     147    
     148    for (i = 0; i < 2; i++) {
     149      vec_arg1_di[i] = 0x123456789ABCDE00ULL + i*0x1111111111111111ULL;
     150      vec_arg2_di[i] = shift;
     151      vec_arg3_di[i] = mask_begin << 8 | mask_end;
     152      vec_expected_result_di[i] = (vec_arg1_di[i] << shift) & mask;
     153    }
     154  
     155    vec_result_di = vec_rlnm (vec_arg1_di, vec_arg2_di, vec_arg3_di);
     156  
     157    for (i = 0; i < 2; i++) {
     158      if (vec_result_di[i] != vec_expected_result_di[i])
     159  #ifdef DEBUG
     160        printf("ERROR: vec_rlnm, i = %d, long long int result 0x%llx does not "
     161  	     "match expected result 0x%llx\n", i, vec_result_di[i],
     162  	     vec_expected_result_di[i]);
     163  #else
     164        abort();
     165  #endif
     166      }
     167  
     168      /* Check vec int version of vec_vrlnm builtin */
     169    mask = 0;
     170    mask_begin = 0;
     171    mask_end   = 4;
     172    shift = 16;
     173  
     174    for (i = 0; i < 31; i++)
     175      if ((i >= mask_begin) && (i <= mask_end))
     176        mask |= 0x80000000ULL >> i;
     177  
     178    for (i = 0; i < 4; i++) {
     179      vec_arg1_int[i] = 0x12345678 + i*0x11111111;
     180      vec_arg2_int[i] = mask_begin << 16 | mask_end << 8 | shift;
     181      vec_expected_result_int[i] = (vec_arg1_int[i] << shift) & mask;
     182    }
     183  
     184    /* vec_vrlnm(arg1, arg2, arg3)
     185       result - rotate each element of arg1 left then AND with mask.  The mask
     186         start, stop bits is specified in the second argument.  The shift amount
     187         is also specified in the second argument.  */
     188    vec_result_int = vec_vrlnm (vec_arg1_int, vec_arg2_int);
     189  
     190    for (i = 0; i < 4; i++) {
     191      if (vec_result_int[i] != vec_expected_result_int[i])
     192  #ifdef DEBUG
     193        printf("ERROR: vec_vrlnm, i = %d, int result 0x%x does not match "
     194  	     "expected result 0x%x\n", i, vec_result_int[i],
     195  	     vec_expected_result_int[i]);
     196  #else
     197        abort();
     198  #endif
     199      }
     200  
     201  /* Check vec long int version of vec_vrlnm builtin */
     202    mask = 0;
     203    mask_begin = 0;
     204    mask_end   = 4;
     205    shift = 20;
     206  
     207    for (i = 0; i < 63; i++)
     208      if ((i >= mask_begin) && (i <= mask_end))
     209        mask |= 0x8000000000000000ULL >> i;
     210    
     211    for (i = 0; i < 2; i++) {
     212      vec_arg1_di[i] = 0x123456789ABCDE00ULL + i*0x1111111111111111ULL;
     213      vec_arg2_di[i] = mask_begin << 16 | mask_end << 8 | shift;
     214      vec_expected_result_di[i] = (vec_arg1_di[i] << shift) & mask;
     215    }
     216  
     217    vec_result_di = vec_vrlnm (vec_arg1_di, vec_arg2_di);
     218  
     219    for (i = 0; i < 2; i++) {
     220      if (vec_result_di[i] != vec_expected_result_di[i])
     221  #ifdef DEBUG
     222        printf("ERROR: vec_vrlnm, i = %d, long long int result 0x%llx does not "
     223  	     "match expected result 0x%llx\n", i, vec_result_di[i],
     224  	     vec_expected_result_di[i]);
     225  #else
     226        abort();
     227  #endif
     228      }
     229  
     230    return 0;
     231  }