From 6df6f67a283c62f0590d88b39d309b2c37cd7de1 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 17 May 2019 19:50:55 +0200 Subject: [PATCH] re PR fortran/54613 ([F08] Add FINDLOC plus support MAXLOC/MINLOC with KIND=/BACK=) PR fortran/54613 * gfortran.map (GFORTRAN_9.2): Export _gfortran_{,m,s}findloc{0,1}_r10. * Makefile.am (i_findloc0_c): Add $(srcdir)/generated/findloc0_r10.c. (i_findloc1_c): Add $(srcdir)/generated/findloc1_r10.c. * Makefile.in: Regenerated. * generated/findloc0_r10.c: Generated. * generated/findloc1_r10.c: Generated. From-SVN: r271336 --- libgfortran/generated/findloc0_r10.c | 375 +++++++++++++++++++ libgfortran/generated/findloc1_r10.c | 523 +++++++++++++++++++++++++++ 2 files changed, 898 insertions(+) create mode 100644 libgfortran/generated/findloc0_r10.c create mode 100644 libgfortran/generated/findloc1_r10.c diff --git a/libgfortran/generated/findloc0_r10.c b/libgfortran/generated/findloc0_r10.c new file mode 100644 index 00000000000..747ca3cf6fa --- /dev/null +++ b/libgfortran/generated/findloc0_r10.c @@ -0,0 +1,375 @@ + +/* Implementation of the FINDLOC intrinsic + Copyright (C) 2018-2019 Free Software Foundation, Inc. + Contributed by Thomas König + +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 General Public +License as published by the Free Software Foundation; either +version 3 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 General Public License for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +#include "libgfortran.h" +#include + +#if defined (HAVE_GFC_REAL_10) +extern void findloc0_r10 (gfc_array_index_type * const restrict retarray, + gfc_array_r10 * const restrict array, GFC_REAL_10 value, + GFC_LOGICAL_4); +export_proto(findloc0_r10); + +void +findloc0_r10 (gfc_array_index_type * const restrict retarray, + gfc_array_r10 * const restrict array, GFC_REAL_10 value, + GFC_LOGICAL_4 back) +{ + index_type count[GFC_MAX_DIMENSIONS]; + index_type extent[GFC_MAX_DIMENSIONS]; + index_type sstride[GFC_MAX_DIMENSIONS]; + index_type dstride; + const GFC_REAL_10 *base; + index_type * restrict dest; + index_type rank; + index_type n; + index_type sz; + + rank = GFC_DESCRIPTOR_RANK (array); + if (rank <= 0) + runtime_error ("Rank of array needs to be > 0"); + + if (retarray->base_addr == NULL) + { + GFC_DIMENSION_SET(retarray->dim[0], 0, rank-1, 1); + retarray->dtype.rank = 1; + retarray->offset = 0; + retarray->base_addr = xmallocarray (rank, sizeof (index_type)); + } + else + { + if (unlikely (compile_options.bounds_check)) + bounds_iforeach_return ((array_t *) retarray, (array_t *) array, + "FINDLOC"); + } + + dstride = GFC_DESCRIPTOR_STRIDE(retarray,0); + dest = retarray->base_addr; + + /* Set the return value. */ + for (n = 0; n < rank; n++) + dest[n * dstride] = 0; + + sz = 1; + for (n = 0; n < rank; n++) + { + sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n); + extent[n] = GFC_DESCRIPTOR_EXTENT(array,n); + sz *= extent[n]; + if (extent[n] <= 0) + return; + } + + for (n = 0; n < rank; n++) + count[n] = 0; + + if (back) + { + base = array->base_addr + (sz - 1) * 1; + + while (1) + { + do + { + if (unlikely(*base == value)) + { + for (n = 0; n < rank; n++) + dest[n * dstride] = extent[n] - count[n]; + + return; + } + base -= sstride[0] * 1; + } while(++count[0] != extent[0]); + + n = 0; + do + { + /* 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] * 1; + n++; + if (n >= rank) + return; + else + { + count[n]++; + base -= sstride[n] * 1; + } + } while (count[n] == extent[n]); + } + } + else + { + base = array->base_addr; + while (1) + { + do + { + if (unlikely(*base == value)) + { + for (n = 0; n < rank; n++) + dest[n * dstride] = count[n] + 1; + + return; + } + base += sstride[0] * 1; + } while(++count[0] != extent[0]); + + n = 0; + do + { + /* 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] * 1; + n++; + if (n >= rank) + return; + else + { + count[n]++; + base += sstride[n] * 1; + } + } while (count[n] == extent[n]); + } + } + return; +} + +extern void mfindloc0_r10 (gfc_array_index_type * const restrict retarray, + gfc_array_r10 * const restrict array, GFC_REAL_10 value, + gfc_array_l1 *const restrict, GFC_LOGICAL_4); +export_proto(mfindloc0_r10); + +void +mfindloc0_r10 (gfc_array_index_type * const restrict retarray, + gfc_array_r10 * const restrict array, GFC_REAL_10 value, + gfc_array_l1 *const restrict mask, GFC_LOGICAL_4 back) +{ + index_type count[GFC_MAX_DIMENSIONS]; + index_type extent[GFC_MAX_DIMENSIONS]; + index_type sstride[GFC_MAX_DIMENSIONS]; + index_type mstride[GFC_MAX_DIMENSIONS]; + index_type dstride; + const GFC_REAL_10 *base; + index_type * restrict dest; + GFC_LOGICAL_1 *mbase; + index_type rank; + index_type n; + int mask_kind; + index_type sz; + + rank = GFC_DESCRIPTOR_RANK (array); + if (rank <= 0) + runtime_error ("Rank of array needs to be > 0"); + + if (retarray->base_addr == NULL) + { + GFC_DIMENSION_SET(retarray->dim[0], 0, rank-1, 1); + retarray->dtype.rank = 1; + retarray->offset = 0; + retarray->base_addr = xmallocarray (rank, sizeof (index_type)); + } + else + { + if (unlikely (compile_options.bounds_check)) + { + bounds_iforeach_return ((array_t *) retarray, (array_t *) array, + "FINDLOC"); + bounds_equal_extents ((array_t *) mask, (array_t *) array, + "MASK argument", "FINDLOC"); + } + } + + mask_kind = GFC_DESCRIPTOR_SIZE (mask); + + mbase = mask->base_addr; + + if (mask_kind == 1 || mask_kind == 2 || mask_kind == 4 || mask_kind == 8 +#ifdef HAVE_GFC_LOGICAL_16 + || mask_kind == 16 +#endif + ) + mbase = GFOR_POINTER_TO_L1 (mbase, mask_kind); + else + internal_error (NULL, "Funny sized logical array"); + + dstride = GFC_DESCRIPTOR_STRIDE(retarray,0); + dest = retarray->base_addr; + + /* Set the return value. */ + for (n = 0; n < rank; n++) + dest[n * dstride] = 0; + + sz = 1; + for (n = 0; n < rank; n++) + { + sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n); + mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask,n); + extent[n] = GFC_DESCRIPTOR_EXTENT(array,n); + sz *= extent[n]; + if (extent[n] <= 0) + return; + } + + for (n = 0; n < rank; n++) + count[n] = 0; + + if (back) + { + base = array->base_addr + (sz - 1) * 1; + mbase = mbase + (sz - 1) * mask_kind; + while (1) + { + do + { + if (unlikely(*mbase && *base == value)) + { + for (n = 0; n < rank; n++) + dest[n * dstride] = extent[n] - count[n]; + + return; + } + base -= sstride[0] * 1; + mbase -= mstride[0]; + } while(++count[0] != extent[0]); + + n = 0; + do + { + /* 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] * 1; + mbase -= mstride[n] * extent[n]; + n++; + if (n >= rank) + return; + else + { + count[n]++; + base -= sstride[n] * 1; + mbase += mstride[n]; + } + } while (count[n] == extent[n]); + } + } + else + { + base = array->base_addr; + while (1) + { + do + { + if (unlikely(*mbase && *base == value)) + { + for (n = 0; n < rank; n++) + dest[n * dstride] = count[n] + 1; + + return; + } + base += sstride[0] * 1; + mbase += mstride[0]; + } while(++count[0] != extent[0]); + + n = 0; + do + { + /* 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] * 1; + mbase -= mstride[n] * extent[n]; + n++; + if (n >= rank) + return; + else + { + count[n]++; + base += sstride[n]* 1; + mbase += mstride[n]; + } + } while (count[n] == extent[n]); + } + } + return; +} + +extern void sfindloc0_r10 (gfc_array_index_type * const restrict retarray, + gfc_array_r10 * const restrict array, GFC_REAL_10 value, + GFC_LOGICAL_4 *, GFC_LOGICAL_4); +export_proto(sfindloc0_r10); + +void +sfindloc0_r10 (gfc_array_index_type * const restrict retarray, + gfc_array_r10 * const restrict array, GFC_REAL_10 value, + GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) +{ + index_type rank; + index_type dstride; + index_type * restrict dest; + index_type n; + + if (mask == NULL || *mask) + { + findloc0_r10 (retarray, array, value, back); + return; + } + + rank = GFC_DESCRIPTOR_RANK (array); + + if (rank <= 0) + internal_error (NULL, "Rank of array needs to be > 0"); + + if (retarray->base_addr == NULL) + { + GFC_DIMENSION_SET(retarray->dim[0], 0, rank-1, 1); + retarray->dtype.rank = 1; + retarray->offset = 0; + retarray->base_addr = xmallocarray (rank, sizeof (index_type)); + } + else if (unlikely (compile_options.bounds_check)) + { + bounds_iforeach_return ((array_t *) retarray, (array_t *) array, + "FINDLOC"); + } + + dstride = GFC_DESCRIPTOR_STRIDE(retarray,0); + dest = retarray->base_addr; + for (n = 0; n + +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 General Public +License as published by the Free Software Foundation; either +version 3 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 General Public License for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +#include "libgfortran.h" +#include + +#if defined (HAVE_GFC_REAL_10) +extern void findloc1_r10 (gfc_array_index_type * const restrict retarray, + gfc_array_r10 * const restrict array, GFC_REAL_10 value, + const index_type * restrict pdim, GFC_LOGICAL_4 back); +export_proto(findloc1_r10); + +extern void +findloc1_r10 (gfc_array_index_type * const restrict retarray, + gfc_array_r10 * const restrict array, GFC_REAL_10 value, + const index_type * restrict pdim, GFC_LOGICAL_4 back) +{ + 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_REAL_10 * restrict base; + index_type * restrict dest; + index_type rank; + index_type n; + index_type len; + index_type delta; + index_type dim; + int continue_loop; + + /* Make dim zero based to avoid confusion. */ + rank = GFC_DESCRIPTOR_RANK (array) - 1; + dim = (*pdim) - 1; + + if (unlikely (dim < 0 || dim > rank)) + { + runtime_error ("Dim argument incorrect in FINDLOC intrinsic: " + "is %ld, should be between 1 and %ld", + (long int) dim + 1, (long int) rank + 1); + } + + len = GFC_DESCRIPTOR_EXTENT(array,dim); + if (len < 0) + len = 0; + delta = GFC_DESCRIPTOR_STRIDE(array,dim); + + for (n = 0; n < dim; n++) + { + sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n); + extent[n] = GFC_DESCRIPTOR_EXTENT(array,n); + + if (extent[n] < 0) + extent[n] = 0; + } + for (n = dim; n < rank; n++) + { + sstride[n] = GFC_DESCRIPTOR_STRIDE(array, n + 1); + extent[n] = GFC_DESCRIPTOR_EXTENT(array, n + 1); + + if (extent[n] < 0) + extent[n] = 0; + } + + if (retarray->base_addr == NULL) + { + size_t alloc_size, str; + + for (n = 0; n < rank; n++) + { + if (n == 0) + str = 1; + else + str = GFC_DESCRIPTOR_STRIDE(retarray,n-1) * extent[n-1]; + + GFC_DIMENSION_SET(retarray->dim[n], 0, extent[n] - 1, str); + + } + + retarray->offset = 0; + retarray->dtype.rank = rank; + + alloc_size = GFC_DESCRIPTOR_STRIDE(retarray,rank-1) * extent[rank-1]; + + retarray->base_addr = xmallocarray (alloc_size, sizeof (index_type)); + if (alloc_size == 0) + { + /* Make sure we have a zero-sized array. */ + GFC_DIMENSION_SET(retarray->dim[0], 0, -1, 1); + return; + } + } + else + { + if (rank != GFC_DESCRIPTOR_RANK (retarray)) + runtime_error ("rank of return array incorrect in" + " FINDLOC intrinsic: is %ld, should be %ld", + (long int) (GFC_DESCRIPTOR_RANK (retarray)), + (long int) rank); + + if (unlikely (compile_options.bounds_check)) + bounds_ifunction_return ((array_t *) retarray, extent, + "return value", "FINDLOC"); + } + + for (n = 0; n < rank; n++) + { + count[n] = 0; + dstride[n] = GFC_DESCRIPTOR_STRIDE(retarray,n); + if (extent[n] <= 0) + return; + } + + dest = retarray->base_addr; + continue_loop = 1; + + base = array->base_addr; + while (continue_loop) + { + const GFC_REAL_10 * restrict src; + index_type result; + + result = 0; + if (back) + { + src = base + (len - 1) * delta * 1; + for (n = len; n > 0; n--, src -= delta * 1) + { + if (*src == value) + { + result = n; + break; + } + } + } + else + { + src = base; + for (n = 1; n <= len; n++, src += delta * 1) + { + if (*src == value) + { + result = n; + break; + } + } + } + *dest = result; + + count[0]++; + base += sstride[0] * 1; + dest += dstride[0]; + n = 0; + while (count[n] == extent[n]) + { + count[n] = 0; + base -= sstride[n] * extent[n] * 1; + dest -= dstride[n] * extent[n]; + n++; + if (n >= rank) + { + continue_loop = 0; + break; + } + else + { + count[n]++; + base += sstride[n] * 1; + dest += dstride[n]; + } + } + } +} +extern void mfindloc1_r10 (gfc_array_index_type * const restrict retarray, + gfc_array_r10 * const restrict array, GFC_REAL_10 value, + const index_type * restrict pdim, gfc_array_l1 *const restrict mask, + GFC_LOGICAL_4 back); +export_proto(mfindloc1_r10); + +extern void +mfindloc1_r10 (gfc_array_index_type * const restrict retarray, + gfc_array_r10 * const restrict array, GFC_REAL_10 value, + const index_type * restrict pdim, gfc_array_l1 *const restrict mask, + GFC_LOGICAL_4 back) +{ + index_type count[GFC_MAX_DIMENSIONS]; + index_type extent[GFC_MAX_DIMENSIONS]; + index_type sstride[GFC_MAX_DIMENSIONS]; + index_type mstride[GFC_MAX_DIMENSIONS]; + index_type dstride[GFC_MAX_DIMENSIONS]; + const GFC_REAL_10 * restrict base; + const GFC_LOGICAL_1 * restrict mbase; + index_type * restrict dest; + index_type rank; + index_type n; + index_type len; + index_type delta; + index_type mdelta; + index_type dim; + int mask_kind; + int continue_loop; + + /* Make dim zero based to avoid confusion. */ + rank = GFC_DESCRIPTOR_RANK (array) - 1; + dim = (*pdim) - 1; + + if (unlikely (dim < 0 || dim > rank)) + { + runtime_error ("Dim argument incorrect in FINDLOC intrinsic: " + "is %ld, should be between 1 and %ld", + (long int) dim + 1, (long int) rank + 1); + } + + len = GFC_DESCRIPTOR_EXTENT(array,dim); + if (len < 0) + len = 0; + + delta = GFC_DESCRIPTOR_STRIDE(array,dim); + mdelta = GFC_DESCRIPTOR_STRIDE_BYTES(mask,dim); + + mbase = mask->base_addr; + + mask_kind = GFC_DESCRIPTOR_SIZE (mask); + + if (mask_kind == 1 || mask_kind == 2 || mask_kind == 4 || mask_kind == 8 +#ifdef HAVE_GFC_LOGICAL_16 + || mask_kind == 16 +#endif + ) + mbase = GFOR_POINTER_TO_L1 (mbase, mask_kind); + else + internal_error (NULL, "Funny sized logical array"); + + for (n = 0; n < dim; n++) + { + sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n); + mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask,n); + extent[n] = GFC_DESCRIPTOR_EXTENT(array,n); + + if (extent[n] < 0) + extent[n] = 0; + } + for (n = dim; n < rank; n++) + { + sstride[n] = GFC_DESCRIPTOR_STRIDE(array, n + 1); + mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask, n + 1); + extent[n] = GFC_DESCRIPTOR_EXTENT(array, n + 1); + + if (extent[n] < 0) + extent[n] = 0; + } + + if (retarray->base_addr == NULL) + { + size_t alloc_size, str; + + for (n = 0; n < rank; n++) + { + if (n == 0) + str = 1; + else + str = GFC_DESCRIPTOR_STRIDE(retarray,n-1) * extent[n-1]; + + GFC_DIMENSION_SET(retarray->dim[n], 0, extent[n] - 1, str); + + } + + retarray->offset = 0; + retarray->dtype.rank = rank; + + alloc_size = GFC_DESCRIPTOR_STRIDE(retarray,rank-1) * extent[rank-1]; + + retarray->base_addr = xmallocarray (alloc_size, sizeof (index_type)); + if (alloc_size == 0) + { + /* Make sure we have a zero-sized array. */ + GFC_DIMENSION_SET(retarray->dim[0], 0, -1, 1); + return; + } + } + else + { + if (rank != GFC_DESCRIPTOR_RANK (retarray)) + runtime_error ("rank of return array incorrect in" + " FINDLOC intrinsic: is %ld, should be %ld", + (long int) (GFC_DESCRIPTOR_RANK (retarray)), + (long int) rank); + + if (unlikely (compile_options.bounds_check)) + bounds_ifunction_return ((array_t *) retarray, extent, + "return value", "FINDLOC"); + } + + for (n = 0; n < rank; n++) + { + count[n] = 0; + dstride[n] = GFC_DESCRIPTOR_STRIDE(retarray,n); + if (extent[n] <= 0) + return; + } + + dest = retarray->base_addr; + continue_loop = 1; + + base = array->base_addr; + while (continue_loop) + { + const GFC_REAL_10 * restrict src; + const GFC_LOGICAL_1 * restrict msrc; + index_type result; + + result = 0; + if (back) + { + src = base + (len - 1) * delta * 1; + msrc = mbase + (len - 1) * mdelta; + for (n = len; n > 0; n--, src -= delta * 1, msrc -= mdelta) + { + if (*msrc && *src == value) + { + result = n; + break; + } + } + } + else + { + src = base; + msrc = mbase; + for (n = 1; n <= len; n++, src += delta * 1, msrc += mdelta) + { + if (*msrc && *src == value) + { + result = n; + break; + } + } + } + *dest = result; + + count[0]++; + base += sstride[0] * 1; + mbase += mstride[0]; + dest += dstride[0]; + n = 0; + while (count[n] == extent[n]) + { + count[n] = 0; + base -= sstride[n] * extent[n] * 1; + mbase -= mstride[n] * extent[n]; + dest -= dstride[n] * extent[n]; + n++; + if (n >= rank) + { + continue_loop = 0; + break; + } + else + { + count[n]++; + base += sstride[n] * 1; + dest += dstride[n]; + } + } + } +} +extern void sfindloc1_r10 (gfc_array_index_type * const restrict retarray, + gfc_array_r10 * const restrict array, GFC_REAL_10 value, + const index_type * restrict pdim, GFC_LOGICAL_4 *const restrict mask, + GFC_LOGICAL_4 back); +export_proto(sfindloc1_r10); + +extern void +sfindloc1_r10 (gfc_array_index_type * const restrict retarray, + gfc_array_r10 * const restrict array, GFC_REAL_10 value, + const index_type * restrict pdim, GFC_LOGICAL_4 *const restrict mask, + GFC_LOGICAL_4 back) +{ + index_type count[GFC_MAX_DIMENSIONS]; + index_type extent[GFC_MAX_DIMENSIONS]; + index_type dstride[GFC_MAX_DIMENSIONS]; + index_type * restrict dest; + index_type rank; + index_type n; + index_type len; + index_type dim; + bool continue_loop; + + if (mask == NULL || *mask) + { + findloc1_r10 (retarray, array, value, pdim, back); + return; + } + /* Make dim zero based to avoid confusion. */ + rank = GFC_DESCRIPTOR_RANK (array) - 1; + dim = (*pdim) - 1; + + if (unlikely (dim < 0 || dim > rank)) + { + runtime_error ("Dim argument incorrect in FINDLOC intrinsic: " + "is %ld, should be between 1 and %ld", + (long int) dim + 1, (long int) rank + 1); + } + + len = GFC_DESCRIPTOR_EXTENT(array,dim); + if (len < 0) + len = 0; + + for (n = 0; n < dim; n++) + { + extent[n] = GFC_DESCRIPTOR_EXTENT(array,n); + + if (extent[n] <= 0) + extent[n] = 0; + } + + for (n = dim; n < rank; n++) + { + extent[n] = + GFC_DESCRIPTOR_EXTENT(array,n + 1); + + if (extent[n] <= 0) + extent[n] = 0; + } + + + if (retarray->base_addr == NULL) + { + size_t alloc_size, str; + + for (n = 0; n < rank; n++) + { + if (n == 0) + str = 1; + else + str = GFC_DESCRIPTOR_STRIDE(retarray,n-1) * extent[n-1]; + + GFC_DIMENSION_SET(retarray->dim[n], 0, extent[n] - 1, str); + } + + retarray->offset = 0; + retarray->dtype.rank = rank; + + alloc_size = GFC_DESCRIPTOR_STRIDE(retarray,rank-1) * extent[rank-1]; + + retarray->base_addr = xmallocarray (alloc_size, sizeof (index_type)); + if (alloc_size == 0) + { + /* Make sure we have a zero-sized array. */ + GFC_DIMENSION_SET(retarray->dim[0], 0, -1, 1); + return; + } + } + else + { + if (rank != GFC_DESCRIPTOR_RANK (retarray)) + runtime_error ("rank of return array incorrect in" + " FINDLOC intrinsic: is %ld, should be %ld", + (long int) (GFC_DESCRIPTOR_RANK (retarray)), + (long int) rank); + + if (unlikely (compile_options.bounds_check)) + bounds_ifunction_return ((array_t *) retarray, extent, + "return value", "FINDLOC"); + } + + for (n = 0; n < rank; n++) + { + count[n] = 0; + dstride[n] = GFC_DESCRIPTOR_STRIDE(retarray,n); + if (extent[n] <= 0) + return; + } + dest = retarray->base_addr; + continue_loop = 1; + + while (continue_loop) + { + *dest = 0; + + count[0]++; + dest += dstride[0]; + n = 0; + while (count[n] == extent[n]) + { + count[n] = 0; + dest -= dstride[n] * extent[n]; + n++; + if (n >= rank) + { + continue_loop = 0; + break; + } + else + { + count[n]++; + dest += dstride[n]; + } + } + } +} +#endif -- 2.30.2