summaryrefslogtreecommitdiff
path: root/libgfortran/m4
diff options
context:
space:
mode:
authortkoenig <tkoenig@138bc75d-0d04-0410-961f-82ee72b054a4>2008-01-15 21:22:07 +0000
committertkoenig <tkoenig@138bc75d-0d04-0410-961f-82ee72b054a4>2008-01-15 21:22:07 +0000
commit76b9f8916aac9ea860e18c74280771ae44bd098b (patch)
tree48e5848dd3732806515c1d1a39309fb7baba909b /libgfortran/m4
parentc45bb9cb2c7a83ddb02eb2d4bdd99b20d0c8fbe9 (diff)
downloadgcc-76b9f8916aac9ea860e18c74280771ae44bd098b.tar.gz
2008-01-15 Thomas Koenig <tkoenig@gcc.gnu.org>
PR libfortran/34671 * gfortran.am: Added _gfortran_all_l1, _gfortran_all_l2, _gfortran_any_l1, _gfortran_any_l2, -28,15 _gfortran_count_1_l, _gfortran_count_16_l, _gfortran_count_2_l, _gfortran_count_4_l and _gfortran_count_8_l Removed _gfortran_count_16_l16, _gfortran_count_16_l4, _gfortran_count_16_l8, _gfortran_count_4_l16, _gfortran_count_4_l4, _gfortran_count_4_l8, _gfortran_count_8_l16, _gfortran_count_8_l4 and _gfortran_count_8_l8. * Makefile.am: Added generated/any_l1.c and generated/any_l2.c to i_any_c. Added generated/all_l1. and generated/all_l2.c to i_all_c. Removed generated/count_4_l4.c, generated/count_8_l4.c, generated/count_16_l4.c, generated/count_4_l8.c, generated/count_8_l8.c, generated/count_16_l8.c, generated/count_4_l16.c, generated/count_8_l16.c, and generated/count_16_l16.c from i_count_c. Added count_1_l.c, count_2_l.c, count_4_l.c, count_8_l.c and count_16_l.c to i_count_c. I_M4_DEPS2 depends on ifunction_logical.m4, for any of the files generated from all.m4, any.m4 and count.m4. * Makefile.in: Regenerated. * m4/ifunction_logical.m4: New file. Use GFC_LOGICAL_1 pointer for access to source arrays. * m4/any.m4: Include ifunction_logical.m4 instead of ifunction.m4. Don't check atype_name. * m4/all.m4: Likewise. * m4/count.m4: Likewise. * generated/any_l1.c: New file. * generated/any_l2.c: New file. * generated/all_l1.c: New file. * generated/count_1_l.c: New file. * generated/count_2_l.c: New file. * generated/count_4_l.c: New file. * generated/count_8_l.c: New file. * generated/count_16_l.c: New file. * generated/any_l4.c: Regenerated. * generated/any_l8.c: Regenerated. * generated/any_l16.c: Regenerated. * generated/all_l4.c: Regenerated. * generated/all_l8.c: Regenerated. * generated/all_l16.c: Regenerated. * generated/count_4_l4.c: Removed. * generated/count_4_l8.c: Removed. * generated/count_4_l16.c: Removed. * generated/count_8_l4.c: Removed. * generated/count_8_l8.c: Removed. * generated/count_8_l16.c: Removed. * generated/count_16_l4.c: Removed. * generated/count_16_l8.c: Removed. * generated/count_16_l16.c: Removed. 2008-01-15 Thomas Koenig <tkoenig@gcc.gnu.org> PR libfortran/34671 * iresolve.c (gfc_resolve_all): Call resolve_mask_arg. (gfc_resolve_any): Likewise. (gfc_resolve_count): Likewise. Don't append kind of argument to function name. 2008-01-15 Thomas Koenig <tkoenig@gcc.gnu.org> PR libfortran/34671 * gfortran.dg/anyallcount_1.f90: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@131553 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgfortran/m4')
-rw-r--r--libgfortran/m4/all.m44
-rw-r--r--libgfortran/m4/any.m44
-rw-r--r--libgfortran/m4/count.m44
-rw-r--r--libgfortran/m4/ifunction_logical.m4204
4 files changed, 210 insertions, 6 deletions
diff --git a/libgfortran/m4/all.m4 b/libgfortran/m4/all.m4
index 0695078a1df..8d4ece3d6ce 100644
--- a/libgfortran/m4/all.m4
+++ b/libgfortran/m4/all.m4
@@ -33,9 +33,9 @@ Boston, MA 02110-1301, USA. */
#include <assert.h>'
include(iparm.m4)dnl
-include(ifunction.m4)dnl
+include(ifunction_logical.m4)dnl
-`#if defined (HAVE_'atype_name`) && defined (HAVE_'rtype_name`)'
+`#if defined (HAVE_'rtype_name`)'
ARRAY_FUNCTION(1,
` /* Return true only if all the elements are set. */
diff --git a/libgfortran/m4/any.m4 b/libgfortran/m4/any.m4
index d1893a0beae..156f6c5b828 100644
--- a/libgfortran/m4/any.m4
+++ b/libgfortran/m4/any.m4
@@ -33,9 +33,9 @@ Boston, MA 02110-1301, USA. */
#include <assert.h>'
include(iparm.m4)dnl
-include(ifunction.m4)dnl
+include(ifunction_logical.m4)dnl
-`#if defined (HAVE_'atype_name`) && defined (HAVE_'rtype_name`)'
+`#if defined (HAVE_'rtype_name`)'
ARRAY_FUNCTION(0,
` result = 0;',
diff --git a/libgfortran/m4/count.m4 b/libgfortran/m4/count.m4
index c9567ab87c7..48ce411b0ab 100644
--- a/libgfortran/m4/count.m4
+++ b/libgfortran/m4/count.m4
@@ -33,9 +33,9 @@ Boston, MA 02110-1301, USA. */
#include <assert.h>'
include(iparm.m4)dnl
-include(ifunction.m4)dnl
+include(ifunction_logical.m4)dnl
-`#if defined (HAVE_'atype_name`) && defined (HAVE_'rtype_name`)'
+`#if defined (HAVE_'rtype_name`)'
ARRAY_FUNCTION(0,
` result = 0;',
diff --git a/libgfortran/m4/ifunction_logical.m4 b/libgfortran/m4/ifunction_logical.m4
new file mode 100644
index 00000000000..b2acb32f115
--- /dev/null
+++ b/libgfortran/m4/ifunction_logical.m4
@@ -0,0 +1,204 @@
+dnl Support macro file for intrinsic functions.
+dnl Contains the generic sections of the array functions.
+dnl This file is part of the GNU Fortran 95 Runtime Library (libgfortran)
+dnl Distributed under the GNU GPL with exception. See COPYING for details.
+dnl
+dnl Pass the implementation for a single section as the parameter to
+dnl {MASK_}ARRAY_FUNCTION.
+dnl The variables base, delta, and len describe the input section.
+dnl For masked section the mask is described by mbase and mdelta.
+dnl These should not be modified. The result should be stored in *dest.
+dnl The names count, extent, sstride, dstride, base, dest, rank, dim
+dnl retarray, array, pdim and mstride should not be used.
+dnl The variable n is declared as index_type and may be used.
+dnl Other variable declarations may be placed at the start of the code,
+dnl The types of the array parameter and the return value are
+dnl atype_name and rtype_name respectively.
+dnl Execution should be allowed to continue to the end of the block.
+dnl You should not return or break from the inner loop of the implementation.
+dnl Care should also be taken to avoid using the names defined in iparm.m4
+define(START_ARRAY_FUNCTION,
+`
+extern void name`'rtype_qual`_'atype_code (rtype * const restrict,
+ gfc_array_l1 * const restrict, const index_type * const restrict);
+export_proto(name`'rtype_qual`_'atype_code);
+
+void
+name`'rtype_qual`_'atype_code (rtype * const restrict retarray,
+ gfc_array_l1 * const restrict array,
+ const index_type * const restrict pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type sstride[GFC_MAX_DIMENSIONS];
+ index_type dstride[GFC_MAX_DIMENSIONS];
+ const GFC_LOGICAL_1 * restrict base;
+ rtype_name * restrict dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+ int src_kind;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+
+ src_kind = GFC_DESCRIPTOR_SIZE (array);
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride * src_kind;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride * src_kind;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+
+ if (extent[n] < 0)
+ extent[n] = 0;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride * src_kind;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+
+ if (extent[n] < 0)
+ extent[n] = 0;
+ }
+
+ if (retarray->data == NULL)
+ {
+ size_t alloc_size;
+
+ for (n = 0; n < rank; n++)
+ {
+ retarray->dim[n].lbound = 0;
+ retarray->dim[n].ubound = extent[n]-1;
+ if (n == 0)
+ retarray->dim[n].stride = 1;
+ else
+ retarray->dim[n].stride = retarray->dim[n-1].stride * extent[n-1];
+ }
+
+ retarray->offset = 0;
+ retarray->dtype = (array->dtype & ~GFC_DTYPE_RANK_MASK) | rank;
+
+ alloc_size = sizeof (rtype_name) * retarray->dim[rank-1].stride
+ * extent[rank-1];
+
+ if (alloc_size == 0)
+ {
+ /* Make sure we have a zero-sized array. */
+ retarray->dim[0].lbound = 0;
+ retarray->dim[0].ubound = -1;
+ return;
+ }
+ else
+ retarray->data = internal_malloc_size (alloc_size);
+ }
+ else
+ {
+ if (rank != GFC_DESCRIPTOR_RANK (retarray))
+ runtime_error ("rank of return array incorrect in"
+ " u_name intrinsic: is %d, should be %d",
+ GFC_DESCRIPTOR_RANK (retarray), rank);
+
+ if (compile_options.bounds_check)
+ {
+ for (n=0; n < rank; n++)
+ {
+ index_type ret_extent;
+
+ ret_extent = retarray->dim[n].ubound + 1
+ - retarray->dim[n].lbound;
+ if (extent[n] != ret_extent)
+ runtime_error ("Incorrect extent in return value of"
+ " u_name intrinsic in dimension %d:"
+ " is %ld, should be %ld", n + 1,
+ (long int) ret_extent, (long int) extent[n]);
+ }
+ }
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+
+ if (src_kind == 1 || src_kind == 2 || src_kind == 4 || src_kind == 8
+#ifdef HAVE_GFC_LOGICAL_16
+ || src_kind == 16
+#endif
+ )
+ {
+ if (base)
+ base = GFOR_POINTER_TO_L1 (base, src_kind);
+ }
+ else
+ internal_error (NULL, "Funny sized logical array in u_name intrinsic");
+
+ dest = retarray->data;
+
+ while (base)
+ {
+ const GFC_LOGICAL_1 * restrict src;
+ rtype_name result;
+ src = base;
+ {
+')dnl
+define(START_ARRAY_BLOCK,
+` if (len <= 0)
+ *dest = '$1`;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+')dnl
+define(FINISH_ARRAY_FUNCTION,
+ ` }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so probably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}')dnl
+define(ARRAY_FUNCTION,
+`START_ARRAY_FUNCTION
+$2
+START_ARRAY_BLOCK($1)
+$3
+FINISH_ARRAY_FUNCTION')dnl