Index: arith.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/fortran/arith.c,v retrieving revision 1.25 diff -c -p -r1.25 arith.c *** arith.c 26 Mar 2005 18:33:53 -0000 1.25 --- arith.c 13 Apr 2005 22:36:06 -0000 *************** gfc_arith_init_1 (void) *** 259,264 **** --- 274,287 ---- mpfr_init (real_info->tiny); mpfr_set (real_info->tiny, b, GFC_RND_MODE); + /* subnormal (x) = b**(emin - digit + 1) */ + mpfr_set_ui (b, real_info->radix, GFC_RND_MODE); + mpfr_pow_si (b, b, real_info->min_exponent - real_info->digits + 1, + GFC_RND_MODE); + + mpfr_init (real_info->subnormal); + mpfr_set (real_info->subnormal, b, GFC_RND_MODE); + /* epsilon(x) = b**(1-p) */ mpfr_set_ui (b, real_info->radix, GFC_RND_MODE); mpfr_pow_si (b, b, 1 - real_info->digits, GFC_RND_MODE); *************** gfc_check_real_range (mpfr_t p, int kind *** 374,380 **** retval = ARITH_OK; else if (mpfr_cmp (q, gfc_real_kinds[i].huge) > 0) retval = ARITH_OVERFLOW; ! else if (mpfr_cmp (q, gfc_real_kinds[i].tiny) < 0) retval = ARITH_UNDERFLOW; else retval = ARITH_OK; --- 405,411 ---- retval = ARITH_OK; else if (mpfr_cmp (q, gfc_real_kinds[i].huge) > 0) retval = ARITH_OVERFLOW; ! else if (mpfr_cmp (q, gfc_real_kinds[i].subnormal) < 0) retval = ARITH_UNDERFLOW; else retval = ARITH_OK; Index: gfortran.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/fortran/gfortran.h,v retrieving revision 1.63 diff -c -p -r1.63 gfortran.h *** gfortran.h 30 Mar 2005 00:30:50 -0000 1.63 --- gfortran.h 13 Apr 2005 22:36:06 -0000 *************** extern gfc_logical_info gfc_logical_kind *** 1146,1152 **** typedef struct { ! mpfr_t epsilon, huge, tiny; int kind, radix, digits, min_exponent, max_exponent; int range, precision; --- 1146,1152 ---- typedef struct { ! mpfr_t epsilon, huge, tiny, subnormal; int kind, radix, digits, min_exponent, max_exponent; int range, precision; Index: simplify.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/fortran/simplify.c,v retrieving revision 1.24 diff -c -p -r1.24 simplify.c *** simplify.c 12 Apr 2005 14:10:38 -0000 1.24 --- simplify.c 13 Apr 2005 22:36:06 -0000 *************** gfc_simplify_nearest (gfc_expr * x, gfc_ *** 2293,2313 **** if (direction > 0) mpfr_add (result->value.real, ! x->value.real, gfc_real_kinds[k].tiny, GFC_RND_MODE); else mpfr_sub (result->value.real, ! x->value.real, gfc_real_kinds[k].tiny, GFC_RND_MODE); ! ! #if 0 ! /* FIXME: This gives an arithmetic error because we compare ! against tiny when range-checking. Also, it doesn't give the ! right value. */ ! /* TINY is the smallest model number, we want the smallest ! machine representable number. Therefore we have to shift the ! value to the right by the number of digits - 1. */ ! mpfr_div_2ui (result->value.real, result->value.real, ! gfc_real_kinds[k].precision - 1, GFC_RND_MODE); ! #endif } else { --- 2293,2302 ---- if (direction > 0) mpfr_add (result->value.real, ! x->value.real, gfc_real_kinds[k].subnormal, GFC_RND_MODE); else mpfr_sub (result->value.real, ! x->value.real, gfc_real_kinds[k].subnormal, GFC_RND_MODE); } else {