diff options
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/dfp/convert-dfp-round-thread.c | 494 |
2 files changed, 498 insertions, 0 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d0d604a..e5486e9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2007-07-06 H.J. Lu <hongjiu.lu@intel.com> + + * gcc.dg/dfp/convert-dfp-round-thread.c: New test. + 2007-07-06 Daniel Franke <franke.daniel@gmail.com> * gfortran.dg/save_parameter.f90: New test. diff --git a/gcc/testsuite/gcc.dg/dfp/convert-dfp-round-thread.c b/gcc/testsuite/gcc.dg/dfp/convert-dfp-round-thread.c new file mode 100644 index 0000000..d288ac7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/convert-dfp-round-thread.c @@ -0,0 +1,494 @@ +/* { dg-options "-std=gnu99 -D_GNU_SOURCE -pthread" } */ +/* { dg-do run { target i?86-*-linux* x86_64-*-linux* } } */ + +/* N1150 5.2: Conversions among decimal floating types and between + decimal floating types and generic floating types. + C99 6.3.1.5(3) New. + + Perform conversions between DFP types in which the assigned value + cannot be represented exactly in the result and must be rounded + correctly according to the current rounding mode. + + Normally this would not be part of compiler testing, but conversions + are currently handled in libgcc via decNumber. */ + +#include <pthread.h> +#include <error.h> +#include <stdlib.h> +#include <stdio.h> +#include <stddef.h> +#include "dfp-round.h" + +extern void abort (void); +static __thread int failcnt = 0; + +/* Support compiling the test to report individual failures; default is + to abort as soon as a check fails. */ +#ifdef DBG +#include <stdio.h> +#define FAILURE { printf ("failed at line %d\n", __LINE__); failcnt++; } +#else +#define FAILURE abort (); +#endif + +pthread_mutex_t mut1 = PTHREAD_MUTEX_INITIALIZER; +pthread_mutex_t mut2 = PTHREAD_MUTEX_INITIALIZER; +pthread_mutex_t mut3 = PTHREAD_MUTEX_INITIALIZER; +pthread_mutex_t mut4 = PTHREAD_MUTEX_INITIALIZER; +pthread_mutex_t mut5 = PTHREAD_MUTEX_INITIALIZER; +pthread_cond_t cond1 = PTHREAD_COND_INITIALIZER; +pthread_cond_t cond2 = PTHREAD_COND_INITIALIZER; +pthread_cond_t cond3 = PTHREAD_COND_INITIALIZER; +pthread_cond_t cond4 = PTHREAD_COND_INITIALIZER; +pthread_cond_t cond5 = PTHREAD_COND_INITIALIZER; +pthread_barrier_t bar1; +pthread_barrier_t bar2; +pthread_barrier_t bar3; +pthread_barrier_t bar4; +pthread_barrier_t bar5; + +__thread _Decimal32 d32; +__thread _Decimal64 d64; +__thread _Decimal128 d128; + +_Decimal32 d64_to_d32 (_Decimal64 d) { return d; } +_Decimal64 d128_to_d64 (_Decimal128 d) { return d; } +_Decimal32 d128_to_d32 (_Decimal128 d) { return d; } + +int +do_d64_to_d32 (_Decimal64 orig, _Decimal32 exp) +{ + d64 = orig; + d32 = d64_to_d32 (d64); + return (d32 == exp); +} + +int +do_d128_to_d32 (_Decimal128 orig, _Decimal32 exp) +{ + d128 = orig; + d32 = d128_to_d32 (d128); + return (d32 == exp); +} + +int +do_d128_to_d64 (_Decimal128 orig, _Decimal64 exp) +{ + d128 = orig; + d64 = d128_to_d64 (d128); + return (d64 == exp); +} + +void * +downward (void *arg) +{ + int err; + + DFP_SETROUND (FE_DEC_DOWNWARD); + + err = pthread_mutex_lock (&mut1); + if (err != 0) + error (EXIT_FAILURE, err, "downward: failed to lock"); + + err = pthread_barrier_wait (&bar1); + if (err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD) + { + puts ("downward: barrier_wait failed"); + exit (1); + } + + err = pthread_cond_wait (&cond1, &mut1); + if (err != 0) + error (EXIT_FAILURE, err, "downward: failed to wait"); + + err = pthread_mutex_unlock (&mut1); + if (err != 0) + error (EXIT_FAILURE, err, "downward: failed to unlock"); + + if (!do_d64_to_d32 (1.1111125dd, 1.111112df)) FAILURE + if (!do_d64_to_d32 (1.1111135dd, 1.111113df)) FAILURE + if (!do_d64_to_d32 (-1.1111125dd, -1.111113df)) FAILURE + if (!do_d64_to_d32 (-1.1111135dd, -1.111114df)) FAILURE + if (!do_d128_to_d32 (1.1111125dl, 1.111112df)) FAILURE + if (!do_d128_to_d32 (1.1111135dl, 1.111113df)) FAILURE + if (!do_d128_to_d32 (-1.1111125dl, -1.111113df)) FAILURE + if (!do_d128_to_d32 (-1.1111135dl, -1.111114df)) FAILURE + if (!do_d128_to_d64 (1.1111111111111125dl, 1.111111111111112dd)) FAILURE + if (!do_d128_to_d64 (1.1111111111111135dl, 1.111111111111113dd)) FAILURE + if (!do_d128_to_d64 (-1.1111111111111125dl, -1.111111111111113dd)) FAILURE + if (!do_d128_to_d64 (-1.1111111111111135dl, -1.111111111111114dd)) FAILURE + +#ifdef DBG + if (failcnt) + printf ("downward: %d fails\n", failcnt); +#endif + return (void *) (ptrdiff_t) failcnt; +} + +void * +tonearest (void *arg) +{ + int err; + DFP_SETROUND (FE_DEC_TONEAREST); + + err = pthread_mutex_lock (&mut2); + if (err != 0) + error (EXIT_FAILURE, err, "tonearest: failed to lock"); + + err = pthread_barrier_wait (&bar2); + if (err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD) + { + puts ("tonearest: barrier_wait failed"); + exit (1); + } + + err = pthread_cond_wait (&cond2, &mut2); + if (err != 0) + error (EXIT_FAILURE, err, "tonearest: failed to wait"); + + err = pthread_mutex_unlock (&mut2); + if (err != 0) + error (EXIT_FAILURE, err, "tonearest: failed to unlock"); + + if (!do_d64_to_d32 (1.1111125dd, 1.111112df)) FAILURE + if (!do_d64_to_d32 (1.1111135dd, 1.111114df)) FAILURE + if (!do_d64_to_d32 (-1.1111125dd, -1.111112df)) FAILURE + if (!do_d64_to_d32 (-1.1111135dd, -1.111114df)) FAILURE + if (!do_d128_to_d32 (1.1111125dl, 1.111112df)) FAILURE + if (!do_d128_to_d32 (1.1111135dl, 1.111114df)) FAILURE + if (!do_d128_to_d32 (-1.1111125dl, -1.111112df)) FAILURE + if (!do_d128_to_d32 (-1.1111135dl, -1.111114df)) FAILURE + if (!do_d128_to_d64 (1.1111111111111125dl, 1.111111111111112dd)) FAILURE + if (!do_d128_to_d64 (1.1111111111111135dl, 1.111111111111114dd)) FAILURE + if (!do_d128_to_d64 (-1.1111111111111125dl, -1.111111111111112dd)) FAILURE + if (!do_d128_to_d64 (-1.1111111111111135dl, -1.111111111111114dd)) FAILURE + +#ifdef DBG + if (failcnt) + printf ("tonearest: %d fails\n", failcnt); +#endif + return (void *) (ptrdiff_t) failcnt; +} + +void * +toneareastfromzero (void *arg) +{ + int err; + DFP_SETROUND (FE_DEC_TONEARESTFROMZERO); + + err = pthread_mutex_lock (&mut3); + if (err != 0) + error (EXIT_FAILURE, err, "toneareastfromzero: failed to lock"); + + err = pthread_barrier_wait (&bar3); + if (err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD) + { + puts ("toneareastfromzero: barrier_wait failed"); + exit (1); + } + + err = pthread_cond_wait (&cond3, &mut3); + if (err != 0) + error (EXIT_FAILURE, err, "toneareastfromzero: failed to wait"); + + err = pthread_mutex_unlock (&mut3); + if (err != 0) + error (EXIT_FAILURE, err, "toneareastfromzero: failed to unlock"); + + if (!do_d64_to_d32 (1.1111125dd, 1.111113df)) FAILURE + if (!do_d64_to_d32 (1.1111135dd, 1.111114df)) FAILURE + if (!do_d64_to_d32 (-1.1111125dd, -1.111113df)) FAILURE + if (!do_d64_to_d32 (-1.1111135dd, -1.111114df)) FAILURE + if (!do_d128_to_d32 (1.1111125dl, 1.111113df)) FAILURE + if (!do_d128_to_d32 (1.1111135dl, 1.111114df)) FAILURE + if (!do_d128_to_d32 (-1.1111125dl, -1.111113df)) FAILURE + if (!do_d128_to_d32 (-1.1111135dl, -1.111114df)) FAILURE + if (!do_d128_to_d64 (1.1111111111111125dl, 1.111111111111113dd)) FAILURE + if (!do_d128_to_d64 (1.1111111111111135dl, 1.111111111111114dd)) FAILURE + if (!do_d128_to_d64 (-1.1111111111111125dl, -1.111111111111113dd)) FAILURE + if (!do_d128_to_d64 (-1.1111111111111135dl, -1.111111111111114dd)) FAILURE + +#ifdef DBG + if (failcnt) + printf ("toneareastfromzero: %d fails\n", failcnt); +#endif + return (void *) (ptrdiff_t) failcnt; +} + +void * +towardzero (void *arg) +{ + int err; + DFP_SETROUND (FE_DEC_TOWARDZERO); + + err = pthread_mutex_lock (&mut4); + if (err != 0) + error (EXIT_FAILURE, err, "towardzero: failed to lock"); + + err = pthread_barrier_wait (&bar4); + if (err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD) + { + puts ("towardzero: barrier_wait failed"); + exit (1); + } + + err = pthread_cond_wait (&cond4, &mut4); + if (err != 0) + error (EXIT_FAILURE, err, "towardzero: failed to wait"); + + err = pthread_mutex_unlock (&mut4); + if (err != 0) + error (EXIT_FAILURE, err, "towardzero: failed to unlock"); + + if (!do_d64_to_d32 (1.1111125dd, 1.111112df)) FAILURE + if (!do_d64_to_d32 (1.1111135dd, 1.111113df)) FAILURE + if (!do_d64_to_d32 (-1.1111125dd, -1.111112df)) FAILURE + if (!do_d64_to_d32 (-1.1111135dd, -1.111113df)) FAILURE + if (!do_d128_to_d32 (1.1111125dl, 1.111112df)) FAILURE + if (!do_d128_to_d32 (1.1111135dl, 1.111113df)) FAILURE + if (!do_d128_to_d32 (-1.1111125dl, -1.111112df)) FAILURE + if (!do_d128_to_d32 (-1.1111135dl, -1.111113df)) FAILURE + if (!do_d128_to_d64 (1.1111111111111125dl, 1.111111111111112dd)) FAILURE + if (!do_d128_to_d64 (1.1111111111111135dl, 1.111111111111113dd)) FAILURE + if (!do_d128_to_d64 (-1.1111111111111125dl, -1.111111111111112dd)) FAILURE + if (!do_d128_to_d64 (-1.1111111111111135dl, -1.111111111111113dd)) FAILURE + +#ifdef DBG + if (failcnt) + printf ("towardzero: %d fails\n", failcnt); +#endif + return (void *) (ptrdiff_t) failcnt; +} + +void * +upward (void *arg) +{ + int err; + DFP_SETROUND (FE_DEC_UPWARD); + + err = pthread_mutex_lock (&mut5); + if (err != 0) + error (EXIT_FAILURE, err, "upward: failed to lock"); + + err = pthread_barrier_wait (&bar5); + if (err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD) + { + puts ("upward: barrier_wait failed"); + exit (1); + } + + err = pthread_cond_wait (&cond5, &mut5); + if (err != 0) + error (EXIT_FAILURE, err, "upward: failed to wait"); + + err = pthread_mutex_unlock (&mut5); + if (err != 0) + error (EXIT_FAILURE, err, "upward: failed to unlock"); + + if (!do_d64_to_d32 (1.1111125dd, 1.111113df)) FAILURE + if (!do_d64_to_d32 (1.1111135dd, 1.111114df)) FAILURE + if (!do_d64_to_d32 (-1.1111125dd, -1.111112df)) FAILURE + if (!do_d64_to_d32 (-1.1111135dd, -1.111113df)) FAILURE + if (!do_d128_to_d32 (1.1111125dl, 1.111113df)) FAILURE + if (!do_d128_to_d32 (1.1111135dl, 1.111114df)) FAILURE + if (!do_d128_to_d32 (-1.1111125dl, -1.111112df)) FAILURE + if (!do_d128_to_d32 (-1.1111135dl, -1.111113df)) FAILURE + if (!do_d128_to_d64 (1.1111111111111125dl, 1.111111111111113dd)) FAILURE + if (!do_d128_to_d64 (1.1111111111111135dl, 1.111111111111114dd)) FAILURE + if (!do_d128_to_d64 (-1.1111111111111125dl, -1.111111111111112dd)) FAILURE + if (!do_d128_to_d64 (-1.1111111111111135dl, -1.111111111111113dd)) FAILURE + +#ifdef DBG + if (failcnt) + printf ("upward: %d fails\n", failcnt); +#endif + return (void *) (ptrdiff_t) failcnt; +} + +int +main (void) +{ + int err; + int count = 0; + void *ret; + pthread_t down, up, tozero, fromzero, nearest; + + if (pthread_barrier_init (&bar1, NULL, 2) != 0 + || pthread_barrier_init (&bar2, NULL, 2) != 0 + || pthread_barrier_init (&bar3, NULL, 2) != 0 + || pthread_barrier_init (&bar4, NULL, 2) != 0 + || pthread_barrier_init (&bar5, NULL, 2) != 0) + { + puts ("parent: failed to init barrier"); + return 1; + } + + if (pthread_create (&down, NULL, downward, NULL) != 0) + { + puts ("parent: failed to create"); + return 1; + } + + if (pthread_create (&nearest, NULL, tonearest, NULL) != 0) + { + puts ("create failed"); + return 1; + } + + if (pthread_create (&fromzero, NULL, toneareastfromzero, NULL) != 0) + { + puts ("create failed"); + return 1; + } + + if (pthread_create (&up, NULL, upward, NULL) != 0) + { + puts ("create failed"); + return 1; + } + + if (pthread_create (&tozero, NULL, towardzero, NULL) != 0) + { + puts ("create failed"); + return 1; + } + + err = pthread_barrier_wait (&bar1); + if (err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD) + { + puts ("parent: failed to wait barrier 1"); + return 1; + } + err = pthread_barrier_wait (&bar2); + if (err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD) + { + puts ("parent: failed to wait barrier 2"); + return 1; + } + err = pthread_barrier_wait (&bar3); + if (err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD) + { + puts ("parent: failed to wait barrier 3"); + return 1; + } + err = pthread_barrier_wait (&bar4); + if (err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD) + { + puts ("parent: failed to wait barrier 4"); + return 1; + } + err = pthread_barrier_wait (&bar5); + if (err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD) + { + puts ("parent: failed to wait barrier 5"); + return 1; + } + + err = pthread_mutex_lock (&mut1); + if (err != 0) + error (EXIT_FAILURE, err, "parent: lock failed"); + err = pthread_mutex_lock (&mut2); + if (err != 0) + error (EXIT_FAILURE, err, "parent: lock failed"); + err = pthread_mutex_lock (&mut3); + if (err != 0) + error (EXIT_FAILURE, err, "parent: lock failed"); + err = pthread_mutex_lock (&mut4); + if (err != 0) + error (EXIT_FAILURE, err, "parent: lock failed"); + err = pthread_mutex_lock (&mut5); + if (err != 0) + error (EXIT_FAILURE, err, "parent: lock failed"); + + err = pthread_cond_signal(&cond1); + if (err != 0) + error (EXIT_FAILURE, err, "parent: broadcast failed"); + err = pthread_cond_signal(&cond2); + if (err != 0) + error (EXIT_FAILURE, err, "parent: broadcast failed"); + err = pthread_cond_signal(&cond3); + if (err != 0) + error (EXIT_FAILURE, err, "parent: broadcast failed"); + err = pthread_cond_signal(&cond4); + if (err != 0) + error (EXIT_FAILURE, err, "parent: broadcast failed"); + err = pthread_cond_signal(&cond5); + if (err != 0) + error (EXIT_FAILURE, err, "parent: broadcast failed"); + + err = pthread_mutex_unlock (&mut1); + if (err != 0) + { + puts ("parent: failed to unlock"); + return 1; + } + err = pthread_mutex_unlock (&mut2); + if (err != 0) + { + puts ("parent: failed to unlock"); + return 1; + } + err = pthread_mutex_unlock (&mut3); + if (err != 0) + { + puts ("parent: failed to unlock"); + return 1; + } + err = pthread_mutex_unlock (&mut4); + if (err != 0) + { + puts ("parent: failed to unlock"); + return 1; + } + err = pthread_mutex_unlock (&mut5); + if (err != 0) + { + puts ("parent: failed to unlock"); + return 1; + } + + if (pthread_join (down, &ret) != 0) + { + puts ("pthread_join failed"); + return 1; + } + count += (int) (ptrdiff_t) ret; + + if (pthread_join (up, &ret) != 0) + { + puts ("pthread_join failed"); + return 1; + } + count += (int) (ptrdiff_t) ret; + + if (pthread_join (tozero, &ret) != 0) + { + puts ("pthread_join failed"); + return 1; + } + count += (int) (ptrdiff_t) ret; + + if (pthread_join (fromzero, &ret) != 0) + { + puts ("pthread_join failed"); + return 1; + } + count += (int) (ptrdiff_t) ret; + + if (pthread_join (nearest, &ret) != 0) + { + puts ("pthread_join failed"); + return 1; + } + count += (int) (ptrdiff_t) ret; + + if (count) + { +#ifdef DBG + printf ("Total: %d fails\n", count); +#endif + abort (); + } + + return 0; +} |