This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Add word-sized conversion functions to libgcc2


Mark Mitchell <mark@codesourcery.com> writes:
> Richard Sandiford wrote:
>> This message is probably going to annoy you, sorry, because I'm going
>> to propose an alternative patch.  However, even if we go with that
>> alternative patch, your description of the problem has surely helped
>> me get this far.  I'll leave it up to the reviewer (hi Mark!) to decide
>> which approach to go for, or whether we should do something else entirely.
>
> I like Richard's patch best.  I find Richard's point about making names
> of object files, etc., match the intuitive names implied by the various
> mode-conversion routines compelling, and, I like that we're eliminating
> some duplicate code.
>
>> +# LIB2LITERAL_CONVERSION_MODES
>
> I didn't find the name of this variable mnemonic; it took me a bit of
> puzzling to figure out what it meant.  How about
> LIB2_CONVERSION_FUNC_NAMES_USE_ACTUAL_MODES?  But, this is bikeshed
> material; if you don't like my name, use your original one, or one of
> your choosing, without feeling you ought to consult with me.
>
> Please test, and, assuming no problems, apply.

OK, thanks.  I changed the name to "LIB2_SIDITI_CONV_FUNCS".
"SIDITI_CONV" was meant to emphasise that we try to generate
conversion functions for all three modes, not just 2 of them
as previously.  "FUNCS" was for consistency with other parameters.

Testing:

  - bootstrapped & regression tested on i686-pc-linux-gnu
  - regression tested on a mips64-linux-gnu cross (all three ABIs)
  - regression tested on a mipsisa64-elf cross
    (--target_board mips-sim{,-mips32}{-EB,-EL}{,-msoft-float})

Here's what I applied.

Richard


	* libgcc2.c (MIN_UNITS_PER_WORD): Move default definition from
	libgcc2.h.
	(LIBGCC2_UNITS_PER_WORD): Provide default definition, using old
	MIN_UNITS_PER_WORD logic from libgcc2.h.  Do nothing if
	LIBGCC2_UNITS_PER_WORD > MIN_UNITS_PER_WORD.
	* libgcc2.h (MIN_UNITS_PER_WORD): Remove definition from here.
	Use LIBGCC2_UNITS_PER_WORD rather than MIN_UNITS_PER_WORD to
	determine the size of Wtype, etc.
	* mklibgcc.in (LIB2_SIDITI_CONV_FUNCS): New argument.
	(swfloatfuncs): New variable.
	(dwfloatfuncs): Likewise.
	(lib2funcs): Remove floating-point conversion functions from
	initial assignment.  Use LIB2_SIDITI_CONV_FUNCS to determine
	the set of conversion routines needed.  Allow entries to specify
	an object name, filename and word size.  Update users accordingly.
	* Makefile.in (libgcc.mk): Pass LIB2_SIDITI_CONV_FUNCS.
	* config/mips/t-mips (LIB2_SIDITI_CONV_FUNCS): Define.

	Revert:

	2006-02-08  Roger Sayle  <roger@eyesopen.com>

	PR target/22209
	* config/fixtfdi.c: New libgcc source file.
	* config/fixunstfdi.c: New source file.
	* config/floatditf.c: New source file.
	* config/floatunditf.c: New souce file.
	* config/mips/t-iris6 (LIB2FUNCS_EXTRA): Include the new source
	files above instead of config/mips/_tilib.c.
	* config/mips/t-linux64 (LIB2FUNCS_EXTRA): Likewise.

Index: gcc/libgcc2.c
===================================================================
--- gcc/libgcc2.c	(revision 113842)
+++ gcc/libgcc2.c	(working copy)
@@ -40,6 +40,23 @@ #define ATTRIBUTE_HIDDEN  __attribute__ 
 #define ATTRIBUTE_HIDDEN
 #endif
 
