Commit 0ee6fdb5 by Richard Henderson Committed by Richard Henderson

real.h (enum real_value_class, [...]): Move from real.c.

        * real.h (enum real_value_class, SIGNIFICAND_BITS, EXP_BITS,
        MAX_EXP, SIGSZ, SIG_MSB, struct real_value): Move from real.c.
        (struct realvaluetype): Remove.
        (REAL_VALUE_TYPE): Use struct real_value.
        (REAL_VALUE_TYPE_SIZE): Use SIGNIFICAND_BITS.
        (test_real_width): New.
        * real.c: Global replace struct real_value with REAL_VALUE_TYPE.
        (real_arithmetic): Avoid hoops for REAL_VALUE_TYPE parameters.
        (real_compare, real_exponent, real_ldexp, real_isinf, real_isnan,
        real_isneg, real_isnegzero, real_identical, exact_real_inverse,
        real_to_integer, real_to_integer2, real_to_decimal,
        real_to_hexadecimal, real_from_string, real_from_integer,
        real_inf, real_nan, real_2expN, real_convert, real_to_target,
        real_from_target): Likewise.
        * tree.h (struct tree_real_cst): Use real_value not realvaluetype.
        * gengtype-yacc.y (bitfieldopt): Accept an ID as well.

From-SVN: r57343
parent 42449812
2002-09-20 Richard Henderson <rth@redhat.com>
* real.h (enum real_value_class, SIGNIFICAND_BITS, EXP_BITS,
MAX_EXP, SIGSZ, SIG_MSB, struct real_value): Move from real.c.
(struct realvaluetype): Remove.
(REAL_VALUE_TYPE): Use struct real_value.
(REAL_VALUE_TYPE_SIZE): Use SIGNIFICAND_BITS.
(test_real_width): New.
* real.c: Global replace struct real_value with REAL_VALUE_TYPE.
(real_arithmetic): Avoid hoops for REAL_VALUE_TYPE parameters.
(real_compare, real_exponent, real_ldexp, real_isinf, real_isnan,
real_isneg, real_isnegzero, real_identical, exact_real_inverse,
real_to_integer, real_to_integer2, real_to_decimal,
real_to_hexadecimal, real_from_string, real_from_integer,
real_inf, real_nan, real_2expN, real_convert, real_to_target,
real_from_target): Likewise.
* tree.h (struct tree_real_cst): Use real_value not realvaluetype.
* gengtype-yacc.y (bitfieldopt): Accept an ID as well.
2002-09-20 Richard Henderson <rth@redhat.com>
* real.h (UNKNOWN_FLOAT_FORMAT, IEEE_FLOAT_FORMAT, VAX_FLOAT_FORMAT,
IBM_FLOAT_FORMAT, C4X_FLOAT_FORMAT, TARGET_FLOAT_FORMAT): Move ...
* defaults.h: ... here.
......@@ -214,6 +214,7 @@ struct_fields: { $$ = NULL; }
bitfieldopt: /* empty */
| ':' NUM
| ':' ID
;
type: SCALAR
......
......@@ -63,44 +63,20 @@
adjust the significand to match. */
/* Enumerate the special cases of numbers that we encounter. */
enum real_value_class {
rvc_zero,
rvc_normal,
rvc_inf,
rvc_nan
};
/* Used to classify two numbers simultaneously. */
#define CLASS2(A, B) ((A) << 2 | (B))
/* An expanded form of the represented number. */
#define SIGNIFICAND_BITS 128
#define EXP_BITS (32 - 3)
#define MAX_EXP ((1 << (EXP_BITS - 1)) - 1)
#define SIGSZ (SIGNIFICAND_BITS / HOST_BITS_PER_LONG)
#define SIG_MSB ((unsigned long)1 << (HOST_BITS_PER_LONG - 1))
#if HOST_BITS_PER_LONG != 64 && HOST_BITS_PER_LONG != 32
#error "Some constant folding done by hand to avoid shift count warnings"
#endif
struct real_value
{
enum real_value_class class : 2;
unsigned int sign : 1;
int exp : EXP_BITS;
unsigned long sig[SIGSZ];
};
/* Describes the properties of the specific target format in use. */
struct real_format
{
/* Move to and from the target bytes. */
void (*encode) (const struct real_format *, long *,
const struct real_value *);
void (*decode) (const struct real_format *, struct real_value *,
const REAL_VALUE_TYPE *);
void (*decode) (const struct real_format *, REAL_VALUE_TYPE *,
const long *);
/* The radix of the exponent and digits of the significand. */
......@@ -130,64 +106,64 @@ struct real_format
static const struct real_format *fmt_for_mode[TFmode - QFmode + 1];
static void get_zero PARAMS ((struct real_value *, int));
static void get_canonical_qnan PARAMS ((struct real_value *, int));
static void get_canonical_snan PARAMS ((struct real_value *, int));
static void get_inf PARAMS ((struct real_value *, int));
static void sticky_rshift_significand PARAMS ((struct real_value *,
const struct real_value *,
static void get_zero PARAMS ((REAL_VALUE_TYPE *, int));
static void get_canonical_qnan PARAMS ((REAL_VALUE_TYPE *, int));
static void get_canonical_snan PARAMS ((REAL_VALUE_TYPE *, int));
static void get_inf PARAMS ((REAL_VALUE_TYPE *, int));
static void sticky_rshift_significand PARAMS ((REAL_VALUE_TYPE *,
const REAL_VALUE_TYPE *,
unsigned int));
static void rshift_significand PARAMS ((struct real_value *,
const struct real_value *,
static void rshift_significand PARAMS ((REAL_VALUE_TYPE *,
const REAL_VALUE_TYPE *,
unsigned int));
static void lshift_significand PARAMS ((struct real_value *,
const struct real_value *,
static void lshift_significand PARAMS ((REAL_VALUE_TYPE *,
const REAL_VALUE_TYPE *,
unsigned int));
static void lshift_significand_1 PARAMS ((struct real_value *,
const struct real_value *));
static bool add_significands PARAMS ((struct real_value *r,
const struct real_value *,
const struct real_value *));
static bool sub_significands PARAMS ((struct real_value *,
const struct real_value *,
const struct real_value *));
static void neg_significand PARAMS ((struct real_value *,
const struct real_value *));
static int cmp_significands PARAMS ((const struct real_value *,
const struct real_value *));
static void set_significand_bit PARAMS ((struct real_value *, unsigned int));
static void clear_significand_bit PARAMS ((struct real_value *, unsigned int));
static bool test_significand_bit PARAMS ((struct real_value *, unsigned int));
static void clear_significand_below PARAMS ((struct real_value *,
static void lshift_significand_1 PARAMS ((REAL_VALUE_TYPE *,
const REAL_VALUE_TYPE *));
static bool add_significands PARAMS ((REAL_VALUE_TYPE *r,
const REAL_VALUE_TYPE *,
const REAL_VALUE_TYPE *));
static bool sub_significands PARAMS ((REAL_VALUE_TYPE *,
const REAL_VALUE_TYPE *,
const REAL_VALUE_TYPE *));
static void neg_significand PARAMS ((REAL_VALUE_TYPE *,
const REAL_VALUE_TYPE *));
static int cmp_significands PARAMS ((const REAL_VALUE_TYPE *,
const REAL_VALUE_TYPE *));
static void set_significand_bit PARAMS ((REAL_VALUE_TYPE *, unsigned int));
static void clear_significand_bit PARAMS ((REAL_VALUE_TYPE *, unsigned int));
static bool test_significand_bit PARAMS ((REAL_VALUE_TYPE *, unsigned int));
static void clear_significand_below PARAMS ((REAL_VALUE_TYPE *,
unsigned int));
static bool div_significands PARAMS ((struct real_value *,
const struct real_value *,
const struct real_value *));
static void normalize PARAMS ((struct real_value *));
static void do_add PARAMS ((struct real_value *, const struct real_value *,
const struct real_value *, int));
static void do_multiply PARAMS ((struct real_value *,
const struct real_value *,
const struct real_value *));
static void do_divide PARAMS ((struct real_value *, const struct real_value *,
const struct real_value *));
static int do_compare PARAMS ((const struct real_value *,
const struct real_value *, int));
static void do_fix_trunc PARAMS ((struct real_value *,
const struct real_value *));
static const struct real_value * ten_to_ptwo PARAMS ((int));
static const struct real_value * real_digit PARAMS ((int));
static bool div_significands PARAMS ((REAL_VALUE_TYPE *,
const REAL_VALUE_TYPE *,
const REAL_VALUE_TYPE *));
static void normalize PARAMS ((REAL_VALUE_TYPE *));
static void do_add PARAMS ((REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *,
const REAL_VALUE_TYPE *, int));
static void do_multiply PARAMS ((REAL_VALUE_TYPE *,
const REAL_VALUE_TYPE *,
const REAL_VALUE_TYPE *));
static void do_divide PARAMS ((REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *,
const REAL_VALUE_TYPE *));
static int do_compare PARAMS ((const REAL_VALUE_TYPE *,
const REAL_VALUE_TYPE *, int));
static void do_fix_trunc PARAMS ((REAL_VALUE_TYPE *,
const REAL_VALUE_TYPE *));
static const REAL_VALUE_TYPE * ten_to_ptwo PARAMS ((int));
static const REAL_VALUE_TYPE * real_digit PARAMS ((int));
static void round_for_format PARAMS ((const struct real_format *,
struct real_value *));
REAL_VALUE_TYPE *));
/* Initialize R with a positive zero. */
static inline void
get_zero (r, sign)
struct real_value *r;
REAL_VALUE_TYPE *r;
int sign;
{
memset (r, 0, sizeof (*r));
......@@ -198,7 +174,7 @@ get_zero (r, sign)
static inline void
get_canonical_qnan (r, sign)
struct real_value *r;
REAL_VALUE_TYPE *r;
int sign;
{
memset (r, 0, sizeof (*r));
......@@ -209,7 +185,7 @@ get_canonical_qnan (r, sign)
static inline void
get_canonical_snan (r, sign)
struct real_value *r;
REAL_VALUE_TYPE *r;
int sign;
{
memset (r, 0, sizeof (*r));
......@@ -220,7 +196,7 @@ get_canonical_snan (r, sign)
static inline void
get_inf (r, sign)
struct real_value *r;
REAL_VALUE_TYPE *r;
int sign;
{
memset (r, 0, sizeof (*r));
......@@ -235,8 +211,8 @@ get_inf (r, sign)
static void
sticky_rshift_significand (r, a, n)
struct real_value *r;
const struct real_value *a;
REAL_VALUE_TYPE *r;
const REAL_VALUE_TYPE *a;
unsigned int n;
{
unsigned long sticky = 0;
......@@ -276,8 +252,8 @@ sticky_rshift_significand (r, a, n)
static void
rshift_significand (r, a, n)
struct real_value *r;
const struct real_value *a;
REAL_VALUE_TYPE *r;
const REAL_VALUE_TYPE *a;
unsigned int n;
{
unsigned int i, ofs = n / HOST_BITS_PER_LONG;
......@@ -307,8 +283,8 @@ rshift_significand (r, a, n)
static void
lshift_significand (r, a, n)
struct real_value *r;
const struct real_value *a;
REAL_VALUE_TYPE *r;
const REAL_VALUE_TYPE *a;
unsigned int n;
{
unsigned int i, ofs = n / HOST_BITS_PER_LONG;
......@@ -335,8 +311,8 @@ lshift_significand (r, a, n)
static inline void
lshift_significand_1 (r, a)
struct real_value *r;
const struct real_value *a;
REAL_VALUE_TYPE *r;
const REAL_VALUE_TYPE *a;
{
unsigned int i;
......@@ -350,8 +326,8 @@ lshift_significand_1 (r, a)
static inline bool
add_significands (r, a, b)
struct real_value *r;
const struct real_value *a, *b;
REAL_VALUE_TYPE *r;
const REAL_VALUE_TYPE *a, *b;
{
bool carry = false;
int i;
......@@ -380,8 +356,8 @@ add_significands (r, a, b)
static inline bool
sub_significands (r, a, b)
struct real_value *r;
const struct real_value *a, *b;
REAL_VALUE_TYPE *r;
const REAL_VALUE_TYPE *a, *b;
{
bool carry = false;
int i;
......@@ -409,8 +385,8 @@ sub_significands (r, a, b)
static inline void
neg_significand (r, a)
struct real_value *r;
const struct real_value *a;
REAL_VALUE_TYPE *r;
const REAL_VALUE_TYPE *a;
{
bool carry = true;
int i;
......@@ -440,7 +416,7 @@ neg_significand (r, a)
static inline int
cmp_significands (a, b)
const struct real_value *a, *b;
const REAL_VALUE_TYPE *a, *b;
{
int i;
......@@ -462,7 +438,7 @@ cmp_significands (a, b)
static inline void
set_significand_bit (r, n)
struct real_value *r;
REAL_VALUE_TYPE *r;
unsigned int n;
{
r->sig[n / HOST_BITS_PER_LONG]
......@@ -473,7 +449,7 @@ set_significand_bit (r, n)
static inline void
clear_significand_bit (r, n)
struct real_value *r;
REAL_VALUE_TYPE *r;
unsigned int n;
{
r->sig[n / HOST_BITS_PER_LONG]
......@@ -484,7 +460,7 @@ clear_significand_bit (r, n)
static inline bool
test_significand_bit (r, n)
struct real_value *r;
REAL_VALUE_TYPE *r;
unsigned int n;
{
/* ??? Compiler bug here if we return this expression directly.
......@@ -498,7 +474,7 @@ test_significand_bit (r, n)
static void
clear_significand_below (r, n)
struct real_value *r;
REAL_VALUE_TYPE *r;
unsigned int n;
{
int i, w = n / HOST_BITS_PER_LONG;
......@@ -514,10 +490,10 @@ clear_significand_below (r, n)
static inline bool
div_significands (r, a, b)
struct real_value *r;
const struct real_value *a, *b;
REAL_VALUE_TYPE *r;
const REAL_VALUE_TYPE *a, *b;
{
struct real_value u;
REAL_VALUE_TYPE u;
int bit = SIGNIFICAND_BITS - 1;
int i;
long inexact;
......@@ -562,7 +538,7 @@ div_significands (r, a, b)
static void
normalize (r)
struct real_value *r;
REAL_VALUE_TYPE *r;
{
int shift = 0, exp;
int i, j;
......@@ -607,12 +583,12 @@ normalize (r)
static void
do_add (r, a, b, subtract_p)
struct real_value *r;
const struct real_value *a, *b;
REAL_VALUE_TYPE *r;
const REAL_VALUE_TYPE *a, *b;
int subtract_p;
{
int dexp, sign, exp;
struct real_value t;
REAL_VALUE_TYPE t;
/* Determine if we need to add or subtract. */
sign = a->sign;
......@@ -671,7 +647,7 @@ do_add (r, a, b, subtract_p)
dexp = a->exp - b->exp;
if (dexp < 0)
{
const struct real_value *t;
const REAL_VALUE_TYPE *t;
t = a, a = b, b = t;
dexp = -dexp;
sign ^= subtract_p;
......@@ -741,10 +717,10 @@ do_add (r, a, b, subtract_p)
static void
do_multiply (r, a, b)
struct real_value *r;
const struct real_value *a, *b;
REAL_VALUE_TYPE *r;
const REAL_VALUE_TYPE *a, *b;
{
struct real_value u, t, *rr;
REAL_VALUE_TYPE u, t, *rr;
unsigned int i, j, k;
int sign = a->sign ^ b->sign;
......@@ -870,11 +846,11 @@ do_multiply (r, a, b)
static void
do_divide (r, a, b)
struct real_value *r;
const struct real_value *a, *b;
REAL_VALUE_TYPE *r;
const REAL_VALUE_TYPE *a, *b;
{
int exp, sign = a->sign ^ b->sign;
struct real_value t, *rr;
REAL_VALUE_TYPE t, *rr;
bool inexact;
switch (CLASS2 (a->class, b->class))
......@@ -962,7 +938,7 @@ do_divide (r, a, b)
static int
do_compare (a, b, nan_result)
const struct real_value *a, *b;
const REAL_VALUE_TYPE *a, *b;
int nan_result;
{
int ret;
......@@ -1019,8 +995,8 @@ do_compare (a, b, nan_result)
void
do_fix_trunc (r, a)
struct real_value *r;
const struct real_value *a;
REAL_VALUE_TYPE *r;
const REAL_VALUE_TYPE *a;
{
*r = *a;
......@@ -1047,14 +1023,11 @@ do_fix_trunc (r, a)
For a unary operation, leave OP1 NULL. */
void
real_arithmetic (tr, icode, top0, top1)
REAL_VALUE_TYPE *tr;
real_arithmetic (r, icode, op0, op1)
REAL_VALUE_TYPE *r;
int icode;
const REAL_VALUE_TYPE *top0, *top1;
const REAL_VALUE_TYPE *op0, *op1;
{
struct real_value *r = (struct real_value *) tr;
const struct real_value *op0 = (const struct real_value *) top0;
const struct real_value *op1 = (const struct real_value *) top1;
enum tree_code code = icode;
switch (code)
......@@ -1115,23 +1088,21 @@ real_arithmetic (tr, icode, top0, top1)
/* Legacy. Similar, but return the result directly. */
REAL_VALUE_TYPE
real_arithmetic2 (icode, top0, top1)
real_arithmetic2 (icode, op0, op1)
int icode;
const REAL_VALUE_TYPE *top0, *top1;
const REAL_VALUE_TYPE *op0, *op1;
{
REAL_VALUE_TYPE r;
real_arithmetic (&r, icode, top0, top1);
real_arithmetic (&r, icode, op0, op1);
return r;
}
bool
real_compare (icode, top0, top1)
real_compare (icode, op0, op1)
int icode;
const REAL_VALUE_TYPE *top0, *top1;
const REAL_VALUE_TYPE *op0, *op1;
{
enum tree_code code = icode;
const struct real_value *op0 = (const struct real_value *) top0;
const struct real_value *op1 = (const struct real_value *) top1;
switch (code)
{
......@@ -1170,11 +1141,9 @@ real_compare (icode, top0, top1)
/* Return floor log2(R). */
int
real_exponent (tr)
const REAL_VALUE_TYPE *tr;
real_exponent (r)
const REAL_VALUE_TYPE *r;
{
const struct real_value *r = (const struct real_value *) tr;
switch (r->class)
{
case rvc_zero:
......@@ -1189,18 +1158,14 @@ real_exponent (tr)
}
}
/* R = OP0 * 2**EXP. */
void
real_ldexp (tr, top0, exp)
REAL_VALUE_TYPE *tr;
const REAL_VALUE_TYPE *top0;
real_ldexp (r, op0, exp)
REAL_VALUE_TYPE *r;
const REAL_VALUE_TYPE *op0;
int exp;
{
struct real_value *r = (struct real_value *) tr;
const struct real_value *op0 = (const struct real_value *) top0;
*r = *op0;
switch (r->class)
{
......@@ -1227,51 +1192,45 @@ real_ldexp (tr, top0, exp)
/* Determine whether a floating-point value X is infinite. */
bool
real_isinf (tr)
const REAL_VALUE_TYPE *tr;
real_isinf (r)
const REAL_VALUE_TYPE *r;
{
const struct real_value *r = (const struct real_value *) tr;
return (r->class == rvc_inf);
}
/* Determine whether a floating-point value X is a NaN. */
bool
real_isnan (tr)
const REAL_VALUE_TYPE *tr;
real_isnan (r)
const REAL_VALUE_TYPE *r;
{
const struct real_value *r = (const struct real_value *) tr;
return (r->class == rvc_nan);
}
/* Determine whether a floating-point value X is negative. */
bool
real_isneg (tr)
const REAL_VALUE_TYPE *tr;
real_isneg (r)
const REAL_VALUE_TYPE *r;
{
const struct real_value *r = (const struct real_value *) tr;
return r->sign;
}
/* Determine whether a floating-point value X is minus zero. */
bool
real_isnegzero (tr)
const REAL_VALUE_TYPE *tr;
real_isnegzero (r)
const REAL_VALUE_TYPE *r;
{
const struct real_value *r = (const struct real_value *) tr;
return r->sign && r->class == rvc_zero;
}
/* Compare two floating-point objects for bitwise identity. */
extern bool
real_identical (ta, tb)
const REAL_VALUE_TYPE *ta, *tb;
real_identical (a, b)
const REAL_VALUE_TYPE *a, *b;
{
const struct real_value *a = (const struct real_value *) ta;
const struct real_value *b = (const struct real_value *) tb;
int i;
if (a->class != b->class)
......@@ -1306,13 +1265,12 @@ real_identical (ta, tb)
mode MODE. Return true if successful. */
bool
exact_real_inverse (mode, tr)
exact_real_inverse (mode, r)
enum machine_mode mode;
REAL_VALUE_TYPE *tr;
REAL_VALUE_TYPE *r;
{
const struct real_value *one = real_digit (1);
struct real_value *r = (struct real_value *) tr;
struct real_value u;
const REAL_VALUE_TYPE *one = real_digit (1);
REAL_VALUE_TYPE u;
int i;
if (r->class != rvc_normal)
......@@ -1327,7 +1285,7 @@ exact_real_inverse (mode, tr)
/* Find the inverse and truncate to the required mode. */
do_divide (&u, one, r);
real_convert ((REAL_VALUE_TYPE *)&u, mode, (REAL_VALUE_TYPE *)&u);
real_convert (&u, mode, &u);
/* The rounding may have overflowed. */
if (u.class != rvc_normal)
......@@ -1345,10 +1303,9 @@ exact_real_inverse (mode, tr)
/* Render R as an integer. */
HOST_WIDE_INT
real_to_integer (tr)
const REAL_VALUE_TYPE *tr;
real_to_integer (r)
const REAL_VALUE_TYPE *r;
{
const struct real_value *r = (const struct real_value *) tr;
unsigned HOST_WIDE_INT i;
switch (r->class)
......@@ -1396,16 +1353,15 @@ real_to_integer (tr)
/* Likewise, but to an integer pair, HI+LOW. */
void
real_to_integer2 (plow, phigh, tr)
real_to_integer2 (plow, phigh, r)
HOST_WIDE_INT *plow, *phigh;
const REAL_VALUE_TYPE *tr;
const REAL_VALUE_TYPE *r;
{
struct real_value r;
REAL_VALUE_TYPE t;
HOST_WIDE_INT low, high;
int exp;
r = *(const struct real_value *) tr;
switch (r.class)
switch (r->class)
{
case rvc_zero:
underflow:
......@@ -1416,7 +1372,7 @@ real_to_integer2 (plow, phigh, tr)
case rvc_nan:
overflow:
high = (unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1);
if (r.sign)
if (r->sign)
low = 0;
else
{
......@@ -1426,32 +1382,32 @@ real_to_integer2 (plow, phigh, tr)
break;
case rvc_normal:
exp = r.exp;
exp = r->exp;
if (exp <= 0)
goto underflow;
if (exp >= 2*HOST_BITS_PER_WIDE_INT)
goto overflow;
rshift_significand (&r, &r, 2*HOST_BITS_PER_WIDE_INT - exp);
rshift_significand (&t, r, 2*HOST_BITS_PER_WIDE_INT - exp);
if (HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG)
{
high = r.sig[SIGSZ-1];
low = r.sig[SIGSZ-2];
high = t.sig[SIGSZ-1];
low = t.sig[SIGSZ-2];
}
else if (HOST_BITS_PER_WIDE_INT == 2*HOST_BITS_PER_LONG)
{
high = r.sig[SIGSZ-1];
high = t.sig[SIGSZ-1];
high = high << (HOST_BITS_PER_LONG - 1) << 1;
high |= r.sig[SIGSZ-2];
high |= t.sig[SIGSZ-2];
low = r.sig[SIGSZ-3];
low = t.sig[SIGSZ-3];
low = low << (HOST_BITS_PER_LONG - 1) << 1;
low |= r.sig[SIGSZ-4];
low |= t.sig[SIGSZ-4];
}
else
abort ();
if (r.sign)
if (r->sign)
{
if (low == 0)
high = -high;
......@@ -1480,13 +1436,13 @@ real_to_decimal (str, r_orig, digits)
const REAL_VALUE_TYPE *r_orig;
int digits;
{
struct real_value r;
const struct real_value *one, *ten;
REAL_VALUE_TYPE r;
const REAL_VALUE_TYPE *one, *ten;
int dec_exp, max_digits, d, cmp_half;
char *p, *first, *last;
bool sign;
r = *(const struct real_value *)r_orig;
r = *r_orig;
switch (r.class)
{
case rvc_zero:
......@@ -1602,30 +1558,27 @@ real_to_decimal (str, r_orig, digits)
for the representation. */
void
real_to_hexadecimal (str, tr, digits)
real_to_hexadecimal (str, r, digits)
char *str;
const REAL_VALUE_TYPE *tr;
const REAL_VALUE_TYPE *r;
int digits;
{
struct real_value r;
int i, j;
int i, j, exp = r->exp;
char *p;
r = *(const struct real_value *) tr;
switch (r.class)
switch (r->class)
{
case rvc_zero:
r.exp = 0;
exp = 0;
break;
case rvc_normal:
break;
case rvc_inf:
strcpy (str, (r.sign ? "+Inf" : "-Inf"));
strcpy (str, (r->sign ? "+Inf" : "-Inf"));
return;
case rvc_nan:
/* ??? Print the significand as well, if not canonical? */
strcpy (str, (r.sign ? "+NaN" : "-NaN"));
strcpy (str, (r->sign ? "+NaN" : "-NaN"));
return;
default:
abort ();
......@@ -1635,7 +1588,7 @@ real_to_hexadecimal (str, tr, digits)
digits = SIGNIFICAND_BITS / 4;
p = str;
if (r.sign)
if (r->sign)
*p++ = '-';
*p++ = '0';
*p++ = 'x';
......@@ -1645,23 +1598,22 @@ real_to_hexadecimal (str, tr, digits)
for (i = SIGSZ - 1; i >= 0; --i)
for (j = HOST_BITS_PER_LONG - 4; j >= 0; j -= 4)
{
*p++ = "0123456789abcdef"[(r.sig[i] >> j) & 15];
*p++ = "0123456789abcdef"[(r->sig[i] >> j) & 15];
if (--digits == 0)
goto out;
}
out:
sprintf (p, "p%+d", r.exp);
sprintf (p, "p%+d", exp);
}
/* Initialize R from a decimal or hexadecimal string. The string is
assumed to have been syntax checked already. */
void
real_from_string (tr, str)
REAL_VALUE_TYPE *tr;
real_from_string (r, str)
REAL_VALUE_TYPE *r;
const char *str;
{
struct real_value *r = (struct real_value *) tr;
int exp = 0;
get_zero (r, 0);
......@@ -1764,7 +1716,7 @@ real_from_string (tr, str)
else
{
/* Decimal floating point. */
const struct real_value *ten = ten_to_ptwo (0);
const REAL_VALUE_TYPE *ten = ten_to_ptwo (0);
int d;
while (*str == '0')
......@@ -1868,15 +1820,13 @@ real_from_string2 (s, mode)
/* Initialize R from the integer pair HIGH+LOW. */
void
real_from_integer (tr, mode, low, high, unsigned_p)
REAL_VALUE_TYPE *tr;
real_from_integer (r, mode, low, high, unsigned_p)
REAL_VALUE_TYPE *r;
enum machine_mode mode;
unsigned HOST_WIDE_INT low;
HOST_WIDE_INT high;
int unsigned_p;
{
struct real_value *r = (struct real_value *) tr;
if (low == 0 && high == 0)
get_zero (r, 0);
else
......@@ -1916,16 +1866,16 @@ real_from_integer (tr, mode, low, high, unsigned_p)
}
if (mode != VOIDmode)
real_convert (tr, mode, tr);
real_convert (r, mode, r);
}
/* Returns 10**2**n. */
static const struct real_value *
static const REAL_VALUE_TYPE *
ten_to_ptwo (n)
int n;
{
static struct real_value tens[EXP_BITS];
static REAL_VALUE_TYPE tens[EXP_BITS];
if (n < 0 || n >= EXP_BITS)
abort ();
......@@ -1940,11 +1890,11 @@ ten_to_ptwo (n)
for (i = 0; i < n; ++i)
t *= t;
real_from_integer ((REAL_VALUE_TYPE *) &tens[n], VOIDmode, t, 0, 1);
real_from_integer (&tens[n], VOIDmode, t, 0, 1);
}
else
{
const struct real_value *t = ten_to_ptwo (n - 1);
const REAL_VALUE_TYPE *t = ten_to_ptwo (n - 1);
do_multiply (&tens[n], t, t);
}
}
......@@ -1954,17 +1904,17 @@ ten_to_ptwo (n)
/* Returns N. */
static const struct real_value *
static const REAL_VALUE_TYPE *
real_digit (n)
int n;
{
static struct real_value num[10];
static REAL_VALUE_TYPE num[10];
if (n < 0 || n > 9)
abort ();
if (n > 0 && num[n].class == rvc_zero)
real_from_integer ((REAL_VALUE_TYPE *) &num[n], VOIDmode, n, 0, 1);
real_from_integer (&num[n], VOIDmode, n, 0, 1);
return &num[n];
}
......@@ -1972,10 +1922,10 @@ real_digit (n)
/* Fills R with +Inf. */
void
real_inf (tr)
REAL_VALUE_TYPE *tr;
real_inf (r)
REAL_VALUE_TYPE *r;
{
get_inf ((struct real_value *)tr, 0);
get_inf (r, 0);
}
/* Fills R with a NaN whose significand is described by STR. If QUIET,
......@@ -1984,13 +1934,12 @@ real_inf (tr)
if the string was successfully parsed. */
bool
real_nan (tr, str, quiet, mode)
REAL_VALUE_TYPE *tr;
real_nan (r, str, quiet, mode)
REAL_VALUE_TYPE *r;
const char *str;
int quiet;
enum machine_mode mode;
{
struct real_value *r = (struct real_value *) tr;
const struct real_format *fmt;
fmt = fmt_for_mode[mode - QFmode];
......@@ -2030,7 +1979,7 @@ real_nan (tr, str, quiet, mode)
while ((d = hex_value (*str)) < base)
{
struct real_value u;
REAL_VALUE_TYPE u;
switch (base)
{
......@@ -2093,12 +2042,10 @@ real_nan (tr, str, quiet, mode)
/* Fills R with 2**N. */
void
real_2expN (tr, n)
REAL_VALUE_TYPE *tr;
real_2expN (r, n)
REAL_VALUE_TYPE *r;
int n;
{
struct real_value *r = (struct real_value *) tr;
memset (r, 0, sizeof (*r));
n++;
......@@ -2118,7 +2065,7 @@ real_2expN (tr, n)
static void
round_for_format (fmt, r)
const struct real_format *fmt;
struct real_value *r;
REAL_VALUE_TYPE *r;
{
int p2, np2, i, w;
unsigned long sticky;
......@@ -2218,7 +2165,7 @@ round_for_format (fmt, r)
/* Round to even. */
if (guard && (sticky || lsb))
{
struct real_value u;
REAL_VALUE_TYPE u;
get_zero (&u, 0);
set_significand_bit (&u, np2);
......@@ -2257,13 +2204,11 @@ round_for_format (fmt, r)
/* Extend or truncate to a new mode. */
void
real_convert (tr, mode, ta)
REAL_VALUE_TYPE *tr;
real_convert (r, mode, a)
REAL_VALUE_TYPE *r;
enum machine_mode mode;
const REAL_VALUE_TYPE *ta;
const REAL_VALUE_TYPE *a;
{
struct real_value *r = (struct real_value *)tr;
const struct real_value *a = (const struct real_value *)ta;
const struct real_format *fmt;
fmt = fmt_for_mode[mode - QFmode];
......@@ -2293,13 +2238,13 @@ real_value_truncate (mode, a)
/* Return true if truncating to MODE is exact. */
bool
exact_real_truncate (mode, ta)
exact_real_truncate (mode, a)
enum machine_mode mode;
const REAL_VALUE_TYPE *ta;
const REAL_VALUE_TYPE *a;
{
REAL_VALUE_TYPE t;
real_convert (&t, mode, ta);
return real_identical (&t, ta);
real_convert (&t, mode, a);
return real_identical (&t, a);
}
/* Write R to the target format of MODE. Place the words of the
......@@ -2309,22 +2254,22 @@ exact_real_truncate (mode, ta)
Legacy: return word 0 for implementing REAL_VALUE_TO_TARGET_SINGLE. */
long
real_to_target (buf, tr, mode)
real_to_target (buf, r_orig, mode)
long *buf;
const REAL_VALUE_TYPE *tr;
const REAL_VALUE_TYPE *r_orig;
enum machine_mode mode;
{
struct real_value r;
REAL_VALUE_TYPE r;
const struct real_format *fmt;
long buf1;
r = *(const struct real_value *) tr;
fmt = fmt_for_mode[mode - QFmode];
if (fmt == NULL)
abort ();
r = *r_orig;
round_for_format (fmt, &r);
if (!buf)
buf = &buf1;
(*fmt->encode) (fmt, buf, &r);
......@@ -2337,12 +2282,11 @@ real_to_target (buf, tr, mode)
in each long, no matter the size of the host long. */
void
real_from_target (tr, buf, mode)
REAL_VALUE_TYPE *tr;
real_from_target (r, buf, mode)
REAL_VALUE_TYPE *r;
const long *buf;
enum machine_mode mode;
{
struct real_value *r = (struct real_value *) tr;
const struct real_format *fmt;
fmt = fmt_for_mode[mode - QFmode];
......@@ -2371,15 +2315,15 @@ significand_size (mode)
/* IEEE single-precision format. */
static void encode_ieee_single PARAMS ((const struct real_format *fmt,
long *, const struct real_value *));
long *, const REAL_VALUE_TYPE *));
static void decode_ieee_single PARAMS ((const struct real_format *,
struct real_value *, const long *));
REAL_VALUE_TYPE *, const long *));
static void
encode_ieee_single (fmt, buf, r)
const struct real_format *fmt;
long *buf;
const struct real_value *r;
const REAL_VALUE_TYPE *r;
{
unsigned long image, sig, exp;
bool denormal = (r->sig[SIGSZ-1] & SIG_MSB) == 0;
......@@ -2430,7 +2374,7 @@ encode_ieee_single (fmt, buf, r)
static void
decode_ieee_single (fmt, r, buf)
const struct real_format *fmt;
struct real_value *r;
REAL_VALUE_TYPE *r;
const long *buf;
{
unsigned long image = buf[0] & 0xffffffff;
......@@ -2499,15 +2443,15 @@ const struct real_format ieee_single =
/* IEEE double-precision format. */
static void encode_ieee_double PARAMS ((const struct real_format *fmt,
long *, const struct real_value *));
long *, const REAL_VALUE_TYPE *));
static void decode_ieee_double PARAMS ((const struct real_format *,
struct real_value *, const long *));
REAL_VALUE_TYPE *, const long *));
static void
encode_ieee_double (fmt, buf, r)
const struct real_format *fmt;
long *buf;
const struct real_value *r;
const REAL_VALUE_TYPE *r;
{
unsigned long image_lo, image_hi, sig_lo, sig_hi, exp;
bool denormal = (r->sig[SIGSZ-1] & SIG_MSB) == 0;
......@@ -2583,7 +2527,7 @@ encode_ieee_double (fmt, buf, r)
static void
decode_ieee_double (fmt, r, buf)
const struct real_format *fmt;
struct real_value *r;
REAL_VALUE_TYPE *r;
const long *buf;
{
unsigned long image_hi, image_lo;
......@@ -2691,22 +2635,22 @@ const struct real_format ieee_double =
and Motorola's. */
static void encode_ieee_extended PARAMS ((const struct real_format *fmt,
long *, const struct real_value *));
long *, const REAL_VALUE_TYPE *));
static void decode_ieee_extended PARAMS ((const struct real_format *,
struct real_value *, const long *));
REAL_VALUE_TYPE *, const long *));
static void encode_ieee_extended_128 PARAMS ((const struct real_format *fmt,
long *,
const struct real_value *));
const REAL_VALUE_TYPE *));
static void decode_ieee_extended_128 PARAMS ((const struct real_format *,
struct real_value *,
REAL_VALUE_TYPE *,
const long *));
static void
encode_ieee_extended (fmt, buf, r)
const struct real_format *fmt;
long *buf;
const struct real_value *r;
const REAL_VALUE_TYPE *r;
{
unsigned long image_hi, sig_hi, sig_lo;
bool denormal = (r->sig[SIGSZ-1] & SIG_MSB) == 0;
......@@ -2814,7 +2758,7 @@ static void
encode_ieee_extended_128 (fmt, buf, r)
const struct real_format *fmt;
long *buf;
const struct real_value *r;
const REAL_VALUE_TYPE *r;
{
buf[3 * !FLOAT_WORDS_BIG_ENDIAN] = 0;
encode_ieee_extended (fmt, buf+!!FLOAT_WORDS_BIG_ENDIAN, r);
......@@ -2823,7 +2767,7 @@ encode_ieee_extended_128 (fmt, buf, r)
static void
decode_ieee_extended (fmt, r, buf)
const struct real_format *fmt;
struct real_value *r;
REAL_VALUE_TYPE *r;
const long *buf;
{
unsigned long image_hi, sig_hi, sig_lo;
......@@ -2915,7 +2859,7 @@ decode_ieee_extended (fmt, r, buf)
static void
decode_ieee_extended_128 (fmt, r, buf)
const struct real_format *fmt;
struct real_value *r;
REAL_VALUE_TYPE *r;
const long *buf;
{
decode_ieee_extended (fmt, r, buf+!!FLOAT_WORDS_BIG_ENDIAN);
......@@ -2973,19 +2917,19 @@ const struct real_format ieee_extended_intel_128 =
/* IEEE quad precision format. */
static void encode_ieee_quad PARAMS ((const struct real_format *fmt,
long *, const struct real_value *));
long *, const REAL_VALUE_TYPE *));
static void decode_ieee_quad PARAMS ((const struct real_format *,
struct real_value *, const long *));
REAL_VALUE_TYPE *, const long *));
static void
encode_ieee_quad (fmt, buf, r)
const struct real_format *fmt;
long *buf;
const struct real_value *r;
const REAL_VALUE_TYPE *r;
{
unsigned long image3, image2, image1, image0, exp;
bool denormal = (r->sig[SIGSZ-1] & SIG_MSB) == 0;
struct real_value u;
REAL_VALUE_TYPE u;
image3 = r->sign << 31;
image2 = 0;
......@@ -3093,7 +3037,7 @@ encode_ieee_quad (fmt, buf, r)
static void
decode_ieee_quad (fmt, r, buf)
const struct real_format *fmt;
struct real_value *r;
REAL_VALUE_TYPE *r;
const long *buf;
{
unsigned long image3, image2, image1, image0;
......@@ -3223,23 +3167,23 @@ const struct real_format ieee_quad =
/* The VAX floating point formats. */
static void encode_vax_f PARAMS ((const struct real_format *fmt,
long *, const struct real_value *));
long *, const REAL_VALUE_TYPE *));
static void decode_vax_f PARAMS ((const struct real_format *,
struct real_value *, const long *));
REAL_VALUE_TYPE *, const long *));
static void encode_vax_d PARAMS ((const struct real_format *fmt,
long *, const struct real_value *));
long *, const REAL_VALUE_TYPE *));
static void decode_vax_d PARAMS ((const struct real_format *,
struct real_value *, const long *));
REAL_VALUE_TYPE *, const long *));
static void encode_vax_g PARAMS ((const struct real_format *fmt,
long *, const struct real_value *));
long *, const REAL_VALUE_TYPE *));
static void decode_vax_g PARAMS ((const struct real_format *,
struct real_value *, const long *));
REAL_VALUE_TYPE *, const long *));
static void
encode_vax_f (fmt, buf, r)
const struct real_format *fmt ATTRIBUTE_UNUSED;
long *buf;
const struct real_value *r;
const REAL_VALUE_TYPE *r;
{
unsigned long sign, exp, sig, image;
......@@ -3273,7 +3217,7 @@ encode_vax_f (fmt, buf, r)
static void
decode_vax_f (fmt, r, buf)
const struct real_format *fmt ATTRIBUTE_UNUSED;
struct real_value *r;
REAL_VALUE_TYPE *r;
const long *buf;
{
unsigned long image = buf[0] & 0xffffffff;
......@@ -3296,7 +3240,7 @@ static void
encode_vax_d (fmt, buf, r)
const struct real_format *fmt ATTRIBUTE_UNUSED;
long *buf;
const struct real_value *r;
const REAL_VALUE_TYPE *r;
{
unsigned long image0, image1, sign = r->sign << 15;
......@@ -3348,7 +3292,7 @@ encode_vax_d (fmt, buf, r)
static void
decode_vax_d (fmt, r, buf)
const struct real_format *fmt ATTRIBUTE_UNUSED;
struct real_value *r;
REAL_VALUE_TYPE *r;
const long *buf;
{
unsigned long image0, image1;
......@@ -3397,7 +3341,7 @@ static void
encode_vax_g (fmt, buf, r)
const struct real_format *fmt ATTRIBUTE_UNUSED;
long *buf;
const struct real_value *r;
const REAL_VALUE_TYPE *r;
{
unsigned long image0, image1, sign = r->sign << 15;
......@@ -3449,7 +3393,7 @@ encode_vax_g (fmt, buf, r)
static void
decode_vax_g (fmt, r, buf)
const struct real_format *fmt ATTRIBUTE_UNUSED;
struct real_value *r;
REAL_VALUE_TYPE *r;
const long *buf;
{
unsigned long image0, image1;
......@@ -3551,19 +3495,19 @@ const struct real_format vax_g_format =
*/
static void encode_i370_single PARAMS ((const struct real_format *fmt,
long *, const struct real_value *));
long *, const REAL_VALUE_TYPE *));
static void decode_i370_single PARAMS ((const struct real_format *,
struct real_value *, const long *));
REAL_VALUE_TYPE *, const long *));
static void encode_i370_double PARAMS ((const struct real_format *fmt,
long *, const struct real_value *));
long *, const REAL_VALUE_TYPE *));
static void decode_i370_double PARAMS ((const struct real_format *,
struct real_value *, const long *));
REAL_VALUE_TYPE *, const long *));
static void
encode_i370_single (fmt, buf, r)
const struct real_format *fmt ATTRIBUTE_UNUSED;
long *buf;
const struct real_value *r;
const REAL_VALUE_TYPE *r;
{
unsigned long sign, exp, sig, image;
......@@ -3593,7 +3537,7 @@ encode_i370_single (fmt, buf, r)
static void
decode_i370_single (fmt, r, buf)
const struct real_format *fmt ATTRIBUTE_UNUSED;
struct real_value *r;
REAL_VALUE_TYPE *r;
const long *buf;
{
unsigned long sign, sig, image = buf[0];
......@@ -3619,7 +3563,7 @@ static void
encode_i370_double (fmt, buf, r)
const struct real_format *fmt ATTRIBUTE_UNUSED;
long *buf;
const struct real_value *r;
const REAL_VALUE_TYPE *r;
{
unsigned long sign, exp, image_hi, image_lo;
......@@ -3666,7 +3610,7 @@ encode_i370_double (fmt, buf, r)
static void
decode_i370_double (fmt, r, buf)
const struct real_format *fmt ATTRIBUTE_UNUSED;
struct real_value *r;
REAL_VALUE_TYPE *r;
const long *buf;
{
unsigned long sign, image_hi, image_lo;
......@@ -3738,19 +3682,19 @@ const struct real_format i370_double =
/* TMS320C[34]x twos complement floating point format. */
static void encode_c4x_single PARAMS ((const struct real_format *fmt,
long *, const struct real_value *));
long *, const REAL_VALUE_TYPE *));
static void decode_c4x_single PARAMS ((const struct real_format *,
struct real_value *, const long *));
REAL_VALUE_TYPE *, const long *));
static void encode_c4x_extended PARAMS ((const struct real_format *fmt,
long *, const struct real_value *));
long *, const REAL_VALUE_TYPE *));
static void decode_c4x_extended PARAMS ((const struct real_format *,
struct real_value *, const long *));
REAL_VALUE_TYPE *, const long *));
static void
encode_c4x_single (fmt, buf, r)
const struct real_format *fmt ATTRIBUTE_UNUSED;
long *buf;
const struct real_value *r;
const REAL_VALUE_TYPE *r;
{
unsigned long image, exp, sig;
......@@ -3788,7 +3732,7 @@ encode_c4x_single (fmt, buf, r)
static void
decode_c4x_single (fmt, r, buf)
const struct real_format *fmt ATTRIBUTE_UNUSED;
struct real_value *r;
REAL_VALUE_TYPE *r;
const long *buf;
{
unsigned long image = buf[0];
......@@ -3824,7 +3768,7 @@ static void
encode_c4x_extended (fmt, buf, r)
const struct real_format *fmt ATTRIBUTE_UNUSED;
long *buf;
const struct real_value *r;
const REAL_VALUE_TYPE *r;
{
unsigned long exp, sig;
......@@ -3872,7 +3816,7 @@ encode_c4x_extended (fmt, buf, r)
static void
decode_c4x_extended (fmt, r, buf)
const struct real_format *fmt ATTRIBUTE_UNUSED;
struct real_value *r;
REAL_VALUE_TYPE *r;
const long *buf;
{
unsigned long sig;
......
......@@ -24,26 +24,47 @@
#include "machmode.h"
/* REAL_VALUE_TYPE is an array of the minimum number of HOST_WIDE_INTs
required to hold a 128-bit floating point type. This is true even
if the maximum precision floating point type on the target is smaller.
/* An expanded form of the represented number. */
/* Enumerate the special cases of numbers that we encounter. */
enum real_value_class {
rvc_zero,
rvc_normal,
rvc_inf,
rvc_nan
};
#define SIGNIFICAND_BITS 128
#define EXP_BITS (32 - 3)
#define MAX_EXP ((1 << (EXP_BITS - 1)) - 1)
#define SIGSZ (SIGNIFICAND_BITS / HOST_BITS_PER_LONG)
#define SIG_MSB ((unsigned long)1 << (HOST_BITS_PER_LONG - 1))
struct real_value GTY(())
{
enum real_value_class class : 2;
unsigned int sign : 1;
int exp : EXP_BITS;
unsigned long sig[SIGSZ];
};
The extra 32 bits are for storing the mode of the float. Ideally
we'd keep this elsewhere, but that's too drastic a change all at once. */
/* Various headers condition prototypes on #ifdef REAL_VALUE_TYPE, so it
needs to be a macro. We do need to continue to have a structure tag
so that other headers can forward declare it. */
#define REAL_VALUE_TYPE struct real_value
#define REAL_VALUE_TYPE_SIZE (128 + 32)
/* We store a REAL_VALUE_TYPE into an rtx, and we do this by putting it in
consecutive "w" slots. Moreover, we've got to compute the number of "w"
slots at preprocessor time, which means we can't use sizeof. Guess. */
#define REAL_VALUE_TYPE_SIZE (SIGNIFICAND_BITS + 32)
#define REAL_WIDTH \
(REAL_VALUE_TYPE_SIZE/HOST_BITS_PER_WIDE_INT \
+ (REAL_VALUE_TYPE_SIZE%HOST_BITS_PER_WIDE_INT ? 1 : 0)) /* round up */
struct realvaluetype GTY(()) {
HOST_WIDE_INT r[REAL_WIDTH];
};
/* Various headers condition prototypes on #ifdef REAL_VALUE_TYPE, so it needs
to be a macro. realvaluetype cannot be a typedef as this interferes with
other headers declaring opaque pointers to it. */
#define REAL_VALUE_TYPE struct realvaluetype
/* Verify the guess. */
extern char test_real_width
[sizeof(REAL_VALUE_TYPE) <= REAL_WIDTH*sizeof(HOST_WIDE_INT) ? 1 : -1];
/* Calculate the format for CONST_DOUBLE. We need as many slots as
are necessary to overlay a REAL_VALUE_TYPE on them. This could be
......
......@@ -726,10 +726,10 @@ struct tree_int_cst GTY(())
#define TREE_CST_RTL(NODE) (CST_OR_CONSTRUCTOR_CHECK (NODE)->real_cst.rtl)
/* In a REAL_CST node. struct realvaluetype is an opaque entity, with
/* In a REAL_CST node. struct real_value is an opaque entity, with
manipulators defined in real.h. We don't want tree.h depending on
real.h and transitively on tm.h. */
struct realvaluetype;
struct real_value;
#define TREE_REAL_CST_PTR(NODE) (REAL_CST_CHECK (NODE)->real_cst.real_cst_ptr)
#define TREE_REAL_CST(NODE) (*TREE_REAL_CST_PTR (NODE))
......@@ -738,7 +738,7 @@ struct tree_real_cst GTY(())
{
struct tree_common common;
rtx rtl; /* acts as link to register transfer language (rtl) info */
struct realvaluetype * real_cst_ptr;
struct real_value * real_cst_ptr;
};
/* In a STRING_CST */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment