/* Simple data type for positive real numbers for the GNU compiler.
- Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA. */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA. */
/* This library supports positive real numbers and 0;
inf and nan are NOT supported.
Value of sreal is
x = sig * 2 ^ exp
- where
+ where
sig = significant
(for < 64-bit machines sig = sig_lo + sig_hi * 2 ^ SREAL_PART_BITS)
exp = exponent
otherwise two HOST_WIDE_INTs are used for the significant.
Only a half of significant bits is used (in normalized sreals) so that we do
not have problems with overflow, for example when c->sig = a->sig * b->sig.
- So the precission for 64-bit and 32-bit machines is 32-bit.
-
+ So the precision for 64-bit and 32-bit machines is 32-bit.
+
Invariant: The numbers are normalized before and after each call of sreal_*.
Normalized sreals:
All numbers (except zero) meet following conditions:
SREAL_MIN_SIG <= sig && sig <= SREAL_MAX_SIG
- -SREAL_MAX_EXP <= exp && exp <= SREAL_MAX_EXP
+ -SREAL_MAX_EXP <= exp && exp <= SREAL_MAX_EXP
If the number would be too large, it is set to upper bounds of these
conditions.
#include "tm.h"
#include "sreal.h"
-void dump_sreal PARAMS ((FILE *, sreal *));
-static inline void copy PARAMS ((sreal *, sreal *));
-static inline void shift_right PARAMS ((sreal *, int));
-static void normalize PARAMS ((sreal *));
+static inline void copy (sreal *, sreal *);
+static inline void shift_right (sreal *, int);
+static void normalize (sreal *);
/* Print the content of struct sreal. */
void
-dump_sreal (file, x)
- FILE *file;
- sreal *x;
+dump_sreal (FILE *file, sreal *x)
{
#if SREAL_PART_BITS < 32
fprintf (file, "((" HOST_WIDE_INT_PRINT_UNSIGNED " * 2^16 + "
/* Copy the sreal number. */
static inline void
-copy (r, a)
- sreal *r;
- sreal *a;
+copy (sreal *r, sreal *a)
{
#if SREAL_PART_BITS < 32
r->sig_lo = a->sig_lo;
When the most significant bit shifted out is 1, add 1 to X (rounding). */
static inline void
-shift_right (x, s)
- sreal *x;
- int s;
+shift_right (sreal *x, int s)
{
-#ifdef ENABLE_CHECKING
- if (s <= 0 || s > SREAL_BITS)
- abort ();
- if (x->exp + s > SREAL_MAX_EXP)
- {
- /* Exponent should never be so large because shift_right is used only by
- sreal_add and sreal_sub ant thus the number cannot be shifted out from
- exponent range. */
- abort ();
- }
-#endif
+ gcc_assert (s > 0);
+ gcc_assert (s <= SREAL_BITS);
+ /* Exponent should never be so large because shift_right is used only by
+ sreal_add and sreal_sub ant thus the number cannot be shifted out from
+ exponent range. */
+ gcc_assert (x->exp + s <= SREAL_MAX_EXP);
x->exp += s;
/* Normalize *X. */
static void
-normalize (x)
- sreal *x;
+normalize (sreal *x)
{
#if SREAL_PART_BITS < 32
int shift;
HOST_WIDE_INT mask;
-
+
if (x->sig_lo == 0 && x->sig_hi == 0)
{
x->exp = -SREAL_MAX_EXP;
/* Set *R to SIG * 2 ^ EXP. Return R. */
sreal *
-sreal_init (r, sig, exp)
- sreal *r;
- unsigned HOST_WIDE_INT sig;
- signed int exp;
+sreal_init (sreal *r, unsigned HOST_WIDE_INT sig, signed int exp)
{
#if SREAL_PART_BITS < 32
r->sig_lo = 0;
/* Return integer value of *R. */
HOST_WIDE_INT
-sreal_to_int (r)
- sreal *r;
+sreal_to_int (sreal *r)
{
#if SREAL_PART_BITS < 32
if (r->exp <= -SREAL_BITS)
/* Compare *A and *B. Return -1 if *A < *B, 1 if *A > *B and 0 if *A == *B. */
int
-sreal_compare (a, b)
- sreal *a;
- sreal *b;
+sreal_compare (sreal *a, sreal *b)
{
if (a->exp > b->exp)
return 1;
/* *R = *A + *B. Return R. */
sreal *
-sreal_add (r, a, b)
- sreal *r;
- sreal *a;
- sreal *b;
+sreal_add (sreal *r, sreal *a, sreal *b)
{
int dexp;
sreal tmp;
/* *R = *A - *B. Return R. */
sreal *
-sreal_sub (r, a, b)
- sreal *r;
- sreal *a;
- sreal *b;
+sreal_sub (sreal *r, sreal *a, sreal *b)
{
int dexp;
sreal tmp;
sreal *bb;
- if (sreal_compare (a, b) < 0)
- {
- abort ();
- }
+ gcc_assert (sreal_compare (a, b) >= 0);
dexp = a->exp - b->exp;
r->exp = a->exp;
/* *R = *A * *B. Return R. */
sreal *
-sreal_mul (r, a, b)
- sreal *r;
- sreal *a;
- sreal *b;
+sreal_mul (sreal *r, sreal *a, sreal *b)
{
#if SREAL_PART_BITS < 32
if (a->sig_hi < SREAL_MIN_SIG || b->sig_hi < SREAL_MIN_SIG)
/* *R = *A / *B. Return R. */
sreal *
-sreal_div (r, a, b)
- sreal *r;
- sreal *a;
- sreal *b;
+sreal_div (sreal *r, sreal *a, sreal *b)
{
#if SREAL_PART_BITS < 32
unsigned HOST_WIDE_INT tmp, tmp1, tmp2;
- if (b->sig_hi < SREAL_MIN_SIG)
- {
- abort ();
- }
- else if (a->sig_hi < SREAL_MIN_SIG)
+ gcc_assert (b->sig_hi >= SREAL_MIN_SIG);
+ if (a->sig_hi < SREAL_MIN_SIG)
{
r->sig_hi = 0;
r->sig_lo = 0;
normalize (r);
}
#else
- if (b->sig == 0)
- {
- abort ();
- }
- else
- {
- r->sig = (a->sig << SREAL_PART_BITS) / b->sig;
- r->exp = a->exp - b->exp - SREAL_PART_BITS;
- normalize (r);
- }
+ gcc_assert (b->sig != 0);
+ r->sig = (a->sig << SREAL_PART_BITS) / b->sig;
+ r->exp = a->exp - b->exp - SREAL_PART_BITS;
+ normalize (r);
#endif
return r;
}