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: [gfortran,patch] fix


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

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