This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
As noted here: http://gcc.gnu.org/ml/fortran/2009-05/msg00382.html a goal for gfortran would be to convert to using mpc_t to represent complex numbers instead of a pair of mpfr_t. The patch below does this. Since we're in the optional phase of MPC, the patch contains a significant amount of cpp conditionals and uglifies the code. However this is temporary until we make MPC hard-required. I felt it was better to suffer the temporary uglification now so that the new code could be better tested rather than doing this conversion later in the release cycle. Once we hard-require MPC, a significant amount of code can be removed. I.e. we can delete all the HAVE_mpc #else clauses, which in some cases are rather large. A couple of notes: 1. MPC accesses the real/imag parts of a complex number using accessor macros mpc_realref/mpc_imagref. I provided a fallback definition for mpc_realref/mpc_imagref for the non-MPC versions of the code which simply accesses the mpfr_t pair. This reduced the amount of cpp conditionals. 2. MPC setter functions have single value forms that set the real part to the supplied value and the imaginary part to zero. So when you see bits omitted that set the imaginary part to zero, that's where it went. 3. I preserved the current gfortran behavior of divide-by-zero to always return NaN, see PR40318. If at some point that PR is resolved and gfortran wants to follow the C99 behavior for these corner cases, it's very easy to remove my special case code below and purely rely on MPC which follows C99 for complex divide. Tested on x86_64-unknown-linux-gnu with and without MPC, no fortran regressions. Okay for mainline? Thanks, --Kaveh 2009-06-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> * gfortran.h (gfc_expr): Use mpc_t to represent complex numbers. * arith.c, dump-parse-tree.c, expr.c, module.c, resolve.c, simplify.c, target-memory.c, target-memory.h, trans-const.c, trans-expr.c: Convert to mpc_t throughout. diff -rup orig/egcc-SVN20090616/gcc/fortran/gfortran.h egcc-SVN20090616/gcc/fortran/gfortran.h --- orig/egcc-SVN20090616/gcc/fortran/gfortran.h 2009-06-13 02:02:16.000000000 +0200 +++ egcc-SVN20090616/gcc/fortran/gfortran.h 2009-06-17 02:42:33.000000000 +0200 @@ -1555,6 +1555,12 @@ gfc_intrinsic_sym; #include <gmp.h> #include <mpfr.h> +#ifdef HAVE_mpc +#include <mpc.h> +#else +#define mpc_realref(X) ((X).r) +#define mpc_imagref(X) ((X).i) +#endif #define GFC_RND_MODE GMP_RNDN #define GFC_MPC_RND_MODE MPC_RNDNN @@ -1613,10 +1619,14 @@ typedef struct gfc_expr mpfr_t real; +#ifdef HAVE_mpc + mpc_t +#else struct { mpfr_t r, i; } +#endif complex; struct diff -rup orig/egcc-SVN20090616/gcc/fortran/arith.c egcc-SVN20090616/gcc/fortran/arith.c --- orig/egcc-SVN20090616/gcc/fortran/arith.c 2009-06-13 02:02:16.000000000 +0200 +++ egcc-SVN20090616/gcc/fortran/arith.c 2009-06-17 03:00:45.000000000 +0200 @@ -429,8 +429,12 @@ gfc_constant_result (bt type, int kind, case BT_COMPLEX: gfc_set_model_kind (kind); +#ifdef HAVE_mpc + mpc_init2 (result->value.complex, mpfr_get_default_prec()); +#else mpfr_init (result->value.complex.r); mpfr_init (result->value.complex.i); +#endif break; default: @@ -543,21 +547,23 @@ gfc_range_check (gfc_expr *e) break; case BT_COMPLEX: - rc = gfc_check_real_range (e->value.complex.r, e->ts.kind); + rc = gfc_check_real_range (mpc_realref (e->value.complex), e->ts.kind); if (rc == ARITH_UNDERFLOW) - mpfr_set_ui (e->value.complex.r, 0, GFC_RND_MODE); + mpfr_set_ui (mpc_realref (e->value.complex), 0, GFC_RND_MODE); if (rc == ARITH_OVERFLOW) - mpfr_set_inf (e->value.complex.r, mpfr_sgn (e->value.complex.r)); + mpfr_set_inf (mpc_realref (e->value.complex), + mpfr_sgn (mpc_realref (e->value.complex))); if (rc == ARITH_NAN) - mpfr_set_nan (e->value.complex.r); + mpfr_set_nan (mpc_realref (e->value.complex)); - rc2 = gfc_check_real_range (e->value.complex.i, e->ts.kind); + rc2 = gfc_check_real_range (mpc_imagref (e->value.complex), e->ts.kind); if (rc == ARITH_UNDERFLOW) - mpfr_set_ui (e->value.complex.i, 0, GFC_RND_MODE); + mpfr_set_ui (mpc_imagref (e->value.complex), 0, GFC_RND_MODE); if (rc == ARITH_OVERFLOW) - mpfr_set_inf (e->value.complex.i, mpfr_sgn (e->value.complex.i)); + mpfr_set_inf (mpc_imagref (e->value.complex), + mpfr_sgn (mpc_imagref (e->value.complex))); if (rc == ARITH_NAN) - mpfr_set_nan (e->value.complex.i); + mpfr_set_nan (mpc_imagref (e->value.complex)); if (rc == ARITH_OK) rc = rc2; @@ -633,8 +639,12 @@ gfc_arith_uminus (gfc_expr *op1, gfc_exp break; case BT_COMPLEX: +#ifdef HAVE_mpc + mpc_neg (result->value.complex, op1->value.complex, GFC_MPC_RND_MODE); +#else mpfr_neg (result->value.complex.r, op1->value.complex.r, GFC_RND_MODE); mpfr_neg (result->value.complex.i, op1->value.complex.i, GFC_RND_MODE); +#endif break; default: @@ -667,11 +677,16 @@ gfc_arith_plus (gfc_expr *op1, gfc_expr break; case BT_COMPLEX: +#ifdef HAVE_mpc + mpc_add (result->value.complex, op1->value.complex, op2->value.complex, + GFC_MPC_RND_MODE); +#else mpfr_add (result->value.complex.r, op1->value.complex.r, op2->value.complex.r, GFC_RND_MODE); mpfr_add (result->value.complex.i, op1->value.complex.i, op2->value.complex.i, GFC_RND_MODE); +#endif break; default: @@ -704,11 +719,16 @@ gfc_arith_minus (gfc_expr *op1, gfc_expr break; case BT_COMPLEX: +#ifdef HAVE_mpc + mpc_sub (result->value.complex, op1->value.complex, + op2->value.complex, GFC_MPC_RND_MODE); +#else mpfr_sub (result->value.complex.r, op1->value.complex.r, op2->value.complex.r, GFC_RND_MODE); mpfr_sub (result->value.complex.i, op1->value.complex.i, op2->value.complex.i, GFC_RND_MODE); +#endif break; default: @@ -725,7 +745,6 @@ static arith gfc_arith_times (gfc_expr *op1, gfc_expr *op2, gfc_expr **resultp) { gfc_expr *result; - mpfr_t x, y; arith rc; result = gfc_constant_result (op1->ts.type, op1->ts.kind, &op1->where); @@ -742,7 +761,13 @@ gfc_arith_times (gfc_expr *op1, gfc_expr break; case BT_COMPLEX: - gfc_set_model (op1->value.complex.r); + gfc_set_model (mpc_realref (op1->value.complex)); +#ifdef HAVE_mpc + mpc_mul (result->value.complex, op1->value.complex, op2->value.complex, + GFC_MPC_RND_MODE); +#else + { + mpfr_t x, y; mpfr_init (x); mpfr_init (y); @@ -755,6 +780,8 @@ gfc_arith_times (gfc_expr *op1, gfc_expr mpfr_add (result->value.complex.i, x, y, GFC_RND_MODE); mpfr_clears (x, y, NULL); + } +#endif break; default: @@ -771,7 +798,6 @@ static arith gfc_arith_divide (gfc_expr *op1, gfc_expr *op2, gfc_expr **resultp) { gfc_expr *result; - mpfr_t x, y, div; arith rc; rc = ARITH_OK; @@ -803,15 +829,36 @@ gfc_arith_divide (gfc_expr *op1, gfc_exp break; case BT_COMPLEX: - if (mpfr_sgn (op2->value.complex.r) == 0 + if ( +#ifdef HAVE_mpc + mpc_cmp_si_si (op2->value.complex, 0, 0) == 0 +#else + mpfr_sgn (op2->value.complex.r) == 0 && mpfr_sgn (op2->value.complex.i) == 0 +#endif && gfc_option.flag_range_check == 1) { rc = ARITH_DIV0; break; } - gfc_set_model (op1->value.complex.r); + + gfc_set_model (mpc_realref (op1->value.complex)); + +#ifdef HAVE_mpc + if (mpc_cmp_si_si (op2->value.complex, 0, 0) == 0) + { + /* For fortran return (NaN + NaN I) for any zero divisor. See + PR 40318. */ + mpfr_set_nan (mpc_realref (result->value.complex)); + mpfr_set_nan (mpc_imagref (result->value.complex)); + } + else + mpc_div (result->value.complex, op1->value.complex, op2->value.complex, + GFC_MPC_RND_MODE); +#else + { + mpfr_t x, y, div; mpfr_init (x); mpfr_init (y); mpfr_init (div); @@ -833,6 +880,8 @@ gfc_arith_divide (gfc_expr *op1, gfc_exp GFC_RND_MODE); mpfr_clears (x, y, div, NULL); + } +#endif break; default: @@ -851,9 +900,13 @@ gfc_arith_divide (gfc_expr *op1, gfc_exp static void complex_reciprocal (gfc_expr *op) { + gfc_set_model (mpc_realref (op->value.complex)); +#ifdef HAVE_mpc + mpc_ui_div (op->value.complex, 1, op->value.complex, GFC_MPC_RND_MODE); +#else + { mpfr_t mod, tmp; - gfc_set_model (op->value.complex.r); mpfr_init (mod); mpfr_init (tmp); @@ -867,9 +920,10 @@ complex_reciprocal (gfc_expr *op) mpfr_div (op->value.complex.i, op->value.complex.i, mod, GFC_RND_MODE); mpfr_clears (tmp, mod, NULL); + } +#endif } - /* Raise a complex number to positive power (power > 0). This function will modify the content of power. @@ -883,7 +937,7 @@ complex_pow (gfc_expr *result, gfc_expr { mpfr_t x_r, x_i, tmp, re, im; - gfc_set_model (base->value.complex.r); + gfc_set_model (mpc_realref (base->value.complex)); mpfr_init (x_r); mpfr_init (x_i); mpfr_init (tmp); @@ -891,12 +945,21 @@ complex_pow (gfc_expr *result, gfc_expr mpfr_init (im); /* res = 1 */ +#ifdef HAVE_mpc + mpc_set_ui (result->value.complex, 1, GFC_MPC_RND_MODE); +#else mpfr_set_ui (result->value.complex.r, 1, GFC_RND_MODE); mpfr_set_ui (result->value.complex.i, 0, GFC_RND_MODE); +#endif /* x = base */ +#ifdef HAVE_mpc + mpfr_set (x_r, mpc_realref (base->value.complex), GFC_RND_MODE); + mpfr_set (x_i, mpc_imagref (base->value.complex), GFC_RND_MODE); +#else mpfr_set (x_r, base->value.complex.r, GFC_RND_MODE); mpfr_set (x_i, base->value.complex.i, GFC_RND_MODE); +#endif /* Macro for complex multiplication. We have to take care that res_r/res_i and a_r/a_i can (and will) be the same variable. */ @@ -910,8 +973,8 @@ complex_pow (gfc_expr *result, gfc_expr mpfr_add (res_i, im, tmp, GFC_RND_MODE), \ mpfr_set (res_r, re, GFC_RND_MODE) -#define res_r result->value.complex.r -#define res_i result->value.complex.i +#define res_r mpc_realref (result->value.complex) +#define res_i mpc_imagref (result->value.complex) /* for (; power > 0; x *= x) */ for (; mpz_cmp_si (power, 0) > 0; CMULT(x_r,x_i,x_r,x_i,x_r,x_i)) @@ -931,7 +994,6 @@ complex_pow (gfc_expr *result, gfc_expr mpfr_clears (x_r, x_i, tmp, re, im, NULL); } - /* Raise a number to a power. */ static arith @@ -966,8 +1028,12 @@ arith_power (gfc_expr *op1, gfc_expr *op break; case BT_COMPLEX: +#ifdef HAVE_mpc + mpc_set_ui (result->value.complex, 1, GFC_MPC_RND_MODE); +#else mpfr_set_ui (result->value.complex.r, 1, GFC_RND_MODE); mpfr_set_ui (result->value.complex.i, 0, GFC_RND_MODE); +#endif break; default: @@ -1089,8 +1155,6 @@ arith_power (gfc_expr *op1, gfc_expr *op case BT_COMPLEX: { - mpfr_t x, y, r, t; - if (init_flag) { if (gfc_notify_std (GFC_STD_F2003,"Fortran 2003: Noninteger " @@ -1099,16 +1163,27 @@ arith_power (gfc_expr *op1, gfc_expr *op return ARITH_PROHIBIT; } - gfc_set_model (op1->value.complex.r); + { + mpfr_t x, y, r, t; + + gfc_set_model (mpc_realref (op1->value.complex)); mpfr_init (r); +#ifdef HAVE_mpc + mpc_abs (r, op1->value.complex, GFC_RND_MODE); +#else mpfr_hypot (r, op1->value.complex.r, op1->value.complex.i, GFC_RND_MODE); +#endif if (mpfr_cmp_si (r, 0) == 0) { +#ifdef HAVE_mpc + mpc_set_ui (result->value.complex, 0, GFC_MPC_RND_MODE); +#else mpfr_set_ui (result->value.complex.r, 0, GFC_RND_MODE); mpfr_set_ui (result->value.complex.i, 0, GFC_RND_MODE); +#endif mpfr_clear (r); break; } @@ -1116,25 +1191,30 @@ arith_power (gfc_expr *op1, gfc_expr *op mpfr_init (t); +#ifdef HAVE_mpc + mpc_arg (t, op1->value.complex, GFC_RND_MODE); +#else mpfr_atan2 (t, op1->value.complex.i, op1->value.complex.r, GFC_RND_MODE); +#endif mpfr_init (x); mpfr_init (y); - mpfr_mul (x, op2->value.complex.r, r, GFC_RND_MODE); - mpfr_mul (y, op2->value.complex.i, t, GFC_RND_MODE); + mpfr_mul (x, mpc_realref (op2->value.complex), r, GFC_RND_MODE); + mpfr_mul (y, mpc_imagref (op2->value.complex), t, GFC_RND_MODE); mpfr_sub (x, x, y, GFC_RND_MODE); mpfr_exp (x, x, GFC_RND_MODE); - mpfr_mul (y, op2->value.complex.r, t, GFC_RND_MODE); - mpfr_mul (t, op2->value.complex.i, r, GFC_RND_MODE); + mpfr_mul (y, mpc_realref (op2->value.complex), t, GFC_RND_MODE); + mpfr_mul (t, mpc_imagref (op2->value.complex), r, GFC_RND_MODE); mpfr_add (y, y, t, GFC_RND_MODE); mpfr_cos (t, y, GFC_RND_MODE); mpfr_sin (y, y, GFC_RND_MODE); - mpfr_mul (result->value.complex.r, x, t, GFC_RND_MODE); - mpfr_mul (result->value.complex.i, x, y, GFC_RND_MODE); + mpfr_mul (mpc_realref (result->value.complex), x, t, GFC_RND_MODE); + mpfr_mul (mpc_imagref (result->value.complex), x, y, GFC_RND_MODE); mpfr_clears (r, t, x, y, NULL); + } } break; default: @@ -1252,8 +1332,12 @@ gfc_compare_expr (gfc_expr *op1, gfc_exp static int compare_complex (gfc_expr *op1, gfc_expr *op2) { +#ifdef HAVE_mpc + return mpc_cmp (op1->value.complex, op2->value.complex) == 0; +#else return (mpfr_equal_p (op1->value.complex.r, op2->value.complex.r) && mpfr_equal_p (op1->value.complex.i, op2->value.complex.i)); +#endif } @@ -2122,8 +2206,13 @@ gfc_convert_complex (gfc_expr *real, gfc gfc_expr *e; e = gfc_constant_result (BT_COMPLEX, kind, &real->where); +#ifdef HAVE_mpc + mpc_set_fr_fr (e->value.complex, real->value.real, imag->value.real, + GFC_MPC_RND_MODE); +#else mpfr_set (e->value.complex.r, real->value.real, GFC_RND_MODE); mpfr_set (e->value.complex.i, imag->value.real, GFC_RND_MODE); +#endif return e; } @@ -2243,10 +2332,15 @@ gfc_int2complex (gfc_expr *src, int kind result = gfc_constant_result (BT_COMPLEX, kind, &src->where); +#ifdef HAVE_mpc + mpc_set_z (result->value.complex, src->value.integer, GFC_MPC_RND_MODE); +#else mpfr_set_z (result->value.complex.r, src->value.integer, GFC_RND_MODE); mpfr_set_ui (result->value.complex.i, 0, GFC_RND_MODE); +#endif - if ((rc = gfc_check_real_range (result->value.complex.r, kind)) != ARITH_OK) + if ((rc = gfc_check_real_range (mpc_realref (result->value.complex), kind)) + != ARITH_OK) { arith_error (rc, &src->ts, &result->ts, &src->where); gfc_free_expr (result); @@ -2321,16 +2415,20 @@ gfc_real2complex (gfc_expr *src, int kin result = gfc_constant_result (BT_COMPLEX, kind, &src->where); +#ifdef HAVE_mpc + mpc_set_fr (result->value.complex, src->value.real, GFC_MPC_RND_MODE); +#else mpfr_set (result->value.complex.r, src->value.real, GFC_RND_MODE); mpfr_set_ui (result->value.complex.i, 0, GFC_RND_MODE); +#endif - rc = gfc_check_real_range (result->value.complex.r, kind); + rc = gfc_check_real_range (mpc_realref (result->value.complex), kind); if (rc == ARITH_UNDERFLOW) { if (gfc_option.warn_underflow) gfc_warning (gfc_arith_error (rc), &src->where); - mpfr_set_ui (result->value.complex.r, 0, GFC_RND_MODE); + mpfr_set_ui (mpc_realref (result->value.complex), 0, GFC_RND_MODE); } else if (rc != ARITH_OK) { @@ -2353,7 +2451,8 @@ gfc_complex2int (gfc_expr *src, int kind result = gfc_constant_result (BT_INTEGER, kind, &src->where); - gfc_mpfr_to_mpz (result->value.integer, src->value.complex.r, &src->where); + gfc_mpfr_to_mpz (result->value.integer, mpc_realref (src->value.complex), + &src->where); if ((rc = gfc_check_integer_range (result->value.integer, kind)) != ARITH_OK) { @@ -2376,7 +2475,11 @@ gfc_complex2real (gfc_expr *src, int kin result = gfc_constant_result (BT_REAL, kind, &src->where); +#ifdef HAVE_mpc + mpc_real (result->value.real, src->value.complex, GFC_RND_MODE); +#else mpfr_set (result->value.real, src->value.complex.r, GFC_RND_MODE); +#endif rc = gfc_check_real_range (result->value.real, kind); @@ -2407,16 +2510,20 @@ gfc_complex2complex (gfc_expr *src, int result = gfc_constant_result (BT_COMPLEX, kind, &src->where); +#ifdef HAVE_mpc + mpc_set (result->value.complex, src->value.complex, GFC_MPC_RND_MODE); +#else mpfr_set (result->value.complex.r, src->value.complex.r, GFC_RND_MODE); mpfr_set (result->value.complex.i, src->value.complex.i, GFC_RND_MODE); +#endif - rc = gfc_check_real_range (result->value.complex.r, kind); + rc = gfc_check_real_range (mpc_realref (result->value.complex), kind); if (rc == ARITH_UNDERFLOW) { if (gfc_option.warn_underflow) gfc_warning (gfc_arith_error (rc), &src->where); - mpfr_set_ui (result->value.complex.r, 0, GFC_RND_MODE); + mpfr_set_ui (mpc_realref (result->value.complex), 0, GFC_RND_MODE); } else if (rc != ARITH_OK) { @@ -2425,13 +2532,13 @@ gfc_complex2complex (gfc_expr *src, int return NULL; } - rc = gfc_check_real_range (result->value.complex.i, kind); + rc = gfc_check_real_range (mpc_imagref (result->value.complex), kind); if (rc == ARITH_UNDERFLOW) { if (gfc_option.warn_underflow) gfc_warning (gfc_arith_error (rc), &src->where); - mpfr_set_ui (result->value.complex.i, 0, GFC_RND_MODE); + mpfr_set_ui (mpc_imagref (result->value.complex), 0, GFC_RND_MODE); } else if (rc != ARITH_OK) { @@ -2579,8 +2686,13 @@ gfc_hollerith2complex (gfc_expr *src, in hollerith2representation (result, src); gfc_interpret_complex (kind, (unsigned char *) result->representation.string, - result->representation.length, result->value.complex.r, - result->value.complex.i); + result->representation.length, +#ifdef HAVE_mpc + result->value.complex +#else + result->value.complex.r, result->value.complex.i +#endif + ); return result; } diff -rup orig/egcc-SVN20090616/gcc/fortran/dump-parse-tree.c egcc-SVN20090616/gcc/fortran/dump-parse-tree.c --- orig/egcc-SVN20090616/gcc/fortran/dump-parse-tree.c 2009-05-15 02:02:23.000000000 +0200 +++ egcc-SVN20090616/gcc/fortran/dump-parse-tree.c 2009-06-17 02:51:17.000000000 +0200 @@ -402,13 +402,15 @@ show_expr (gfc_expr *p) case BT_COMPLEX: fputs ("(complex ", dumpfile); - mpfr_out_str (stdout, 10, 0, p->value.complex.r, GFC_RND_MODE); + mpfr_out_str (stdout, 10, 0, mpc_realref (p->value.complex), + GFC_RND_MODE); if (p->ts.kind != gfc_default_complex_kind) fprintf (dumpfile, "_%d", p->ts.kind); fputc (' ', dumpfile); - mpfr_out_str (stdout, 10, 0, p->value.complex.i, GFC_RND_MODE); + mpfr_out_str (stdout, 10, 0, mpc_imagref (p->value.complex), + GFC_RND_MODE); if (p->ts.kind != gfc_default_complex_kind) fprintf (dumpfile, "_%d", p->ts.kind); diff -rup orig/egcc-SVN20090616/gcc/fortran/expr.c egcc-SVN20090616/gcc/fortran/expr.c --- orig/egcc-SVN20090616/gcc/fortran/expr.c 2009-06-12 02:01:45.000000000 +0200 +++ egcc-SVN20090616/gcc/fortran/expr.c 2009-06-17 02:50:55.000000000 +0200 @@ -156,8 +156,12 @@ free_expr0 (gfc_expr *e) break; case BT_COMPLEX: +#ifdef HAVE_mpc + mpc_clear (e->value.complex); +#else mpfr_clear (e->value.complex.r); mpfr_clear (e->value.complex.i); +#endif break; default: @@ -439,10 +443,15 @@ gfc_copy_expr (gfc_expr *p) case BT_COMPLEX: gfc_set_model_kind (q->ts.kind); +#ifdef HAVE_mpc + mpc_init2 (q->value.complex, mpfr_get_default_prec()); + mpc_set (q->value.complex, p->value.complex, GFC_MPC_RND_MODE); +#else mpfr_init (q->value.complex.r); mpfr_init (q->value.complex.i); mpfr_set (q->value.complex.r, p->value.complex.r, GFC_RND_MODE); mpfr_set (q->value.complex.i, p->value.complex.i, GFC_RND_MODE); +#endif break; case BT_CHARACTER: diff -rup orig/egcc-SVN20090616/gcc/fortran/module.c egcc-SVN20090616/gcc/fortran/module.c --- orig/egcc-SVN20090616/gcc/fortran/module.c 2009-06-04 02:01:57.000000000 +0200 +++ egcc-SVN20090616/gcc/fortran/module.c 2009-06-17 02:50:29.000000000 +0200 @@ -3027,8 +3027,8 @@ mio_expr (gfc_expr **ep) case BT_COMPLEX: gfc_set_model_kind (e->ts.kind); - mio_gmp_real (&e->value.complex.r); - mio_gmp_real (&e->value.complex.i); + mio_gmp_real (&mpc_realref (e->value.complex)); + mio_gmp_real (&mpc_imagref (e->value.complex)); break; case BT_LOGICAL: diff -rup orig/egcc-SVN20090616/gcc/fortran/resolve.c egcc-SVN20090616/gcc/fortran/resolve.c --- orig/egcc-SVN20090616/gcc/fortran/resolve.c 2009-06-13 02:02:16.000000000 +0200 +++ egcc-SVN20090616/gcc/fortran/resolve.c 2009-06-17 02:50:00.000000000 +0200 @@ -7610,31 +7610,39 @@ build_default_init_expr (gfc_symbol *sym break; case BT_COMPLEX: +#ifdef HAVE_mpc + mpc_init2 (init_expr->value.complex, mpfr_get_default_prec()); +#else mpfr_init (init_expr->value.complex.r); mpfr_init (init_expr->value.complex.i); +#endif switch (gfc_option.flag_init_real) { case GFC_INIT_REAL_SNAN: init_expr->is_snan = 1; /* Fall through. */ case GFC_INIT_REAL_NAN: - mpfr_set_nan (init_expr->value.complex.r); - mpfr_set_nan (init_expr->value.complex.i); + mpfr_set_nan (mpc_realref (init_expr->value.complex)); + mpfr_set_nan (mpc_imagref (init_expr->value.complex)); break; case GFC_INIT_REAL_INF: - mpfr_set_inf (init_expr->value.complex.r, 1); - mpfr_set_inf (init_expr->value.complex.i, 1); + mpfr_set_inf (mpc_realref (init_expr->value.complex), 1); + mpfr_set_inf (mpc_imagref (init_expr->value.complex), 1); break; case GFC_INIT_REAL_NEG_INF: - mpfr_set_inf (init_expr->value.complex.r, -1); - mpfr_set_inf (init_expr->value.complex.i, -1); + mpfr_set_inf (mpc_realref (init_expr->value.complex), -1); + mpfr_set_inf (mpc_imagref (init_expr->value.complex), -1); break; case GFC_INIT_REAL_ZERO: +#ifdef HAVE_mpc + mpc_set_ui (init_expr->value.complex, 0, GFC_MPC_RND_MODE); +#else mpfr_set_ui (init_expr->value.complex.r, 0.0, GFC_RND_MODE); mpfr_set_ui (init_expr->value.complex.i, 0.0, GFC_RND_MODE); +#endif break; default: diff -rup orig/egcc-SVN20090616/gcc/fortran/simplify.c egcc-SVN20090616/gcc/fortran/simplify.c --- orig/egcc-SVN20090616/gcc/fortran/simplify.c 2009-06-12 02:01:45.000000000 +0200 +++ egcc-SVN20090616/gcc/fortran/simplify.c 2009-06-17 02:49:23.000000000 +0200 @@ -214,26 +214,6 @@ convert_mpz_to_signed (mpz_t x, int bits } } -/* Helper function to convert to/from mpfr_t & mpc_t and call the - supplied mpc function on the respective values. */ - -#ifdef HAVE_mpc -static void -call_mpc_func (mpfr_ptr result_re, mpfr_ptr result_im, - mpfr_srcptr input_re, mpfr_srcptr input_im, - int (*func)(mpc_ptr, mpc_srcptr, mpc_rnd_t)) -{ - mpc_t c; - mpc_init2 (c, mpfr_get_default_prec()); - mpc_set_fr_fr (c, input_re, input_im, GFC_MPC_RND_MODE); - func (c, c, GFC_MPC_RND_MODE); - mpfr_set (result_re, mpc_realref (c), GFC_RND_MODE); - mpfr_set (result_im, mpc_imagref (c), GFC_RND_MODE); - mpc_clear (c); -} -#endif - - /* Test that the expression is an constant array. */ static bool @@ -303,8 +283,12 @@ init_result_expr (gfc_expr *e, int init, break; case BT_COMPLEX: +#ifdef HAVE_mpc + mpc_set_si (e->value.complex, init, GFC_MPC_RND_MODE); +#else mpfr_set_si (e->value.complex.r, init, GFC_RND_MODE); mpfr_set_si (e->value.complex.i, 0, GFC_RND_MODE); +#endif break; case BT_CHARACTER: @@ -660,8 +644,12 @@ gfc_simplify_abs (gfc_expr *e) gfc_set_model_kind (e->ts.kind); +#ifdef HAVE_mpc + mpc_abs (result->value.real, e->value.complex, GFC_RND_MODE); +#else mpfr_hypot (result->value.real, e->value.complex.r, e->value.complex.i, GFC_RND_MODE); +#endif result = range_check (result, "CABS"); break; @@ -867,7 +855,7 @@ gfc_simplify_aimag (gfc_expr *e) return NULL; result = gfc_constant_result (BT_REAL, e->ts.kind, &e->where); - mpfr_set (result->value.real, e->value.complex.i, GFC_RND_MODE); + mpfr_set (result->value.real, mpc_imagref (e->value.complex), GFC_RND_MODE); return range_check (result, "AIMAG"); } @@ -1286,22 +1274,36 @@ simplify_cmplx (const char *name, gfc_ex result = gfc_constant_result (BT_COMPLEX, kind, &x->where); +#ifndef HAVE_mpc mpfr_set_ui (result->value.complex.i, 0, GFC_RND_MODE); +#endif switch (x->ts.type) { case BT_INTEGER: if (!x->is_boz) +#ifdef HAVE_mpc + mpc_set_z (result->value.complex, x->value.integer, GFC_MPC_RND_MODE); +#else mpfr_set_z (result->value.complex.r, x->value.integer, GFC_RND_MODE); +#endif break; case BT_REAL: +#ifdef HAVE_mpc + mpc_set_fr (result->value.complex, x->value.real, GFC_RND_MODE); +#else mpfr_set (result->value.complex.r, x->value.real, GFC_RND_MODE); +#endif break; case BT_COMPLEX: +#ifdef HAVE_mpc + mpc_set (result->value.complex, x->value.complex, GFC_MPC_RND_MODE); +#else mpfr_set (result->value.complex.r, x->value.complex.r, GFC_RND_MODE); mpfr_set (result->value.complex.i, x->value.complex.i, GFC_RND_MODE); +#endif break; default: @@ -1314,12 +1316,13 @@ simplify_cmplx (const char *name, gfc_ex { case BT_INTEGER: if (!y->is_boz) - mpfr_set_z (result->value.complex.i, y->value.integer, - GFC_RND_MODE); + mpfr_set_z (mpc_imagref (result->value.complex), + y->value.integer, GFC_RND_MODE); break; case BT_REAL: - mpfr_set (result->value.complex.i, y->value.real, GFC_RND_MODE); + mpfr_set (mpc_imagref (result->value.complex), + y->value.real, GFC_RND_MODE); break; default: @@ -1336,7 +1339,8 @@ simplify_cmplx (const char *name, gfc_ex ts.type = BT_REAL; if (!gfc_convert_boz (x, &ts)) return &gfc_bad_expr; - mpfr_set (result->value.complex.r, x->value.real, GFC_RND_MODE); + mpfr_set (mpc_realref (result->value.complex), + x->value.real, GFC_RND_MODE); } if (y && y->is_boz) @@ -1347,7 +1351,8 @@ simplify_cmplx (const char *name, gfc_ex ts.type = BT_REAL; if (!gfc_convert_boz (y, &ts)) return &gfc_bad_expr; - mpfr_set (result->value.complex.i, y->value.real, GFC_RND_MODE); + mpfr_set (mpc_imagref (result->value.complex), + y->value.real, GFC_RND_MODE); } return range_check (result, name); @@ -1429,7 +1434,11 @@ gfc_simplify_conjg (gfc_expr *e) return NULL; result = gfc_copy_expr (e); +#ifdef HAVE_mpc + mpc_conj (result->value.complex, result->value.complex, GFC_MPC_RND_MODE); +#else mpfr_neg (result->value.complex.i, result->value.complex.i, GFC_RND_MODE); +#endif return range_check (result, "CONJG"); } @@ -1453,8 +1462,7 @@ gfc_simplify_cos (gfc_expr *x) case BT_COMPLEX: gfc_set_model_kind (x->ts.kind); #ifdef HAVE_mpc - call_mpc_func (result->value.complex.r, result->value.complex.i, - x->value.complex.r, x->value.complex.i, mpc_cos); + mpc_cos (result->value.complex, x->value.complex, GFC_MPC_RND_MODE); #else { mpfr_t xp, xq; @@ -1898,8 +1906,7 @@ gfc_simplify_exp (gfc_expr *x) case BT_COMPLEX: gfc_set_model_kind (x->ts.kind); #ifdef HAVE_mpc - call_mpc_func (result->value.complex.r, result->value.complex.i, - x->value.complex.r, x->value.complex.i, mpc_exp); + mpc_exp (result->value.complex, x->value.complex, GFC_MPC_RND_MODE); #else { mpfr_t xp, xq; @@ -3281,8 +3288,8 @@ gfc_simplify_log (gfc_expr *x) break; case BT_COMPLEX: - if ((mpfr_sgn (x->value.complex.r) == 0) - && (mpfr_sgn (x->value.complex.i) == 0)) + if ((mpfr_sgn (mpc_realref (x->value.complex)) == 0) + && (mpfr_sgn (mpc_imagref (x->value.complex)) == 0)) { gfc_error ("Complex argument of LOG at %L cannot be zero", &x->where); @@ -3292,8 +3299,7 @@ gfc_simplify_log (gfc_expr *x) gfc_set_model_kind (x->ts.kind); #ifdef HAVE_mpc - call_mpc_func (result->value.complex.r, result->value.complex.i, - x->value.complex.r, x->value.complex.i, mpc_log); + mpc_log (result->value.complex, x->value.complex, GFC_MPC_RND_MODE); #else { mpfr_t xr, xi; @@ -4204,7 +4210,11 @@ gfc_simplify_realpart (gfc_expr *e) return NULL; result = gfc_constant_result (BT_REAL, e->ts.kind, &e->where); +#ifdef HAVE_mpc + mpc_real (result->value.real, e->value.complex, GFC_RND_MODE); +#else mpfr_set (result->value.real, e->value.complex.r, GFC_RND_MODE); +#endif return range_check (result, "REALPART"); } @@ -4986,8 +4996,7 @@ gfc_simplify_sin (gfc_expr *x) case BT_COMPLEX: gfc_set_model (x->value.real); #ifdef HAVE_mpc - call_mpc_func (result->value.complex.r, result->value.complex.i, - x->value.complex.r, x->value.complex.i, mpc_sin); + mpc_sin (result->value.complex, x->value.complex, GFC_MPC_RND_MODE); #else { mpfr_t xp, xq; @@ -5200,8 +5209,7 @@ gfc_simplify_sqrt (gfc_expr *e) case BT_COMPLEX: gfc_set_model (e->value.real); #ifdef HAVE_mpc - call_mpc_func (result->value.complex.r, result->value.complex.i, - e->value.complex.r, e->value.complex.i, mpc_sqrt); + mpc_sqrt (result->value.complex, e->value.complex, GFC_MPC_RND_MODE); #else { /* Formula taken from Numerical Recipes to avoid over- and diff -rup orig/egcc-SVN20090616/gcc/fortran/target-memory.c egcc-SVN20090616/gcc/fortran/target-memory.c --- orig/egcc-SVN20090616/gcc/fortran/target-memory.c 2009-03-27 23:23:36.000000000 +0100 +++ egcc-SVN20090616/gcc/fortran/target-memory.c 2009-06-17 02:55:49.000000000 +0200 @@ -266,8 +266,10 @@ gfc_target_encode_expr (gfc_expr *source return encode_float (source->ts.kind, source->value.real, buffer, buffer_size); case BT_COMPLEX: - return encode_complex (source->ts.kind, source->value.complex.r, - source->value.complex.i, buffer, buffer_size); + return encode_complex (source->ts.kind, + mpc_realref (source->value.complex), + mpc_imagref (source->value.complex), + buffer, buffer_size); case BT_LOGICAL: return encode_logical (source->ts.kind, source->value.logical, buffer, buffer_size); @@ -368,12 +370,28 @@ gfc_interpret_float (int kind, unsigned int gfc_interpret_complex (int kind, unsigned char *buffer, size_t buffer_size, - mpfr_t real, mpfr_t imaginary) +#ifdef HAVE_mpc + mpc_t complex +#else + mpfr_t real, mpfr_t imaginary +#endif + ) { int size; - size = gfc_interpret_float (kind, &buffer[0], buffer_size, real); + size = gfc_interpret_float (kind, &buffer[0], buffer_size, +#ifdef HAVE_mpc + mpc_realref (complex) +#else + real +#endif + ); size += gfc_interpret_float (kind, &buffer[size], buffer_size - size, - imaginary); +#ifdef HAVE_mpc + mpc_imagref (complex) +#else + imaginary +#endif + ); return size; } @@ -520,8 +538,13 @@ gfc_target_interpret_expr (unsigned char case BT_COMPLEX: result->representation.length = gfc_interpret_complex (result->ts.kind, buffer, buffer_size, +#ifdef HAVE_mpc + result->value.complex +#else result->value.complex.r, - result->value.complex.i); + result->value.complex.i +#endif + ); break; case BT_LOGICAL: @@ -722,10 +745,19 @@ gfc_convert_boz (gfc_expr *expr, gfc_typ } else { +#ifdef HAVE_mpc + mpc_init2 (expr->value.complex, mpfr_get_default_prec()); +#else mpfr_init (expr->value.complex.r); mpfr_init (expr->value.complex.i); +#endif gfc_interpret_complex (ts->kind, buffer, buffer_size, - expr->value.complex.r, expr->value.complex.i); +#ifdef HAVE_mpc + expr->value.complex +#else + expr->value.complex.r, expr->value.complex.i +#endif + ); } expr->is_boz = 0; expr->ts.type = ts->type; diff -rup orig/egcc-SVN20090616/gcc/fortran/target-memory.h egcc-SVN20090616/gcc/fortran/target-memory.h --- orig/egcc-SVN20090616/gcc/fortran/target-memory.h 2008-05-19 02:02:28.000000000 +0200 +++ egcc-SVN20090616/gcc/fortran/target-memory.h 2009-06-17 02:55:49.000000000 +0200 @@ -39,7 +39,11 @@ int gfc_target_encode_expr (gfc_expr *, int gfc_interpret_integer (int, unsigned char *, size_t, mpz_t); int gfc_interpret_float (int, unsigned char *, size_t, mpfr_t); +#ifdef HAVE_mpc +int gfc_interpret_complex (int, unsigned char *, size_t, mpc_t); +#else int gfc_interpret_complex (int, unsigned char *, size_t, mpfr_t, mpfr_t); +#endif int gfc_interpret_logical (int, unsigned char *, size_t, int *); int gfc_interpret_character (unsigned char *, size_t, gfc_expr *); int gfc_interpret_derived (unsigned char *, size_t, gfc_expr *); diff -rup orig/egcc-SVN20090616/gcc/fortran/trans-const.c egcc-SVN20090616/gcc/fortran/trans-const.c --- orig/egcc-SVN20090616/gcc/fortran/trans-const.c 2009-04-23 02:02:19.000000000 +0200 +++ egcc-SVN20090616/gcc/fortran/trans-const.c 2009-06-17 02:51:49.000000000 +0200 @@ -307,9 +307,9 @@ gfc_conv_constant_to_tree (gfc_expr * ex expr->representation.string)); else { - tree real = gfc_conv_mpfr_to_tree (expr->value.complex.r, + tree real = gfc_conv_mpfr_to_tree (mpc_realref (expr->value.complex), expr->ts.kind, expr->is_snan); - tree imag = gfc_conv_mpfr_to_tree (expr->value.complex.i, + tree imag = gfc_conv_mpfr_to_tree (mpc_imagref (expr->value.complex), expr->ts.kind, expr->is_snan); return build_complex (gfc_typenode_for_spec (&expr->ts), diff -rup orig/egcc-SVN20090616/gcc/fortran/trans-expr.c egcc-SVN20090616/gcc/fortran/trans-expr.c --- orig/egcc-SVN20090616/gcc/fortran/trans-expr.c 2009-06-13 02:02:16.000000000 +0200 +++ egcc-SVN20090616/gcc/fortran/trans-expr.c 2009-06-17 02:48:36.000000000 +0200 @@ -4405,10 +4405,10 @@ is_zero_initializer_p (gfc_expr * expr) return expr->value.logical == 0; case BT_COMPLEX: - return mpfr_zero_p (expr->value.complex.r) - && MPFR_SIGN (expr->value.complex.r) >= 0 - && mpfr_zero_p (expr->value.complex.i) - && MPFR_SIGN (expr->value.complex.i) >= 0; + return mpfr_zero_p (mpc_realref (expr->value.complex)) + && MPFR_SIGN (mpc_realref (expr->value.complex)) >= 0 + && mpfr_zero_p (mpc_imagref (expr->value.complex)) + && MPFR_SIGN (mpc_imagref (expr->value.complex)) >= 0; default: break;
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |