1  /*
       2     Test of vec_xl_sext and vec_xl_zext (load into rightmost
       3     vector element and zero/sign extend). */
       4  
       5  /* { dg-do run { target power10_hw } } */
       6  /* { dg-do compile { target { ! power10_hw } } } */
       7  /* { dg-require-effective-target power10_ok } */
       8  /* { dg-require-effective-target int128 } */
       9  /* { dg-options "-mdejagnu-cpu=power10 -O3 -save-temps" } */
      10  
      11  /* At the time of writing, the number of lxvrbx instructions is
      12     double what we expect because we are generating a 
      13     .constprop copy of the function.  */
      14  /* { dg-final { scan-assembler-times {\mlxvrbx\M} 4 } } */
      15  /* { dg-final { scan-assembler-times {\mlbx\M} 0 } } */
      16  
      17  #define NUM_VEC_ELEMS 16
      18  #define ITERS 16
      19  
      20  /*
      21  Codegen at time of writing is a lxvrbx for both the
      22  zero and sign extended tests.  The sign extension test
      23  also uses mfvsr*d, extsb, mtvsrdd, vextsd2q.
      24  
      25  0000000010000c90 <test_sign_extended_load>:
      26      10000c90:	1a 18 04 7c 	lxvrbx  vs0,r4,r3
      27      10000c94:	66 00 0b 7c 	mfvsrd  r11,vs0
      28      10000c98:	66 02 0a 7c 	mfvsrld r10,vs0
      29      10000c9c:	74 07 4a 7d 	extsb   r10,r10
      30      10000ca0:	67 53 40 7c 	mtvsrdd vs34,0,r10
      31      10000ca4:	02 16 5b 10 	vextsd2q v2,v2
      32      10000ca8:	20 00 80 4e 	blr
      33  
      34  0000000010000cc0 <test_zero_extended_unsigned_load>:
      35      10000cc0:	1b 18 44 7c 	lxvrbx  vs34,r4,r3
      36      10000cc4:	20 00 80 4e 	blr
      37  */
      38  
      39  #include <altivec.h>
      40  #include <stdio.h>
      41  #include <inttypes.h>
      42  #include <string.h>
      43  #include <stdlib.h>
      44  
      45  long long buffer[8];
      46  unsigned long verbose=0;
      47  
      48  char initbuffer[64] = {
      49  	0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
      50  			0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x80,
      51  	0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
      52  			0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0x90,
      53  	0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
      54  			0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xa0,
      55  	0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
      56  			0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xb0
      57  };
      58  
      59  vector signed __int128 signed_expected[16] = {
      60  	{ (__int128) 0x0000000000000000 << 64 | (__int128) 0x0000000000000011},
      61  	{ (__int128) 0x0000000000000000 << 64 | (__int128) 0x0000000000000012},
      62  	{ (__int128) 0x0000000000000000 << 64 | (__int128) 0x0000000000000013},
      63  	{ (__int128) 0x0000000000000000 << 64 | (__int128) 0x0000000000000014},
      64  	{ (__int128) 0x0000000000000000 << 64 | (__int128) 0x0000000000000015},
      65  	{ (__int128) 0x0000000000000000 << 64 | (__int128) 0x0000000000000016},
      66  	{ (__int128) 0x0000000000000000 << 64 | (__int128) 0x0000000000000017},
      67  	{ (__int128) 0x0000000000000000 << 64 | (__int128) 0x0000000000000018},
      68  	{ (__int128) 0xffffffffffffffff << 64 | (__int128) 0xffffffffffffff89},
      69  	{ (__int128) 0xffffffffffffffff << 64 | (__int128) 0xffffffffffffff8a},
      70  	{ (__int128) 0xffffffffffffffff << 64 | (__int128) 0xffffffffffffff8b},
      71  	{ (__int128) 0xffffffffffffffff << 64 | (__int128) 0xffffffffffffff8c},
      72  	{ (__int128) 0xffffffffffffffff << 64 | (__int128) 0xffffffffffffff8d},
      73  	{ (__int128) 0xffffffffffffffff << 64 | (__int128) 0xffffffffffffff8e},
      74  	{ (__int128) 0xffffffffffffffff << 64 | (__int128) 0xffffffffffffff8f},
      75  	{ (__int128) 0xffffffffffffffff << 64 | (__int128) 0xffffffffffffff80}
      76  };
      77  
      78  vector unsigned __int128 unsigned_expected[16] = {
      79  	{ (unsigned __int128) 0x0000000000000000 << 64 | (unsigned __int128) 0x0000000000000011},
      80  	{ (unsigned __int128) 0x0000000000000000 << 64 | (unsigned __int128) 0x0000000000000012},
      81  	{ (unsigned __int128) 0x0000000000000000 << 64 | (unsigned __int128) 0x0000000000000013},
      82  	{ (unsigned __int128) 0x0000000000000000 << 64 | (unsigned __int128) 0x0000000000000014},
      83  	{ (unsigned __int128) 0x0000000000000000 << 64 | (unsigned __int128) 0x0000000000000015},
      84  	{ (unsigned __int128) 0x0000000000000000 << 64 | (unsigned __int128) 0x0000000000000016},
      85  	{ (unsigned __int128) 0x0000000000000000 << 64 | (unsigned __int128) 0x0000000000000017},
      86  	{ (unsigned __int128) 0x0000000000000000 << 64 | (unsigned __int128) 0x0000000000000018},
      87  	{ (unsigned __int128) 0x0000000000000000 << 64 | (unsigned __int128) 0x0000000000000089},
      88  	{ (unsigned __int128) 0x0000000000000000 << 64 | (unsigned __int128) 0x000000000000008a},
      89  	{ (unsigned __int128) 0x0000000000000000 << 64 | (unsigned __int128) 0x000000000000008b},
      90  	{ (unsigned __int128) 0x0000000000000000 << 64 | (unsigned __int128) 0x000000000000008c},
      91  	{ (unsigned __int128) 0x0000000000000000 << 64 | (unsigned __int128) 0x000000000000008d},
      92  	{ (unsigned __int128) 0x0000000000000000 << 64 | (unsigned __int128) 0x000000000000008e},
      93  	{ (unsigned __int128) 0x0000000000000000 << 64 | (unsigned __int128) 0x000000000000008f},
      94  	{ (unsigned __int128) 0x0000000000000000 << 64 | (unsigned __int128) 0x0000000000000080}
      95  };
      96  
      97  __attribute__ ((noinline))
      98  vector signed __int128 test_sign_extended_load(int RA, signed char * RB) {
      99  	return vec_xl_sext (RA, RB);
     100  }
     101  
     102  __attribute__ ((noinline))
     103  vector unsigned __int128 test_zero_extended_unsigned_load(int RA, unsigned char * RB) {
     104  	return vec_xl_zext (RA, RB);
     105  }
     106  
     107  int main (int argc, char *argv [])
     108  {
     109     int iteration=0;
     110     int mismatch=0;
     111     vector signed __int128 signed_result_v;
     112     vector unsigned __int128 unsigned_result_v;
     113  #if VERBOSE
     114     verbose=1;
     115     printf("%s %s\n", __DATE__, __TIME__);
     116  #endif
     117  
     118    memcpy(&buffer, &initbuffer, sizeof(buffer));
     119  
     120     if (verbose) {
     121  	   printf("input buffer:\n");
     122  	   for (int k=0;k<64;k++) {
     123  		   printf("%x ",initbuffer[k]);
     124  		   if (k && (k+1)%16==0) printf("\n");
     125  	   }
     126  	   printf("signed_expected:\n");
     127  	   for (int k=0;k<ITERS;k++) {
     128  		printf("%llx ",signed_expected[iteration][0]>>64);
     129  		printf(" %llx \n",signed_expected[iteration][0]&0xffffffffffffffff);
     130  		   printf("\n");
     131  	   }
     132  	   printf("unsigned_expected:\n");
     133  	   for (int k=0;k<ITERS;k++) {
     134  		printf("%llx ",signed_expected[iteration][0]>>64);
     135  		printf(" %llx \n",signed_expected[iteration][0]&0xffffffffffffffff);
     136  		   printf("\n");
     137  	   }
     138     }
     139  
     140     for (iteration = 0; iteration < ITERS ; iteration++ ) {
     141        signed_result_v = test_sign_extended_load (iteration, (signed char*)buffer);
     142        if (signed_result_v[0] != signed_expected[iteration][0] ) {
     143  		mismatch++;
     144  		printf("Unexpected results from signed load. i=%d \n", iteration);
     145  		printf("got:      %llx ",signed_result_v[0]>>64);
     146  		printf(" %llx \n",signed_result_v[0]&0xffffffffffffffff);
     147  		printf("expected: %llx ",signed_expected[iteration][0]>>64);
     148  		printf(" %llx \n",signed_expected[iteration][0]&0xffffffffffffffff);
     149  		fflush(stdout);
     150        }
     151     }
     152  
     153     for (iteration = 0; iteration < ITERS ; iteration++ ) {
     154        unsigned_result_v = test_zero_extended_unsigned_load (iteration, (unsigned char*)buffer);
     155        if (unsigned_result_v[0] != unsigned_expected[iteration][0]) {
     156  		mismatch++;
     157  		printf("Unexpected results from unsigned load. i=%d \n", iteration);
     158  		printf("got:      %llx ",unsigned_result_v[0]>>64);
     159  		printf(" %llx \n",unsigned_result_v[0]&0xffffffffffffffff);
     160  		printf("expected: %llx ",unsigned_expected[iteration][0]>>64);
     161  		printf(" %llx \n",unsigned_expected[iteration][0]&0xffffffffffffffff);
     162  		fflush(stdout);
     163        }
     164     }
     165  
     166     if (mismatch) {
     167        printf("%d mismatches. \n",mismatch);
     168        abort();
     169     }
     170     return 0;
     171  }
     172