1  /* { dg-options "-std=gnu99 -D_GNU_SOURCE -pthread" } */
       2  /* { dg-do run { target i?86-*-linux* i?86-*-gnu* x86_64-*-linux* } } */
       3  /* { dg-require-effective-target error_h } */
       4  
       5  
       6  /* N1150 5.2: Conversions among decimal floating types and between
       7     decimal floating types and generic floating types.
       8     C99 6.3.1.5(3) New.
       9  
      10     Perform conversions between DFP types in which the assigned value
      11     cannot be represented exactly in the result and must be rounded
      12     correctly according to the current rounding mode.
      13  
      14     Normally this would not be part of compiler testing, but conversions
      15     are currently handled in libgcc via decNumber.  */
      16  
      17  #include <pthread.h>
      18  #include <error.h>
      19  #include <stdlib.h>
      20  #include <stdio.h>
      21  #include <stddef.h>
      22  #include "dfp-round.h"
      23  
      24  extern void abort (void);
      25  static __thread int failcnt = 0;
      26  
      27  /* Support compiling the test to report individual failures; default is
      28     to abort as soon as a check fails.  */
      29  #ifdef DBG
      30  #include <stdio.h>
      31  #define FAILURE { printf ("failed at line %d\n", __LINE__); failcnt++; }
      32  #else
      33  #define FAILURE abort ();
      34  #endif
      35  
      36  pthread_mutex_t mut1 = PTHREAD_MUTEX_INITIALIZER;
      37  pthread_mutex_t mut2 = PTHREAD_MUTEX_INITIALIZER;
      38  pthread_mutex_t mut3 = PTHREAD_MUTEX_INITIALIZER;
      39  pthread_mutex_t mut4 = PTHREAD_MUTEX_INITIALIZER;
      40  pthread_mutex_t mut5 = PTHREAD_MUTEX_INITIALIZER;
      41  pthread_cond_t cond1 = PTHREAD_COND_INITIALIZER;
      42  pthread_cond_t cond2 = PTHREAD_COND_INITIALIZER;
      43  pthread_cond_t cond3 = PTHREAD_COND_INITIALIZER;
      44  pthread_cond_t cond4 = PTHREAD_COND_INITIALIZER;
      45  pthread_cond_t cond5 = PTHREAD_COND_INITIALIZER;
      46  pthread_barrier_t bar1;
      47  pthread_barrier_t bar2;
      48  pthread_barrier_t bar3;
      49  pthread_barrier_t bar4;
      50  pthread_barrier_t bar5;
      51  
      52  __thread _Decimal32 d32;
      53  __thread _Decimal64 d64;
      54  __thread _Decimal128 d128;
      55  
      56  _Decimal32 d64_to_d32 (_Decimal64 d) { return d; }
      57  _Decimal64 d128_to_d64 (_Decimal128 d) { return d; }
      58  _Decimal32 d128_to_d32 (_Decimal128 d) { return d; }
      59  
      60  int
      61  do_d64_to_d32 (_Decimal64 orig, _Decimal32 exp)
      62  {
      63    d64 = orig;
      64    d32 = d64_to_d32 (d64);
      65    return (d32 == exp);
      66  }
      67  
      68  int
      69  do_d128_to_d32 (_Decimal128 orig, _Decimal32 exp)
      70  {
      71    d128 = orig;
      72    d32 = d128_to_d32 (d128);
      73    return (d32 == exp);
      74  }
      75  
      76  int
      77  do_d128_to_d64 (_Decimal128 orig, _Decimal64 exp)
      78  {
      79    d128 = orig;
      80    d64 = d128_to_d64 (d128);
      81    return (d64 == exp);
      82  }
      83  
      84  void *
      85  downward (void *arg)
      86  {
      87    int err;
      88  
      89    DFP_SETROUND (FE_DEC_DOWNWARD);
      90  
      91    err = pthread_mutex_lock (&mut1);
      92    if (err != 0)
      93      error (EXIT_FAILURE, err, "downward: failed to lock");
      94  
      95    err = pthread_barrier_wait (&bar1);
      96    if (err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD)
      97      {
      98        puts ("downward: barrier_wait failed");
      99        exit (1);
     100      } 
     101  
     102    err = pthread_cond_wait (&cond1, &mut1);
     103    if (err != 0)
     104      error (EXIT_FAILURE, err, "downward: failed to wait");
     105  
     106    err = pthread_mutex_unlock (&mut1);
     107    if (err != 0)
     108      error (EXIT_FAILURE, err, "downward: failed to unlock");
     109  
     110    if (!do_d64_to_d32 (1.1111125dd, 1.111112df)) FAILURE
     111    if (!do_d64_to_d32 (1.1111135dd, 1.111113df)) FAILURE
     112    if (!do_d64_to_d32 (-1.1111125dd, -1.111113df)) FAILURE
     113    if (!do_d64_to_d32 (-1.1111135dd, -1.111114df)) FAILURE
     114    if (!do_d128_to_d32 (1.1111125dl, 1.111112df)) FAILURE
     115    if (!do_d128_to_d32 (1.1111135dl, 1.111113df)) FAILURE
     116    if (!do_d128_to_d32 (-1.1111125dl, -1.111113df)) FAILURE
     117    if (!do_d128_to_d32 (-1.1111135dl, -1.111114df)) FAILURE
     118    if (!do_d128_to_d64 (1.1111111111111125dl, 1.111111111111112dd)) FAILURE
     119    if (!do_d128_to_d64 (1.1111111111111135dl, 1.111111111111113dd)) FAILURE
     120    if (!do_d128_to_d64 (-1.1111111111111125dl, -1.111111111111113dd)) FAILURE
     121    if (!do_d128_to_d64 (-1.1111111111111135dl, -1.111111111111114dd)) FAILURE
     122    
     123  #ifdef DBG
     124    if (failcnt)
     125      printf ("downward: %d fails\n", failcnt);
     126  #endif
     127    return (void *) (ptrdiff_t) failcnt;
     128  }
     129  
     130  void *
     131  tonearest (void *arg)
     132  {
     133    int err;
     134    DFP_SETROUND (FE_DEC_TONEAREST);
     135  
     136    err = pthread_mutex_lock (&mut2);
     137    if (err != 0)
     138      error (EXIT_FAILURE, err, "tonearest: failed to lock");
     139  
     140    err = pthread_barrier_wait (&bar2);
     141    if (err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD)
     142      {
     143        puts ("tonearest: barrier_wait failed");
     144        exit (1);
     145      } 
     146  
     147    err = pthread_cond_wait (&cond2, &mut2);
     148    if (err != 0)
     149      error (EXIT_FAILURE, err, "tonearest: failed to wait");
     150  
     151    err = pthread_mutex_unlock (&mut2);
     152    if (err != 0)
     153      error (EXIT_FAILURE, err, "tonearest: failed to unlock");
     154  
     155    if (!do_d64_to_d32 (1.1111125dd, 1.111112df)) FAILURE
     156    if (!do_d64_to_d32 (1.1111135dd, 1.111114df)) FAILURE
     157    if (!do_d64_to_d32 (-1.1111125dd, -1.111112df)) FAILURE
     158    if (!do_d64_to_d32 (-1.1111135dd, -1.111114df)) FAILURE
     159    if (!do_d128_to_d32 (1.1111125dl, 1.111112df)) FAILURE
     160    if (!do_d128_to_d32 (1.1111135dl, 1.111114df)) FAILURE
     161    if (!do_d128_to_d32 (-1.1111125dl, -1.111112df)) FAILURE
     162    if (!do_d128_to_d32 (-1.1111135dl, -1.111114df)) FAILURE
     163    if (!do_d128_to_d64 (1.1111111111111125dl, 1.111111111111112dd)) FAILURE
     164    if (!do_d128_to_d64 (1.1111111111111135dl, 1.111111111111114dd)) FAILURE
     165    if (!do_d128_to_d64 (-1.1111111111111125dl, -1.111111111111112dd)) FAILURE
     166    if (!do_d128_to_d64 (-1.1111111111111135dl, -1.111111111111114dd)) FAILURE
     167    
     168  #ifdef DBG
     169    if (failcnt)
     170      printf ("tonearest: %d fails\n", failcnt);
     171  #endif
     172    return (void *) (ptrdiff_t) failcnt;
     173  } 
     174  
     175  void *
     176  toneareastfromzero (void *arg)
     177  {
     178    int err;
     179    DFP_SETROUND (FE_DEC_TONEARESTFROMZERO);
     180  
     181    err = pthread_mutex_lock (&mut3);
     182    if (err != 0)
     183      error (EXIT_FAILURE, err, "toneareastfromzero: failed to lock");
     184  
     185    err = pthread_barrier_wait (&bar3);
     186    if (err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD)
     187      {
     188        puts ("toneareastfromzero: barrier_wait failed");
     189        exit (1);
     190      } 
     191  
     192    err = pthread_cond_wait (&cond3, &mut3);
     193    if (err != 0)
     194      error (EXIT_FAILURE, err, "toneareastfromzero: failed to wait");
     195  
     196    err = pthread_mutex_unlock (&mut3);
     197    if (err != 0)
     198      error (EXIT_FAILURE, err, "toneareastfromzero: failed to unlock");
     199  
     200    if (!do_d64_to_d32 (1.1111125dd, 1.111113df)) FAILURE
     201    if (!do_d64_to_d32 (1.1111135dd, 1.111114df)) FAILURE
     202    if (!do_d64_to_d32 (-1.1111125dd, -1.111113df)) FAILURE
     203    if (!do_d64_to_d32 (-1.1111135dd, -1.111114df)) FAILURE
     204    if (!do_d128_to_d32 (1.1111125dl, 1.111113df)) FAILURE
     205    if (!do_d128_to_d32 (1.1111135dl, 1.111114df)) FAILURE
     206    if (!do_d128_to_d32 (-1.1111125dl, -1.111113df)) FAILURE
     207    if (!do_d128_to_d32 (-1.1111135dl, -1.111114df)) FAILURE
     208    if (!do_d128_to_d64 (1.1111111111111125dl, 1.111111111111113dd)) FAILURE
     209    if (!do_d128_to_d64 (1.1111111111111135dl, 1.111111111111114dd)) FAILURE
     210    if (!do_d128_to_d64 (-1.1111111111111125dl, -1.111111111111113dd)) FAILURE
     211    if (!do_d128_to_d64 (-1.1111111111111135dl, -1.111111111111114dd)) FAILURE
     212    
     213  #ifdef DBG
     214    if (failcnt)
     215      printf ("toneareastfromzero: %d fails\n", failcnt);
     216  #endif
     217    return (void *) (ptrdiff_t) failcnt;
     218  } 
     219    
     220  void *
     221  towardzero (void *arg)
     222  {
     223    int err;
     224    DFP_SETROUND (FE_DEC_TOWARDZERO);
     225  
     226    err = pthread_mutex_lock (&mut4);
     227    if (err != 0)
     228      error (EXIT_FAILURE, err, "towardzero: failed to lock");
     229  
     230    err = pthread_barrier_wait (&bar4);
     231    if (err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD)
     232      {
     233        puts ("towardzero: barrier_wait failed");
     234        exit (1);
     235      } 
     236  
     237    err = pthread_cond_wait (&cond4, &mut4);
     238    if (err != 0)
     239      error (EXIT_FAILURE, err, "towardzero: failed to wait");
     240  
     241    err = pthread_mutex_unlock (&mut4);
     242    if (err != 0)
     243      error (EXIT_FAILURE, err, "towardzero: failed to unlock");
     244  
     245    if (!do_d64_to_d32 (1.1111125dd, 1.111112df)) FAILURE
     246    if (!do_d64_to_d32 (1.1111135dd, 1.111113df)) FAILURE
     247    if (!do_d64_to_d32 (-1.1111125dd, -1.111112df)) FAILURE
     248    if (!do_d64_to_d32 (-1.1111135dd, -1.111113df)) FAILURE
     249    if (!do_d128_to_d32 (1.1111125dl, 1.111112df)) FAILURE
     250    if (!do_d128_to_d32 (1.1111135dl, 1.111113df)) FAILURE
     251    if (!do_d128_to_d32 (-1.1111125dl, -1.111112df)) FAILURE
     252    if (!do_d128_to_d32 (-1.1111135dl, -1.111113df)) FAILURE
     253    if (!do_d128_to_d64 (1.1111111111111125dl, 1.111111111111112dd)) FAILURE
     254    if (!do_d128_to_d64 (1.1111111111111135dl, 1.111111111111113dd)) FAILURE
     255    if (!do_d128_to_d64 (-1.1111111111111125dl, -1.111111111111112dd)) FAILURE
     256    if (!do_d128_to_d64 (-1.1111111111111135dl, -1.111111111111113dd)) FAILURE
     257  
     258  #ifdef DBG
     259    if (failcnt)
     260      printf ("towardzero: %d fails\n", failcnt);
     261  #endif
     262    return (void *) (ptrdiff_t) failcnt;
     263  } 
     264  
     265  void *
     266  upward (void *arg)
     267  {
     268    int err;
     269    DFP_SETROUND (FE_DEC_UPWARD);
     270  
     271    err = pthread_mutex_lock (&mut5);
     272    if (err != 0)
     273      error (EXIT_FAILURE, err, "upward: failed to lock");
     274  
     275    err = pthread_barrier_wait (&bar5);
     276    if (err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD)
     277      {
     278        puts ("upward: barrier_wait failed");
     279        exit (1);
     280      } 
     281  
     282    err = pthread_cond_wait (&cond5, &mut5);
     283    if (err != 0)
     284      error (EXIT_FAILURE, err, "upward: failed to wait");
     285  
     286    err = pthread_mutex_unlock (&mut5);
     287    if (err != 0)
     288      error (EXIT_FAILURE, err, "upward: failed to unlock");
     289  
     290    if (!do_d64_to_d32 (1.1111125dd, 1.111113df)) FAILURE
     291    if (!do_d64_to_d32 (1.1111135dd, 1.111114df)) FAILURE
     292    if (!do_d64_to_d32 (-1.1111125dd, -1.111112df)) FAILURE
     293    if (!do_d64_to_d32 (-1.1111135dd, -1.111113df)) FAILURE
     294    if (!do_d128_to_d32 (1.1111125dl, 1.111113df)) FAILURE
     295    if (!do_d128_to_d32 (1.1111135dl, 1.111114df)) FAILURE
     296    if (!do_d128_to_d32 (-1.1111125dl, -1.111112df)) FAILURE
     297    if (!do_d128_to_d32 (-1.1111135dl, -1.111113df)) FAILURE
     298    if (!do_d128_to_d64 (1.1111111111111125dl, 1.111111111111113dd)) FAILURE
     299    if (!do_d128_to_d64 (1.1111111111111135dl, 1.111111111111114dd)) FAILURE
     300    if (!do_d128_to_d64 (-1.1111111111111125dl, -1.111111111111112dd)) FAILURE
     301    if (!do_d128_to_d64 (-1.1111111111111135dl, -1.111111111111113dd)) FAILURE
     302    
     303  #ifdef DBG
     304    if (failcnt)
     305      printf ("upward: %d fails\n", failcnt);
     306  #endif
     307    return (void *) (ptrdiff_t) failcnt;
     308  }
     309  
     310  int
     311  main (void)
     312  {
     313    int err;
     314    int count = 0;
     315    void *ret;
     316    pthread_t down, up, tozero, fromzero, nearest;
     317  
     318    if (pthread_barrier_init (&bar1, NULL, 2) != 0
     319        || pthread_barrier_init (&bar2, NULL, 2) != 0
     320        || pthread_barrier_init (&bar3, NULL, 2) != 0
     321        || pthread_barrier_init (&bar4, NULL, 2) != 0
     322        || pthread_barrier_init (&bar5, NULL, 2) != 0)
     323      {
     324        puts ("parent: failed to init barrier");
     325        return 1;
     326      }
     327  
     328    if (pthread_create (&down, NULL, downward, NULL) != 0)
     329      {
     330        puts ("parent: failed to create");
     331        return 1;
     332      }
     333  
     334    if (pthread_create (&nearest, NULL, tonearest, NULL) != 0)
     335      {
     336        puts ("create failed");
     337        return 1;
     338      }
     339  
     340    if (pthread_create (&fromzero, NULL, toneareastfromzero, NULL) != 0)
     341      {
     342        puts ("create failed");
     343        return 1;
     344      }
     345  
     346    if (pthread_create (&up, NULL, upward, NULL) != 0)
     347      {
     348        puts ("create failed");
     349        return 1;
     350      }
     351  
     352    if (pthread_create (&tozero, NULL, towardzero, NULL) != 0)
     353      {
     354        puts ("create failed");
     355        return 1;
     356      }
     357  
     358    err = pthread_barrier_wait (&bar1);
     359    if (err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD)
     360      {
     361        puts ("parent: failed to wait barrier 1");
     362        return 1;
     363      }
     364    err = pthread_barrier_wait (&bar2);
     365    if (err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD)
     366      {
     367        puts ("parent: failed to wait barrier 2");
     368        return 1;
     369      }
     370    err = pthread_barrier_wait (&bar3);
     371    if (err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD)
     372      {
     373        puts ("parent: failed to wait barrier 3");
     374        return 1;
     375      }
     376    err = pthread_barrier_wait (&bar4);
     377    if (err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD)
     378      {
     379        puts ("parent: failed to wait barrier 4");
     380        return 1;
     381      }
     382    err = pthread_barrier_wait (&bar5);
     383    if (err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD)
     384      {
     385        puts ("parent: failed to wait barrier 5");
     386        return 1;
     387      }
     388  
     389    err = pthread_mutex_lock (&mut1);
     390    if (err != 0)
     391      error (EXIT_FAILURE, err, "parent: lock failed");
     392    err = pthread_mutex_lock (&mut2);
     393    if (err != 0)
     394      error (EXIT_FAILURE, err, "parent: lock failed");
     395    err = pthread_mutex_lock (&mut3);
     396    if (err != 0)
     397      error (EXIT_FAILURE, err, "parent: lock failed");
     398    err = pthread_mutex_lock (&mut4);
     399    if (err != 0)
     400      error (EXIT_FAILURE, err, "parent: lock failed");
     401    err = pthread_mutex_lock (&mut5);
     402    if (err != 0)
     403      error (EXIT_FAILURE, err, "parent: lock failed");
     404  
     405    err = pthread_cond_signal(&cond1);
     406    if (err != 0)
     407      error (EXIT_FAILURE, err, "parent: broadcast failed");
     408    err = pthread_cond_signal(&cond2);
     409    if (err != 0)
     410      error (EXIT_FAILURE, err, "parent: broadcast failed");
     411    err = pthread_cond_signal(&cond3);
     412    if (err != 0)
     413      error (EXIT_FAILURE, err, "parent: broadcast failed");
     414    err = pthread_cond_signal(&cond4);
     415    if (err != 0)
     416      error (EXIT_FAILURE, err, "parent: broadcast failed");
     417    err = pthread_cond_signal(&cond5);
     418    if (err != 0)
     419      error (EXIT_FAILURE, err, "parent: broadcast failed");
     420  
     421    err = pthread_mutex_unlock (&mut1);
     422    if (err != 0)
     423      {
     424        puts ("parent: failed to unlock");
     425        return 1;
     426      }
     427    err = pthread_mutex_unlock (&mut2);
     428    if (err != 0)
     429      {
     430        puts ("parent: failed to unlock");
     431        return 1;
     432      }
     433    err = pthread_mutex_unlock (&mut3);
     434    if (err != 0)
     435      {
     436        puts ("parent: failed to unlock");
     437        return 1;
     438      }
     439    err = pthread_mutex_unlock (&mut4);
     440    if (err != 0)
     441      {
     442        puts ("parent: failed to unlock");
     443        return 1;
     444      }
     445    err = pthread_mutex_unlock (&mut5);
     446    if (err != 0)
     447      {
     448        puts ("parent: failed to unlock");
     449        return 1;
     450      }
     451  
     452    if (pthread_join (down, &ret) != 0)
     453      {
     454        puts ("pthread_join failed");
     455        return 1;
     456      }
     457    count += (int) (ptrdiff_t) ret;
     458  
     459    if (pthread_join (up, &ret) != 0)
     460      {
     461        puts ("pthread_join failed");
     462        return 1;
     463      }
     464    count += (int) (ptrdiff_t) ret;
     465  
     466    if (pthread_join (tozero, &ret) != 0)
     467      {
     468        puts ("pthread_join failed");
     469        return 1;
     470      }
     471    count += (int) (ptrdiff_t) ret;
     472  
     473    if (pthread_join (fromzero, &ret) != 0)
     474      {
     475        puts ("pthread_join failed");
     476        return 1;
     477      }
     478    count += (int) (ptrdiff_t) ret;
     479  
     480    if (pthread_join (nearest, &ret) != 0)
     481      {
     482        puts ("pthread_join failed");
     483        return 1;
     484      }
     485    count += (int) (ptrdiff_t) ret;
     486  
     487    if (count)
     488      {
     489  #ifdef DBG
     490        printf ("Total: %d fails\n", count);
     491  #endif
     492        abort ();
     493      }
     494  
     495    return 0;
     496  }