Allow real_format to be passed to more real.h functions
Most real.h routines used machine modes to specify the format of an operation and converted that to a float_format * internally. Some also had alternative versions that accepted a float_format *. In an upcoming patch it seemed more convenient for the callers I was adding to use float_format directly, since the callers need to examine the format themselves for other reasons. This patch therefore replaces the machine_mode arguments with a new class that allows both machine modes and float_format pointers to be used. Tested on x86_64-linux-gnu, arm-linux-gnueabi and aarch64-linux-gnu. gcc/ * real.h (format_helper): New. (real_convert, exact_real_truncate, real_from_string3, real_to_target) (real_from_target, real_nan, real_2expN, real_value_truncate) (significand_size, real_from_string2, exact_real_inverse) (exact_real_inverse, real_powi, real_trunc, real_floor, real_ceil) (real_round, real_isinteger, real_from_integer): Replace machine_mode arguments with format_helper arguments. * real.c (exact_real_inverse, real_from_string2, real_from_string3) (real_from_integer, real_nan, real_2expN, real_convert) (real_value_truncate, exact_real_truncate, real_to_target) (real_from_target, significand_size, real_powi, real_trunc) (real_floor, real_ceil, real_round, real_isinteger): Replace machine_mode arguments with format_helper arguments. (real_to_target_fmt, real_from_target_fmt): Delete. * dfp.h (decimal_real_convert): Replace mode argument with real_format. * dfp.c (decimal_to_binary, decimal_real_convert): Replace mode argument with real_format. * builtins.c (do_real_to_int_conversion): Update type of fn argument. gcc/java/ * jcf-parse.c (get_constant): Use real_from_target rather than real_from_target_fmt. From-SVN: r229581
This commit is contained in:
parent
4ff7defd04
commit
f16e6077ea
|
@ -1,3 +1,24 @@
|
|||
2015-10-30 Richard Sandiford <richard.sandiford@arm.com>
|
||||
|
||||
* real.h (format_helper): New.
|
||||
(real_convert, exact_real_truncate, real_from_string3, real_to_target)
|
||||
(real_from_target, real_nan, real_2expN, real_value_truncate)
|
||||
(significand_size, real_from_string2, exact_real_inverse)
|
||||
(exact_real_inverse, real_powi, real_trunc, real_floor, real_ceil)
|
||||
(real_round, real_isinteger, real_from_integer): Replace
|
||||
machine_mode arguments with format_helper arguments.
|
||||
* real.c (exact_real_inverse, real_from_string2, real_from_string3)
|
||||
(real_from_integer, real_nan, real_2expN, real_convert)
|
||||
(real_value_truncate, exact_real_truncate, real_to_target)
|
||||
(real_from_target, significand_size, real_powi, real_trunc)
|
||||
(real_floor, real_ceil, real_round, real_isinteger): Replace
|
||||
machine_mode arguments with format_helper arguments.
|
||||
(real_to_target_fmt, real_from_target_fmt): Delete.
|
||||
* dfp.h (decimal_real_convert): Replace mode argument with real_format.
|
||||
* dfp.c (decimal_to_binary, decimal_real_convert): Replace mode
|
||||
argument with real_format.
|
||||
* builtins.c (do_real_to_int_conversion): Update type of fn argument.
|
||||
|
||||
2015-10-30 Richard Sandiford <richard.sandiford@arm.com>
|
||||
|
||||
* fixed-value.c (check_real_for_fixed_mode, fixed_from_string)
|
||||
|
|
|
@ -7273,7 +7273,7 @@ fold_builtin_strlen (location_t loc, tree type, tree arg)
|
|||
|
||||
static tree
|
||||
do_real_to_int_conversion (tree itype, tree arg,
|
||||
void (*fn) (REAL_VALUE_TYPE *, machine_mode,
|
||||
void (*fn) (REAL_VALUE_TYPE *, format_helper,
|
||||
const REAL_VALUE_TYPE *))
|
||||
{
|
||||
if (TREE_CODE (arg) != REAL_CST || TREE_OVERFLOW (arg))
|
||||
|
|
10
gcc/dfp.c
10
gcc/dfp.c
|
@ -343,13 +343,13 @@ decode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED,
|
|||
|
||||
static void
|
||||
decimal_to_binary (REAL_VALUE_TYPE *to, const REAL_VALUE_TYPE *from,
|
||||
machine_mode mode)
|
||||
const real_format *fmt)
|
||||
{
|
||||
char string[256];
|
||||
const decimal128 *const d128 = (const decimal128 *) from->sig;
|
||||
|
||||
decimal128ToString (d128, string);
|
||||
real_from_string3 (to, string, mode);
|
||||
real_from_string3 (to, string, fmt);
|
||||
}
|
||||
|
||||
|
||||
|
@ -459,15 +459,13 @@ decimal_round_for_format (const struct real_format *fmt, REAL_VALUE_TYPE *r)
|
|||
binary and decimal types. */
|
||||
|
||||
void
|
||||
decimal_real_convert (REAL_VALUE_TYPE *r, machine_mode mode,
|
||||
decimal_real_convert (REAL_VALUE_TYPE *r, const real_format *fmt,
|
||||
const REAL_VALUE_TYPE *a)
|
||||
{
|
||||
const struct real_format *fmt = REAL_MODE_FORMAT (mode);
|
||||
|
||||
if (a->decimal && fmt->b == 10)
|
||||
return;
|
||||
if (a->decimal)
|
||||
decimal_to_binary (r, a, mode);
|
||||
decimal_to_binary (r, a, fmt);
|
||||
else
|
||||
decimal_from_binary (r, a);
|
||||
}
|
||||
|
|
|
@ -34,7 +34,8 @@ void encode_decimal128 (const struct real_format *fmt, long *, const REAL_VALUE_
|
|||
int decimal_do_compare (const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, int);
|
||||
void decimal_real_from_string (REAL_VALUE_TYPE *, const char *);
|
||||
void decimal_round_for_format (const struct real_format *, REAL_VALUE_TYPE *);
|
||||
void decimal_real_convert (REAL_VALUE_TYPE *, machine_mode, const REAL_VALUE_TYPE *);
|
||||
void decimal_real_convert (REAL_VALUE_TYPE *, const real_format *,
|
||||
const REAL_VALUE_TYPE *);
|
||||
void decimal_real_to_decimal (char *, const REAL_VALUE_TYPE *, size_t, size_t, int);
|
||||
void decimal_do_fix_trunc (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *);
|
||||
void decimal_real_maxval (REAL_VALUE_TYPE *, int, machine_mode);
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2015-10-30 Richard Sandiford <richard.sandiford@arm.com>
|
||||
|
||||
* jcf-parse.c (get_constant): Use real_from_target rather than
|
||||
real_from_target_fmt.
|
||||
|
||||
2015-10-29 Andrew MacLeod <amacleod@redhat.com>
|
||||
|
||||
* boehm.c: Reorder #include's and remove duplicates.
|
||||
|
|
|
@ -1058,7 +1058,7 @@ get_constant (JCF *jcf, int index)
|
|||
long buf = num;
|
||||
REAL_VALUE_TYPE d;
|
||||
|
||||
real_from_target_fmt (&d, &buf, &ieee_single_format);
|
||||
real_from_target (&d, &buf, &ieee_single_format);
|
||||
value = build_real (float_type_node, d);
|
||||
break;
|
||||
}
|
||||
|
@ -1076,7 +1076,7 @@ get_constant (JCF *jcf, int index)
|
|||
else
|
||||
buf[0] = lo, buf[1] = hi;
|
||||
|
||||
real_from_target_fmt (&d, buf, &ieee_double_format);
|
||||
real_from_target (&d, buf, &ieee_double_format);
|
||||
value = build_real (double_type_node, d);
|
||||
break;
|
||||
}
|
||||
|
|
163
gcc/real.c
163
gcc/real.c
|
@ -1266,11 +1266,11 @@ real_identical (const REAL_VALUE_TYPE *a, const REAL_VALUE_TYPE *b)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* Try to change R into its exact multiplicative inverse in machine
|
||||
mode MODE. Return true if successful. */
|
||||
/* Try to change R into its exact multiplicative inverse in format FMT.
|
||||
Return true if successful. */
|
||||
|
||||
bool
|
||||
exact_real_inverse (machine_mode mode, REAL_VALUE_TYPE *r)
|
||||
exact_real_inverse (format_helper fmt, REAL_VALUE_TYPE *r)
|
||||
{
|
||||
const REAL_VALUE_TYPE *one = real_digit (1);
|
||||
REAL_VALUE_TYPE u;
|
||||
|
@ -1286,9 +1286,9 @@ exact_real_inverse (machine_mode mode, REAL_VALUE_TYPE *r)
|
|||
if (r->sig[SIGSZ-1] != SIG_MSB)
|
||||
return false;
|
||||
|
||||
/* Find the inverse and truncate to the required mode. */
|
||||
/* Find the inverse and truncate to the required format. */
|
||||
do_divide (&u, one, r);
|
||||
real_convert (&u, mode, &u);
|
||||
real_convert (&u, fmt, &u);
|
||||
|
||||
/* The rounding may have overflowed. */
|
||||
if (u.cl != rvc_normal)
|
||||
|
@ -2104,35 +2104,36 @@ real_from_string (REAL_VALUE_TYPE *r, const char *str)
|
|||
/* Legacy. Similar, but return the result directly. */
|
||||
|
||||
REAL_VALUE_TYPE
|
||||
real_from_string2 (const char *s, machine_mode mode)
|
||||
real_from_string2 (const char *s, format_helper fmt)
|
||||
{
|
||||
REAL_VALUE_TYPE r;
|
||||
|
||||
real_from_string (&r, s);
|
||||
if (mode != VOIDmode)
|
||||
real_convert (&r, mode, &r);
|
||||
if (fmt)
|
||||
real_convert (&r, fmt, &r);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Initialize R from string S and desired MODE. */
|
||||
/* Initialize R from string S and desired format FMT. */
|
||||
|
||||
void
|
||||
real_from_string3 (REAL_VALUE_TYPE *r, const char *s, machine_mode mode)
|
||||
real_from_string3 (REAL_VALUE_TYPE *r, const char *s, format_helper fmt)
|
||||
{
|
||||
if (DECIMAL_FLOAT_MODE_P (mode))
|
||||
if (fmt.decimal_p ())
|
||||
decimal_real_from_string (r, s);
|
||||
else
|
||||
real_from_string (r, s);
|
||||
|
||||
if (mode != VOIDmode)
|
||||
real_convert (r, mode, r);
|
||||
if (fmt)
|
||||
real_convert (r, fmt, r);
|
||||
}
|
||||
|
||||
/* Initialize R from the wide_int VAL_IN. The MODE is not VOIDmode,*/
|
||||
/* Initialize R from the wide_int VAL_IN. Round it to format FMT if
|
||||
FMT is nonnull. */
|
||||
|
||||
void
|
||||
real_from_integer (REAL_VALUE_TYPE *r, machine_mode mode,
|
||||
real_from_integer (REAL_VALUE_TYPE *r, format_helper fmt,
|
||||
const wide_int_ref &val_in, signop sgn)
|
||||
{
|
||||
if (val_in == 0)
|
||||
|
@ -2216,10 +2217,10 @@ real_from_integer (REAL_VALUE_TYPE *r, machine_mode mode,
|
|||
normalize (r);
|
||||
}
|
||||
|
||||
if (DECIMAL_FLOAT_MODE_P (mode))
|
||||
if (fmt.decimal_p ())
|
||||
decimal_from_integer (r);
|
||||
else if (mode != VOIDmode)
|
||||
real_convert (r, mode, r);
|
||||
else if (fmt)
|
||||
real_convert (r, fmt, r);
|
||||
}
|
||||
|
||||
/* Render R, an integral value, as a floating point constant with no
|
||||
|
@ -2448,13 +2449,8 @@ real_inf (REAL_VALUE_TYPE *r)
|
|||
|
||||
bool
|
||||
real_nan (REAL_VALUE_TYPE *r, const char *str, int quiet,
|
||||
machine_mode mode)
|
||||
format_helper fmt)
|
||||
{
|
||||
const struct real_format *fmt;
|
||||
|
||||
fmt = REAL_MODE_FORMAT (mode);
|
||||
gcc_assert (fmt);
|
||||
|
||||
if (*str == 0)
|
||||
{
|
||||
if (quiet)
|
||||
|
@ -2574,7 +2570,7 @@ real_maxval (REAL_VALUE_TYPE *r, int sign, machine_mode mode)
|
|||
/* Fills R with 2**N. */
|
||||
|
||||
void
|
||||
real_2expN (REAL_VALUE_TYPE *r, int n, machine_mode fmode)
|
||||
real_2expN (REAL_VALUE_TYPE *r, int n, format_helper fmt)
|
||||
{
|
||||
memset (r, 0, sizeof (*r));
|
||||
|
||||
|
@ -2589,8 +2585,8 @@ real_2expN (REAL_VALUE_TYPE *r, int n, machine_mode fmode)
|
|||
SET_REAL_EXP (r, n);
|
||||
r->sig[SIGSZ-1] = SIG_MSB;
|
||||
}
|
||||
if (DECIMAL_FLOAT_MODE_P (fmode))
|
||||
decimal_real_convert (r, fmode, r);
|
||||
if (fmt.decimal_p ())
|
||||
decimal_real_convert (r, fmt, r);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2612,7 +2608,7 @@ round_for_format (const struct real_format *fmt, REAL_VALUE_TYPE *r)
|
|||
(e.g. -O0 on '_Decimal32 x = 1.0 + 2.0dd'), but have not
|
||||
investigated whether this convert needs to be here, or
|
||||
something else is missing. */
|
||||
decimal_real_convert (r, DFmode, r);
|
||||
decimal_real_convert (r, REAL_MODE_FORMAT (DFmode), r);
|
||||
}
|
||||
|
||||
p2 = fmt->p;
|
||||
|
@ -2718,21 +2714,16 @@ round_for_format (const struct real_format *fmt, REAL_VALUE_TYPE *r)
|
|||
clear_significand_below (r, np2);
|
||||
}
|
||||
|
||||
/* Extend or truncate to a new mode. */
|
||||
/* Extend or truncate to a new format. */
|
||||
|
||||
void
|
||||
real_convert (REAL_VALUE_TYPE *r, machine_mode mode,
|
||||
real_convert (REAL_VALUE_TYPE *r, format_helper fmt,
|
||||
const REAL_VALUE_TYPE *a)
|
||||
{
|
||||
const struct real_format *fmt;
|
||||
|
||||
fmt = REAL_MODE_FORMAT (mode);
|
||||
gcc_assert (fmt);
|
||||
|
||||
*r = *a;
|
||||
|
||||
if (a->decimal || fmt->b == 10)
|
||||
decimal_real_convert (r, mode, a);
|
||||
decimal_real_convert (r, fmt, a);
|
||||
|
||||
round_for_format (fmt, r);
|
||||
|
||||
|
@ -2744,32 +2735,28 @@ real_convert (REAL_VALUE_TYPE *r, machine_mode mode,
|
|||
/* Legacy. Likewise, except return the struct directly. */
|
||||
|
||||
REAL_VALUE_TYPE
|
||||
real_value_truncate (machine_mode mode, REAL_VALUE_TYPE a)
|
||||
real_value_truncate (format_helper fmt, REAL_VALUE_TYPE a)
|
||||
{
|
||||
REAL_VALUE_TYPE r;
|
||||
real_convert (&r, mode, &a);
|
||||
real_convert (&r, fmt, &a);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Return true if truncating to MODE is exact. */
|
||||
/* Return true if truncating to FMT is exact. */
|
||||
|
||||
bool
|
||||
exact_real_truncate (machine_mode mode, const REAL_VALUE_TYPE *a)
|
||||
exact_real_truncate (format_helper fmt, const REAL_VALUE_TYPE *a)
|
||||
{
|
||||
const struct real_format *fmt;
|
||||
REAL_VALUE_TYPE t;
|
||||
int emin2m1;
|
||||
|
||||
fmt = REAL_MODE_FORMAT (mode);
|
||||
gcc_assert (fmt);
|
||||
|
||||
/* Don't allow conversion to denormals. */
|
||||
emin2m1 = fmt->emin - 1;
|
||||
if (REAL_EXP (a) <= emin2m1)
|
||||
return false;
|
||||
|
||||
/* After conversion to the new mode, the value must be identical. */
|
||||
real_convert (&t, mode, a);
|
||||
/* After conversion to the new format, the value must be identical. */
|
||||
real_convert (&t, fmt, a);
|
||||
return real_identical (&t, a);
|
||||
}
|
||||
|
||||
|
@ -2780,8 +2767,8 @@ exact_real_truncate (machine_mode mode, const REAL_VALUE_TYPE *a)
|
|||
Legacy: return word 0 for implementing REAL_VALUE_TO_TARGET_SINGLE. */
|
||||
|
||||
long
|
||||
real_to_target_fmt (long *buf, const REAL_VALUE_TYPE *r_orig,
|
||||
const struct real_format *fmt)
|
||||
real_to_target (long *buf, const REAL_VALUE_TYPE *r_orig,
|
||||
format_helper fmt)
|
||||
{
|
||||
REAL_VALUE_TYPE r;
|
||||
long buf1;
|
||||
|
@ -2796,62 +2783,32 @@ real_to_target_fmt (long *buf, const REAL_VALUE_TYPE *r_orig,
|
|||
return *buf;
|
||||
}
|
||||
|
||||
/* Similar, but look up the format from MODE. */
|
||||
|
||||
long
|
||||
real_to_target (long *buf, const REAL_VALUE_TYPE *r, machine_mode mode)
|
||||
{
|
||||
const struct real_format *fmt;
|
||||
|
||||
fmt = REAL_MODE_FORMAT (mode);
|
||||
gcc_assert (fmt);
|
||||
|
||||
return real_to_target_fmt (buf, r, fmt);
|
||||
}
|
||||
|
||||
/* Read R from the given target format. Read the words of the result
|
||||
in target word order in BUF. There are always 32 bits in each
|
||||
long, no matter the size of the host long. */
|
||||
|
||||
void
|
||||
real_from_target_fmt (REAL_VALUE_TYPE *r, const long *buf,
|
||||
const struct real_format *fmt)
|
||||
real_from_target (REAL_VALUE_TYPE *r, const long *buf, format_helper fmt)
|
||||
{
|
||||
(*fmt->decode) (fmt, r, buf);
|
||||
}
|
||||
|
||||
/* Similar, but look up the format from MODE. */
|
||||
|
||||
void
|
||||
real_from_target (REAL_VALUE_TYPE *r, const long *buf, machine_mode mode)
|
||||
{
|
||||
const struct real_format *fmt;
|
||||
|
||||
fmt = REAL_MODE_FORMAT (mode);
|
||||
gcc_assert (fmt);
|
||||
|
||||
(*fmt->decode) (fmt, r, buf);
|
||||
}
|
||||
|
||||
/* Return the number of bits of the largest binary value that the
|
||||
significand of MODE will hold. */
|
||||
significand of FMT will hold. */
|
||||
/* ??? Legacy. Should get access to real_format directly. */
|
||||
|
||||
int
|
||||
significand_size (machine_mode mode)
|
||||
significand_size (format_helper fmt)
|
||||
{
|
||||
const struct real_format *fmt;
|
||||
|
||||
fmt = REAL_MODE_FORMAT (mode);
|
||||
if (fmt == NULL)
|
||||
return 0;
|
||||
|
||||
if (fmt->b == 10)
|
||||
{
|
||||
/* Return the size in bits of the largest binary value that can be
|
||||
held by the decimal coefficient for this mode. This is one more
|
||||
held by the decimal coefficient for this format. This is one more
|
||||
than the number of bits required to hold the largest coefficient
|
||||
of this mode. */
|
||||
of this format. */
|
||||
double log2_10 = 3.3219281;
|
||||
return fmt->p * log2_10;
|
||||
}
|
||||
|
@ -4861,14 +4818,14 @@ const struct real_format real_internal_format =
|
|||
"real_internal"
|
||||
};
|
||||
|
||||
/* Calculate X raised to the integer exponent N in mode MODE and store
|
||||
/* Calculate X raised to the integer exponent N in format FMT and store
|
||||
the result in R. Return true if the result may be inexact due to
|
||||
loss of precision. The algorithm is the classic "left-to-right binary
|
||||
method" described in section 4.6.3 of Donald Knuth's "Seminumerical
|
||||
Algorithms", "The Art of Computer Programming", Volume 2. */
|
||||
|
||||
bool
|
||||
real_powi (REAL_VALUE_TYPE *r, machine_mode mode,
|
||||
real_powi (REAL_VALUE_TYPE *r, format_helper fmt,
|
||||
const REAL_VALUE_TYPE *x, HOST_WIDE_INT n)
|
||||
{
|
||||
unsigned HOST_WIDE_INT bit;
|
||||
|
@ -4910,27 +4867,27 @@ real_powi (REAL_VALUE_TYPE *r, machine_mode mode,
|
|||
if (neg)
|
||||
inexact |= do_divide (&t, &dconst1, &t);
|
||||
|
||||
real_convert (r, mode, &t);
|
||||
real_convert (r, fmt, &t);
|
||||
return inexact;
|
||||
}
|
||||
|
||||
/* Round X to the nearest integer not larger in absolute value, i.e.
|
||||
towards zero, placing the result in R in mode MODE. */
|
||||
towards zero, placing the result in R in format FMT. */
|
||||
|
||||
void
|
||||
real_trunc (REAL_VALUE_TYPE *r, machine_mode mode,
|
||||
real_trunc (REAL_VALUE_TYPE *r, format_helper fmt,
|
||||
const REAL_VALUE_TYPE *x)
|
||||
{
|
||||
do_fix_trunc (r, x);
|
||||
if (mode != VOIDmode)
|
||||
real_convert (r, mode, r);
|
||||
if (fmt)
|
||||
real_convert (r, fmt, r);
|
||||
}
|
||||
|
||||
/* Round X to the largest integer not greater in value, i.e. round
|
||||
down, placing the result in R in mode MODE. */
|
||||
down, placing the result in R in format FMT. */
|
||||
|
||||
void
|
||||
real_floor (REAL_VALUE_TYPE *r, machine_mode mode,
|
||||
real_floor (REAL_VALUE_TYPE *r, format_helper fmt,
|
||||
const REAL_VALUE_TYPE *x)
|
||||
{
|
||||
REAL_VALUE_TYPE t;
|
||||
|
@ -4938,17 +4895,17 @@ real_floor (REAL_VALUE_TYPE *r, machine_mode mode,
|
|||
do_fix_trunc (&t, x);
|
||||
if (! real_identical (&t, x) && x->sign)
|
||||
do_add (&t, &t, &dconstm1, 0);
|
||||
if (mode != VOIDmode)
|
||||
real_convert (r, mode, &t);
|
||||
if (fmt)
|
||||
real_convert (r, fmt, &t);
|
||||
else
|
||||
*r = t;
|
||||
}
|
||||
|
||||
/* Round X to the smallest integer not less then argument, i.e. round
|
||||
up, placing the result in R in mode MODE. */
|
||||
up, placing the result in R in format FMT. */
|
||||
|
||||
void
|
||||
real_ceil (REAL_VALUE_TYPE *r, machine_mode mode,
|
||||
real_ceil (REAL_VALUE_TYPE *r, format_helper fmt,
|
||||
const REAL_VALUE_TYPE *x)
|
||||
{
|
||||
REAL_VALUE_TYPE t;
|
||||
|
@ -4956,8 +4913,8 @@ real_ceil (REAL_VALUE_TYPE *r, machine_mode mode,
|
|||
do_fix_trunc (&t, x);
|
||||
if (! real_identical (&t, x) && ! x->sign)
|
||||
do_add (&t, &t, &dconst1, 0);
|
||||
if (mode != VOIDmode)
|
||||
real_convert (r, mode, &t);
|
||||
if (fmt)
|
||||
real_convert (r, fmt, &t);
|
||||
else
|
||||
*r = t;
|
||||
}
|
||||
|
@ -4966,13 +4923,13 @@ real_ceil (REAL_VALUE_TYPE *r, machine_mode mode,
|
|||
zero. */
|
||||
|
||||
void
|
||||
real_round (REAL_VALUE_TYPE *r, machine_mode mode,
|
||||
real_round (REAL_VALUE_TYPE *r, format_helper fmt,
|
||||
const REAL_VALUE_TYPE *x)
|
||||
{
|
||||
do_add (r, x, &dconsthalf, x->sign);
|
||||
do_fix_trunc (r, r);
|
||||
if (mode != VOIDmode)
|
||||
real_convert (r, mode, r);
|
||||
if (fmt)
|
||||
real_convert (r, fmt, r);
|
||||
}
|
||||
|
||||
/* Set the sign of R to the sign of X. */
|
||||
|
@ -4986,11 +4943,11 @@ real_copysign (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *x)
|
|||
/* Check whether the real constant value given is an integer. */
|
||||
|
||||
bool
|
||||
real_isinteger (const REAL_VALUE_TYPE *c, machine_mode mode)
|
||||
real_isinteger (const REAL_VALUE_TYPE *c, format_helper fmt)
|
||||
{
|
||||
REAL_VALUE_TYPE cint;
|
||||
|
||||
real_trunc (&cint, mode, c);
|
||||
real_trunc (&cint, fmt, c);
|
||||
return real_identical (c, &cint);
|
||||
}
|
||||
|
||||
|
|
69
gcc/real.h
69
gcc/real.h
|
@ -193,6 +193,28 @@ extern const struct real_format *
|
|||
(FLOAT_MODE_P (MODE) \
|
||||
&& FLOAT_MODE_FORMAT (MODE)->has_sign_dependent_rounding)
|
||||
|
||||
/* This class allows functions in this file to accept a floating-point
|
||||
format as either a mode or an explicit real_format pointer. In the
|
||||
former case the mode must be VOIDmode (which means "no particular
|
||||
format") or must satisfy SCALAR_FLOAT_MODE_P. */
|
||||
class format_helper
|
||||
{
|
||||
public:
|
||||
format_helper (const real_format *format) : m_format (format) {}
|
||||
format_helper (machine_mode m);
|
||||
const real_format *operator-> () const { return m_format; }
|
||||
operator const real_format *() const { return m_format; }
|
||||
|
||||
bool decimal_p () const { return m_format && m_format->b == 10; }
|
||||
|
||||
private:
|
||||
const real_format *m_format;
|
||||
};
|
||||
|
||||
inline format_helper::format_helper (machine_mode m)
|
||||
: m_format (m == VOIDmode ? 0 : REAL_MODE_FORMAT (m))
|
||||
{}
|
||||
|
||||
/* Declare functions in real.c. */
|
||||
|
||||
/* True if the given mode has a NaN representation and the treatment of
|
||||
|
@ -254,12 +276,12 @@ extern bool real_identical (const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *);
|
|||
extern bool real_equal (const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *);
|
||||
extern bool real_less (const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *);
|
||||
|
||||
/* Extend or truncate to a new mode. */
|
||||
extern void real_convert (REAL_VALUE_TYPE *, machine_mode,
|
||||
/* Extend or truncate to a new format. */
|
||||
extern void real_convert (REAL_VALUE_TYPE *, format_helper,
|
||||
const REAL_VALUE_TYPE *);
|
||||
|
||||
/* Return true if truncating to NEW is exact. */
|
||||
extern bool exact_real_truncate (machine_mode, const REAL_VALUE_TYPE *);
|
||||
extern bool exact_real_truncate (format_helper, const REAL_VALUE_TYPE *);
|
||||
|
||||
/* Render R as a decimal floating point constant. */
|
||||
extern void real_to_decimal (char *, const REAL_VALUE_TYPE *, size_t,
|
||||
|
@ -281,24 +303,20 @@ extern HOST_WIDE_INT real_to_integer (const REAL_VALUE_TYPE *);
|
|||
the value underflows, +1 if overflows, and 0 otherwise. */
|
||||
extern int real_from_string (REAL_VALUE_TYPE *, const char *);
|
||||
/* Wrapper to allow different internal representation for decimal floats. */
|
||||
extern void real_from_string3 (REAL_VALUE_TYPE *, const char *, machine_mode);
|
||||
extern void real_from_string3 (REAL_VALUE_TYPE *, const char *, format_helper);
|
||||
|
||||
extern long real_to_target_fmt (long *, const REAL_VALUE_TYPE *,
|
||||
const struct real_format *);
|
||||
extern long real_to_target (long *, const REAL_VALUE_TYPE *, machine_mode);
|
||||
extern long real_to_target (long *, const REAL_VALUE_TYPE *, format_helper);
|
||||
|
||||
extern void real_from_target_fmt (REAL_VALUE_TYPE *, const long *,
|
||||
const struct real_format *);
|
||||
extern void real_from_target (REAL_VALUE_TYPE *, const long *,
|
||||
machine_mode);
|
||||
format_helper);
|
||||
|
||||
extern void real_inf (REAL_VALUE_TYPE *);
|
||||
|
||||
extern bool real_nan (REAL_VALUE_TYPE *, const char *, int, machine_mode);
|
||||
extern bool real_nan (REAL_VALUE_TYPE *, const char *, int, format_helper);
|
||||
|
||||
extern void real_maxval (REAL_VALUE_TYPE *, int, machine_mode);
|
||||
|
||||
extern void real_2expN (REAL_VALUE_TYPE *, int, machine_mode);
|
||||
extern void real_2expN (REAL_VALUE_TYPE *, int, format_helper);
|
||||
|
||||
extern unsigned int real_hash (const REAL_VALUE_TYPE *);
|
||||
|
||||
|
@ -370,15 +388,14 @@ extern const struct real_format arm_half_format;
|
|||
#define REAL_VALUE_TO_TARGET_DECIMAL32(IN, OUT) \
|
||||
((OUT) = real_to_target (NULL, &(IN), mode_for_size (32, MODE_DECIMAL_FLOAT, 0)))
|
||||
|
||||
extern REAL_VALUE_TYPE real_value_truncate (machine_mode,
|
||||
REAL_VALUE_TYPE);
|
||||
extern REAL_VALUE_TYPE real_value_truncate (format_helper, REAL_VALUE_TYPE);
|
||||
|
||||
extern REAL_VALUE_TYPE real_value_negate (const REAL_VALUE_TYPE *);
|
||||
extern REAL_VALUE_TYPE real_value_abs (const REAL_VALUE_TYPE *);
|
||||
|
||||
extern int significand_size (machine_mode);
|
||||
extern int significand_size (format_helper);
|
||||
|
||||
extern REAL_VALUE_TYPE real_from_string2 (const char *, machine_mode);
|
||||
extern REAL_VALUE_TYPE real_from_string2 (const char *, format_helper);
|
||||
|
||||
#define REAL_VALUE_ATOF(s, m) \
|
||||
real_from_string2 (s, m)
|
||||
|
@ -437,8 +454,8 @@ REAL_VALUE_TYPE real_value_from_int_cst (const_tree, const_tree);
|
|||
/* Return a CONST_DOUBLE with value R and mode M. */
|
||||
extern rtx const_double_from_real_value (REAL_VALUE_TYPE, machine_mode);
|
||||
|
||||
/* Replace R by 1/R in the given machine mode, if the result is exact. */
|
||||
extern bool exact_real_inverse (machine_mode, REAL_VALUE_TYPE *);
|
||||
/* Replace R by 1/R in the given format, if the result is exact. */
|
||||
extern bool exact_real_inverse (format_helper, REAL_VALUE_TYPE *);
|
||||
|
||||
/* Return true if arithmetic on values in IMODE that were promoted
|
||||
from values in TMODE is equivalent to direct arithmetic on values
|
||||
|
@ -451,25 +468,25 @@ extern tree build_real (tree, REAL_VALUE_TYPE);
|
|||
/* Likewise, but first truncate the value to the type. */
|
||||
extern tree build_real_truncate (tree, REAL_VALUE_TYPE);
|
||||
|
||||
/* Calculate R as X raised to the integer exponent N in mode MODE. */
|
||||
extern bool real_powi (REAL_VALUE_TYPE *, machine_mode,
|
||||
/* Calculate R as X raised to the integer exponent N in format FMT. */
|
||||
extern bool real_powi (REAL_VALUE_TYPE *, format_helper,
|
||||
const REAL_VALUE_TYPE *, HOST_WIDE_INT);
|
||||
|
||||
/* Standard round to integer value functions. */
|
||||
extern void real_trunc (REAL_VALUE_TYPE *, machine_mode,
|
||||
extern void real_trunc (REAL_VALUE_TYPE *, format_helper,
|
||||
const REAL_VALUE_TYPE *);
|
||||
extern void real_floor (REAL_VALUE_TYPE *, machine_mode,
|
||||
extern void real_floor (REAL_VALUE_TYPE *, format_helper,
|
||||
const REAL_VALUE_TYPE *);
|
||||
extern void real_ceil (REAL_VALUE_TYPE *, machine_mode,
|
||||
extern void real_ceil (REAL_VALUE_TYPE *, format_helper,
|
||||
const REAL_VALUE_TYPE *);
|
||||
extern void real_round (REAL_VALUE_TYPE *, machine_mode,
|
||||
extern void real_round (REAL_VALUE_TYPE *, format_helper,
|
||||
const REAL_VALUE_TYPE *);
|
||||
|
||||
/* Set the sign of R to the sign of X. */
|
||||
extern void real_copysign (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *);
|
||||
|
||||
/* Check whether the real constant value given is an integer. */
|
||||
extern bool real_isinteger (const REAL_VALUE_TYPE *, machine_mode);
|
||||
extern bool real_isinteger (const REAL_VALUE_TYPE *, format_helper);
|
||||
extern bool real_isinteger (const REAL_VALUE_TYPE *, HOST_WIDE_INT *);
|
||||
|
||||
/* Write into BUF the maximum representable finite floating-point
|
||||
|
@ -480,7 +497,7 @@ extern void get_max_float (const struct real_format *, char *, size_t);
|
|||
#ifndef GENERATOR_FILE
|
||||
/* real related routines. */
|
||||
extern wide_int real_to_integer (const REAL_VALUE_TYPE *, bool *, int);
|
||||
extern void real_from_integer (REAL_VALUE_TYPE *, machine_mode,
|
||||
extern void real_from_integer (REAL_VALUE_TYPE *, format_helper,
|
||||
const wide_int_ref &, signop);
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in New Issue