diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index eca621b172e075a974c96ffd9db7c8a1f236978f..6d9739a6f8c1d6e38642f07a6d27896819998ca0 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,3 +1,12 @@
+2006-12-06  Francois-Xavier Coudert  <coudert@clipper.ens.fr>
+
+	PR libfortran/29810
+	* intrinsics/c99_functions.c (fmodf, fmodl, floorl): New functions.
+	* c99_protos.h (fmodf, fmodl, floorl): New prototypes.
+	* configure.ac: Check for fmodf, fmod and fmodl.
+	* configure: Regenerate.
+	* config.h.in: Regenerate.
+
 2006-12-06  Thomas Koenig  <Thomas.Koenig@online.de>
 
 	PR libfortran/30009
diff --git a/libgfortran/c99_protos.h b/libgfortran/c99_protos.h
index 26c0aa2b54702c1d9ef1315bc3c5e825ed2edf93..369299dc77dca6f476f560a479652068e877a08c 100644
--- a/libgfortran/c99_protos.h
+++ b/libgfortran/c99_protos.h
@@ -100,6 +100,21 @@ extern float fabsf(float);
 extern float floorf(float);
 #endif
 
+#ifndef HAVE_FLOORL
+#define HAVE_FLOORL 1
+extern long double floorl (long double x);
+#endif
+
+#ifndef HAVE_FMODF
+#define HAVE_FMODF 1
+extern float fmodf (float x, float y);
+#endif
+
+#ifndef HAVE_FMODL
+#define HAVE_FMODL 1
+extern long double fmodl (long double x, long double y);
+#endif
+
 #ifndef HAVE_FREXPF
 #define HAVE_FREXPF 1
 extern float frexpf(float, int *);
diff --git a/libgfortran/config.h.in b/libgfortran/config.h.in
index a198d42c7bb21182963d01b94748fdf612e30664..11f7cc6db754f17da87b734e5b48447fb8e32d3b 100644
--- a/libgfortran/config.h.in
+++ b/libgfortran/config.h.in
@@ -327,6 +327,15 @@
 /* libm includes floorl */
 #undef HAVE_FLOORL
 
+/* libm includes fmod */
+#undef HAVE_FMOD
+
+/* libm includes fmodf */
+#undef HAVE_FMODF
+
+/* libm includes fmodl */
+#undef HAVE_FMODL
+
 /* Define to 1 if you have the `fork' function. */
 #undef HAVE_FORK
 
diff --git a/libgfortran/configure b/libgfortran/configure
index 2410a3d341c53c9074c3eccaa7551d0c82255e75..d775aec393582c5aa14b60d1ac417a3481ba64be 100755
--- a/libgfortran/configure
+++ b/libgfortran/configure
@@ -14893,6 +14893,237 @@ _ACEOF
 
 fi
 
