1  /* { dg-do run } */
       2  /* { dg-require-effective-target power10_hw } */
       3  /* { dg-options "-mdejagnu-cpu=power10 -save-temps" } */
       4  
       5  /* Check that the expected 128-bit instructions are generated if the processor
       6     supports the 128-bit integer instructions. */
       7  /* { dg-final { scan-assembler-times {\mxscvsqqp\M} 1 } } */
       8  /* { dg-final { scan-assembler-times {\mxscvuqqp\M} 1 } } */
       9  /* { dg-final { scan-assembler-times {\mxscvqpsqz\M} 1 } } */
      10  /* { dg-final { scan-assembler-times {\mxscvqpuqz\M} 1 } } */
      11  
      12  #include <stdio.h>
      13  #include <math.h>
      14  #include <fenv.h>
      15  #include <stdlib.h>
      16  #include <wchar.h>
      17  
      18  #define DEBUG 0
      19  
      20  void
      21  abort (void);
      22  
      23  float
      24  conv_i_2_fp( long long int a)
      25  {
      26    return (float) a;
      27  }
      28  
      29  double
      30  conv_i_2_fpd( long long int a)
      31  {
      32    return (double) a;
      33  }
      34  
      35  double
      36  conv_ui_2_fpd( unsigned long long int a)
      37  {
      38    return (double) a;
      39  }
      40  
      41  __float128
      42  conv_i128_2_fp128 (__int128_t a)
      43  {
      44    // default, gen inst KF mode
      45    // -mabi=ibmlongdouble, gen inst floattiieee KF mode
      46    // -mabi=ieeelongdouble gen inst floattiieee TF mode
      47    return (__float128) a;
      48  }
      49  
      50  __float128
      51  conv_ui128_2_fp128 (__uint128_t a)
      52  {
      53    // default, gen inst KF mode
      54    // -mabi=ibmlongdouble, gen inst floattiieee KF mode
      55    // -mabi=ieeelongdouble gen inst floattiieee TF mode
      56    return (__float128) a;
      57  }
      58  
      59  __int128_t
      60  conv_fp128_2_i128 (__float128 a)
      61  {
      62    // default, gen inst KF mode
      63    // -mabi=ibmlongdouble, gen inst floattiieee KF mode
      64    // -mabi=ieeelongdouble gen inst floattiieee TF mode
      65    return (__int128_t) a;
      66  }
      67  
      68  __uint128_t
      69  conv_fp128_2_ui128 (__float128 a)
      70  {
      71    // default, gen inst KF mode
      72    // -mabi=ibmlongdouble, gen inst floattiieee KF mode
      73    // -mabi=ieeelongdouble gen inst floattiieee TF mode
      74    return (__uint128_t) a;
      75  }
      76  
      77  long double
      78  conv_i128_2_ld (__int128_t a)
      79  {
      80    // default, gen call __floattitf
      81    // -mabi=ibmlongdouble, gen call __floattitf
      82    // -mabi=ieeelongdouble gen inst floattiieee TF mode
      83    return (long double) a;
      84  }
      85  
      86  __ibm128
      87  conv_i128_2_ibm128 (__int128_t a)
      88  {
      89    // default, gen call __floattitf
      90    // -mabi=ibmlongdouble, gen call __floattitf
      91    // -mabi=ieeelongdouble, message uses IBM long double, no binary output
      92    return (__ibm128) a;
      93  }
      94  
      95  int
      96  main()
      97  {
      98  	float a, expected_result_float;
      99  	double b, expected_result_double;
     100  	long long int c, expected_result_llint;
     101  	unsigned long long int u;
     102  	__int128_t d;
     103  	__uint128_t u128;
     104  	unsigned long long expected_result_uint128[2] ;
     105  	__float128 e;
     106  	long double ld;     // another 128-bit float version
     107  
     108  	union conv_t {
     109  		float a;
     110  		double b;
     111  		long long int c;
     112  		long long int128[2] ;
     113  		unsigned long long uint128[2] ;
     114  		unsigned long long int u;
     115  		__int128_t d;
     116  		__uint128_t u128;
     117  		__float128 e;
     118  		long double ld;     // another 128-bit float version
     119  	} conv, conv_result;
     120  
     121  	c = 20;
     122  	expected_result_llint = 20.00000;
     123  	a = conv_i_2_fp (c);
     124  
     125  	if (a != expected_result_llint) {
     126  #if DEBUG
     127  		printf("ERROR: conv_i_2_fp(%lld) = %10.5f\n", c, a);
     128  		printf("\n does not match expected_result = %10.5f\n\n",
     129  				 expected_result_llint);
     130  #else
     131  		abort();
     132  #endif
     133  	}
     134  
     135  	c = 20;
     136  	expected_result_double = 20.00000;
     137  	b = conv_i_2_fpd (c);
     138  
     139  	if (b != expected_result_double) {
     140  #if DEBUG
     141  		printf("ERROR: conv_i_2_fpd(%lld) = %10.5f\n", d, b);
     142  		printf("\n does not match expected_result = %10.5f\n\n",
     143  				 expected_result_double);
     144   #else
     145  		abort();
     146  #endif
     147  	}
     148  
     149  	u = 20;
     150  	expected_result_double = 20.00000;
     151  	b = conv_ui_2_fpd (u);
     152  
     153  	if (b != expected_result_double) {
     154  #if DEBUG
     155  		printf("ERROR: conv_ui_2_fpd(%llu) = %10.5f\n", u, b);
     156  		printf("\n does not match expected_result = %10.5f\n\n",
     157  				 expected_result_double);
     158   #else
     159  		abort();
     160  #endif
     161  	}
     162  
     163    d = -3210;
     164    d = (d * 10000000000) + 9876543210;
     165    conv_result.e = conv_i128_2_fp128 (d);
     166    expected_result_uint128[1] = 0xc02bd2f9068d1160;
     167    expected_result_uint128[0] = 0x0;
     168    
     169    if ((conv_result.uint128[1] != expected_result_uint128[1])
     170  		&& (conv_result.uint128[0] != expected_result_uint128[0])) {
     171  #if DEBUG
     172  	  printf("ERROR: conv_i128_2_fp128(-32109876543210) = (result in hex) 0x%llx %llx\n",
     173  				conv.uint128[1], conv.uint128[0]);
     174  	  printf("\n does not match expected_result = (result in hex) 0x%llx %llx\n\n",
     175  				expected_result_uint128[1], expected_result_uint128[0]);
     176   #else
     177  	  abort();
     178  #endif
     179  	}
     180  
     181    d = 123;
     182    d = (d * 10000000000) + 1234567890;
     183    conv_result.ld = conv_i128_2_fp128 (d);
     184    expected_result_uint128[1] = 0x0;
     185    expected_result_uint128[0] = 0x4271eab4c8ed2000;
     186  
     187    if ((conv_result.uint128[1] != expected_result_uint128[1])
     188  		&& (conv_result.uint128[0] != expected_result_uint128[0])) {
     189  #if DEBUG
     190  	  printf("ERROR: conv_i128_2_fp128(1231234567890) = (result in hex) 0x%llx %llx\n",
     191  				conv.uint128[1], conv.uint128[0]);
     192  	  printf("\n does not match expected_result = (result in hex) 0x%llx %llx\n\n",
     193  				expected_result_uint128[1], expected_result_uint128[0]);
     194   #else
     195  	  abort();
     196  #endif
     197  	}
     198  
     199    u128 = 8760;
     200    u128 = (u128 * 10000000000) + 1234567890;
     201    conv_result.e = conv_ui128_2_fp128 (u128);
     202    expected_result_uint128[1] = 0x402d3eb101df8b48;
     203    expected_result_uint128[0] = 0x0;
     204  
     205    if ((conv_result.uint128[1] != expected_result_uint128[1])
     206  		&& (conv_result.uint128[0] != expected_result_uint128[0])) {
     207  #if DEBUG
     208  	  printf("ERROR: conv_ui128_2_fp128(87601234567890) = (result in hex) 0x%llx %llx\n",
     209  				conv.uint128[1], conv.uint128[0]);
     210  	  printf("\n does not match expected_result = (result in hex) 0x%llx %llx\n\n",
     211  				expected_result_uint128[1], expected_result_uint128[0]);
     212   #else
     213  	  abort();
     214  #endif
     215  	}
     216  
     217    u128 = 3210;
     218    u128 = (u128 * 10000000000) + 9876543210;
     219    expected_result_uint128[1] = 0x402bd3429c8feea0;
     220    expected_result_uint128[0] = 0x0;
     221    conv_result.e = conv_ui128_2_fp128 (u128);
     222  
     223    if ((conv_result.uint128[1] != expected_result_uint128[1])
     224  		&& (conv_result.uint128[0] != expected_result_uint128[0])) {
     225  #if DEBUG
     226  	  printf("ERROR: conv_ui128_2_fp128(32109876543210) = (result in hex) 0x%llx %llx\n",
     227  				conv.uint128[1], conv.uint128[0]);
     228  	  printf("\n does not match expected_result = (result in hex) 0x%llx %llx\n\n",
     229  				expected_result_uint128[1], expected_result_uint128[0]);
     230   #else
     231  	  abort();
     232  #endif
     233  	}
     234  
     235    conv.e = 12345.6789;
     236    expected_result_uint128[1] = 0x1407374883526960;
     237    expected_result_uint128[0] = 0x3039;
     238  
     239    conv_result.d = conv_fp128_2_i128 (conv.e);
     240  
     241    if ((conv_result.uint128[1] != expected_result_uint128[1])
     242  		&& (conv_result.uint128[0] != expected_result_uint128[0])) {
     243  #if DEBUG
     244  	  printf("ERROR: conv_fp128_2_i128(0x%llx %llx) =  ",
     245  				conv.uint128[1], conv.uint128[0]);
     246  	  printf("0x%llx %llx\n", conv_result.uint128[1], conv_result.uint128[0]);
     247  
     248  	  printf("\n does not match expected_result = (result in hex) 0x%llx %llx\n\n",
     249  				expected_result_uint128[1], expected_result_uint128[0]);
     250   #else
     251  	  abort();
     252  #endif
     253  	}
     254  
     255    conv.e = -6789.12345;
     256    expected_result_uint128[1] = 0x0;
     257    expected_result_uint128[0] = 0xffffffffffffe57b;
     258    conv_result.d = conv_fp128_2_i128 (conv.e);
     259   
     260    if ((conv_result.uint128[1] != expected_result_uint128[1])
     261  		&& (conv_result.uint128[0] != expected_result_uint128[0])) {
     262  #if DEBUG
     263  	  printf("ERROR: conv_fp128_2_i128(0x%llx %llx) = ",
     264  				conv.uint128[1], conv.uint128[0]);
     265  	  printf("0x%llx %llx\n", conv_result.uint128[1], conv_result.uint128[0]);
     266  
     267  	  printf("\n does not match expected_result = (result in hex) 0x%llx %llx\n\n",
     268  				expected_result_uint128[1], expected_result_uint128[0]);
     269   #else
     270  	  abort();
     271  #endif
     272  	}
     273  
     274    conv.e = 6789.12345;
     275    expected_result_uint128[1] = 0x0;
     276    expected_result_uint128[0] = 0x1a85;
     277    conv_result.d = conv_fp128_2_ui128 (conv.e);
     278   
     279    if ((conv_result.uint128[1] != expected_result_uint128[1])
     280  		&& (conv_result.uint128[0] != expected_result_uint128[0])) {
     281  #if DEBUG
     282  	  printf("ERROR: conv_fp128_2_ui128(0x%llx %llx) = ",
     283  				conv.uint128[1], conv.uint128[0]);
     284  	  printf("0x%llx %llx\n", conv_result.uint128[1], conv_result.uint128[0]);
     285  	  
     286  	  printf("\n does not match expected_result = (result in hex) 0x%llx %llx\n\n",
     287  				expected_result_uint128[1], expected_result_uint128[0]);
     288   #else
     289  	  abort();
     290  #endif
     291  	}
     292  
     293    return 0;
     294  }