diff options
author | kenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4> | 1996-04-14 12:53:43 +0000 |
---|---|---|
committer | kenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4> | 1996-04-14 12:53:43 +0000 |
commit | 29e608937034c2fd1df96e630d3055fc23c8e35c (patch) | |
tree | 2be7c84d1b2d454e09d66c00d9e936b43ddc0089 /gcc/real.c | |
parent | 24460e25851eea59dd6c881b16c5d0ee6bfef0f5 (diff) | |
download | gcc-29e608937034c2fd1df96e630d3055fc23c8e35c.tar.gz |
(ereal_from_{int,uint}): New arg, MODE.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@11763 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/real.c')
-rw-r--r-- | gcc/real.c | 70 |
1 files changed, 68 insertions, 2 deletions
diff --git a/gcc/real.c b/gcc/real.c index e8f78ad73cf..b5e29859658 100644 --- a/gcc/real.c +++ b/gcc/real.c @@ -758,14 +758,17 @@ efixui (x) /* REAL_VALUE_FROM_INT macro. */ void -ereal_from_int (d, i, j) +ereal_from_int (d, i, j, mode) REAL_VALUE_TYPE *d; HOST_WIDE_INT i, j; + enum machine_mode mode; { unsigned EMUSHORT df[NE], dg[NE]; HOST_WIDE_INT low, high; int sign; + if (GET_MODE_CLASS (mode) != MODE_FLOAT) + abort (); sign = 0; low = i; if ((high = j) < 0) @@ -785,6 +788,36 @@ ereal_from_int (d, i, j) eadd (df, dg, dg); if (sign) eneg (dg); + + /* A REAL_VALUE_TYPE may not be wide enough to hold the two HOST_WIDE_INTS. + Avoid double-rounding errors later by rounding off now from the + extra-wide internal format to the requested precision. */ + switch (GET_MODE_BITSIZE (mode)) + { + case 32: + etoe24 (dg, df); + e24toe (df, dg); + break; + + case 64: + etoe53 (dg, df); + e53toe (df, dg); + break; + + case 96: + etoe64 (dg, df); + e64toe (df, dg); + break; + + case 128: + etoe113 (dg, df); + e113toe (df, dg); + break; + + default: + abort (); + } + PUT_REAL (dg, d); } @@ -792,13 +825,16 @@ ereal_from_int (d, i, j) /* REAL_VALUE_FROM_UNSIGNED_INT macro. */ void -ereal_from_uint (d, i, j) +ereal_from_uint (d, i, j, mode) REAL_VALUE_TYPE *d; unsigned HOST_WIDE_INT i, j; + enum machine_mode mode; { unsigned EMUSHORT df[NE], dg[NE]; unsigned HOST_WIDE_INT low, high; + if (GET_MODE_CLASS (mode) != MODE_FLOAT) + abort (); low = i; high = j; eldexp (eone, HOST_BITS_PER_WIDE_INT, df); @@ -806,6 +842,36 @@ ereal_from_uint (d, i, j) emul (dg, df, dg); ultoe (&low, df); eadd (df, dg, dg); + + /* A REAL_VALUE_TYPE may not be wide enough to hold the two HOST_WIDE_INTS. + Avoid double-rounding errors later by rounding off now from the + extra-wide internal format to the requested precision. */ + switch (GET_MODE_BITSIZE (mode)) + { + case 32: + etoe24 (dg, df); + e24toe (df, dg); + break; + + case 64: + etoe53 (dg, df); + e53toe (df, dg); + break; + + case 96: + etoe64 (dg, df); + e64toe (df, dg); + break; + + case 128: + etoe113 (dg, df); + e113toe (df, dg); + break; + + default: + abort (); + } + PUT_REAL (dg, d); } |