Home | History | Annotate | Line # | Download | only in m4
      1  1.1  mrg dnl Support macro file for intrinsic functions.
      2  1.1  mrg dnl Contains the generic sections of the array functions.
      3  1.1  mrg dnl This file is part of the GNU Fortran Runtime Library (libgfortran)
      4  1.1  mrg dnl Distributed under the GNU GPL with exception.  See COPYING for details.
      5  1.1  mrg define(START_FOREACH_FUNCTION,
      6  1.1  mrg `
      7  1.1  mrg extern void name`'rtype_qual`_'atype_code (rtype * const restrict retarray, 
      8  1.1  mrg 	atype * const restrict array, GFC_LOGICAL_4);
      9  1.1  mrg export_proto(name`'rtype_qual`_'atype_code);
     10  1.1  mrg 
     11  1.1  mrg void
     12  1.1  mrg name`'rtype_qual`_'atype_code (rtype * const restrict retarray, 
     13  1.1  mrg 	atype * const restrict array, GFC_LOGICAL_4 back)
     14  1.1  mrg {
     15  1.1  mrg   index_type count[GFC_MAX_DIMENSIONS];
     16  1.1  mrg   index_type extent[GFC_MAX_DIMENSIONS];
     17  1.1  mrg   index_type sstride[GFC_MAX_DIMENSIONS];
     18  1.1  mrg   index_type dstride;
     19  1.1  mrg   const atype_name *base;
     20  1.1  mrg   rtype_name * restrict dest;
     21  1.1  mrg   index_type rank;
     22  1.1  mrg   index_type n;
     23  1.1  mrg 
     24  1.1  mrg   rank = GFC_DESCRIPTOR_RANK (array);
     25  1.1  mrg   if (rank <= 0)
     26  1.1  mrg     runtime_error ("Rank of array needs to be > 0");
     27  1.1  mrg 
     28  1.1  mrg   if (retarray->base_addr == NULL)
     29  1.1  mrg     {
     30  1.1  mrg       GFC_DIMENSION_SET(retarray->dim[0], 0, rank-1, 1);
     31  1.1  mrg       retarray->dtype.rank = 1;
     32  1.1  mrg       retarray->offset = 0;
     33  1.1  mrg       retarray->base_addr = xmallocarray (rank, sizeof (rtype_name));
     34  1.1  mrg     }
     35  1.1  mrg   else
     36  1.1  mrg     {
     37  1.1  mrg       if (unlikely (compile_options.bounds_check))
     38  1.1  mrg 	bounds_iforeach_return ((array_t *) retarray, (array_t *) array,
     39  1.1  mrg 				"u_name");
     40  1.1  mrg     }
     41  1.1  mrg 
     42  1.1  mrg   dstride = GFC_DESCRIPTOR_STRIDE(retarray,0);
     43  1.1  mrg   dest = retarray->base_addr;
     44  1.1  mrg   for (n = 0; n < rank; n++)
     45  1.1  mrg     {
     46  1.1  mrg       sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n);
     47  1.1  mrg       extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
     48  1.1  mrg       count[n] = 0;
     49  1.1  mrg       if (extent[n] <= 0)
     50  1.1  mrg 	{
     51  1.1  mrg 	  /* Set the return value.  */
     52  1.1  mrg 	  for (n = 0; n < rank; n++)
     53  1.1  mrg 	    dest[n * dstride] = 0;
     54  1.1  mrg 	  return;
     55  1.1  mrg 	}
     56  1.1  mrg     }
     57  1.1  mrg 
     58  1.1  mrg   base = array->base_addr;
     59  1.1  mrg 
     60  1.1  mrg   /* Initialize the return value.  */
     61  1.1  mrg   for (n = 0; n < rank; n++)
     62  1.1  mrg     dest[n * dstride] = 1;
     63  1.1  mrg   {
     64  1.1  mrg ')dnl
     65  1.1  mrg define(START_FOREACH_BLOCK,
     66  1.1  mrg `  while (base)
     67  1.1  mrg     {
     68  1.1  mrg 	  /* Implementation start.  */
     69  1.1  mrg ')dnl
     70  1.1  mrg define(FINISH_FOREACH_FUNCTION,
     71  1.1  mrg `	  /* Implementation end.  */
     72  1.1  mrg 	  /* Advance to the next element.  */
     73  1.1  mrg 	  base += sstride[0];
     74  1.1  mrg 	}
     75  1.1  mrg       while (++count[0] != extent[0]);
     76  1.1  mrg       n = 0;
     77  1.1  mrg       do
     78  1.1  mrg 	{
     79  1.1  mrg 	  /* When we get to the end of a dimension, reset it and increment
     80  1.1  mrg 	     the next dimension.  */
     81  1.1  mrg 	  count[n] = 0;
     82  1.1  mrg 	  /* We could precalculate these products, but this is a less
     83  1.1  mrg 	     frequently used path so probably not worth it.  */
     84  1.1  mrg 	  base -= sstride[n] * extent[n];
     85  1.1  mrg 	  n++;
     86  1.1  mrg 	  if (n >= rank)
     87  1.1  mrg 	    {
     88  1.1  mrg 	      /* Break out of the loop.  */
     89  1.1  mrg 	      base = NULL;
     90  1.1  mrg 	      break;
     91  1.1  mrg 	    }
     92  1.1  mrg 	  else
     93  1.1  mrg 	    {
     94  1.1  mrg 	      count[n]++;
     95  1.1  mrg 	      base += sstride[n];
     96  1.1  mrg 	    }
     97  1.1  mrg 	}
     98  1.1  mrg       while (count[n] == extent[n]);
     99  1.1  mrg     }
    100  1.1  mrg   }
    101  1.1  mrg }')dnl
    102  1.1  mrg define(START_MASKED_FOREACH_FUNCTION,
    103  1.1  mrg `
    104  1.1  mrg extern void `m'name`'rtype_qual`_'atype_code (rtype * const restrict, 
    105  1.1  mrg 	atype * const restrict, gfc_array_l1 * const restrict,
    106  1.1  mrg 	GFC_LOGICAL_4);
    107  1.1  mrg export_proto(`m'name`'rtype_qual`_'atype_code);
    108  1.1  mrg 
    109  1.1  mrg void
    110  1.1  mrg `m'name`'rtype_qual`_'atype_code (rtype * const restrict retarray, 
    111  1.1  mrg 	atype * const restrict array,
    112  1.1  mrg 	gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back)
    113  1.1  mrg {
    114  1.1  mrg   index_type count[GFC_MAX_DIMENSIONS];
    115  1.1  mrg   index_type extent[GFC_MAX_DIMENSIONS];
    116  1.1  mrg   index_type sstride[GFC_MAX_DIMENSIONS];
    117  1.1  mrg   index_type mstride[GFC_MAX_DIMENSIONS];
    118  1.1  mrg   index_type dstride;
    119  1.1  mrg   rtype_name *dest;
    120  1.1  mrg   const atype_name *base;
    121  1.1  mrg   GFC_LOGICAL_1 *mbase;
    122  1.1  mrg   int rank;
    123  1.1  mrg   index_type n;
    124  1.1  mrg   int mask_kind;
    125  1.1  mrg 
    126  1.1  mrg 
    127  1.1  mrg   if (mask == NULL)
    128  1.1  mrg     {
    129  1.1  mrg       name`'rtype_qual`_'atype_code (retarray, array, back);
    130  1.1  mrg       return;
    131  1.1  mrg     }
    132  1.1  mrg 
    133  1.1  mrg   rank = GFC_DESCRIPTOR_RANK (array);
    134  1.1  mrg   if (rank <= 0)
    135  1.1  mrg     runtime_error ("Rank of array needs to be > 0");
    136  1.1  mrg 
    137  1.1  mrg   if (retarray->base_addr == NULL)
    138  1.1  mrg     {
    139  1.1  mrg       GFC_DIMENSION_SET(retarray->dim[0], 0, rank - 1, 1);
    140  1.1  mrg       retarray->dtype.rank = 1;
    141  1.1  mrg       retarray->offset = 0;
    142  1.1  mrg       retarray->base_addr = xmallocarray (rank, sizeof (rtype_name));
    143  1.1  mrg     }
    144  1.1  mrg   else
    145  1.1  mrg     {
    146  1.1  mrg       if (unlikely (compile_options.bounds_check))
    147  1.1  mrg 	{
    148  1.1  mrg 
    149  1.1  mrg 	  bounds_iforeach_return ((array_t *) retarray, (array_t *) array,
    150  1.1  mrg 				  "u_name");
    151  1.1  mrg 	  bounds_equal_extents ((array_t *) mask, (array_t *) array,
    152  1.1  mrg 				  "MASK argument", "u_name");
    153  1.1  mrg 	}
    154  1.1  mrg     }
    155  1.1  mrg 
    156  1.1  mrg   mask_kind = GFC_DESCRIPTOR_SIZE (mask);
    157  1.1  mrg 
    158  1.1  mrg   mbase = mask->base_addr;
    159  1.1  mrg 
    160  1.1  mrg   if (mask_kind == 1 || mask_kind == 2 || mask_kind == 4 || mask_kind == 8
    161  1.1  mrg #ifdef HAVE_GFC_LOGICAL_16
    162  1.1  mrg       || mask_kind == 16
    163  1.1  mrg #endif
    164  1.1  mrg       )
    165  1.1  mrg     mbase = GFOR_POINTER_TO_L1 (mbase, mask_kind);
    166  1.1  mrg   else
    167  1.1  mrg     runtime_error ("Funny sized logical array");
    168  1.1  mrg 
    169  1.1  mrg   dstride = GFC_DESCRIPTOR_STRIDE(retarray,0);
    170  1.1  mrg   dest = retarray->base_addr;
    171  1.1  mrg   for (n = 0; n < rank; n++)
    172  1.1  mrg     {
    173  1.1  mrg       sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n);
    174  1.1  mrg       mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask,n);
    175  1.1  mrg       extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
    176  1.1  mrg       count[n] = 0;
    177  1.1  mrg       if (extent[n] <= 0)
    178  1.1  mrg 	{
    179  1.1  mrg 	  /* Set the return value.  */
    180  1.1  mrg 	  for (n = 0; n < rank; n++)
    181  1.1  mrg 	    dest[n * dstride] = 0;
    182  1.1  mrg 	  return;
    183  1.1  mrg 	}
    184  1.1  mrg     }
    185  1.1  mrg 
    186  1.1  mrg   base = array->base_addr;
    187  1.1  mrg 
    188  1.1  mrg   /* Initialize the return value.  */
    189  1.1  mrg   for (n = 0; n < rank; n++)
    190  1.1  mrg     dest[n * dstride] = 0;
    191  1.1  mrg   {
    192  1.1  mrg ')dnl
    193  1.1  mrg define(START_MASKED_FOREACH_BLOCK, `START_FOREACH_BLOCK')dnl
    194  1.1  mrg define(FINISH_MASKED_FOREACH_FUNCTION,
    195  1.1  mrg `	  /* Implementation end.  */
    196  1.1  mrg 	  /* Advance to the next element.  */
    197  1.1  mrg 	  base += sstride[0];
    198  1.1  mrg 	  mbase += mstride[0];
    199  1.1  mrg 	}
    200  1.1  mrg       while (++count[0] != extent[0]);
    201  1.1  mrg       n = 0;
    202  1.1  mrg       do
    203  1.1  mrg 	{
    204  1.1  mrg 	  /* When we get to the end of a dimension, reset it and increment
    205  1.1  mrg 	     the next dimension.  */
    206  1.1  mrg 	  count[n] = 0;
    207  1.1  mrg 	  /* We could precalculate these products, but this is a less
    208  1.1  mrg 	     frequently used path so probably not worth it.  */
    209  1.1  mrg 	  base -= sstride[n] * extent[n];
    210  1.1  mrg 	  mbase -= mstride[n] * extent[n];
    211  1.1  mrg 	  n++;
    212  1.1  mrg 	  if (n >= rank)
    213  1.1  mrg 	    {
    214  1.1  mrg 	      /* Break out of the loop.  */
    215  1.1  mrg 	      base = NULL;
    216  1.1  mrg 	      break;
    217  1.1  mrg 	    }
    218  1.1  mrg 	  else
    219  1.1  mrg 	    {
    220  1.1  mrg 	      count[n]++;
    221  1.1  mrg 	      base += sstride[n];
    222  1.1  mrg 	      mbase += mstride[n];
    223  1.1  mrg 	    }
    224  1.1  mrg 	}
    225  1.1  mrg       while (count[n] == extent[n]);
    226  1.1  mrg     }
    227  1.1  mrg   }
    228  1.1  mrg }')dnl
    229  1.1  mrg define(FOREACH_FUNCTION,
    230  1.1  mrg `START_FOREACH_FUNCTION
    231  1.1  mrg $1
    232  1.1  mrg START_FOREACH_BLOCK
    233  1.1  mrg $2
    234  1.1  mrg FINISH_FOREACH_FUNCTION')dnl
    235  1.1  mrg define(MASKED_FOREACH_FUNCTION,
    236  1.1  mrg `START_MASKED_FOREACH_FUNCTION
    237  1.1  mrg $1
    238  1.1  mrg START_MASKED_FOREACH_BLOCK
    239  1.1  mrg $2
    240  1.1  mrg FINISH_MASKED_FOREACH_FUNCTION')dnl
    241  1.1  mrg define(SCALAR_FOREACH_FUNCTION,
    242  1.1  mrg `
    243  1.1  mrg extern void `s'name`'rtype_qual`_'atype_code (rtype * const restrict, 
    244  1.1  mrg 	atype * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4);
    245  1.1  mrg export_proto(`s'name`'rtype_qual`_'atype_code);
    246  1.1  mrg 
    247  1.1  mrg void
    248  1.1  mrg `s'name`'rtype_qual`_'atype_code (rtype * const restrict retarray, 
    249  1.1  mrg 	atype * const restrict array,
    250  1.1  mrg 	GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back)
    251  1.1  mrg {
    252  1.1  mrg   index_type rank;
    253  1.1  mrg   index_type dstride;
    254  1.1  mrg   index_type n;
    255  1.1  mrg   rtype_name *dest;
    256  1.1  mrg 
    257  1.1  mrg   if (mask == NULL || *mask)
    258  1.1  mrg     {
    259  1.1  mrg       name`'rtype_qual`_'atype_code (retarray, array, back);
    260  1.1  mrg       return;
    261  1.1  mrg     }
    262  1.1  mrg 
    263  1.1  mrg   rank = GFC_DESCRIPTOR_RANK (array);
    264  1.1  mrg 
    265  1.1  mrg   if (rank <= 0)
    266  1.1  mrg     runtime_error ("Rank of array needs to be > 0");
    267  1.1  mrg 
    268  1.1  mrg   if (retarray->base_addr == NULL)
    269  1.1  mrg     {
    270  1.1  mrg       GFC_DIMENSION_SET(retarray->dim[0], 0, rank-1, 1);
    271  1.1  mrg       retarray->dtype.rank = 1;
    272  1.1  mrg       retarray->offset = 0;
    273  1.1  mrg       retarray->base_addr = xmallocarray (rank, sizeof (rtype_name));
    274  1.1  mrg     }
    275  1.1  mrg   else if (unlikely (compile_options.bounds_check))
    276  1.1  mrg     {
    277  1.1  mrg        bounds_iforeach_return ((array_t *) retarray, (array_t *) array,
    278  1.1  mrg 			       "u_name");
    279  1.1  mrg     }
    280  1.1  mrg 
    281  1.1  mrg   dstride = GFC_DESCRIPTOR_STRIDE(retarray,0);
    282  1.1  mrg   dest = retarray->base_addr;
    283  1.1  mrg   for (n = 0; n<rank; n++)
    284  1.1  mrg     dest[n * dstride] = $1 ;
    285  1.1  mrg }')dnl
    286