check.c (gfc_check_system_clock): New function.
authorSteven G. Kargl <kargls@comcast.net>
Sat, 22 May 2004 12:47:42 +0000 (12:47 +0000)
committerPaul Brook <pbrook@gcc.gnu.org>
Sat, 22 May 2004 12:47:42 +0000 (12:47 +0000)
* check.c (gfc_check_system_clock): New function.
* intrinsic.c (add_sym_3s): New function.
(add_subroutines): Use it.
* intrinsic.h (gfc_check_system_clock, gfc_resolve_system_clock):
Add prototypes.
* iresolve.c (gfc_resolve_system_clock): New function.
libgfortran/
* intrinsics/system_clock: New file.
* Makefile.am: Add intrinsics/system_clock.c.
* Makefile.in: Regenerate.

From-SVN: r82131

gcc/fortran/ChangeLog
gcc/fortran/check.c
gcc/fortran/intrinsic.c
gcc/fortran/intrinsic.h
gcc/fortran/iresolve.c
libgfortran/ChangeLog
libgfortran/Makefile.am
libgfortran/Makefile.in
libgfortran/intrinsics/system_clock.c [new file with mode: 0644]

index 7b24d0472006f31179b841752f825db8c0dd47e7..f2c23546bbcff0768b323efe926df289b36d8ad7 100644 (file)
@@ -1,3 +1,12 @@
+2004-05-22  Steven G. Kargl  <kargls@comcast.net>
+
+       * check.c (gfc_check_system_clock): New function.
+       * intrinsic.c (add_sym_3s): New function.
+       (add_subroutines): Use it.
+       * intrinsic.h (gfc_check_system_clock, gfc_resolve_system_clock):
+       Add prototypes.
+       * iresolve.c (gfc_resolve_system_clock): New function.
+
 2004-05-22  Steven G. Kargl  <kargls@comcast.net>
 
        * invoke.texi: Document -Wunderflow and spell check.
index 703002f0fece3cef0f6672b28805d573ee046fc2..dadb1166ea9cf481d51905c224d845faf306a70c 100644 (file)
@@ -1864,3 +1864,62 @@ gfc_check_random_seed (gfc_expr * size, gfc_expr * put, gfc_expr * get)
 
   return SUCCESS;
 }
+
+/* The arguments of SYSTEM_CLOCK are scalar, integer variables.  Note,
+   count, count_rate, and count_max are all optional arguments */
+
+try
+gfc_check_system_clock (gfc_expr * count, gfc_expr * count_rate,
+                        gfc_expr * count_max)
+{
+
+  if (count != NULL)
+    {
+      if (scalar_check (count, 0) == FAILURE)
+        return FAILURE;
+
+      if (type_check (count, 0, BT_INTEGER) == FAILURE)
+        return FAILURE;
+
+      if (variable_check (count, 0) == FAILURE)
+        return FAILURE;
+    }
+
+  if (count_rate != NULL)
+    {
+      if (scalar_check (count_rate, 1) == FAILURE)
+        return FAILURE;
+
+      if (type_check (count_rate, 1, BT_INTEGER) == FAILURE)
+        return FAILURE;
+
+      if (variable_check (count_rate, 1) == FAILURE)
+        return FAILURE;
+
+      if (count != NULL && same_type_check(count, 0, count_rate, 1) == FAILURE)
+        return FAILURE;
+
+    }
+
+  if (count_max != NULL)
+    {
+      if (scalar_check (count_max, 2) == FAILURE)
+        return FAILURE;
+
+      if (type_check (count_max, 2, BT_INTEGER) == FAILURE)
+        return FAILURE;
+
+      if (variable_check (count_max, 2) == FAILURE)
+        return FAILURE;
+
+      if (count != NULL && same_type_check(count, 0, count_max, 2) == FAILURE)
+        return FAILURE;
+
+      if (count_rate != NULL
+          && same_type_check(count_rate, 1, count_max, 2) == FAILURE)
+        return FAILURE;
+
+   }
+
+    return SUCCESS;
+}
index c787e227a4eba68f64c83721ecd176ddbe5f666b..7b77fdb6eedda9426eac1fe98a9f80367386877f 100644 (file)
@@ -453,6 +453,33 @@ static void add_sym_3 (const char *name, int elemental, int actual_ok, bt type,
           (void*)0);
 }
 
