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