RFC: Make IEEE extended have 80, not 96, bits of TYPE_PRECISION

Zack Weinberg zack@codesourcery.com
Wed Jul 21 08:27:00 GMT 2004


This patch adjusts the TYPE_PRECISION of all XFmode types to be 80,
not 96.  Likewise, LONG_DOUBLE_TYPE_SIZE changes when it's XFmode, and
so on.  The motivation for this patch is to make it possible to define
an ia64-specific "RFmode" whose precision is 82 bits.  (This is the
full precision of an ia64 floating point register.  The semantics of
that mode are kind of strange, but that's the hardware's fault.)  This
does *not* change the size in memory of any such type; that's
determined by the floatformat structure.  (See the discussion last
year about simultaneous use of XFmode and TFmode.)

I am testing this patch in the usual fashion on i386-linux, being one
of the few targets with an XFmode long double.  However, I would
appreciate suggestions for additional testing; I don't think the usual
test suite exercises long double very much.  Also, if anyone knows a
place I neglected to change, please tell me.  (I audited every
instance of the integer literal "96" in the source tree, but that may
well not be sufficient.)

N.B. config/m68k/netbsd-elf.h has an #ifdef __mc68010__ in it, which
will give the wrong result when cross-compiling; that's a preexisting
condition so I did not attempt to fix it.

zw

        * libgcc2.c: Change all conditionals testing
        LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96 to == 80.
        * libgcc2.h: Likewise.
        * config/i386/i386.c (ix86_init_mmx_sse_builtins): Set
        TYPE_PRECISION of float80_type to 80.
        * config/ia64/ia64.c (ia64_init_builtins): Set TYPE_PRECISION
        of fpreg_type and float80_type to 80.
        * config/i386/i386.h, config/ia64/ia64.h, config/m68k/m68k.h
        * config/m68k/netbsd-elf.h:
        Change LONG_DOUBLE_TYPE_SIZE and possibly LIBGCC2_LONG_DOUBLE_TYPE_SIZE
        to evaluate to 80 whenever they would formerly have evaluated to 96.
        * config/i386/sco5.h: Remove unnecessary redefinition of
        LONG_DOUBLE_TYPE_SIZE.
        * doc/rtl.texi: Clarify uses of XFmode and TFmode.

===================================================================
Index: gcc/libgcc2.c
--- gcc/libgcc2.c	17 Jul 2004 21:09:09 -0000	1.172
+++ gcc/libgcc2.c	20 Jul 2004 23:08:47 -0000
@@ -1137,7 +1137,7 @@ __fixtfdi (TFtype a)
 }
 #endif
 
-#if defined(L_fixunsxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
+#if defined(L_fixunsxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 80)
 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
 
@@ -1166,7 +1166,7 @@ __fixunsxfDI (XFtype a)
 }
 #endif
 
-#if defined(L_fixxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
+#if defined(L_fixxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 80)
 DWtype
 __fixxfdi (XFtype a)
 {
@@ -1245,7 +1245,7 @@ __fixsfdi (SFtype a)
 }
 #endif
 
-#if defined(L_floatdixf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
+#if defined(L_floatdixf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 80)
 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
@@ -1340,7 +1340,7 @@ __floatdisf (DWtype u)
 }
 #endif
 
-#if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
+#if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 80
 /* Reenable the normal types, in case limits.h needs them.  */
 #undef char
 #undef short
===================================================================
Index: gcc/libgcc2.h
--- gcc/libgcc2.h	21 Dec 2003 14:08:34 -0000	1.28
+++ gcc/libgcc2.h	20 Jul 2004 23:08:47 -0000
@@ -89,7 +89,7 @@ typedef unsigned int UTItype	__attribute
 typedef 	float SFtype	__attribute__ ((mode (SF)));
 typedef		float DFtype	__attribute__ ((mode (DF)));
 
-#if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
+#if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 80
 typedef		float XFtype	__attribute__ ((mode (XF)));
 #endif
 #if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128
@@ -272,7 +272,7 @@ extern UWtype __fixunssfSI (SFtype);
 extern DWtype __fixunsdfDI (DFtype);
 extern DWtype __fixunssfDI (SFtype);
 
-#if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
+#if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 80
 extern DWtype __fixxfdi (XFtype);
 extern DWtype __fixunsxfDI (XFtype);
 extern XFtype __floatdixf (DWtype);
===================================================================
Index: gcc/config/i386/i386.c
--- gcc/config/i386/i386.c	20 Jul 2004 12:25:51 -0000	1.696
+++ gcc/config/i386/i386.c	20 Jul 2004 23:08:47 -0000
@@ -13368,7 +13368,7 @@ ix86_init_mmx_sse_builtins (void)
     {
       /* The __float80 type.  */
       float80_type = make_node (REAL_TYPE);
-      TYPE_PRECISION (float80_type) = 96;
+      TYPE_PRECISION (float80_type) = 80;
       layout_type (float80_type);
       (*lang_hooks.types.register_builtin_type) (float80_type, "__float80");
     }
===================================================================
Index: gcc/config/i386/i386.h
--- gcc/config/i386/i386.h	16 Jul 2004 23:25:43 -0000	1.391
+++ gcc/config/i386/i386.h	20 Jul 2004 23:08:47 -0000
@@ -736,7 +736,7 @@ extern int x86_prefetch_sse;
 
 /* target machine storage layout */
 