+/* Add the name of an intrinsic subroutine with three arguments to the list
+   of intrinsic names. */
+
+static void add_sym_3s (const char *name, int elemental, int actual_ok, bt type,
+                      int kind,
+                      try (*check)(gfc_expr *,gfc_expr *,gfc_expr *),
+                      gfc_expr *(*simplify)(gfc_expr *,gfc_expr *,gfc_expr *),
+                      void (*resolve)(gfc_code *),
+                      const char* a1, bt type1, int kind1, int optional1,
+                      const char* a2, bt type2, int kind2, int optional2,
+                      const char* a3, bt type3, int kind3, int optional3
+                      ) {
+  gfc_check_f cf;
+  gfc_simplify_f sf;
+  gfc_resolve_f rf;
+
+  cf.f3 = check;
+  sf.f3 = simplify;
+  rf.s1 = resolve;
+
+  add_sym (name, elemental, actual_ok, type, kind, cf, sf, rf,
+          a1, type1, kind1, optional1,
+          a2, type2, kind2, optional2,
+          a3, type3, kind3, optional3,
+          (void*)0);
+}
+
 
 static void add_sym_4 (const char *name, int elemental, int actual_ok, bt type,
                       int kind,
@@ -1632,8 +1659,8 @@ add_subroutines (void)
             sz, BT_INTEGER, di, 1, pt, BT_INTEGER, di, 1,
             gt, BT_INTEGER, di, 1);
 
-  add_sym_3 ("system_clock", 0, 1, BT_UNKNOWN, 0,
-            NULL, NULL, NULL,
+  add_sym_3s ("system_clock", 0, 1, BT_UNKNOWN, 0,
+            gfc_check_system_clock, NULL, gfc_resolve_system_clock,
             c, BT_INTEGER, di, 1, cr, BT_INTEGER, di, 1,
             cm, BT_INTEGER, di, 1);
 }
index fa39a3e4234ca4455c8188cf4e3f81b664ac642e..b2c0e780f4ef291e7f23e44a12a2a9b4ca5686be 100644 (file)
@@ -99,6 +99,7 @@ try gfc_check_x (gfc_expr *);
 
 /* Intrinsic subroutines.  */
 try gfc_check_cpu_time (gfc_expr *);
+try gfc_check_system_clock (gfc_expr *, gfc_expr *, gfc_expr *);
 try gfc_check_date_and_time (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *);
 try gfc_check_mvbits (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *,
                      gfc_expr *);
@@ -303,6 +304,7 @@ void gfc_resolve_verify (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *);
 
 /* Intrinsic subroutine resolution.  */
 void gfc_resolve_cpu_time (gfc_code *);
+void gfc_resolve_system_clock(gfc_code *);
 void gfc_resolve_random_number (gfc_code *);
 
 
index e873f03f0dc834905eba7497a78d207377696b37..46e38037f60adb5077574461390bd546db837bc9 100644 (file)
@@ -1369,6 +1369,27 @@ gfc_resolve_random_number (gfc_code * c ATTRIBUTE_UNUSED)
   c->resolved_sym = gfc_get_intrinsic_sub_symbol (name);
 }
 
+/* Determine if the arguments to SYSTEM_CLOCK are INTEGER(4) or INTEGER(8) */
+
+void
+gfc_resolve_system_clock (gfc_code * c)
+{
+  const char *name;
+  int kind;
+
+  if (c->ext.actual->expr != NULL)
+    kind = c->ext.actual->expr->ts.kind;
+  else if (c->ext.actual->next->expr != NULL)
+      kind = c->ext.actual->next->expr->ts.kind;
+  else if (c->ext.actual->next->next->expr != NULL)
+      kind = c->ext.actual->next->next->expr->ts.kind;
+  else
+    kind = gfc_default_integer_kind ();
+
+  name = gfc_get_string (PREFIX("system_clock_%d"), kind);
+  c->resolved_sym = gfc_get_intrinsic_sub_symbol (name);
+}
+
 
 void
 gfc_iresolve_init_1 (void)
