Home | History | Annotate | Line # | Download | only in generated
      1      1.1  mrg /* Implementation of the FINDLOC intrinsic
      2  1.1.1.3  mrg    Copyright (C) 2018-2024 Free Software Foundation, Inc.
      3      1.1  mrg    Contributed by Thomas Knig <tk (at) tkoenig.net>
      4      1.1  mrg 
      5      1.1  mrg This file is part of the GNU Fortran 95 runtime library (libgfortran).
      6      1.1  mrg 
      7      1.1  mrg Libgfortran is free software; you can redistribute it and/or
      8      1.1  mrg modify it under the terms of the GNU General Public
      9      1.1  mrg License as published by the Free Software Foundation; either
     10      1.1  mrg version 3 of the License, or (at your option) any later version.
     11      1.1  mrg 
     12      1.1  mrg Libgfortran is distributed in the hope that it will be useful,
     13      1.1  mrg but WITHOUT ANY WARRANTY; without even the implied warranty of
     14      1.1  mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15      1.1  mrg GNU General Public License for more details.
     16      1.1  mrg 
     17      1.1  mrg Under Section 7 of GPL version 3, you are granted additional
     18      1.1  mrg permissions described in the GCC Runtime Library Exception, version
     19      1.1  mrg 3.1, as published by the Free Software Foundation.
     20      1.1  mrg 
     21      1.1  mrg You should have received a copy of the GNU General Public License and
     22      1.1  mrg a copy of the GCC Runtime Library Exception along with this program;
     23      1.1  mrg see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     24      1.1  mrg <http://www.gnu.org/licenses/>.  */
     25      1.1  mrg 
     26      1.1  mrg #include "libgfortran.h"
     27      1.1  mrg #include <assert.h>
     28      1.1  mrg 
     29      1.1  mrg #if defined (HAVE_GFC_COMPLEX_10)
     30      1.1  mrg extern void findloc1_c10 (gfc_array_index_type * const restrict retarray,
     31      1.1  mrg 		         gfc_array_c10 * const restrict array, GFC_COMPLEX_10 value,
     32      1.1  mrg 			 const index_type * restrict pdim, GFC_LOGICAL_4 back);
     33      1.1  mrg export_proto(findloc1_c10);
     34      1.1  mrg 
     35      1.1  mrg extern void
     36      1.1  mrg findloc1_c10 (gfc_array_index_type * const restrict retarray,
     37      1.1  mrg 	    gfc_array_c10 * const restrict array, GFC_COMPLEX_10 value,
     38      1.1  mrg 	    const index_type * restrict pdim, GFC_LOGICAL_4 back)
     39      1.1  mrg {
     40      1.1  mrg   index_type count[GFC_MAX_DIMENSIONS];
     41      1.1  mrg   index_type extent[GFC_MAX_DIMENSIONS];
     42      1.1  mrg   index_type sstride[GFC_MAX_DIMENSIONS];
     43      1.1  mrg   index_type dstride[GFC_MAX_DIMENSIONS];
     44      1.1  mrg   const GFC_COMPLEX_10 * restrict base;
     45      1.1  mrg   index_type * restrict dest;
     46      1.1  mrg   index_type rank;
     47      1.1  mrg   index_type n;
     48      1.1  mrg   index_type len;
     49      1.1  mrg   index_type delta;
     50      1.1  mrg   index_type dim;
     51      1.1  mrg   int continue_loop;
     52      1.1  mrg 
     53      1.1  mrg   /* Make dim zero based to avoid confusion.  */
     54      1.1  mrg   rank = GFC_DESCRIPTOR_RANK (array) - 1;
     55      1.1  mrg   dim = (*pdim) - 1;
     56      1.1  mrg 
     57      1.1  mrg   if (unlikely (dim < 0 || dim > rank))
     58      1.1  mrg     {
     59      1.1  mrg       runtime_error ("Dim argument incorrect in FINDLOC intrinsic: "
     60      1.1  mrg  		     "is %ld, should be between 1 and %ld",
     61      1.1  mrg 		     (long int) dim + 1, (long int) rank + 1);
     62      1.1  mrg     }
     63      1.1  mrg 
     64      1.1  mrg   len = GFC_DESCRIPTOR_EXTENT(array,dim);
     65      1.1  mrg   if (len < 0)
     66      1.1  mrg     len = 0;
     67      1.1  mrg   delta = GFC_DESCRIPTOR_STRIDE(array,dim);
     68      1.1  mrg 
     69      1.1  mrg   for (n = 0; n < dim; n++)
     70      1.1  mrg     {
     71      1.1  mrg       sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n);
     72      1.1  mrg       extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
     73      1.1  mrg 
     74      1.1  mrg       if (extent[n] < 0)
     75      1.1  mrg 	extent[n] = 0;
     76      1.1  mrg     }
     77      1.1  mrg   for (n = dim; n < rank; n++)
     78      1.1  mrg     {
     79      1.1  mrg       sstride[n] = GFC_DESCRIPTOR_STRIDE(array, n + 1);
     80      1.1  mrg       extent[n] = GFC_DESCRIPTOR_EXTENT(array, n + 1);
     81      1.1  mrg 
     82      1.1  mrg       if (extent[n] < 0)
     83      1.1  mrg 	extent[n] = 0;
     84      1.1  mrg     }
     85      1.1  mrg 
     86      1.1  mrg   if (retarray->base_addr == NULL)
     87      1.1  mrg     {
     88      1.1  mrg       size_t alloc_size, str;
     89      1.1  mrg 
     90      1.1  mrg       for (n = 0; n < rank; n++)
     91      1.1  mrg 	{
     92      1.1  mrg 	  if (n == 0)
     93      1.1  mrg 	    str = 1;
     94      1.1  mrg 	  else
     95      1.1  mrg 	    str = GFC_DESCRIPTOR_STRIDE(retarray,n-1) * extent[n-1];
     96      1.1  mrg 
     97      1.1  mrg 	  GFC_DIMENSION_SET(retarray->dim[n], 0, extent[n] - 1, str);
     98      1.1  mrg 
     99      1.1  mrg 	}
    100      1.1  mrg 
    101      1.1  mrg       retarray->offset = 0;
    102      1.1  mrg       retarray->dtype.rank = rank;
    103      1.1  mrg 
    104      1.1  mrg       alloc_size = GFC_DESCRIPTOR_STRIDE(retarray,rank-1) * extent[rank-1];
    105      1.1  mrg 
    106      1.1  mrg       retarray->base_addr = xmallocarray (alloc_size, sizeof (index_type));
    107      1.1  mrg       if (alloc_size == 0)
    108  1.1.1.3  mrg 	return;
    109      1.1  mrg     }
    110      1.1  mrg   else
    111      1.1  mrg     {
    112      1.1  mrg       if (rank != GFC_DESCRIPTOR_RANK (retarray))
    113      1.1  mrg 	runtime_error ("rank of return array incorrect in"
    114      1.1  mrg 		       " FINDLOC intrinsic: is %ld, should be %ld",
    115      1.1  mrg 		       (long int) (GFC_DESCRIPTOR_RANK (retarray)),
    116      1.1  mrg 		       (long int) rank);
    117      1.1  mrg 
    118      1.1  mrg       if (unlikely (compile_options.bounds_check))
    119      1.1  mrg 	bounds_ifunction_return ((array_t *) retarray, extent,
    120      1.1  mrg 				 "return value", "FINDLOC");
    121      1.1  mrg     }
    122      1.1  mrg 
    123      1.1  mrg   for (n = 0; n < rank; n++)
    124      1.1  mrg     {
    125      1.1  mrg       count[n] = 0;
    126      1.1  mrg       dstride[n] = GFC_DESCRIPTOR_STRIDE(retarray,n);
    127      1.1  mrg       if (extent[n] <= 0)
    128      1.1  mrg 	return;
    129      1.1  mrg     }
    130      1.1  mrg 
    131      1.1  mrg   dest = retarray->base_addr;
    132      1.1  mrg   continue_loop = 1;
    133      1.1  mrg 
    134      1.1  mrg   base = array->base_addr;
    135      1.1  mrg   while (continue_loop)
    136      1.1  mrg     {
    137      1.1  mrg       const GFC_COMPLEX_10 * restrict src;
    138      1.1  mrg       index_type result;
    139      1.1  mrg 
    140      1.1  mrg       result = 0;
    141      1.1  mrg       if (back)
    142      1.1  mrg 	{
    143      1.1  mrg 	  src = base + (len - 1) * delta * 1;
    144      1.1  mrg 	  for (n = len; n > 0; n--, src -= delta * 1)
    145      1.1  mrg 	    {
    146      1.1  mrg 	      if (*src == value)
    147      1.1  mrg 		{
    148      1.1  mrg 		  result = n;
    149      1.1  mrg 		  break;
    150      1.1  mrg 		}
    151      1.1  mrg 	    }
    152      1.1  mrg 	}
    153      1.1  mrg       else
    154      1.1  mrg 	{
    155      1.1  mrg 	  src = base;
    156      1.1  mrg 	  for (n = 1; n <= len; n++, src += delta * 1)
    157      1.1  mrg 	    {
    158      1.1  mrg 	      if (*src == value)
    159      1.1  mrg 		{
    160      1.1  mrg 		  result = n;
    161      1.1  mrg 		  break;
    162      1.1  mrg 		}
    163      1.1  mrg 	    }
    164      1.1  mrg 	}
    165      1.1  mrg       *dest = result;
    166      1.1  mrg 
    167      1.1  mrg       count[0]++;
    168      1.1  mrg       base += sstride[0] * 1;
    169      1.1  mrg       dest += dstride[0];
    170      1.1  mrg       n = 0;
    171      1.1  mrg       while (count[n] == extent[n])
    172      1.1  mrg 	{
    173      1.1  mrg 	  count[n] = 0;
    174      1.1  mrg 	  base -= sstride[n] * extent[n] * 1;
    175      1.1  mrg 	  dest -= dstride[n] * extent[n];
    176      1.1  mrg 	  n++;
    177      1.1  mrg 	  if (n >= rank)
    178      1.1  mrg 	    {
    179      1.1  mrg 	      continue_loop = 0;
    180      1.1  mrg 	      break;
    181      1.1  mrg 	    }
    182      1.1  mrg 	  else
    183      1.1  mrg 	    {
    184      1.1  mrg 	      count[n]++;
    185      1.1  mrg 	      base += sstride[n] * 1;
    186      1.1  mrg 	      dest += dstride[n];
    187      1.1  mrg 	    }
    188      1.1  mrg 	}
    189      1.1  mrg     }
    190      1.1  mrg }
    191      1.1  mrg extern void mfindloc1_c10 (gfc_array_index_type * const restrict retarray,
    192      1.1  mrg 		         gfc_array_c10 * const restrict array, GFC_COMPLEX_10 value,
    193      1.1  mrg 			 const index_type * restrict pdim, gfc_array_l1 *const restrict mask,
    194      1.1  mrg 			 GFC_LOGICAL_4 back);
    195      1.1  mrg export_proto(mfindloc1_c10);
    196      1.1  mrg 
    197      1.1  mrg extern void
    198      1.1  mrg mfindloc1_c10 (gfc_array_index_type * const restrict retarray,
    199      1.1  mrg 	    gfc_array_c10 * const restrict array, GFC_COMPLEX_10 value,
    200      1.1  mrg 	    const index_type * restrict pdim, gfc_array_l1 *const restrict mask,
    201      1.1  mrg 	    GFC_LOGICAL_4 back)
    202      1.1  mrg {
    203      1.1  mrg   index_type count[GFC_MAX_DIMENSIONS];
    204      1.1  mrg   index_type extent[GFC_MAX_DIMENSIONS];
    205      1.1  mrg   index_type sstride[GFC_MAX_DIMENSIONS];
    206      1.1  mrg   index_type mstride[GFC_MAX_DIMENSIONS];
    207      1.1  mrg   index_type dstride[GFC_MAX_DIMENSIONS];
    208      1.1  mrg   const GFC_COMPLEX_10 * restrict base;
    209      1.1  mrg   const GFC_LOGICAL_1 * restrict mbase;
    210      1.1  mrg   index_type * restrict dest;
    211      1.1  mrg   index_type rank;
    212      1.1  mrg   index_type n;
    213      1.1  mrg   index_type len;
    214      1.1  mrg   index_type delta;
    215      1.1  mrg   index_type mdelta;
    216      1.1  mrg   index_type dim;
    217      1.1  mrg   int mask_kind;
    218      1.1  mrg   int continue_loop;
    219      1.1  mrg 
    220      1.1  mrg   /* Make dim zero based to avoid confusion.  */
    221      1.1  mrg   rank = GFC_DESCRIPTOR_RANK (array) - 1;
    222      1.1  mrg   dim = (*pdim) - 1;
    223      1.1  mrg 
    224      1.1  mrg   if (unlikely (dim < 0 || dim > rank))
    225      1.1  mrg     {
    226      1.1  mrg       runtime_error ("Dim argument incorrect in FINDLOC intrinsic: "
    227      1.1  mrg  		     "is %ld, should be between 1 and %ld",
    228      1.1  mrg 		     (long int) dim + 1, (long int) rank + 1);
    229      1.1  mrg     }
    230      1.1  mrg 
    231      1.1  mrg   len = GFC_DESCRIPTOR_EXTENT(array,dim);
    232      1.1  mrg   if (len < 0)
    233      1.1  mrg     len = 0;
    234      1.1  mrg 
    235      1.1  mrg   delta = GFC_DESCRIPTOR_STRIDE(array,dim);
    236      1.1  mrg   mdelta = GFC_DESCRIPTOR_STRIDE_BYTES(mask,dim);
    237      1.1  mrg 
    238      1.1  mrg   mbase = mask->base_addr;
    239      1.1  mrg 
    240      1.1  mrg   mask_kind = GFC_DESCRIPTOR_SIZE (mask);
    241      1.1  mrg 
    242      1.1  mrg   if (mask_kind == 1 || mask_kind == 2 || mask_kind == 4 || mask_kind == 8
    243      1.1  mrg #ifdef HAVE_GFC_LOGICAL_16
    244      1.1  mrg       || mask_kind == 16
    245      1.1  mrg #endif
    246      1.1  mrg       )
    247      1.1  mrg     mbase = GFOR_POINTER_TO_L1 (mbase, mask_kind);
    248      1.1  mrg   else
    249      1.1  mrg     internal_error (NULL, "Funny sized logical array");
    250      1.1  mrg 
    251      1.1  mrg   for (n = 0; n < dim; n++)
    252      1.1  mrg     {
    253      1.1  mrg       sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n);
    254      1.1  mrg       mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask,n);
    255      1.1  mrg       extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
    256      1.1  mrg 
    257      1.1  mrg       if (extent[n] < 0)
    258      1.1  mrg 	extent[n] = 0;
    259      1.1  mrg     }
    260      1.1  mrg   for (n = dim; n < rank; n++)
    261      1.1  mrg     {
    262      1.1  mrg       sstride[n] = GFC_DESCRIPTOR_STRIDE(array, n + 1);
    263      1.1  mrg       mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask, n + 1);
    264      1.1  mrg       extent[n] = GFC_DESCRIPTOR_EXTENT(array, n + 1);
    265      1.1  mrg 
    266      1.1  mrg       if (extent[n] < 0)
    267      1.1  mrg 	extent[n] = 0;
    268      1.1  mrg     }
    269      1.1  mrg 
    270      1.1  mrg   if (retarray->base_addr == NULL)
    271      1.1  mrg     {
    272      1.1  mrg       size_t alloc_size, str;
    273      1.1  mrg 
    274      1.1  mrg       for (n = 0; n < rank; n++)
    275      1.1  mrg 	{
    276      1.1  mrg 	  if (n == 0)
    277      1.1  mrg 	    str = 1;
    278      1.1  mrg 	  else
    279      1.1  mrg 	    str = GFC_DESCRIPTOR_STRIDE(retarray,n-1) * extent[n-1];
    280      1.1  mrg 
    281      1.1  mrg 	  GFC_DIMENSION_SET(retarray->dim[n], 0, extent[n] - 1, str);
    282      1.1  mrg 
    283      1.1  mrg 	}
    284      1.1  mrg 
    285      1.1  mrg       retarray->offset = 0;
    286      1.1  mrg       retarray->dtype.rank = rank;
    287      1.1  mrg 
    288      1.1  mrg       alloc_size = GFC_DESCRIPTOR_STRIDE(retarray,rank-1) * extent[rank-1];
    289      1.1  mrg 
    290      1.1  mrg       retarray->base_addr = xmallocarray (alloc_size, sizeof (index_type));
    291      1.1  mrg       if (alloc_size == 0)
    292  1.1.1.3  mrg 	return;
    293      1.1  mrg     }
    294      1.1  mrg   else
    295      1.1  mrg     {
    296      1.1  mrg       if (rank != GFC_DESCRIPTOR_RANK (retarray))
    297      1.1  mrg 	runtime_error ("rank of return array incorrect in"
    298      1.1  mrg 		       " FINDLOC intrinsic: is %ld, should be %ld",
    299      1.1  mrg 		       (long int) (GFC_DESCRIPTOR_RANK (retarray)),
    300      1.1  mrg 		       (long int) rank);
    301      1.1  mrg 
    302      1.1  mrg       if (unlikely (compile_options.bounds_check))
    303      1.1  mrg 	bounds_ifunction_return ((array_t *) retarray, extent,
    304      1.1  mrg 				 "return value", "FINDLOC");
    305      1.1  mrg     }
    306      1.1  mrg 
    307      1.1  mrg   for (n = 0; n < rank; n++)
    308      1.1  mrg     {
    309      1.1  mrg       count[n] = 0;
    310      1.1  mrg       dstride[n] = GFC_DESCRIPTOR_STRIDE(retarray,n);
    311      1.1  mrg       if (extent[n] <= 0)
    312      1.1  mrg 	return;
    313      1.1  mrg     }
    314      1.1  mrg 
    315      1.1  mrg   dest = retarray->base_addr;
    316      1.1  mrg   continue_loop = 1;
    317      1.1  mrg 
    318      1.1  mrg   base = array->base_addr;
    319      1.1  mrg   while (continue_loop)
    320      1.1  mrg     {
    321      1.1  mrg       const GFC_COMPLEX_10 * restrict src;
    322      1.1  mrg       const GFC_LOGICAL_1 * restrict msrc;
    323      1.1  mrg       index_type result;
    324      1.1  mrg 
    325      1.1  mrg       result = 0;
    326      1.1  mrg       if (back)
    327      1.1  mrg 	{
    328      1.1  mrg 	  src = base + (len - 1) * delta * 1;
    329      1.1  mrg 	  msrc = mbase + (len - 1) * mdelta;
    330      1.1  mrg 	  for (n = len; n > 0; n--, src -= delta * 1, msrc -= mdelta)
    331      1.1  mrg 	    {
    332      1.1  mrg 	      if (*msrc && *src == value)
    333      1.1  mrg 		{
    334      1.1  mrg 		  result = n;
    335      1.1  mrg 		  break;
    336      1.1  mrg 		}
    337      1.1  mrg 	    }
    338      1.1  mrg 	}
    339      1.1  mrg       else
    340      1.1  mrg 	{
    341      1.1  mrg 	  src = base;
    342      1.1  mrg 	  msrc = mbase;
    343      1.1  mrg 	  for (n = 1; n <= len; n++, src += delta * 1, msrc += mdelta)
    344      1.1  mrg 	    {
    345      1.1  mrg 	      if (*msrc && *src == value)
    346      1.1  mrg 		{
    347      1.1  mrg 		  result = n;
    348      1.1  mrg 		  break;
    349      1.1  mrg 		}
    350      1.1  mrg 	    }
    351      1.1  mrg 	}
    352      1.1  mrg       *dest = result;
    353      1.1  mrg 
    354      1.1  mrg       count[0]++;
    355      1.1  mrg       base += sstride[0] * 1;
    356      1.1  mrg       mbase += mstride[0];
    357      1.1  mrg       dest += dstride[0];
    358      1.1  mrg       n = 0;
    359      1.1  mrg       while (count[n] == extent[n])
    360      1.1  mrg 	{
    361      1.1  mrg 	  count[n] = 0;
    362      1.1  mrg 	  base -= sstride[n] * extent[n] * 1;
    363      1.1  mrg 	  mbase -= mstride[n] * extent[n];
    364      1.1  mrg 	  dest -= dstride[n] * extent[n];
    365      1.1  mrg 	  n++;
    366      1.1  mrg 	  if (n >= rank)
    367      1.1  mrg 	    {
    368      1.1  mrg 	      continue_loop = 0;
    369      1.1  mrg 	      break;
    370      1.1  mrg 	    }
    371      1.1  mrg 	  else
    372      1.1  mrg 	    {
    373      1.1  mrg 	      count[n]++;
    374      1.1  mrg 	      base += sstride[n] * 1;
    375      1.1  mrg 	      dest += dstride[n];
    376      1.1  mrg 	    }
    377      1.1  mrg 	}
    378      1.1  mrg     }
    379      1.1  mrg }
    380      1.1  mrg extern void sfindloc1_c10 (gfc_array_index_type * const restrict retarray,
    381      1.1  mrg 		         gfc_array_c10 * const restrict array, GFC_COMPLEX_10 value,
    382      1.1  mrg 			 const index_type * restrict pdim, GFC_LOGICAL_4 *const restrict mask,
    383      1.1  mrg 			 GFC_LOGICAL_4 back);
    384      1.1  mrg export_proto(sfindloc1_c10);
    385      1.1  mrg 
    386      1.1  mrg extern void
    387      1.1  mrg sfindloc1_c10 (gfc_array_index_type * const restrict retarray,
    388      1.1  mrg 	    gfc_array_c10 * const restrict array, GFC_COMPLEX_10 value,
    389      1.1  mrg 	    const index_type * restrict pdim, GFC_LOGICAL_4 *const restrict  mask,
    390      1.1  mrg 	    GFC_LOGICAL_4 back)
    391      1.1  mrg {
    392      1.1  mrg   index_type count[GFC_MAX_DIMENSIONS];
    393      1.1  mrg   index_type extent[GFC_MAX_DIMENSIONS];
    394      1.1  mrg   index_type dstride[GFC_MAX_DIMENSIONS];
    395      1.1  mrg   index_type * restrict dest;
    396      1.1  mrg   index_type rank;
    397      1.1  mrg   index_type n;
    398      1.1  mrg   index_type len;
    399      1.1  mrg   index_type dim;
    400      1.1  mrg   bool continue_loop;
    401      1.1  mrg 
    402      1.1  mrg   if (mask == NULL || *mask)
    403      1.1  mrg     {
    404      1.1  mrg       findloc1_c10 (retarray, array, value, pdim, back);
    405      1.1  mrg       return;
    406      1.1  mrg     }
    407      1.1  mrg     /* Make dim zero based to avoid confusion.  */
    408      1.1  mrg   rank = GFC_DESCRIPTOR_RANK (array) - 1;
    409      1.1  mrg   dim = (*pdim) - 1;
    410      1.1  mrg 
    411      1.1  mrg   if (unlikely (dim < 0 || dim > rank))
    412      1.1  mrg     {
    413      1.1  mrg       runtime_error ("Dim argument incorrect in FINDLOC intrinsic: "
    414      1.1  mrg  		     "is %ld, should be between 1 and %ld",
    415      1.1  mrg 		     (long int) dim + 1, (long int) rank + 1);
    416      1.1  mrg     }
    417      1.1  mrg 
    418      1.1  mrg   len = GFC_DESCRIPTOR_EXTENT(array,dim);
    419      1.1  mrg   if (len < 0)
    420      1.1  mrg     len = 0;
    421      1.1  mrg 
    422      1.1  mrg   for (n = 0; n < dim; n++)
    423      1.1  mrg     {
    424      1.1  mrg       extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
    425      1.1  mrg 
    426      1.1  mrg       if (extent[n] <= 0)
    427      1.1  mrg 	extent[n] = 0;
    428      1.1  mrg     }
    429      1.1  mrg 
    430      1.1  mrg   for (n = dim; n < rank; n++)
    431      1.1  mrg     {
    432      1.1  mrg       extent[n] =
    433      1.1  mrg 	GFC_DESCRIPTOR_EXTENT(array,n + 1);
    434      1.1  mrg 
    435      1.1  mrg       if (extent[n] <= 0)
    436      1.1  mrg 	extent[n] = 0;
    437      1.1  mrg     }
    438      1.1  mrg 
    439      1.1  mrg 
    440      1.1  mrg   if (retarray->base_addr == NULL)
    441      1.1  mrg     {
    442      1.1  mrg       size_t alloc_size, str;
    443      1.1  mrg 
    444      1.1  mrg       for (n = 0; n < rank; n++)
    445      1.1  mrg 	{
    446      1.1  mrg 	  if (n == 0)
    447      1.1  mrg 	    str = 1;
    448      1.1  mrg 	  else
    449      1.1  mrg 	    str = GFC_DESCRIPTOR_STRIDE(retarray,n-1) * extent[n-1];
    450      1.1  mrg 
    451      1.1  mrg 	  GFC_DIMENSION_SET(retarray->dim[n], 0, extent[n] - 1, str);
    452      1.1  mrg 	}
    453      1.1  mrg 
    454      1.1  mrg       retarray->offset = 0;
    455      1.1  mrg       retarray->dtype.rank = rank;
    456      1.1  mrg 
    457      1.1  mrg       alloc_size = GFC_DESCRIPTOR_STRIDE(retarray,rank-1) * extent[rank-1];
    458      1.1  mrg 
    459      1.1  mrg       retarray->base_addr = xmallocarray (alloc_size, sizeof (index_type));
    460      1.1  mrg       if (alloc_size == 0)
    461  1.1.1.3  mrg 	return;
    462      1.1  mrg     }
    463      1.1  mrg   else
    464      1.1  mrg     {
    465      1.1  mrg       if (rank != GFC_DESCRIPTOR_RANK (retarray))
    466      1.1  mrg 	runtime_error ("rank of return array incorrect in"
    467      1.1  mrg 		       " FINDLOC intrinsic: is %ld, should be %ld",
    468      1.1  mrg 		       (long int) (GFC_DESCRIPTOR_RANK (retarray)),
    469      1.1  mrg 		       (long int) rank);
    470      1.1  mrg 
    471      1.1  mrg       if (unlikely (compile_options.bounds_check))
    472      1.1  mrg 	bounds_ifunction_return ((array_t *) retarray, extent,
    473      1.1  mrg 				 "return value", "FINDLOC");
    474      1.1  mrg     }
    475      1.1  mrg 
    476      1.1  mrg   for (n = 0; n < rank; n++)
    477      1.1  mrg     {
    478      1.1  mrg       count[n] = 0;
    479      1.1  mrg       dstride[n] = GFC_DESCRIPTOR_STRIDE(retarray,n);
    480      1.1  mrg       if (extent[n] <= 0)
    481      1.1  mrg 	return;
    482      1.1  mrg     }
    483      1.1  mrg   dest = retarray->base_addr;
    484      1.1  mrg   continue_loop = 1;
    485      1.1  mrg 
    486      1.1  mrg   while (continue_loop)
    487      1.1  mrg     {
    488      1.1  mrg       *dest = 0;
    489      1.1  mrg 
    490      1.1  mrg       count[0]++;
    491      1.1  mrg       dest += dstride[0];
    492      1.1  mrg       n = 0;
    493      1.1  mrg       while (count[n] == extent[n])
    494      1.1  mrg 	{
    495      1.1  mrg 	  count[n] = 0;
    496      1.1  mrg 	  dest -= dstride[n] * extent[n];
    497      1.1  mrg 	  n++;
    498      1.1  mrg 	  if (n >= rank)
    499      1.1  mrg 	    {
    500      1.1  mrg 	      continue_loop = 0;
    501      1.1  mrg 	      break;
    502      1.1  mrg 	    }
    503      1.1  mrg 	  else
    504      1.1  mrg 	    {
    505      1.1  mrg 	      count[n]++;
    506      1.1  mrg 	      dest += dstride[n];
    507      1.1  mrg 	    }
    508      1.1  mrg 	}
    509      1.1  mrg     }
    510      1.1  mrg }
    511      1.1  mrg #endif
    512