OSDN Git Service

* config/xtensa/xtensa.c (xtensa_init_machine_status): Fix
[pf3gnuchains/gcc-fork.git] / gcc / real.h
index 5683bbc..174d2c4 100644 (file)
@@ -22,6 +22,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #ifndef GCC_REAL_H
 #define GCC_REAL_H
 
+#include "machmode.h"
+
 /* Define codes for all the float formats that we know of.  */
 #define UNKNOWN_FLOAT_FORMAT 0
 #define IEEE_FLOAT_FORMAT 1
@@ -76,19 +78,53 @@ 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 REAL_VALUE_TYPE_SIZE 96
+#endif
+#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
+
+/* 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    "ww"
 #else
-#define N (MAX_LONG_DOUBLE_TYPE_SIZE / BITS_PER_UNIT)
+# if REAL_WIDTH == 2
+#  define CONST_DOUBLE_FORMAT   "ww"
+# else
+#  if REAL_WIDTH == 3
+#   define CONST_DOUBLE_FORMAT  "www"
+#  else
+#   if REAL_WIDTH == 4
+#    define CONST_DOUBLE_FORMAT         "wwww"
+#   else
+#    if REAL_WIDTH == 5
+#     define CONST_DOUBLE_FORMAT "wwwww"
+#    else
+      #error "REAL_WIDTH > 5 not supported"
+#    endif
+#   endif
+#  endif
+# endif
 #endif
-#define S sizeof (HOST_WIDE_INT)
-typedef struct {
-  HOST_WIDE_INT r[N/S + (N%S ? 1 : 0)]; /* round up */
-} REAL_VALUE_TYPE;
-#undef N
-#undef S
 
 extern unsigned int significand_size   PARAMS ((enum machine_mode));
 
@@ -147,6 +183,11 @@ extern REAL_VALUE_TYPE ereal_from_double PARAMS ((HOST_WIDE_INT *));
 extern REAL_VALUE_TYPE real_value_truncate PARAMS ((enum machine_mode,
                                                  REAL_VALUE_TYPE));
 
+/* Expansion of REAL_VALUE_TRUNCATE.
+   The result is in floating point, rounded to nearest or even.  */
+extern bool exact_real_truncate PARAMS ((enum machine_mode,
+                                        REAL_VALUE_TYPE *));
+
 /* These return HOST_WIDE_INT: */
 /* Convert a floating-point value to integer, rounding toward zero.  */
 #define REAL_VALUE_FIX(x) (efixi (x))
@@ -161,6 +202,10 @@ extern REAL_VALUE_TYPE real_value_truncate PARAMS ((enum machine_mode,
 
 #define REAL_VALUE_NEGATE ereal_negate
 
+/* Compute the absolute value of a floating-point value X.  */
+#define REAL_VALUE_ABS(x) \
+   (REAL_VALUE_NEGATIVE (x) ? REAL_VALUE_NEGATE (x) : (x))
+
 /* Determine whether a floating-point value X is infinite.  */
 #define REAL_VALUE_ISINF(x) (target_isinf (x))
 
@@ -231,9 +276,14 @@ REAL_VALUE_TYPE real_value_from_int_cst    PARAMS ((union tree_node *,
 
 /* Return a CONST_DOUBLE with value R and mode M.  */
 
-#define CONST_DOUBLE_FROM_REAL_VALUE(r, m) immed_real_const_1 (r,  m)
-extern struct rtx_def *immed_real_const_1      PARAMS ((REAL_VALUE_TYPE,
-                                                      enum machine_mode));
+#define CONST_DOUBLE_FROM_REAL_VALUE(r, m) \
+  const_double_from_real_value (r, m)
+extern rtx const_double_from_real_value PARAMS ((REAL_VALUE_TYPE,
+                                                enum machine_mode));
+
+/* Shorthand; can be handy in machine descriptions.  */
+#define CONST_DOUBLE_ATOF(s, m) \
+  CONST_DOUBLE_FROM_REAL_VALUE (REAL_VALUE_ATOF (s, m), m)
 
 /* Replace R by 1/R in the given machine mode, if the result is exact.  */
 extern int exact_real_inverse  PARAMS ((enum machine_mode, REAL_VALUE_TYPE *));
@@ -243,4 +293,8 @@ extern int target_negative  PARAMS ((REAL_VALUE_TYPE));
 extern void debug_real         PARAMS ((REAL_VALUE_TYPE));
 extern REAL_VALUE_TYPE ereal_atof PARAMS ((const char *, enum machine_mode));
 
+/* In tree.c: wrap up a REAL_VALUE_TYPE in a tree node.  */
+extern tree build_real                 PARAMS ((tree, REAL_VALUE_TYPE));
+
+
 #endif /* ! GCC_REAL_H */