index 3eedff3926a6a1faab394d855a98c6ffb2982208..e6cfffb132c9df397289afec2b70fa8d5284c686 100644 (file)
@@ -1,3 +1,9 @@
+2004-05-22  Steven G. Kargl  <kargls@comcast.net>
+
+       * intrinsics/system_clock: New file.
+       * Makefile.am: Add intrinsics/system_clock.c.
+       * Makefile.in: Regenerate.
+
 2004-05-21  Roger Sayle  <roger@eyesopen.com>
 
        * io/format.c (parse_format_list): Allow the comma after a string
index 12977f5bd3d05f83219252b8bb5f5d6bdaf6fb57..b451b3811461357e0aae189b001b52083ddec91e 100644 (file)
@@ -49,6 +49,7 @@ intrinsics/random.c \
 intrinsics/reshape_generic.c \
 intrinsics/reshape_packed.c \
 intrinsics/selected_kind.f90 \
+intrinsics/system_clock.c \
 intrinsics/transpose_generic.c \
 intrinsics/unpack_generic.c \
 runtime/in_pack_generic.c \
index 1bb1dd57627bede024670022aef78d1a39a6a072..9c878de3f5d30d9ac52573e00e412b246e9175ac 100644 (file)
@@ -121,8 +121,8 @@ am__objects_33 = associated.lo abort.lo cpu_time.lo cshift0.lo \
        eoshift0.lo eoshift2.lo ishftc.lo pack_generic.lo size.lo \
        spread_generic.lo string_intrinsics.lo random.lo \
        reshape_generic.lo reshape_packed.lo selected_kind.lo \
-       transpose_generic.lo unpack_generic.lo in_pack_generic.lo \
-       in_unpack_generic.lo
+       system_clock.lo transpose_generic.lo unpack_generic.lo \
+       in_pack_generic.lo in_unpack_generic.lo
 am__objects_34 =
 am__objects_35 = _abs_c4.lo _abs_c8.lo _abs_i4.lo _abs_i8.lo \
        _abs_r4.lo _abs_r8.lo _exp_r4.lo _exp_r8.lo _exp_c4.lo \
@@ -272,6 +272,7 @@ am__depfiles_maybe = depfiles
 @AMDEP_TRUE@   ./$(DEPDIR)/sum_c4.Plo ./$(DEPDIR)/sum_c8.Plo \
 @AMDEP_TRUE@   ./$(DEPDIR)/sum_i4.Plo ./$(DEPDIR)/sum_i8.Plo \
 @AMDEP_TRUE@   ./$(DEPDIR)/sum_r4.Plo ./$(DEPDIR)/sum_r8.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/system_clock.Plo \
 @AMDEP_TRUE@   ./$(DEPDIR)/transfer.Plo \
 @AMDEP_TRUE@   ./$(DEPDIR)/transpose_generic.Plo \
 @AMDEP_TRUE@   ./$(DEPDIR)/transpose_i4.Plo \
@@ -442,6 +443,7 @@ intrinsics/random.c \
 intrinsics/reshape_generic.c \
 intrinsics/reshape_packed.c \
 intrinsics/selected_kind.f90 \
+intrinsics/system_clock.c \
 intrinsics/transpose_generic.c \
 intrinsics/unpack_generic.c \
 runtime/in_pack_generic.c \
@@ -1009,6 +1011,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sum_i8.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sum_r4.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sum_r8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/system_clock.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transfer.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transpose_generic.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transpose_i4.Plo@am__quote@
@@ -4596,6 +4599,30 @@ reshape_packed.lo: intrinsics/reshape_packed.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o reshape_packed.lo `test -f 'intrinsics/reshape_packed.c' || echo '$(srcdir)/'`intrinsics/reshape_packed.c
 
