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