(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.target/
powerpc/
signbit-3.c
       1  /* { dg-do run } */
       2  /* { dg-require-effective-target ppc_float128_sw } */
       3  /* { dg-options "-mdejagnu-cpu=power7 -O2 -mfloat128 -lm" } */
       4  
       5  #ifdef DEBUG
       6  #include <stdio.h>
       7  #endif
       8  
       9  #include <stddef.h>
      10  #include <stdint.h>
      11  #include <inttypes.h>
      12  #include <stdlib.h>
      13  #include <math.h>
      14  
      15  #if defined(__BIG_ENDIAN__)
      16  struct ieee128 {
      17    uint64_t upper;
      18    uint64_t lower;
      19  };
      20  
      21  #elif defined(__LITTLE_ENDIAN__)
      22  struct ieee128 {
      23    uint64_t lower;
      24    uint64_t upper;
      25  };
      26  
      27  #else
      28  #error "Unknown system"
      29  #endif
      30  
      31  union ieee_union {
      32    __float128 f128;
      33    struct ieee128 st128;
      34  };
      35  
      36  #ifdef DEBUG
      37  static int num_errors = 0;
      38  
      39  __attribute__((__noinline__))
      40  static void
      41  failure (int expected, int got, __float128 x)
      42  {
      43    unsigned sign;
      44    unsigned exponent;
      45    uint64_t mantissa1;
      46    uint64_t mantissa2;
      47    uint64_t upper;
      48    uint64_t lower;
      49  
      50    union ieee_union u;
      51  
      52    u.f128 = x;
      53    upper  = u.st128.upper;
      54    lower  = u.st128.lower;
      55  
      56    sign      = (unsigned)((upper >> 63) & 1);
      57    exponent  = (unsigned)((upper >> 48) & ((((uint64_t)1) << 16) - 1));
      58    mantissa1 = (upper & ((((uint64_t)1) << 48) - 1));
      59    mantissa2 = lower;
      60  
      61    printf ("Expected %d, got %d, %c 0x%.4x 0x%.12" PRIx64 " 0x%.16" PRIx64,
      62  	  expected, got,
      63  	  sign ? '-' : '+',
      64  	  exponent,
      65  	  mantissa1,
      66  	  mantissa2);
      67  
      68    num_errors++;
      69  }
      70  
      71  #else
      72  
      73  #define failure(E, G, F) abort ()
      74  #endif
      75  
      76  __attribute__((__noinline__))
      77  static void
      78  test_signbit_arg (__float128 f128, int expected)
      79  {
      80    int sign = __builtin_signbit (f128);
      81  
      82    if ((expected != 0 && sign == 0)
      83        || (expected == 0 && sign != 0))
      84      failure (f128, expected, sign);
      85  }
      86  
      87  __attribute__((__noinline__))
      88  static void
      89  test_signbit_mem (__float128 *ptr, int expected)
      90  {
      91    int sign = __builtin_signbit (*ptr);
      92  
      93    if ((expected != 0 && sign == 0)
      94        || (expected == 0 && sign != 0))
      95      failure (*ptr, expected, sign);
      96  }
      97  
      98  __attribute__((__noinline__))
      99  static void
     100  test_signbit_gpr (__float128 *ptr, int expected)
     101  {
     102    __float128 f128 = *ptr;
     103    int sign;
     104  
     105    __asm__ (" # %0" : "+r" (f128));
     106  
     107    sign = __builtin_signbit (f128);
     108    if ((expected != 0 && sign == 0)
     109        || (expected == 0 && sign != 0))
     110      failure (f128, expected, sign);
     111  }
     112  
     113  __attribute__((__noinline__))
     114  static void
     115  test_signbit (__float128 f128, int expected)
     116  {
     117  #ifdef DEBUG
     118    union ieee_union u;
     119    u.f128 = f128;
     120    printf ("Expecting %d, trying %-5g "
     121  	  "(0x%.16" PRIx64 " 0x%.16" PRIx64 ")\n",
     122  	  expected, (double)f128,
     123  	  u.st128.upper, u.st128.lower);
     124  #endif
     125  
     126    test_signbit_arg (f128,  expected);
     127    test_signbit_mem (&f128, expected);
     128    test_signbit_gpr (&f128, expected);
     129  }
     130  
     131  int
     132  main (void)
     133  {
     134    union ieee_union u;
     135  
     136    test_signbit (+0.0q, 0);
     137    test_signbit (+1.0q, 0);
     138  
     139    test_signbit (-0.0q, 1);
     140    test_signbit (-1.0q, 1);
     141  
     142    test_signbit (__builtin_copysign (__builtin_infq (), +1.0q), 0);
     143    test_signbit (__builtin_copysign (__builtin_infq (), -1.0q), 1);
     144  
     145    test_signbit (__builtin_copysign (__builtin_nanq (""), +1.0q), 0);
     146    test_signbit (__builtin_copysign (__builtin_nanq (""), -1.0q), 1);
     147  
     148    /* force the bottom double word to have specific bits in the 'sign' bit to
     149       make sure we are picking the right word.  */
     150    u.f128 = 1.0q;
     151    u.st128.lower = 0ULL;
     152    test_signbit (u.f128, 0);
     153  
     154    u.st128.lower = ~0ULL;
     155    test_signbit (u.f128, 0);
     156  
     157    u.f128 = -1.0q;
     158    u.st128.lower = 0ULL;
     159    test_signbit (u.f128, 1);
     160  
     161    u.st128.lower = ~0ULL;
     162    test_signbit (u.f128, 1);
     163  
     164  #ifdef DEBUG
     165    printf ("%d error(s) were found\n", num_errors);
     166    if (num_errors)
     167      return num_errors;
     168  #endif
     169  
     170    return 0;
     171  }
     172