-#define LONG_DOUBLE_TYPE_SIZE 96
+#define LONG_DOUBLE_TYPE_SIZE 80
 
 /* Set the value of FLT_EVAL_METHOD in float.h.  When using only the
    FPU, assume that the fpcw is set to extended precision; when using
===================================================================
Index: gcc/config/i386/sco5.h
--- gcc/config/i386/sco5.h	24 Dec 2003 00:14:20 -0000	1.83
+++ gcc/config/i386/sco5.h	20 Jul 2004 23:08:47 -0000
@@ -96,13 +96,11 @@ Boston, MA 02111-1307, USA.  */
 #undef WCHAR_TYPE
 #undef WCHAR_TYPE_SIZE
 #undef WINT_TYPE
-#undef LONG_DOUBLE_TYPE_SIZE
 #define SIZE_TYPE		"unsigned int"
 #define PTRDIFF_TYPE		"int"
 #define WCHAR_TYPE		"long int"
 #define WCHAR_TYPE_SIZE		BITS_PER_WORD
 #define WINT_TYPE		"long int"
-#define LONG_DOUBLE_TYPE_SIZE 	96
 
 /*
  * New for multilib support. Set the default switches for multilib,
===================================================================
Index: gcc/config/ia64/ia64.c
--- gcc/config/ia64/ia64.c	20 Jul 2004 07:27:08 -0000	1.309
+++ gcc/config/ia64/ia64.c	20 Jul 2004 23:08:47 -0000
@@ -8158,13 +8158,13 @@ ia64_init_builtins (void)
   fpreg_type = make_node (REAL_TYPE);
   /* ??? The back end should know to load/save __fpreg variables using
      the ldf.fill and stf.spill instructions.  */
-  TYPE_PRECISION (fpreg_type) = 96;
+  TYPE_PRECISION (fpreg_type) = 80;
   layout_type (fpreg_type);
   (*lang_hooks.types.register_builtin_type) (fpreg_type, "__fpreg");
 
   /* The __float80 type.  */
   float80_type = make_node (REAL_TYPE);
-  TYPE_PRECISION (float80_type) = 96;
+  TYPE_PRECISION (float80_type) = 80;
   layout_type (float80_type);
   (*lang_hooks.types.register_builtin_type) (float80_type, "__float80");
 
===================================================================
Index: gcc/config/ia64/ia64.h
--- gcc/config/ia64/ia64.h	16 Jul 2004 23:25:45 -0000	1.182
+++ gcc/config/ia64/ia64.h	20 Jul 2004 23:08:47 -0000
@@ -443,10 +443,10 @@ while (0)
 #define DOUBLE_TYPE_SIZE 64
 
 /* long double is XFmode normally, TFmode for HPUX.  */
-#define LONG_DOUBLE_TYPE_SIZE (TARGET_HPUX ? 128 : 96)
+#define LONG_DOUBLE_TYPE_SIZE (TARGET_HPUX ? 128 : 80)
 
 /* We always want the XFmode operations from libgcc2.c.  */
-#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 96
+#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 80
 
 #define DEFAULT_SIGNED_CHAR 1
 
===================================================================
Index: gcc/config/m68k/m68k.h
--- gcc/config/m68k/m68k.h	15 Jul 2004 21:18:10 -0000	1.117
+++ gcc/config/m68k/m68k.h	20 Jul 2004 23:08:47 -0000
@@ -354,7 +354,7 @@ extern int target_flags;
 
 /* target machine storage layout */
 
-#define LONG_DOUBLE_TYPE_SIZE 96
+#define LONG_DOUBLE_TYPE_SIZE 80
 
 /* Set the value of FLT_EVAL_METHOD in float.h.  When using 68040 fp
    instructions, we get proper intermediate rounding, otherwise we
===================================================================
Index: gcc/config/m68k/netbsd-elf.h
--- gcc/config/m68k/netbsd-elf.h	8 Feb 2004 23:30:49 -0000	1.23
+++ gcc/config/m68k/netbsd-elf.h	20 Jul 2004 23:08:47 -0000
@@ -43,12 +43,12 @@ Boston, MA 02111-1307, USA.  */
 #undef LONG_DOUBLE_TYPE_SIZE
 #define LONG_DOUBLE_TYPE_SIZE			\
   ((TARGET_68020 || TARGET_68040 || TARGET_68040_ONLY || \
-    TARGET_68060) ? 96 : 64)
+    TARGET_68060) ? 80 : 64)
 
 #ifdef __mc68010__
 #define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64
 #else
-#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 96
+#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 80
 #endif
 
 #define EXTRA_SPECS \
===================================================================
Index: gcc/doc/rtl.texi
--- gcc/doc/rtl.texi	7 Jul 2004 19:25:00 -0000	1.68
+++ gcc/doc/rtl.texi	20 Jul 2004 23:08:48 -0000
@@ -1100,15 +1100,16 @@ this is a double-precision IEEE floating
 
 @findex XFmode
 @item XFmode
-``Extended Floating'' mode represents a twelve byte floating point
-number.  This mode is used for IEEE extended floating point.  On some
-systems not all bits within these bytes will actually be used.
+``Extended Floating'' mode represents an IEEE extended floating point
+number.  This mode only has 80 meaningful bits (ten bytes).  Some
+processors require such numbers to be padded to twelve bytes, others
+to sixteen; this mode is used for either.
 
 @findex TFmode
 @item TFmode
-``Tetra Floating'' mode represents a sixteen byte floating point number.
-This gets used for both the 96-bit extended IEEE floating-point types
-padded to 128 bits, and true 128-bit extended IEEE floating-point types.
+``Tetra Floating'' mode represents a sixteen byte floating point number
+all 128 of whose bits are meaningful.  One common use is the
+IEEE quad-precision format.
 
 @findex CCmode
 @item CCmode



More information about the Gcc-patches mailing list