+#ifndef MIN_UNITS_PER_WORD
+#define MIN_UNITS_PER_WORD UNITS_PER_WORD
+#endif
+
+#ifndef LIBGCC2_UNITS_PER_WORD
+# if MIN_UNITS_PER_WORD > 4
+#  define LIBGCC2_UNITS_PER_WORD 8
+# elif (MIN_UNITS_PER_WORD > 2 \
+        || (MIN_UNITS_PER_WORD > 1 && LONG_LONG_TYPE_SIZE > 32))
+#  define LIBGCC2_UNITS_PER_WORD 4
+# else
+#  define LIBGCC2_UNITS_PER_WORD MIN_UNITS_PER_WORD
+# endif
+#endif
+
+#if LIBGCC2_UNITS_PER_WORD <= MIN_UNITS_PER_WORD
+
 #include "libgcc2.h"
 
 #ifdef DECLARE_LIBRARY_RENAMES
@@ -2162,3 +2179,4 @@ func_ptr __DTOR_LIST__[2] = {0, 0};
 #endif
 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
 #endif /* L_ctors */
+#endif /* LIBGCC2_UNITS_PER_WORD <= MIN_UNITS_PER_WORD */
Index: gcc/libgcc2.h
===================================================================
--- gcc/libgcc2.h	(revision 113842)
+++ gcc/libgcc2.h	(working copy)
@@ -125,10 +125,6 @@ #define IS_IBM_EXTENDED(SIZE) (SIZE == 1
 #define IS_IBM_EXTENDED(SIZE) 0
 #endif
 
-#ifndef MIN_UNITS_PER_WORD
-#define MIN_UNITS_PER_WORD UNITS_PER_WORD
-#endif
-
 /* In the first part of this file, we are interfacing to calls generated
    by the compiler itself.  These calls pass values into these routines
    which have very specific modes (rather than very specific types), and
@@ -201,7 +197,7 @@ #define double bogus_type
    turns out that no platform would define COMPAT_DIMODE_TRAPPING_ARITHMETIC
    if it existed.  */
 
-#if MIN_UNITS_PER_WORD > 4
+#if LIBGCC2_UNITS_PER_WORD == 8
 #define W_TYPE_SIZE (8 * BITS_PER_UNIT)
 #define Wtype	DItype
 #define UWtype	UDItype
@@ -212,8 +208,7 @@ #define UDWtype	UTItype
 #define __NW(a,b)	__ ## a ## di ## b
 #define __NDW(a,b)	__ ## a ## ti ## b
 #define COMPAT_SIMODE_TRAPPING_ARITHMETIC
-#elif MIN_UNITS_PER_WORD > 2 \
-      || (MIN_UNITS_PER_WORD > 1 && LONG_LONG_TYPE_SIZE > 32)
+#elif LIBGCC2_UNITS_PER_WORD == 4
 #define W_TYPE_SIZE (4 * BITS_PER_UNIT)
 #define Wtype	SItype
 #define UWtype	USItype
@@ -223,7 +218,7 @@ #define DWtype	DItype
 #define UDWtype	UDItype
 #define __NW(a,b)	__ ## a ## si ## b
 #define __NDW(a,b)	__ ## a ## di ## b
-#elif MIN_UNITS_PER_WORD > 1
+#elif LIBGCC2_UNITS_PER_WORD == 2
 #define W_TYPE_SIZE (2 * BITS_PER_UNIT)
 #define Wtype	HItype
 #define UWtype	UHItype
Index: gcc/mklibgcc.in
===================================================================
--- gcc/mklibgcc.in	(revision 113842)
+++ gcc/mklibgcc.in	(working copy)
@@ -26,6 +26,7 @@
 # FPBIT
 # FPBIT_FUNCS
 # LIB2_DIVMOD_FUNCS
+# LIB2_SIDITI_CONV_FUNCS
 # DFP_ENABLE
 # DFP_CFLAGS
 # DPBIT
@@ -64,16 +65,48 @@ echo 'dirs = libgcc'
 echo
 
 # Library members defined in libgcc2.c.
+
+# The floating-point conversion routines that involve a single-word integer.
+# XX stands for the integer mode.
+swfloatfuncs=
+for mode in sf df xf; do
+  swfloatfuncs="$swfloatfuncs _fixuns${mode}XX"
+done
+
+# Likewise double-word routines.
+dwfloatfuncs=
+for mode in sf df xf tf; do
+  dwfloatfuncs="$dwfloatfuncs _fix${mode}XX _fixuns${mode}XX"
+  dwfloatfuncs="$dwfloatfuncs _floatXX${mode} _floatunXX${mode}"
+done
+
+# Entries of the form <objfile>:<func>:<wordsize> indicate that libgcc2.c
+# should be compiled with L<func> defined and with LIBGCC2_UNITS_PER_WORD
+# set to <wordsize>.  <objfile> is the name of the associated object file
+
 lib2funcs='_muldi3 _negdi2 _lshrdi3 _ashldi3 _ashrdi3
