Commit 46468cd9 by Zack Weinberg

real.h: Define REAL_VALUE_TYPE_SIZE as 96 or 160, as appropriate.

	* real.h: Define REAL_VALUE_TYPE_SIZE as 96 or 160, as
	appropriate.  Document need for extended precision even when
	MAX_LONG_DOUBLE_TYPE_SIZE is smaller.  Define REAL_WIDTH here,
	based on REAL_VALUE_TYPE_SIZE.  Use REAL_WIDTH to size
	REAL_VALUE_TYPE.  Define CONST_DOUBLE_FORMAT here.  Use #error
	instead of relying on later syntax error when REAL_WIDTH > 5.
	* real.c: Define NE based only on whether or not we have a
	full 128-bit extended type (not INTEL_EXTENDED_IEEE_FORMAT).
	Require sizeof(REAL_VALUE_TYPE) == 2*NE.  Unconditionally
	define GET_REAL and PUT_REAL as simple memcpy operations; no
	need to byteswap or round.
	Use #error instead of #ifdef-ing out the entire file, for
	prompt error detection.

	* rtl.c, gengenrtl.c: No need to calculate CONST_DOUBLE_FORMAT here.

From-SVN: r52502
parent 36ce7daa
2002-04-18 Zack Weinberg <zack@codesourcery.com>
* real.h: Define REAL_VALUE_TYPE_SIZE as 96 or 160, as
appropriate. Document need for extended precision even when
MAX_LONG_DOUBLE_TYPE_SIZE is smaller. Define REAL_WIDTH here,
based on REAL_VALUE_TYPE_SIZE. Use REAL_WIDTH to size
REAL_VALUE_TYPE. Define CONST_DOUBLE_FORMAT here. Use #error
instead of relying on later syntax error when REAL_WIDTH > 5.
* real.c: Define NE based only on whether or not we have a
full 128-bit extended type (not INTEL_EXTENDED_IEEE_FORMAT).
Require sizeof(REAL_VALUE_TYPE) == 2*NE. Unconditionally
define GET_REAL and PUT_REAL as simple memcpy operations; no
need to byteswap or round.
Use #error instead of #ifdef-ing out the entire file, for
prompt error detection.
* rtl.c, gengenrtl.c: No need to calculate CONST_DOUBLE_FORMAT here.
2002-04-18 David S. Miller <davem@redhat.com>
* config/sparc/sparc.h (BRANCH_COST): Define.
......
......@@ -28,69 +28,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "real.h"
/* Calculate the format for CONST_DOUBLE. This depends on the relative
widths of HOST_WIDE_INT and REAL_VALUE_TYPE.
We need to go out to e0wwwww, since real.c assumes 16 bits per element
in REAL_VALUE_TYPE.
This is duplicated in rtl.c.
A number of places assume that there are always at least two 'w'
slots in a CONST_DOUBLE, so we provide them even if one would suffice. */
#if MAX_LONG_DOUBLE_TYPE_SIZE == 96
# define REAL_WIDTH \
(11*8 + HOST_BITS_PER_WIDE_INT)/HOST_BITS_PER_WIDE_INT
#else
# if MAX_LONG_DOUBLE_TYPE_SIZE == 128
# define REAL_WIDTH \
(19*8 + HOST_BITS_PER_WIDE_INT)/HOST_BITS_PER_WIDE_INT
# else
# if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
# define REAL_WIDTH \
(7*8 + HOST_BITS_PER_WIDE_INT)/HOST_BITS_PER_WIDE_INT
# endif
# endif
#endif
#ifndef REAL_WIDTH
# if HOST_BITS_PER_WIDE_INT*2 >= MAX_LONG_DOUBLE_TYPE_SIZE
# define REAL_WIDTH 2
# else
# if HOST_BITS_PER_WIDE_INT*3 >= MAX_LONG_DOUBLE_TYPE_SIZE
# define REAL_WIDTH 3
# else
# if HOST_BITS_PER_WIDE_INT*4 >= MAX_LONG_DOUBLE_TYPE_SIZE
# define REAL_WIDTH 4
# endif
# endif
# endif
#endif /* REAL_WIDTH */
#if REAL_WIDTH == 1
# define CONST_DOUBLE_FORMAT "0ww"
#else
# if REAL_WIDTH == 2
# define CONST_DOUBLE_FORMAT "0ww"
# else
# if REAL_WIDTH == 3
# define CONST_DOUBLE_FORMAT "0www"
# else
# if REAL_WIDTH == 4
# define CONST_DOUBLE_FORMAT "0wwww"
# else
# if REAL_WIDTH == 5
# define CONST_DOUBLE_FORMAT "0wwwww"
# else
# define CONST_DOUBLE_FORMAT /* nothing - will cause syntax error */
# endif
# endif
# endif
# endif
#endif
struct rtx_definition
{
const char *const enumname, *const name, *const format;
......
......@@ -165,8 +165,7 @@ unknown arithmetic type
#define EMUSHORT_SIZE HOST_BITS_PER_LONG
#define EMULONG_SIZE (2 * HOST_BITS_PER_LONG)
#else
/* You will have to modify this program to have a smaller unit size. */
#define EMU_NON_COMPILE
#error "You will have to modify this program to have a smaller unit size."
#endif
#endif
#endif
......@@ -199,92 +198,45 @@ typedef unsigned int UHItype __attribute__ ((mode (HI)));
#if HOST_BITS_PER_LONGLONG >= EMULONG_SIZE
#define EMULONG long long int
#else
/* You will have to modify this program to have a smaller unit size. */
#define EMU_NON_COMPILE
#error "You will have to modify this program to have a smaller unit size."
#endif
#endif
#endif
#endif
/* The host interface doesn't work if no 16-bit size exists. */
#if EMUSHORT_SIZE != 16
#define EMU_NON_COMPILE
#error "The host interface doesn't work if no 16-bit size exists."
#endif
/* OK to continue compilation. */
#ifndef EMU_NON_COMPILE
/* Construct macros to translate between REAL_VALUE_TYPE and e type.
In GET_REAL and PUT_REAL, r and e are pointers.
A REAL_VALUE_TYPE is guaranteed to occupy contiguous locations
in memory, with no holes. */
/* Calculate the size of the generic "e" type. This always has
identical in-memory size and representation to REAL_VALUE_TYPE.
There are only two supported sizes: ten and six 16-bit words (160
or 96 bits). */
#if MAX_LONG_DOUBLE_TYPE_SIZE == 96 || \
((INTEL_EXTENDED_IEEE_FORMAT != 0) && MAX_LONG_DOUBLE_TYPE_SIZE == 128)
/* Number of 16 bit words in external e type format */
# define NE 6
# define MAXDECEXP 4932
# define MINDECEXP -4956
# define GET_REAL(r,e) memcpy ((e), (r), 2*NE)
# define PUT_REAL(e,r) \
do { \
memcpy ((r), (e), 2*NE); \
if (2*NE < sizeof (*r)) \
memset ((char *) (r) + 2*NE, 0, sizeof (*r) - 2*NE); \
} while (0)
# else /* no XFmode */
# if MAX_LONG_DOUBLE_TYPE_SIZE == 128
#if MAX_LONG_DOUBLE_TYPE_SIZE == 128 && !INTEL_EXTENDED_IEEE_FORMAT
/* TFmode */
# define NE 10
# define MAXDECEXP 4932
# define MINDECEXP -4977
# define GET_REAL(r,e) memcpy ((e), (r), 2*NE)
# define PUT_REAL(e,r) \
do { \
memcpy ((r), (e), 2*NE); \
if (2*NE < sizeof (*r)) \
memset ((char *) (r) + 2*NE, 0, sizeof (*r) - 2*NE); \
} while (0)
#else
#define NE 6
#define MAXDECEXP 4932
#define MINDECEXP -4956
/* Emulator uses target format internally
but host stores it in host endian-ness. */
#define GET_REAL(r,e) \
do { \
if (HOST_FLOAT_WORDS_BIG_ENDIAN == REAL_WORDS_BIG_ENDIAN) \
e53toe ((const UEMUSHORT *) (r), (e)); \
else \
{ \
UEMUSHORT w[4]; \
memcpy (&w[3], ((const EMUSHORT *) r), sizeof (EMUSHORT)); \
memcpy (&w[2], ((const EMUSHORT *) r) + 1, sizeof (EMUSHORT)); \
memcpy (&w[1], ((const EMUSHORT *) r) + 2, sizeof (EMUSHORT)); \
memcpy (&w[0], ((const EMUSHORT *) r) + 3, sizeof (EMUSHORT)); \
e53toe (w, (e)); \
} \
} while (0)
#define PUT_REAL(e,r) \
do { \
if (HOST_FLOAT_WORDS_BIG_ENDIAN == REAL_WORDS_BIG_ENDIAN) \
etoe53 ((e), (UEMUSHORT *) (r)); \
else \
{ \
UEMUSHORT w[4]; \
etoe53 ((e), w); \
memcpy (((EMUSHORT *) r), &w[3], sizeof (EMUSHORT)); \
memcpy (((EMUSHORT *) r) + 1, &w[2], sizeof (EMUSHORT)); \
memcpy (((EMUSHORT *) r) + 2, &w[1], sizeof (EMUSHORT)); \
memcpy (((EMUSHORT *) r) + 3, &w[0], sizeof (EMUSHORT)); \
} \
} while (0)
#endif /* not TFmode */
#endif /* not XFmode */
# define NE 6
# define MAXDECEXP 4932
# define MINDECEXP -4956
#endif
/* Fail compilation if 2*NE is not the appropriate size. */
struct compile_test_dummy {
char twice_NE_must_equal_sizeof_REAL_VALUE_TYPE
[(sizeof (REAL_VALUE_TYPE) == 2*NE) ? 1 : -1];
};
/* Construct macros to translate between REAL_VALUE_TYPE and e type.
In GET_REAL and PUT_REAL, r and e are pointers.
A REAL_VALUE_TYPE is guaranteed to occupy contiguous locations
in memory, with no holes. */
#define GET_REAL(r, e) memcpy ((e), (r), 2*NE)
#define PUT_REAL(e, r) memcpy ((r), (e), 2*NE)
/* Number of 16 bit words in internal format */
#define NI (NE+3)
......@@ -6918,7 +6870,6 @@ esqrt (x, y)
emovo (sq, y);
}
#endif
#endif /* EMU_NON_COMPILE not defined */
/* Return the binary precision of the significand for a given
floating point mode. The mode can hold an integer value
......
......@@ -76,19 +76,49 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
/* **** Start of software floating point emulator interface macros **** */
/* REAL_VALUE_TYPE is an array of the minimum number of HOST_WIDE_INTs
required to hold MAX_LONG_DOUBLE_TYPE_SIZE bits. */
#if MAX_LONG_DOUBLE_TYPE_SIZE == 128
/* For 128 bit reals, we calculate internally with extra precision. */
#define N (160 / BITS_PER_UNIT)
required to hold either a 96- or 160-bit extended precision floating
point type. This is true even if the maximum precision floating
point type on the target is smaller. */
#if MAX_LONG_DOUBLE_TYPE_SIZE == 128 && !INTEL_EXTENDED_IEEE_FORMAT
#define REAL_VALUE_TYPE_SIZE 160
#else
#define N (MAX_LONG_DOUBLE_TYPE_SIZE / BITS_PER_UNIT)
#define REAL_VALUE_TYPE_SIZE 96
#endif
#define S sizeof (HOST_WIDE_INT)
#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 */
typedef struct {
HOST_WIDE_INT r[N/S + (N%S ? 1 : 0)]; /* round up */
HOST_WIDE_INT r[REAL_WIDTH];
} REAL_VALUE_TYPE;
#undef N
#undef S
/* 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
as many as five (32-bit HOST_WIDE_INT, 160-bit REAL_VALUE_TYPE).
A number of places assume that there are always at least two 'w'
slots in a CONST_DOUBLE, so we provide them even if one would suffice. */
#if REAL_WIDTH == 1
# define CONST_DOUBLE_FORMAT "0ww"
#else
# if REAL_WIDTH == 2
# define CONST_DOUBLE_FORMAT "0ww"
# else
# if REAL_WIDTH == 3
# define CONST_DOUBLE_FORMAT "0www"
# else
# if REAL_WIDTH == 4
# define CONST_DOUBLE_FORMAT "0wwww"
# else
# if REAL_WIDTH == 5
# define CONST_DOUBLE_FORMAT "0wwwww"
# else
#error "REAL_WIDTH > 5 not supported"
# endif
# endif
# endif
# endif
#endif
extern unsigned int significand_size PARAMS ((enum machine_mode));
......
......@@ -27,68 +27,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "errors.h"
/* Calculate the format for CONST_DOUBLE. This depends on the relative
widths of HOST_WIDE_INT and REAL_VALUE_TYPE.
We need to go out to 0wwwww, since real.c assumes 16 bits per element
in REAL_VALUE_TYPE.
This is duplicated in gengenrtl.c.
A number of places assume that there are always at least two 'w'
slots in a CONST_DOUBLE, so we provide them even if one would suffice. */
#if MAX_LONG_DOUBLE_TYPE_SIZE == 96
# define REAL_WIDTH \
(11*8 + HOST_BITS_PER_WIDE_INT)/HOST_BITS_PER_WIDE_INT
#else
# if MAX_LONG_DOUBLE_TYPE_SIZE == 128
# define REAL_WIDTH \
(19*8 + HOST_BITS_PER_WIDE_INT)/HOST_BITS_PER_WIDE_INT
# else
# if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
# define REAL_WIDTH \
(7*8 + HOST_BITS_PER_WIDE_INT)/HOST_BITS_PER_WIDE_INT
# endif
# endif
#endif
#ifndef REAL_WIDTH
# if HOST_BITS_PER_WIDE_INT*2 >= MAX_LONG_DOUBLE_TYPE_SIZE
# define REAL_WIDTH 2
# else
# if HOST_BITS_PER_WIDE_INT*3 >= MAX_LONG_DOUBLE_TYPE_SIZE
# define REAL_WIDTH 3
# else
# if HOST_BITS_PER_WIDE_INT*4 >= MAX_LONG_DOUBLE_TYPE_SIZE
# define REAL_WIDTH 4
# endif
# endif
# endif
#endif /* REAL_WIDTH */
#if REAL_WIDTH == 1
# define CONST_DOUBLE_FORMAT "0ww"
#else
# if REAL_WIDTH == 2
# define CONST_DOUBLE_FORMAT "0ww"
# else
# if REAL_WIDTH == 3
# define CONST_DOUBLE_FORMAT "0www"
# else
# if REAL_WIDTH == 4
# define CONST_DOUBLE_FORMAT "0wwww"
# else
# if REAL_WIDTH == 5
# define CONST_DOUBLE_FORMAT "0wwwww"
# else
# define CONST_DOUBLE_FORMAT /* nothing - will cause syntax error */
# endif
# endif
# endif
# endif
#endif
/* Indexed by rtx code, gives number of operands for an rtx with that code.
Does NOT include rtx header data (code and links). */
......
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