Home | History | Annotate | Line # | Download | only in generated
      1      1.1  mrg /* Implementation of the ALL intrinsic
      2  1.1.1.4  mrg    Copyright (C) 2002-2024 Free Software Foundation, Inc.
      3      1.1  mrg    Contributed by Paul Brook <paul (at) nowt.org>
      4      1.1  mrg 
      5      1.1  mrg This file is part of the GNU Fortran 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 
     28      1.1  mrg 
     29      1.1  mrg #if defined (HAVE_GFC_LOGICAL_4)
     30      1.1  mrg 
     31      1.1  mrg 
     32      1.1  mrg extern void all_l4 (gfc_array_l4 * const restrict,
     33      1.1  mrg 	gfc_array_l1 * const restrict, const index_type * const restrict);
     34      1.1  mrg export_proto(all_l4);
     35      1.1  mrg 
     36      1.1  mrg void
     37      1.1  mrg all_l4 (gfc_array_l4 * const restrict retarray,
     38      1.1  mrg 	gfc_array_l1 * const restrict array,
     39      1.1  mrg 	const index_type * const restrict pdim)
     40      1.1  mrg {
     41      1.1  mrg   index_type count[GFC_MAX_DIMENSIONS];
     42      1.1  mrg   index_type extent[GFC_MAX_DIMENSIONS];
     43      1.1  mrg   index_type sstride[GFC_MAX_DIMENSIONS];
     44      1.1  mrg   index_type dstride[GFC_MAX_DIMENSIONS];
     45      1.1  mrg   const GFC_LOGICAL_1 * restrict base;
     46      1.1  mrg   GFC_LOGICAL_4 * restrict dest;
     47      1.1  mrg   index_type rank;
     48      1.1  mrg   index_type n;
     49      1.1  mrg   index_type len;
     50      1.1  mrg   index_type delta;
     51      1.1  mrg   index_type dim;
     52      1.1  mrg   int src_kind;
     53      1.1  mrg   int continue_loop;
     54      1.1  mrg 
     55      1.1  mrg   /* Make dim zero based to avoid confusion.  */
     56      1.1  mrg   dim = (*pdim) - 1;
     57      1.1  mrg   rank = GFC_DESCRIPTOR_RANK (array) - 1;
     58      1.1  mrg 
     59      1.1  mrg   src_kind = GFC_DESCRIPTOR_SIZE (array);
     60      1.1  mrg 
     61      1.1  mrg   len = GFC_DESCRIPTOR_EXTENT(array,dim);
     62      1.1  mrg   if (len < 0)
     63      1.1  mrg     len = 0;
     64      1.1  mrg 
     65      1.1  mrg   delta = GFC_DESCRIPTOR_STRIDE_BYTES(array,dim);
     66      1.1  mrg 
     67      1.1  mrg   for (n = 0; n < dim; n++)
     68      1.1  mrg     {
     69      1.1  mrg       sstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(array,n);
     70      1.1  mrg       extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
     71      1.1  mrg 
     72      1.1  mrg       if (extent[n] < 0)
     73      1.1  mrg 	extent[n] = 0;
     74      1.1  mrg     }
     75      1.1  mrg   for (n = dim; n < rank; n++)
     76      1.1  mrg     {
     77      1.1  mrg       sstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(array,n + 1);
     78      1.1  mrg       extent[n] = GFC_DESCRIPTOR_EXTENT(array,n + 1);
     79      1.1  mrg 
     80      1.1  mrg       if (extent[n] < 0)
     81      1.1  mrg 	extent[n] = 0;
     82      1.1  mrg     }
     83      1.1  mrg 
     84      1.1  mrg   if (retarray->base_addr == NULL)
     85      1.1  mrg     {
     86      1.1  mrg       size_t alloc_size, str;
     87      1.1  mrg 
     88      1.1  mrg       for (n = 0; n < rank; n++)
     89      1.1  mrg         {
     90      1.1  mrg           if (n == 0)
     91      1.1  mrg             str = 1;
     92      1.1  mrg           else
     93      1.1  mrg             str = GFC_DESCRIPTOR_STRIDE(retarray,n-1) * extent[n-1];
     94      1.1  mrg 
     95      1.1  mrg 	  GFC_DIMENSION_SET(retarray->dim[n], 0, extent[n] - 1, str);
     96      1.1  mrg 
     97      1.1  mrg         }
     98      1.1  mrg 
     99      1.1  mrg       retarray->offset = 0;
    100      1.1  mrg       retarray->dtype.rank = rank;
    101      1.1  mrg 
    102      1.1  mrg       alloc_size = GFC_DESCRIPTOR_STRIDE(retarray,rank-1) * extent[rank-1];
    103      1.1  mrg 
    104  1.1.1.4  mrg       retarray->base_addr = xmallocarray (alloc_size, sizeof (GFC_LOGICAL_4));
    105      1.1  mrg       if (alloc_size == 0)
    106  1.1.1.4  mrg 	return;
    107      1.1  mrg     }
    108      1.1  mrg   else
    109      1.1  mrg     {
    110      1.1  mrg       if (rank != GFC_DESCRIPTOR_RANK (retarray))
    111      1.1  mrg 	runtime_error ("rank of return array incorrect in"
    112      1.1  mrg 		       " ALL intrinsic: is %ld, should be %ld",
    113      1.1  mrg 		       (long int) GFC_DESCRIPTOR_RANK (retarray),
    114      1.1  mrg 		       (long int) rank);
    115      1.1  mrg 
    116      1.1  mrg       if (unlikely (compile_options.bounds_check))
    117      1.1  mrg 	{
    118      1.1  mrg 	  for (n=0; n < rank; n++)
    119      1.1  mrg 	    {
    120      1.1  mrg 	      index_type ret_extent;
    121      1.1  mrg 
    122      1.1  mrg 	      ret_extent = GFC_DESCRIPTOR_EXTENT(retarray,n);
    123      1.1  mrg 	      if (extent[n] != ret_extent)
    124      1.1  mrg 		runtime_error ("Incorrect extent in return value of"
    125      1.1  mrg 			       " ALL intrinsic in dimension %d:"
    126      1.1  mrg 			       " is %ld, should be %ld", (int) n + 1,
    127      1.1  mrg 			       (long int) ret_extent, (long int) extent[n]);
    128      1.1  mrg 	    }
    129      1.1  mrg 	}
    130      1.1  mrg     }
    131      1.1  mrg 
    132      1.1  mrg   for (n = 0; n < rank; n++)
    133      1.1  mrg     {
    134      1.1  mrg       count[n] = 0;
    135      1.1  mrg       dstride[n] = GFC_DESCRIPTOR_STRIDE(retarray,n);
    136      1.1  mrg       if (extent[n] <= 0)
    137      1.1  mrg 	return;
    138      1.1  mrg     }
    139      1.1  mrg 
    140      1.1  mrg   base = array->base_addr;
    141      1.1  mrg 
    142      1.1  mrg   if (src_kind == 1 || src_kind == 2 || src_kind == 4 || src_kind == 8
    143      1.1  mrg #ifdef HAVE_GFC_LOGICAL_16
    144      1.1  mrg       || src_kind == 16
    145      1.1  mrg #endif
    146      1.1  mrg     )
    147      1.1  mrg     {
    148      1.1  mrg       if (base)
    149      1.1  mrg 	base = GFOR_POINTER_TO_L1 (base, src_kind);
    150      1.1  mrg     }
    151      1.1  mrg   else
    152      1.1  mrg     internal_error (NULL, "Funny sized logical array in ALL intrinsic");
    153      1.1  mrg 
    154      1.1  mrg   dest = retarray->base_addr;
    155      1.1  mrg 
    156      1.1  mrg   continue_loop = 1;
    157      1.1  mrg   while (continue_loop)
    158      1.1  mrg     {
    159      1.1  mrg       const GFC_LOGICAL_1 * restrict src;
    160      1.1  mrg       GFC_LOGICAL_4 result;
    161      1.1  mrg       src = base;
    162      1.1  mrg       {
    163      1.1  mrg 
    164      1.1  mrg   /* Return true only if all the elements are set.  */
    165      1.1  mrg   result = 1;
    166      1.1  mrg         if (len <= 0)
    167      1.1  mrg 	  *dest = 1;
    168      1.1  mrg 	else
    169      1.1  mrg 	  {
    170      1.1  mrg 	    for (n = 0; n < len; n++, src += delta)
    171      1.1  mrg 	      {
    172      1.1  mrg 
    173      1.1  mrg   if (! *src)
    174      1.1  mrg     {
    175      1.1  mrg       result = 0;
    176      1.1  mrg       break;
    177      1.1  mrg     }
    178      1.1  mrg           }
    179      1.1  mrg 	    *dest = result;
    180      1.1  mrg 	  }
    181      1.1  mrg       }
    182      1.1  mrg       /* Advance to the next element.  */
    183      1.1  mrg       count[0]++;
    184      1.1  mrg       base += sstride[0];
    185      1.1  mrg       dest += dstride[0];
    186      1.1  mrg       n = 0;
    187      1.1  mrg       while (count[n] == extent[n])
    188      1.1  mrg         {
    189      1.1  mrg           /* When we get to the end of a dimension, reset it and increment
    190      1.1  mrg              the next dimension.  */
    191      1.1  mrg           count[n] = 0;
    192      1.1  mrg           /* We could precalculate these products, but this is a less
    193      1.1  mrg              frequently used path so probably not worth it.  */
    194      1.1  mrg           base -= sstride[n] * extent[n];
    195      1.1  mrg           dest -= dstride[n] * extent[n];
    196      1.1  mrg           n++;
    197      1.1  mrg           if (n >= rank)
    198      1.1  mrg             {
    199      1.1  mrg               /* Break out of the loop.  */
    200      1.1  mrg               continue_loop = 0;
    201      1.1  mrg               break;
    202      1.1  mrg             }
    203      1.1  mrg           else
    204      1.1  mrg             {
    205      1.1  mrg               count[n]++;
    206      1.1  mrg               base += sstride[n];
    207      1.1  mrg               dest += dstride[n];
    208      1.1  mrg             }
    209      1.1  mrg         }
    210      1.1  mrg     }
    211      1.1  mrg }
    212      1.1  mrg 
    213      1.1  mrg #endif
    214