-	_cmpdi2 _ucmpdi2 _floatdidf _floatdisf _fixunsdfsi _fixunssfsi
-	_fixunsdfdi _fixdfdi _fixunssfdi _fixsfdi _fixxfdi _fixunsxfdi
-	_floatdixf _fixunsxfsi _fixtfdi _fixunstfdi _floatditf _clear_cache
+	_cmpdi2 _ucmpdi2 _floatdidf _clear_cache
 	_enable_execute_stack _trampoline __main _absvsi2 _absvdi2 _addvsi3
 	_addvdi3 _subvsi3 _subvdi3 _mulvsi3 _mulvdi3 _negvsi2 _negvdi2 _ctors
 	_ffssi2 _ffsdi2 _clz _clzsi2 _clzdi2 _ctzsi2 _ctzdi2 _popcount_tab
 	_popcountsi2 _popcountdi2 _paritysi2 _paritydi2 _powisf2 _powidf2
 	_powixf2 _powitf2 _mulsc3 _muldc3 _mulxc3 _multc3 _divsc3 _divdc3
-	_divxc3 _divtc3 _floatundidf _floatundisf _floatundixf _floatunditf'
+	_divxc3 _divtc3'
+
+if [ "$LIB2_SIDITI_CONV_FUNCS" ]; then
+  for func in $swfloatfuncs; do
+    sifunc=`echo $func | sed -e 's/XX/si/'`
+    lib2funcs="$lib2funcs $sifunc:$sifunc:4"
+  done
+  for func in $dwfloatfuncs; do
+    difunc=`echo $func | sed -e 's/XX/di/'`
+    tifunc=`echo $func | sed -e 's/XX/ti/'`
+    lib2funcs="$lib2funcs $difunc:$difunc:4 $tifunc:$difunc:8"
+  done
+else
+  lib2funcs="$lib2funcs `echo $swfloatfuncs | sed -e 's/XX/si/g'`"
+  lib2funcs="$lib2funcs `echo $dwfloatfuncs | sed -e 's/XX/di/g'`"
+fi
 
 # Disable SHLIB_LINK if shared libgcc not enabled.
 if [ "@enable_shared@" = "no" ]; then
@@ -162,8 +195,8 @@ fi
 # defined as optimized assembly code in LIB1ASMFUNCS or as C code
 # in LIB2FUNCS_EXCLUDE.
 for name in $LIB1ASMFUNCS $LIB2FUNCS_EXCLUDE; do
-  lib2funcs=`echo $lib2funcs | sed -e 's/^'$name' //' \
-				   -e 's/ '$name' / /' \
+  lib2funcs=`echo $lib2funcs | sed -e 's/^'$name'[ :]//' \
+				   -e 's/ '$name'[ :]/ /' \
 				   -e 's/ '$name'$//'`
   LIB2_DIVMOD_FUNCS=`echo $LIB2_DIVMOD_FUNCS | sed -e 's/^'$name' //' \
 				                   -e 's/ '$name' / /' \
@@ -265,16 +298,25 @@ for ml in $MULTILIBS; do
   #
 
   for name in $lib2funcs; do
+    case $name in
+      *:*:*)
+	defines=`echo $name | sed -e 's/.*:\(.*\):\(.*\)/-DL\1 -DLIBGCC2_UNITS_PER_WORD=\2/'`
+	name=`echo $name | sed -e 's/\(.*\):.*:.*/\1/'`
+	;;
+      *)
+	defines="-DL$name"
+	;;
+    esac
     if [ "$libgcc_s_so" ]; then
       out="libgcc/${dir}/${name}${objext}"
       outS="libgcc/${dir}/${name}_s${objext}"
 
       echo $outS: $libgcc2_c_dep
