Home | History | Annotate | Line # | Download | only in m4
ifindloc1.m4 revision 1.1.1.4
      1      1.1  mrg `/* Implementation of the FINDLOC intrinsic
      2  1.1.1.4  mrg    Copyright (C) 2018-2024 Free Software Foundation, Inc.
      3      1.1  mrg    Contributed by Thomas Knig <tk (a] 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_'atype_name`)
     30      1.1  mrg 'header1`
     31      1.1  mrg {
     32      1.1  mrg   index_type count[GFC_MAX_DIMENSIONS];
     33      1.1  mrg   index_type extent[GFC_MAX_DIMENSIONS];
     34      1.1  mrg   index_type sstride[GFC_MAX_DIMENSIONS];
     35      1.1  mrg   index_type dstride[GFC_MAX_DIMENSIONS];
     36      1.1  mrg   const 'atype_name`'` * restrict base;
     37      1.1  mrg   index_type * restrict dest;
     38      1.1  mrg   index_type rank;
     39      1.1  mrg   index_type n;
     40      1.1  mrg   index_type len;
     41      1.1  mrg   index_type delta;
     42      1.1  mrg   index_type dim;
     43      1.1  mrg   int continue_loop;
     44      1.1  mrg 
     45      1.1  mrg   /* Make dim zero based to avoid confusion.  */
     46      1.1  mrg   rank = GFC_DESCRIPTOR_RANK (array) - 1;
     47      1.1  mrg   dim = (*pdim) - 1;
     48      1.1  mrg 
     49      1.1  mrg   if (unlikely (dim < 0 || dim > rank))
     50      1.1  mrg     {
     51      1.1  mrg       runtime_error ("Dim argument incorrect in FINDLOC intrinsic: "
     52      1.1  mrg  		     "is %ld, should be between 1 and %ld",
     53      1.1  mrg 		     (long int) dim + 1, (long int) rank + 1);
     54      1.1  mrg     }
     55      1.1  mrg 
     56      1.1  mrg   len = GFC_DESCRIPTOR_EXTENT(array,dim);
     57      1.1  mrg   if (len < 0)
     58      1.1  mrg     len = 0;
     59      1.1  mrg   delta = GFC_DESCRIPTOR_STRIDE(array,dim);
     60      1.1  mrg 
     61      1.1  mrg   for (n = 0; n < dim; n++)
     62      1.1  mrg     {
     63      1.1  mrg       sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n);
     64      1.1  mrg       extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
     65      1.1  mrg 
     66      1.1  mrg       if (extent[n] < 0)
     67      1.1  mrg 	extent[n] = 0;
     68      1.1  mrg     }
     69      1.1  mrg   for (n = dim; n < rank; n++)
     70      1.1  mrg     {
     71      1.1  mrg       sstride[n] = GFC_DESCRIPTOR_STRIDE(array, n + 1);
     72      1.1  mrg       extent[n] = GFC_DESCRIPTOR_EXTENT(array, n + 1);
     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 
     78      1.1  mrg   if (retarray->base_addr == NULL)
     79      1.1  mrg     {
     80      1.1  mrg       size_t alloc_size, str;
     81      1.1  mrg 
     82      1.1  mrg       for (n = 0; n < rank; n++)
     83      1.1  mrg 	{
     84      1.1  mrg 	  if (n == 0)
     85      1.1  mrg 	    str = 1;
     86      1.1  mrg 	  else
     87      1.1  mrg 	    str = GFC_DESCRIPTOR_STRIDE(retarray,n-1) * extent[n-1];
     88      1.1  mrg 
     89      1.1  mrg 	  GFC_DIMENSION_SET(retarray->dim[n], 0, extent[n] - 1, str);
     90      1.1  mrg 
     91      1.1  mrg 	}
     92      1.1  mrg 
     93      1.1  mrg       retarray->offset = 0;
     94      1.1  mrg       retarray->dtype.rank = rank;
     95      1.1  mrg 
     96      1.1  mrg       alloc_size = GFC_DESCRIPTOR_STRIDE(retarray,rank-1) * extent[rank-1];
     97      1.1  mrg 
     98      1.1  mrg       retarray->base_addr = xmallocarray (alloc_size, sizeof (index_type));
     99      1.1  mrg       if (alloc_size == 0)
    100  1.1.1.4  mrg 	return;
    101      1.1  mrg     }
    102      1.1  mrg   else
    103      1.1  mrg     {
    104      1.1  mrg       if (rank != GFC_DESCRIPTOR_RANK (retarray))
    105      1.1  mrg 	runtime_error ("rank of return array incorrect in"
    106      1.1  mrg 		       " FINDLOC intrinsic: is %ld, should be %ld",
    107      1.1  mrg 		       (long int) (GFC_DESCRIPTOR_RANK (retarray)),
    108      1.1  mrg 		       (long int) rank);
    109      1.1  mrg 
    110      1.1  mrg       if (unlikely (compile_options.bounds_check))
    111      1.1  mrg 	bounds_ifunction_return ((array_t *) retarray, extent,
    112      1.1  mrg 				 "return value", "FINDLOC");
    113      1.1  mrg     }
    114      1.1  mrg 
    115      1.1  mrg   for (n = 0; n < rank; n++)
    116      1.1  mrg     {
    117      1.1  mrg       count[n] = 0;
    118      1.1  mrg       dstride[n] = GFC_DESCRIPTOR_STRIDE(retarray,n);
    119      1.1  mrg       if (extent[n] <= 0)
    120      1.1  mrg 	return;
    121      1.1  mrg     }
    122      1.1  mrg 
    123      1.1  mrg   dest = retarray->base_addr;
    124      1.1  mrg   continue_loop = 1;
    125      1.1  mrg 
    126      1.1  mrg   base = array->base_addr;
    127      1.1  mrg   while (continue_loop)
    128      1.1  mrg     {
    129      1.1  mrg       const 'atype_name`'` * restrict src;
    130      1.1  mrg       index_type result;
    131      1.1  mrg 
    132      1.1  mrg       result = 0;
    133      1.1  mrg       if (back)
    134      1.1  mrg 	{
    135      1.1  mrg 	  src = base + (len - 1) * delta * 'base_mult`;
    136      1.1  mrg 	  for (n = len; n > 0; n--, src -= delta * 'base_mult`)
    137      1.1  mrg 	    {
    138      1.1  mrg 	      if ('comparison`'`)
    139      1.1  mrg 		{
    140      1.1  mrg 		  result = n;
    141      1.1  mrg 		  break;
    142      1.1  mrg 		}
    143      1.1  mrg 	    }
    144      1.1  mrg 	}
    145      1.1  mrg       else
    146      1.1  mrg 	{
    147      1.1  mrg 	  src = base;
    148      1.1  mrg 	  for (n = 1; n <= len; n++, src += delta * 'base_mult`)
    149      1.1  mrg 	    {
    150      1.1  mrg 	      if ('comparison`'`)
    151      1.1  mrg 		{
    152      1.1  mrg 		  result = n;
    153      1.1  mrg 		  break;
    154      1.1  mrg 		}
    155      1.1  mrg 	    }
    156      1.1  mrg 	}
    157      1.1  mrg       *dest = result;
    158      1.1  mrg 
    159      1.1  mrg       count[0]++;
    160      1.1  mrg       base += sstride[0] * 'base_mult`;
    161      1.1  mrg       dest += dstride[0];
    162      1.1  mrg       n = 0;
    163      1.1  mrg       while (count[n] == extent[n])
    164      1.1  mrg 	{
    165      1.1  mrg 	  count[n] = 0;
    166      1.1  mrg 	  base -= sstride[n] * extent[n] * 'base_mult`;
    167      1.1  mrg 	  dest -= dstride[n] * extent[n];
    168      1.1  mrg 	  n++;
    169      1.1  mrg 	  if (n >= rank)
    170      1.1  mrg 	    {
    171      1.1  mrg 	      continue_loop = 0;
    172      1.1  mrg 	      break;
    173      1.1  mrg 	    }
    174      1.1  mrg 	  else
    175      1.1  mrg 	    {
    176      1.1  mrg 	      count[n]++;
    177      1.1  mrg 	      base += sstride[n] * 'base_mult`;
    178      1.1  mrg 	      dest += dstride[n];
    179      1.1  mrg 	    }
    180      1.1  mrg 	}
    181      1.1  mrg     }
    182      1.1  mrg }
    183      1.1  mrg 'header2`'`
    184      1.1  mrg {
    185      1.1  mrg   index_type count[GFC_MAX_DIMENSIONS];
    186      1.1  mrg   index_type extent[GFC_MAX_DIMENSIONS];
    187      1.1  mrg   index_type sstride[GFC_MAX_DIMENSIONS];
    188      1.1  mrg   index_type mstride[GFC_MAX_DIMENSIONS];
    189      1.1  mrg   index_type dstride[GFC_MAX_DIMENSIONS];
    190      1.1  mrg   const 'atype_name`'` * restrict base;
    191      1.1  mrg   const GFC_LOGICAL_1 * restrict mbase;
    192      1.1  mrg   index_type * restrict dest;
    193      1.1  mrg   index_type rank;
    194      1.1  mrg   index_type n;
    195      1.1  mrg   index_type len;
    196      1.1  mrg   index_type delta;
    197      1.1  mrg   index_type mdelta;
    198      1.1  mrg   index_type dim;
    199      1.1  mrg   int mask_kind;
    200      1.1  mrg   int continue_loop;
    201      1.1  mrg 
    202      1.1  mrg   /* Make dim zero based to avoid confusion.  */
    203      1.1  mrg   rank = GFC_DESCRIPTOR_RANK (array) - 1;
    204      1.1  mrg   dim = (*pdim) - 1;
    205      1.1  mrg 
    206      1.1  mrg   if (unlikely (dim < 0 || dim > rank))
    207      1.1  mrg     {
    208      1.1  mrg       runtime_error ("Dim argument incorrect in FINDLOC intrinsic: "
    209      1.1  mrg  		     "is %ld, should be between 1 and %ld",
    210      1.1  mrg 		     (long int) dim + 1, (long int) rank + 1);
    211      1.1  mrg     }
    212      1.1  mrg 
    213      1.1  mrg   len = GFC_DESCRIPTOR_EXTENT(array,dim);
    214      1.1  mrg   if (len < 0)
    215      1.1  mrg     len = 0;
    216      1.1  mrg 
    217      1.1  mrg   delta = GFC_DESCRIPTOR_STRIDE(array,dim);
    218      1.1  mrg   mdelta = GFC_DESCRIPTOR_STRIDE_BYTES(mask,dim);
    219      1.1  mrg 
    220      1.1  mrg   mbase = mask->base_addr;
    221      1.1  mrg 
    222      1.1  mrg   mask_kind = GFC_DESCRIPTOR_SIZE (mask);
    223      1.1  mrg 
    224      1.1  mrg   if (mask_kind == 1 || mask_kind == 2 || mask_kind == 4 || mask_kind == 8
    225      1.1  mrg #ifdef HAVE_GFC_LOGICAL_16
    226      1.1  mrg       || mask_kind == 16
    227      1.1  mrg #endif
    228      1.1  mrg       )
    229      1.1  mrg     mbase = GFOR_POINTER_TO_L1 (mbase, mask_kind);
    230      1.1  mrg   else
    231      1.1  mrg     internal_error (NULL, "Funny sized logical array");
    232      1.1  mrg 
    233      1.1  mrg   for (n = 0; n < dim; n++)
    234      1.1  mrg     {
    235      1.1  mrg       sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n);
    236      1.1  mrg       mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask,n);
    237      1.1  mrg       extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
    238      1.1  mrg 
    239      1.1  mrg       if (extent[n] < 0)
    240      1.1  mrg 	extent[n] = 0;
    241      1.1  mrg     }
    242      1.1  mrg   for (n = dim; n < rank; n++)
    243      1.1  mrg     {
    244      1.1  mrg       sstride[n] = GFC_DESCRIPTOR_STRIDE(array, n + 1);
    245      1.1  mrg       mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask, n + 1);
    246      1.1  mrg       extent[n] = GFC_DESCRIPTOR_EXTENT(array, n + 1);
    247      1.1  mrg 
    248      1.1  mrg       if (extent[n] < 0)
    249      1.1  mrg 	extent[n] = 0;
    250      1.1  mrg     }
    251      1.1  mrg 
    252      1.1  mrg   if (retarray->base_addr == NULL)
    253      1.1  mrg     {
    254      1.1  mrg       size_t alloc_size, str;
    255      1.1  mrg 
    256      1.1  mrg       for (n = 0; n < rank; n++)
    257      1.1  mrg 	{
    258      1.1  mrg 	  if (n == 0)
    259      1.1  mrg 	    str = 1;
    260      1.1  mrg 	  else
    261      1.1  mrg 	    str = GFC_DESCRIPTOR_STRIDE(retarray,n-1) * extent[n-1];
    262      1.1  mrg 
    263      1.1  mrg 	  GFC_DIMENSION_SET(retarray->dim[n], 0, extent[n] - 1, str);
    264      1.1  mrg 
    265      1.1  mrg 	}
    266      1.1  mrg 
    267      1.1  mrg       retarray->offset = 0;
    268      1.1  mrg       retarray->dtype.rank = rank;
    269      1.1  mrg 
    270      1.1  mrg       alloc_size = GFC_DESCRIPTOR_STRIDE(retarray,rank-1) * extent[rank-1];
    271      1.1  mrg 
    272      1.1  mrg       retarray->base_addr = xmallocarray (alloc_size, sizeof (index_type));
    273      1.1  mrg       if (alloc_size == 0)
    274  1.1.1.4  mrg 	return;
    275      1.1  mrg     }
    276      1.1  mrg   else
    277      1.1  mrg     {
    278      1.1  mrg       if (rank != GFC_DESCRIPTOR_RANK (retarray))
    279      1.1  mrg 	runtime_error ("rank of return array incorrect in"
    280      1.1  mrg 		       " FINDLOC intrinsic: is %ld, should be %ld",
    281      1.1  mrg 		       (long int) (GFC_DESCRIPTOR_RANK (retarray)),
    282      1.1  mrg 		       (long int) rank);
    283      1.1  mrg 
    284      1.1  mrg       if (unlikely (compile_options.bounds_check))
    285      1.1  mrg 	bounds_ifunction_return ((array_t *) retarray, extent,
    286      1.1  mrg 				 "return value", "FINDLOC");
    287      1.1  mrg     }
    288      1.1  mrg 
    289      1.1  mrg   for (n = 0; n < rank; n++)
    290      1.1  mrg     {
    291      1.1  mrg       count[n] = 0;
    292      1.1  mrg       dstride[n] = GFC_DESCRIPTOR_STRIDE(retarray,n);
    293      1.1  mrg       if (extent[n] <= 0)
    294      1.1  mrg 	return;
    295      1.1  mrg     }
    296      1.1  mrg 
    297      1.1  mrg   dest = retarray->base_addr;
    298      1.1  mrg   continue_loop = 1;
    299      1.1  mrg 
    300      1.1  mrg   base = array->base_addr;
    301      1.1  mrg   while (continue_loop)
    302      1.1  mrg     {
    303      1.1  mrg       const 'atype_name`'` * restrict src;
    304      1.1  mrg       const GFC_LOGICAL_1 * restrict msrc;
    305      1.1  mrg       index_type result;
    306      1.1  mrg 
    307      1.1  mrg       result = 0;
    308      1.1  mrg       if (back)
    309      1.1  mrg 	{
    310      1.1  mrg 	  src = base + (len - 1) * delta * 'base_mult`;
    311      1.1  mrg 	  msrc = mbase + (len - 1) * mdelta; 
    312      1.1  mrg 	  for (n = len; n > 0; n--, src -= delta * 'base_mult`, msrc -= mdelta)
    313      1.1  mrg 	    {
    314      1.1  mrg 	      if (*msrc && 'comparison`'`)
    315      1.1  mrg 		{
    316      1.1  mrg 		  result = n;
    317      1.1  mrg 		  break;
    318      1.1  mrg 		}
    319      1.1  mrg 	    }
    320      1.1  mrg 	}
    321      1.1  mrg       else
    322      1.1  mrg 	{
    323      1.1  mrg 	  src = base;
    324      1.1  mrg 	  msrc = mbase;
    325      1.1  mrg 	  for (n = 1; n <= len; n++, src += delta * 'base_mult`, msrc += mdelta)
    326      1.1  mrg 	    {
    327      1.1  mrg 	      if (*msrc && 'comparison`'`)
    328      1.1  mrg 		{
    329      1.1  mrg 		  result = n;
    330      1.1  mrg 		  break;
    331      1.1  mrg 		}
    332      1.1  mrg 	    }
    333      1.1  mrg 	}
    334      1.1  mrg       *dest = result;
    335      1.1  mrg 
    336      1.1  mrg       count[0]++;
    337      1.1  mrg       base += sstride[0] * 'base_mult`;
    338      1.1  mrg       mbase += mstride[0];
    339      1.1  mrg       dest += dstride[0];
    340      1.1  mrg       n = 0;
    341      1.1  mrg       while (count[n] == extent[n])
    342      1.1  mrg 	{
    343      1.1  mrg 	  count[n] = 0;
    344      1.1  mrg 	  base -= sstride[n] * extent[n] * 'base_mult`;
    345      1.1  mrg 	  mbase -= mstride[n] * extent[n];
    346      1.1  mrg 	  dest -= dstride[n] * extent[n];
    347      1.1  mrg 	  n++;
    348      1.1  mrg 	  if (n >= rank)
    349      1.1  mrg 	    {
    350      1.1  mrg 	      continue_loop = 0;
    351      1.1  mrg 	      break;
    352      1.1  mrg 	    }
    353      1.1  mrg 	  else
    354      1.1  mrg 	    {
    355      1.1  mrg 	      count[n]++;
    356      1.1  mrg 	      base += sstride[n] * 'base_mult`;
    357      1.1  mrg 	      dest += dstride[n];
    358      1.1  mrg 	    }
    359      1.1  mrg 	}
    360      1.1  mrg     }
    361      1.1  mrg }
    362      1.1  mrg 'header3`'`
    363      1.1  mrg {
    364      1.1  mrg   index_type count[GFC_MAX_DIMENSIONS];
    365      1.1  mrg   index_type extent[GFC_MAX_DIMENSIONS];
    366      1.1  mrg   index_type dstride[GFC_MAX_DIMENSIONS];
    367      1.1  mrg   index_type * restrict dest;
    368      1.1  mrg   index_type rank;
    369      1.1  mrg   index_type n;
    370      1.1  mrg   index_type len;
    371      1.1  mrg   index_type dim;
    372      1.1  mrg   bool continue_loop;
    373      1.1  mrg 
    374      1.1  mrg   if (mask == NULL || *mask)
    375      1.1  mrg     {
    376      1.1  mrg       findloc1_'atype_code`'` (retarray, array, value, pdim, back'len_arg`'`);
    377      1.1  mrg       return;
    378      1.1  mrg     }
    379      1.1  mrg     /* Make dim zero based to avoid confusion.  */
    380      1.1  mrg   rank = GFC_DESCRIPTOR_RANK (array) - 1;
    381      1.1  mrg   dim = (*pdim) - 1;
    382      1.1  mrg 
    383      1.1  mrg   if (unlikely (dim < 0 || dim > rank))
    384      1.1  mrg     {
    385      1.1  mrg       runtime_error ("Dim argument incorrect in FINDLOC intrinsic: "
    386      1.1  mrg  		     "is %ld, should be between 1 and %ld",
    387      1.1  mrg 		     (long int) dim + 1, (long int) rank + 1);
    388      1.1  mrg     }
    389      1.1  mrg 
    390      1.1  mrg   len = GFC_DESCRIPTOR_EXTENT(array,dim);
    391      1.1  mrg   if (len < 0)
    392      1.1  mrg     len = 0;
    393      1.1  mrg 
    394      1.1  mrg   for (n = 0; n < dim; n++)
    395      1.1  mrg     {
    396      1.1  mrg       extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
    397      1.1  mrg 
    398      1.1  mrg       if (extent[n] <= 0)
    399      1.1  mrg 	extent[n] = 0;
    400      1.1  mrg     }
    401      1.1  mrg 
    402      1.1  mrg   for (n = dim; n < rank; n++)
    403      1.1  mrg     {
    404      1.1  mrg       extent[n] =
    405      1.1  mrg 	GFC_DESCRIPTOR_EXTENT(array,n + 1);
    406      1.1  mrg 
    407      1.1  mrg       if (extent[n] <= 0)
    408      1.1  mrg 	extent[n] = 0;
    409      1.1  mrg     }
    410      1.1  mrg 
    411      1.1  mrg 
    412      1.1  mrg   if (retarray->base_addr == NULL)
    413      1.1  mrg     {
    414      1.1  mrg       size_t alloc_size, str;
    415      1.1  mrg 
    416      1.1  mrg       for (n = 0; n < rank; n++)
    417      1.1  mrg 	{
    418      1.1  mrg 	  if (n == 0)
    419      1.1  mrg 	    str = 1;
    420      1.1  mrg 	  else
    421      1.1  mrg 	    str = GFC_DESCRIPTOR_STRIDE(retarray,n-1) * extent[n-1];
    422      1.1  mrg 
    423      1.1  mrg 	  GFC_DIMENSION_SET(retarray->dim[n], 0, extent[n] - 1, str);
    424      1.1  mrg 	}
    425      1.1  mrg 
    426      1.1  mrg       retarray->offset = 0;
    427      1.1  mrg       retarray->dtype.rank = rank;
    428      1.1  mrg 
    429      1.1  mrg       alloc_size = GFC_DESCRIPTOR_STRIDE(retarray,rank-1) * extent[rank-1];
    430      1.1  mrg 
    431      1.1  mrg       retarray->base_addr = xmallocarray (alloc_size, sizeof (index_type));
    432      1.1  mrg       if (alloc_size == 0)
    433  1.1.1.4  mrg 	return;
    434      1.1  mrg     }
    435      1.1  mrg   else
    436      1.1  mrg     {
    437      1.1  mrg       if (rank != GFC_DESCRIPTOR_RANK (retarray))
    438      1.1  mrg 	runtime_error ("rank of return array incorrect in"
    439      1.1  mrg 		       " FINDLOC intrinsic: is %ld, should be %ld",
    440      1.1  mrg 		       (long int) (GFC_DESCRIPTOR_RANK (retarray)),
    441      1.1  mrg 		       (long int) rank);
    442      1.1  mrg 
    443      1.1  mrg       if (unlikely (compile_options.bounds_check))
    444      1.1  mrg 	bounds_ifunction_return ((array_t *) retarray, extent,
    445      1.1  mrg 				 "return value", "FINDLOC");
    446      1.1  mrg     }
    447      1.1  mrg 
    448      1.1  mrg   for (n = 0; n < rank; n++)
    449      1.1  mrg     {
    450      1.1  mrg       count[n] = 0;
    451      1.1  mrg       dstride[n] = GFC_DESCRIPTOR_STRIDE(retarray,n);
    452      1.1  mrg       if (extent[n] <= 0)
    453      1.1  mrg 	return;
    454      1.1  mrg     }
    455      1.1  mrg   dest = retarray->base_addr;
    456      1.1  mrg   continue_loop = 1;
    457      1.1  mrg 
    458      1.1  mrg   while (continue_loop)
    459      1.1  mrg     {
    460      1.1  mrg       *dest = 0;
    461      1.1  mrg 
    462      1.1  mrg       count[0]++;
    463      1.1  mrg       dest += dstride[0];
    464      1.1  mrg       n = 0;
    465      1.1  mrg       while (count[n] == extent[n])
    466      1.1  mrg 	{
    467      1.1  mrg 	  count[n] = 0;
    468      1.1  mrg 	  dest -= dstride[n] * extent[n];
    469      1.1  mrg 	  n++;
    470      1.1  mrg 	  if (n >= rank)
    471      1.1  mrg 	    {
    472      1.1  mrg 	      continue_loop = 0;
    473      1.1  mrg 	      break;
    474      1.1  mrg 	    }
    475      1.1  mrg 	  else
    476      1.1  mrg 	    {
    477      1.1  mrg 	      count[n]++;
    478      1.1  mrg 	      dest += dstride[n];
    479      1.1  mrg 	    }
    480      1.1  mrg 	}
    481      1.1  mrg     }
    482      1.1  mrg }
    483      1.1  mrg #endif'
    484