This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [gfortran,patch] fix
- From: FX Coudert <fxcoudert at gmail dot com>
- To: FX Coudert <fxcoudert at gmail dot com>
- Cc: Steve Ellcey <sje at cup dot hp dot com>, fortran at gcc dot gnu dot org, patch <gcc-patches at gcc dot gnu dot org>,Steve Kargl <sgk at troutmask dot apl dot washington dot edu>
- Date: Tue, 30 Aug 2005 19:36:20 +0200
- Subject: Re: [gfortran,patch] fix
- References: <200508291522.IAA02968@hpsje.cup.hp.com> <4314163F.1090105@gmail.com>
OK for 4.1?
And Steve (Ellcey), could you test it? (that is, build libgfortran with
this patch on ia64-hpux and send me (or the list) the generated kinds.h
file?
Sorry about the forgottent attachment: here it is.
2005-08-30 Francois-Xavier Coudert <coudert@clipper.ens.fr>
* mk-kinds-h.sh: Match Fortran real kinds to C floating-point
types in a more general way.
* Makefile.am: Add C compiler as argument to mk-kinds-h.sh.
* Makefile.in: Regenerate.
Index: libgfortran/Makefile.am
===================================================================
RCS file: /cvsroot/gcc/gcc/libgfortran/Makefile.am,v
retrieving revision 1.41
diff -u -3 -p -r1.41 Makefile.am
--- libgfortran/Makefile.am 11 Aug 2005 13:50:10 -0000 1.41
+++ libgfortran/Makefile.am 30 Aug 2005 09:55:13 -0000
@@ -421,7 +421,7 @@ I_M4_DEPS0=$(I_M4_DEPS) m4/iforeach.m4
I_M4_DEPS1=$(I_M4_DEPS) m4/ifunction.m4
kinds.h: $(srcdir)/mk-kinds-h.sh
- $(SHELL) $(srcdir)/mk-kinds-h.sh '$(FCCOMPILE)' > $@
+ $(SHELL) $(srcdir)/mk-kinds-h.sh '$(FCCOMPILE)' '$(COMPILE)' > $@
selected_int_kind.inc: $(srcdir)/mk-sik-inc.sh
$(SHELL) $(srcdir)/mk-sik-inc.sh '$(FCCOMPILE)' > $@
Index: libgfortran/mk-kinds-h.sh
===================================================================
RCS file: /cvsroot/gcc/gcc/libgfortran/mk-kinds-h.sh,v
retrieving revision 1.1
diff -u -3 -p -r1.1 mk-kinds-h.sh
--- libgfortran/mk-kinds-h.sh 23 Jun 2005 18:50:24 -0000 1.1
+++ libgfortran/mk-kinds-h.sh 30 Aug 2005 09:55:18 -0000
@@ -1,17 +1,20 @@
#!/bin/sh
-compile="$1"
+FC="$1"
+CC="$2"
-# Possible types must be listed in ascending order
-possible_integer_kinds="1 2 4 8 16"
-possible_real_kinds="4 8 10 16"
+#############################################################
+# Part of the script dealing with integer types.
+
+# List of possible integer kinds
+possible_integer_kinds="1 2 4 8 16"
largest=""
for k in $possible_integer_kinds; do
echo " integer (kind=$k) :: i" > tmp$$.f90
echo " end" >> tmp$$.f90
- if $compile -c tmp$$.f90 > /dev/null 2>&1; then
+ if ${FC} -c tmp$$.f90 > /dev/null 2>&1; then
s=`expr 8 \* $k`
largest="$k"
@@ -25,41 +28,128 @@ for k in $possible_integer_kinds; do
echo "typedef ${prefix}uint${s}_t GFC_UINTEGER_${k};"
echo "typedef GFC_INTEGER_${k} GFC_LOGICAL_${k};"
echo "#define HAVE_GFC_INTEGER_${k}"
+ echo "#define HAVE_GFC_UINTEGER_${k}"
+ echo "#define HAVE_GFC_LOGICAl_${k}"
fi
rm -f tmp$$.*
done
+echo ""
echo "#define GFC_INTEGER_LARGEST GFC_INTEGER_${largest}"
echo "#define GFC_UINTEGER_LARGEST GFC_UINTEGER_${largest}"
+echo "#define GFC_LOGICAL_LARGEST GFC_LOGICAL_${largest}"
echo ""
-largest_ctype=""
-for k in $possible_real_kinds; do
- echo " real (kind=$k) :: x" > tmp$$.f90
- echo " end" >> tmp$$.f90
- if $compile -c tmp$$.f90 > /dev/null 2>&1; then
- case $k in
- 4) ctype="float" ;;
- 8) ctype="double" ;;
- 10) ctype="long double" ;;
- 16) ctype="long double" ;;
- *) echo "$0: Unknown type" >&2 ; exit 1 ;;
- esac
- largest_ctype="$ctype"
- echo "typedef ${ctype} GFC_REAL_${k};"
- echo "typedef complex ${ctype} GFC_COMPLEX_${k};"
- echo "#define HAVE_GFC_REAL_${k}"
+#############################################################
+# Part of the script dealing with floating-point types.
+
+# A list of possible Fortran real kinds.
+possible_fkinds="4 8 10 16"
+
+# The possible sizes for floating-points types. We could test for all
+# sizes between 1 and 50 (or any arbitrary limit), but that would not
+# be efficient at all.
+possible_sizes="4 8 10 12 16"
+
+# The list of possible C floating-point types, and corresponding
+# printf "format" specifier and suffix for math library functions.
+# This is a colon-separated list, since some shells don't have arrays.
+# It is necessary to keep a colon as last character of possible_ctypes.
+possible_ctypes="float:double:__float80:long double:"
+ctypes_format=":l:hL:L:"
+ctypes_suffix="f::w:l:"
+
+# Test if a given C type (argument 1) has a given size (argument 2).
+ctype_has_size ()
+{
+ echo "int dummy[(sizeof($1) == $2) ? 1 : -1];" > a.c
+ if ( ${CC} -c a.c 2>/dev/null ); then
+ rm -f a.c a.o
+ return 0
+ fi
+ rm -f a.c a.o
+ return 1
+}
+
+# Test if a given Fortran kind (argument 1) has a given size (argument 2).
+fkind_has_size ()
+{
+ i=`expr $2 + 1`
+ echo "real(kind=$1) r(2)" > a.f90
+ echo "integer(kind=1) i(100)" >> a.f90
+ echo "equivalence (r(1),i(1)), (r(2),i($i))" >> a.f90
+ echo "end" >> a.f90
+ if ( ${FC} -c a.f90 2>/dev/null ); then
+ rm -f a.f90 a.o
+ return 0
+ fi
+ rm -f a.f90 a.o
+ return 1
+}
+
+# Uses fkind_has_size to find the given size (argument 1) of a Fortran kind.
+# The return value is equal to the size; shell does not allow return
+# values larger than 255, but that should not be a problem right now ;-)
+fkind_size ()
+{
+ for j in $possible_sizes; do
+ if fkind_has_size $1 $j; then
+ return $j
+ fi
+ done
+}
+
+# Find which C types has a given size (argument 1). If there is more than
+# one, the first one in the possible_ctypes array is selected (therefore,
+# the order in possible_ctypes is important!). The return value of the
+# function is the index of the C type in the possible_ctypes array.
+which_ctype_has_size ()
+{
+ ctypes=$possible_ctypes
+ formats=$ctypes_format
+ suffices=$ctypes_suffix
+ while ( true ); do
+ ctype=`echo $ctypes | sed 's/:.*//'`
+ if ctype_has_size "$ctype" $1; then
+ ctype_format=`echo $formats | sed 's/:.*//'`
+ ctype_suffix=`echo $suffices | sed 's/:.*//'`
+ possible_ctypes=$ctypes
+ ctypes_format=$formats
+ ctypes_suffix=$suffices
+ return 0
+ fi
+ ctypes=`echo $ctypes | sed 's/^[^:]*://'`
+ if ( test "x$ctypes" = "x" ); then
+ echo "Error: could not find a C type for Fortran real(kind=$fkind)">&2
+ exit 1
+ fi
+ formats=`echo $formats | sed 's/^[^:]*://'`
+ suffices=`echo $suffices | sed 's/^[^:]*://'`
+ done
+}
+
+fsize_max=-1
+for fkind in $possible_fkinds; do
+ fkind_size $fkind
+ fsize=$?
+ if ( test $fsize -ne 0 ); then
+ which_ctype_has_size $fsize
+ if ( test $fsize -gt $fsize_max); then
+ fsize_max=$fsize
+ ctype_max=$ctype
+ ctype_format_max=$ctype_format
+ fi
+ echo "typedef $ctype GFC_REAL_$fkind;"
+ echo "typedef complex $ctype GFC_COMPLEX_$fkind;"
+ echo "#define HAVE_GFC_REAL_$fkind"
+ echo "#define HAVE_GFC_COMPLEX_$fkind"
+ echo "#define GFC_MATH_SUFFIX_$fkind $ctype_suffix"
fi
- rm -f tmp$$.*
done
-case $largest_ctype in
- float) echo "#define GFC_REAL_LARGEST_FORMAT \"\"" ;;
- double) echo "#define GFC_REAL_LARGEST_FORMAT \"l\"" ;;
- "long double") echo "#define GFC_REAL_LARGEST_FORMAT \"L\"" ;;
- *) echo "$0: Unknown type" >&2 ; exit 1 ;;
-esac
-echo "#define GFC_REAL_LARGEST $largest_ctype"
+echo ""
+echo "#define GFC_REAL_LARGEST_FORMAT \"$ctype_format_max\""
+echo "#define GFC_REAL_LARGEST $ctype_max"
exit 0