-      echo "	$gcc_s_compile" $flags -DL$name -c '$(srcdir)/libgcc2.c' \
+      echo "	$gcc_s_compile" $flags $defines -c '$(srcdir)/libgcc2.c' \
 	-o $outS
 
       echo $out: $libgcc2_c_dep
-      echo "	$gcc_compile" $flags -DL$name '$(vis_hide)' \
+      echo "	$gcc_compile" $flags $defines '$(vis_hide)' \
         -c '$(srcdir)/libgcc2.c' -o $out
 
       echo $libgcc_a: $out
@@ -285,7 +327,7 @@ for ml in $MULTILIBS; do
     else
       out="libgcc/${dir}/${name}${objext}"
       echo ${out}: stmp-dirs '$(srcdir)/config/$(LIB1ASMSRC)'
-      echo "	$gcc_compile" $flags -DL$name -c '$(srcdir)/libgcc2.c' -o $out
+      echo "	$gcc_compile" $flags $defines -c '$(srcdir)/libgcc2.c' -o $out
       echo $libgcc_a: $out
     fi
   done
Index: gcc/Makefile.in
===================================================================
--- gcc/Makefile.in	(revision 113842)
+++ gcc/Makefile.in	(working copy)
@@ -1415,6 +1415,7 @@ libgcc.mk: config.status Makefile mklibg
 	LIB2ADDEHSTATIC='$(LIB2ADDEHSTATIC)' \
 	LIB2ADDEHSHARED='$(LIB2ADDEHSHARED)' \
 	LIB2ADDEHDEP='$(LIB2ADDEHDEP)' \
+	LIB2_SIDITI_CONV_FUNCS='$(LIB2_SIDITI_CONV_FUNCS)' \
 	LIBUNWIND='$(LIBUNWIND)' \
 	LIBUNWINDDEP='$(LIBUNWINDDEP)' \
 	SHLIBUNWIND_LINK='$(SHLIBUNWIND_LINK)' \