+system_clock.o: intrinsics/system_clock.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT system_clock.o -MD -MP -MF "$(DEPDIR)/system_clock.Tpo" -c -o system_clock.o `test -f 'intrinsics/system_clock.c' || echo '$(srcdir)/'`intrinsics/system_clock.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/system_clock.Tpo" "$(DEPDIR)/system_clock.Po"; else rm -f "$(DEPDIR)/system_clock.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='intrinsics/system_clock.c' object='system_clock.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/system_clock.Po' tmpdepfile='$(DEPDIR)/system_clock.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o system_clock.o `test -f 'intrinsics/system_clock.c' || echo '$(srcdir)/'`intrinsics/system_clock.c
+
+system_clock.obj: intrinsics/system_clock.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT system_clock.obj -MD -MP -MF "$(DEPDIR)/system_clock.Tpo" -c -o system_clock.obj `if test -f 'intrinsics/system_clock.c'; then $(CYGPATH_W) 'intrinsics/system_clock.c'; else $(CYGPATH_W) '$(srcdir)/intrinsics/system_clock.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/system_clock.Tpo" "$(DEPDIR)/system_clock.Po"; else rm -f "$(DEPDIR)/system_clock.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='intrinsics/system_clock.c' object='system_clock.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/system_clock.Po' tmpdepfile='$(DEPDIR)/system_clock.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o system_clock.obj `if test -f 'intrinsics/system_clock.c'; then $(CYGPATH_W) 'intrinsics/system_clock.c'; else $(CYGPATH_W) '$(srcdir)/intrinsics/system_clock.c'; fi`
+
+system_clock.lo: intrinsics/system_clock.c
+@am__fastdepCC_TRUE@   if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT system_clock.lo -MD -MP -MF "$(DEPDIR)/system_clock.Tpo" -c -o system_clock.lo `test -f 'intrinsics/system_clock.c' || echo '$(srcdir)/'`intrinsics/system_clock.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/system_clock.Tpo" "$(DEPDIR)/system_clock.Plo"; else rm -f "$(DEPDIR)/system_clock.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='intrinsics/system_clock.c' object='system_clock.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/system_clock.Plo' tmpdepfile='$(DEPDIR)/system_clock.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o system_clock.lo `test -f 'intrinsics/system_clock.c' || echo '$(srcdir)/'`intrinsics/system_clock.c
+
 transpose_generic.o: intrinsics/transpose_generic.c
 @am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT transpose_generic.o -MD -MP -MF "$(DEPDIR)/transpose_generic.Tpo" -c -o transpose_generic.o `test -f 'intrinsics/transpose_generic.c' || echo '$(srcdir)/'`intrinsics/transpose_generic.c; \
 @am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/transpose_generic.Tpo" "$(DEPDIR)/transpose_generic.Po"; else rm -f "$(DEPDIR)/transpose_generic.Tpo"; exit 1; fi
diff --git a/libgfortran/intrinsics/system_clock.c b/libgfortran/intrinsics/system_clock.c
new file mode 100644 (file)
index 0000000..6b6ae9d
--- /dev/null
@@ -0,0 +1,200 @@
+/* Implementation of the SYSTEM_CLOCK intrinsic.
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU Fortran 95 runtime library (libgfortran).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfortran; see the file COPYING.LIB.  If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#include "config.h"
+#include <sys/types.h>
+#include "libgfortran.h"
+
+#include <limits.h>
+
+#if defined(HAVE_SYS_TIME_H) && defined(HAVE_GETTIMEOFDAY)
+#  include <sys/time.h>
+#  define TCK 1000
+#elif defined(HAVE_TIME_H)
+#  include <time.h>
+#  define TCK 1
+#else
+#define TCK 0
+#endif
+
+
+#if defined(HAVE_SYS_TIME_H) && defined(HAVE_GETTIMEOFDAY)
+static struct timeval tp0 = {-1, 0};
+#elif defined(HAVE_TIME_H)
+static time_t t0 = (time_t) -2;
+#endif
+
+/* prefix(system_clock_4) is the INTEGER(4) version of the SYSTEM_CLOCK
+   intrinsic subroutine.  It returns the number of clock ticks for the current
+   system time, the number of ticks per second, and the maximum possible value
+   for COUNT.  On the first call to SYSTEM_CLOCK, COUNT is set to zero. */
+
+void
+prefix(system_clock_4)(GFC_INTEGER_4 *count, GFC_INTEGER_4 *count_rate,
+                      GFC_INTEGER_4 *count_max)
+{
+  GFC_INTEGER_4 cnt;
+  GFC_INTEGER_4 rate;
+  GFC_INTEGER_4 mx;
+
+#if defined(HAVE_SYS_TIME_H) && defined(HAVE_GETTIMEOFDAY)
+  struct timeval tp1;
+  struct timezone tzp;
+  double t;
+
+  if (gettimeofday(&tp1, &tzp) == 0)
+    {
+      if (tp0.tv_sec < 0)
+        {
+          tp0 = tp1;
+          cnt = 0;
+        }
+      else
+        {
+         /* TODO: Convert this to integer arithmetic.  */
+          t  = (double) (tp1.tv_sec  - tp0.tv_sec);
+          t += (double) (tp1.tv_usec - tp0.tv_usec) * 1.e-6;
+          t *= TCK;
+
+          if (t > (double) GFC_INTEGER_4_HUGE)
+            {
+              /* Time has wrapped. */
+              while (t > (double) GFC_INTEGER_4_HUGE)
+                t -= (double) GFC_INTEGER_4_HUGE;
+              tp0 = tp1;
+            }
+         cnt = (GFC_INTEGER_4) t;
+        }
+      rate = TCK;
+      mx = GFC_INTEGER_4_HUGE;
+    }
+  else
+    {
+      if (count != NULL) *count = - GFC_INTEGER_4_HUGE;
+      if (count_rate != NULL) *count_rate = 0;
+      if (count_max != NULL) *count_max = 0;
+    }
+#elif defined(HAVE_TIME_H)
+  time_t t, t1;
+
+  t1 = time(NULL);
+
+  if (t1 == (time_t) -1)
+    {
+      cnt = - GFC_INTEGER_4_HUGE;
+      mx = 0;
+    }
+  else if (t0 == (time_t) -2) 
+    t0 = t1;
+  else
+    {
+      /* The timer counts in seconts, so for simplicity assume it never wraps.
+        Even with 32-bit counters this only happens once every 68 years.  */
+      cnt = t1 - t0;
+      mx = GFC_INTEGER_4_HUGE;
+    }
+#else
+  cnt = - GFC_INTEGER_4_HUGE;
+  mx = 0;
+#endif
+  if (count != NULL) *count = cnt;
+  if (count_rate != NULL) *count_rate = TCK;
+  if (count_max != NULL) *count_max = mx;
+}
+
+
+/* INTEGER(8) version of the above routine.  */
+
+void
+prefix(system_clock_8)(GFC_INTEGER_8 *count, GFC_INTEGER_8 *count_rate,
+                      GFC_INTEGER_8 *count_max)
+{
+  GFC_INTEGER_8 cnt;
+  GFC_INTEGER_8 rate;
+  GFC_INTEGER_8 mx;
+
+#if defined(HAVE_SYS_TIME_H) && defined(HAVE_GETTIMEOFDAY)
+  struct timeval tp1;
+  struct timezone tzp;
+  double t;
+
+  if (gettimeofday(&tp1, &tzp) == 0)
+    {
+      if (tp0.tv_sec < 0)
+        {
+          tp0 = tp1;
+          cnt = 0;
+        }
+      else
+        {
+         /* TODO: Convert this to integer arithmetic.  */
+          t  = (double) (tp1.tv_sec  - tp0.tv_sec);
+          t += (double) (tp1.tv_usec - tp0.tv_usec) * 1.e-6;
+          t *= TCK;
+
+          if (t > (double) GFC_INTEGER_8_HUGE)
+            {
+              /* Time has wrapped. */
+              while (t > (double) GFC_INTEGER_8_HUGE)
+                t -= (double) GFC_INTEGER_8_HUGE;
+              tp0 = tp1;
+            }
+         cnt = (GFC_INTEGER_8) t;
+        }
+      rate = TCK;
+      mx = GFC_INTEGER_8_HUGE;
+    }
+  else
+    {
+      if (count != NULL) *count = - GFC_INTEGER_8_HUGE;
+      if (count_rate != NULL) *count_rate = 0;
+      if (count_max != NULL) *count_max = 0;
+    }
+#elif defined(HAVE_TIME_H)
+  time_t t, t1;
+
+  t1 = time(NULL);
+
+  if (t1 == (time_t) -1)
+    {
+      cnt = - GFC_INTEGER_8_HUGE;
+      mx = 0;
+    }
+  else if (t0 == (time_t) -2) 
+    t0 = t1;
+  else
+    {
+      /* The timer counts in seconts, so for simplicity assume it never wraps.
+        Even with 32-bit counters this only happens once every 68 years.  */
+      cnt = t1 - t0;
+      mx = GFC_INTEGER_8_HUGE;
+    }
+#else
+  cnt = - GFC_INTEGER_8_HUGE;
+  mx = 0;
+#endif
+  if (count != NULL)
+    *count = cnt;
+  if (count_rate != NULL)
+    *count_rate = TCK;
+  if (count_max != NULL)
+    *count_max = mx;
+}
+