+echo "$as_me:$LINENO: checking for fmodf in -lm" >&5
+echo $ECHO_N "checking for fmodf in -lm... $ECHO_C" >&6
+if test "${ac_cv_lib_m_fmodf+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm  $LIBS"
+if test x$gcc_no_link = xyes; then
+  { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char fmodf ();
+int
+main ()
+{
+fmodf ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_m_fmodf=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_m_fmodf=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_m_fmodf" >&5
+echo "${ECHO_T}$ac_cv_lib_m_fmodf" >&6
+if test $ac_cv_lib_m_fmodf = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_FMODF 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for fmod in -lm" >&5
+echo $ECHO_N "checking for fmod in -lm... $ECHO_C" >&6
+if test "${ac_cv_lib_m_fmod+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm  $LIBS"
+if test x$gcc_no_link = xyes; then
+  { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char fmod ();
+int
+main ()
+{
+fmod ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_m_fmod=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_m_fmod=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_m_fmod" >&5
+echo "${ECHO_T}$ac_cv_lib_m_fmod" >&6
+if test $ac_cv_lib_m_fmod = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_FMOD 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for fmodl in -lm" >&5
+echo $ECHO_N "checking for fmodl in -lm... $ECHO_C" >&6
+if test "${ac_cv_lib_m_fmodl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm  $LIBS"
+if test x$gcc_no_link = xyes; then
+  { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char fmodl ();
+int
+main ()
+{
+fmodl ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_m_fmodl=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_m_fmodl=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_m_fmodl" >&5
+echo "${ECHO_T}$ac_cv_lib_m_fmodl" >&6
+if test $ac_cv_lib_m_fmodl = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_FMODL 1
+_ACEOF
+
+fi
+
 echo "$as_me:$LINENO: checking for frexpf in -lm" >&5
 echo $ECHO_N "checking for frexpf in -lm... $ECHO_C" >&6
 if test "${ac_cv_lib_m_frexpf+set}" = set; then
diff --git a/libgfortran/configure.ac b/libgfortran/configure.ac
index f8f1d3e93c52b3c994e54965af75ad9fcdd36de1..23e80fda38bcdb8df7e53528f2027314c43059e1 100644
--- a/libgfortran/configure.ac
+++ b/libgfortran/configure.ac
@@ -241,6 +241,9 @@ AC_CHECK_LIB([m],[cabsl],[AC_DEFINE([HAVE_CABSL],[1],[libm includes cabsl])])
 AC_CHECK_LIB([m],[floorf],[AC_DEFINE([HAVE_FLOORF],[1],[libm includes floorf])])
 AC_CHECK_LIB([m],[floor],[AC_DEFINE([HAVE_FLOOR],[1],[libm includes floor])])
 AC_CHECK_LIB([m],[floorl],[AC_DEFINE([HAVE_FLOORL],[1],[libm includes floorl])])
+AC_CHECK_LIB([m],[fmodf],[AC_DEFINE([HAVE_FMODF],[1],[libm includes fmodf])])
+AC_CHECK_LIB([m],[fmod],[AC_DEFINE([HAVE_FMOD],[1],[libm includes fmod])])
+AC_CHECK_LIB([m],[fmodl],[AC_DEFINE([HAVE_FMODL],[1],[libm includes fmodl])])
 AC_CHECK_LIB([m],[frexpf],[AC_DEFINE([HAVE_FREXPF],[1],[libm includes frexpf])])
 AC_CHECK_LIB([m],[frexp],[AC_DEFINE([HAVE_FREXP],[1],[libm includes frexp])])
 AC_CHECK_LIB([m],[frexpl],[AC_DEFINE([HAVE_FREXPL],[1],[libm includes frexpl])])
diff --git a/libgfortran/intrinsics/c99_functions.c b/libgfortran/intrinsics/c99_functions.c
index 96b5ef88851a39aaa6d6bc837a2ad32a46c574be..7278169684f9dfe6a5b87cbefd0f053b4fe4839c 100644
--- a/libgfortran/intrinsics/c99_functions.c
+++ b/libgfortran/intrinsics/c99_functions.c
@@ -294,6 +294,15 @@ floorf(float x)
 }
 #endif
 
+#ifndef HAVE_FMODF
+#define HAVE_FMODF 1
+float
+fmodf (float x, float y)
+{
+  return (float) fmod (x, y);
+}
+#endif
+
 #ifndef HAVE_FREXPF
 #define HAVE_FREXPF 1
 float
@@ -592,6 +601,47 @@ log10l(long double x)
 #endif
 
 
+#ifndef HAVE_FLOORL
+#define HAVE_FLOORL 1
+long double
+floorl (long double x)
+{
+  /* Zero, possibly signed.  */
+  if (x == 0)
+    return x;
+
+  /* Large magnitude.  */
+  if (x > DBL_MAX || x < (-DBL_MAX))
+    return x;
+
+  /* Small positive values.  */
+  if (x >= 0 && x < DBL_MIN)
+    return 0;
+
+  /* Small negative values.  */
+  if (x < 0 && x > (-DBL_MIN))
+    return -1;
+
+  return floor (x);
+}
+#endif
+
+
+#ifndef HAVE_FMODL
+#define HAVE_FMODL 1
+long double
+fmodl (long double x, long double y)
+{
+  if (y == 0.0L)
+    return 0.0L;
+
+  /* Need to check that the result has the same sign as x and magnitude
+     less than the magnitude of y.  */
+  return x - floorl (x / y) * y;
+}
+#endif
+
+
 #if !defined(HAVE_CABSF)
 #define HAVE_CABSF 1
 float