Index: gcc/config/floatunditf.c
===================================================================
--- gcc/config/floatunditf.c	(revision 113842)
+++ gcc/config/floatunditf.c	(working copy)
@@ -1,25 +0,0 @@
-/* Public domain.  */
-#if __LDBL_MANT_DIG__ == 106 || __LDBL_MANT_DIG__ == 113
-typedef int DItype __attribute__ ((mode (DI)));
-typedef int SItype __attribute__ ((mode (SI)));
-typedef unsigned int UDItype __attribute__ ((mode (DI)));
-typedef unsigned int USItype __attribute__ ((mode (SI)));
-typedef float DFtype __attribute__ ((mode (DF)));
-typedef float TFtype __attribute__ ((mode (TF)));
-
-TFtype __floatunditf (UDItype);
-
-TFtype
-__floatunditf (UDItype u)
-{
-  DFtype dh, dl;
-
-  dh = (USItype) (u >> (sizeof (SItype) * 8));
-  dh *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
-  dl = (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
-
-  return (TFtype) dh + (TFtype) dl;
-}
-
-#endif
-
Index: gcc/config/fixtfdi.c
===================================================================
--- gcc/config/fixtfdi.c	(revision 113842)
+++ gcc/config/fixtfdi.c	(working copy)
@@ -1,18 +0,0 @@
-/* Public domain.  */
-#if __LDBL_MANT_DIG__ == 106 || __LDBL_MANT_DIG__ == 113
-typedef int DItype __attribute__ ((mode (DI)));
-typedef float TFtype __attribute__ ((mode (TF)));
-
-DItype __fixtfdi (TFtype);
-DItype __fixunstfdi (TFtype);
-
-
-DItype
-__fixtfdi (TFtype x)
-{
-  if (x < 0)
-    return - __fixunstfdi (-x);
-  return __fixunstfdi (x);
-}
-
-#endif
Index: gcc/config/fixunstfdi.c
===================================================================
--- gcc/config/fixunstfdi.c	(revision 113842)
+++ gcc/config/fixunstfdi.c	(working copy)
@@ -1,35 +0,0 @@
-/* Public domain.  */
-#if __LDBL_MANT_DIG__ == 106 || __LDBL_MANT_DIG__ == 113
-typedef int DItype __attribute__ ((mode (DI)));
-typedef int SItype __attribute__ ((mode (SI)));
-typedef unsigned int UDItype __attribute__ ((mode (DI)));
-typedef unsigned int USItype __attribute__ ((mode (SI)));
-typedef float TFtype __attribute__ ((mode (TF)));
-
-DItype __fixunstfdi (TFtype);
-
-DItype
-__fixunstfdi (TFtype a)
-{
-  if (a < 0)
-    return 0;
-
-  /* Compute high word of result, as a flonum.  */
-  const TFtype b = (a / (((UDItype) 1) << (sizeof (SItype) * 8)));
-  /* Convert that to fixed (but not to DItype!),
-     and shift it into the high word.  */
-  UDItype v = (USItype) b;
-  v <<= (sizeof (SItype) * 8);
-  /* Remove high part from the TFtype, leaving the low part as flonum.  */
-  a -= (TFtype) v;
-  /* Convert that to fixed (but not to DItype!) and add it in.
-     Sometimes A comes out negative.  This is significant, since
-     A has more bits than a long int does.  */
-  if (a < 0)
-    v -= (USItype) (-a);
-  else
-    v += (USItype) a;
-  return v;
-}
-
-#endif
Index: gcc/config/mips/t-iris6
===================================================================
--- gcc/config/mips/t-iris6	(revision 113842)
+++ gcc/config/mips/t-iris6	(working copy)
@@ -6,8 +6,6 @@ MULTILIB_OSDIRNAMES=../lib32 ../lib ../l
 LIBGCC = stmp-multilib
 INSTALL_LIBGCC = install-multilib
 
-LIB2FUNCS_EXTRA = $(srcdir)/config/fixtfdi.c $(srcdir)/config/fixunstfdi.c $(srcdir)/config/floatditf.c $(srcdir)/config/floatunditf.c
-
 TPBIT = tp-bit.c
 
 tp-bit.c: $(srcdir)/config/fp-bit.c
Index: gcc/config/mips/t-linux64
===================================================================
--- gcc/config/mips/t-linux64	(revision 113842)
+++ gcc/config/mips/t-linux64	(working copy)
@@ -4,8 +4,6 @@ MULTILIB_OSDIRNAMES = ../lib32 ../lib ..
 
 EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o
 
-LIB2FUNCS_EXTRA = $(srcdir)/config/fixtfdi.c $(srcdir)/config/fixunstfdi.c $(srcdir)/config/floatditf.c $(srcdir)/config/floatunditf.c
-
 TPBIT = tp-bit.c
 
 tp-bit.c: $(srcdir)/config/fp-bit.c
Index: gcc/config/mips/t-mips
===================================================================
--- gcc/config/mips/t-mips	(revision 113842)
+++ gcc/config/mips/t-mips	(working copy)
@@ -19,3 +19,5 @@ fp-bit.c: $(srcdir)/config/fp-bit.c
 	echo '#endif' >> fp-bit.c
 	echo '#define QUIET_NAN_NEGATED' >> fp-bit.c
 	cat $(srcdir)/config/fp-bit.c >> fp-bit.c
+
+LIB2_SIDITI_CONV_FUNCS=yes
Index: gcc/config/floatditf.c
===================================================================
--- gcc/config/floatditf.c	(revision 113842)
+++ gcc/config/floatditf.c	(working copy)
@@ -1,25 +0,0 @@
-/* Public domain.  */
-#if __LDBL_MANT_DIG__ == 106 || __LDBL_MANT_DIG__ == 113
-typedef int DItype __attribute__ ((mode (DI)));
-typedef int SItype __attribute__ ((mode (SI)));
-typedef unsigned int UDItype __attribute__ ((mode (DI)));
-typedef unsigned int USItype __attribute__ ((mode (SI)));
-typedef float DFtype __attribute__ ((mode (DF)));
-typedef float TFtype __attribute__ ((mode (TF)));
-
-TFtype __floatditf (UDItype);
-
-TFtype
-__floatditf (UDItype u)
-{
-  DFtype dh, dl;
-
-  dh = (SItype) (u >> (sizeof (SItype) * 8));
-  dh *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
-  dl = (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
-
-  return (TFtype) dh + (TFtype) dl;
-}
-
-#endif
-


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]