1 dnl Support macro file for intrinsic functions.
2 dnl Contains the generic sections of the array functions.
3 dnl This file is part of the GNU Fortran Runtime Library (libgfortran)
4 dnl Distributed under the GNU GPL with exception. See COPYING for details.
5 define(START_FOREACH_FUNCTION,
7 extern void name`'rtype_qual`_'atype_code (rtype * const restrict retarray,
8 atype * const restrict array, GFC_LOGICAL_4);
9 export_proto(name`'rtype_qual`_'atype_code);
12 name`'rtype_qual`_'atype_code (rtype * const restrict retarray,
13 atype * const restrict array, GFC_LOGICAL_4 back)
15 index_type count[GFC_MAX_DIMENSIONS];
16 index_type extent[GFC_MAX_DIMENSIONS];
17 index_type sstride[GFC_MAX_DIMENSIONS];
19 const atype_name *base;
20 rtype_name * restrict dest;
25 rank = GFC_DESCRIPTOR_RANK (array);
27 runtime_error ("Rank of array needs to be > 0");
29 if (retarray->base_addr == NULL)
31 GFC_DIMENSION_SET(retarray->dim[0], 0, rank-1, 1);
32 GFC_DTYPE_COPY_SETRANK(retarray,retarray,1);
34 retarray->base_addr = xmallocarray (rank, sizeof (rtype_name));
38 if (unlikely (compile_options.bounds_check))
39 bounds_iforeach_return ((array_t *) retarray, (array_t *) array,
43 dstride = GFC_DESCRIPTOR_STRIDE(retarray,0);
44 dest = retarray->base_addr;
45 for (n = 0; n < rank; n++)
47 sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n);
48 extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
52 /* Set the return value. */
53 for (n = 0; n < rank; n++)
54 dest[n * dstride] = 0;
59 base = array->base_addr;
61 /* Initialize the return value. */
62 for (n = 0; n < rank; n++)
63 dest[n * dstride] = 1;
66 define(START_FOREACH_BLOCK,
71 /* Implementation start. */
73 define(FINISH_FOREACH_FUNCTION,
74 ` /* Implementation end. */
75 /* Advance to the next element. */
78 while (++count[0] != extent[0]);
82 /* When we get to the end of a dimension, reset it and increment
83 the next dimension. */
85 /* We could precalculate these products, but this is a less
86 frequently used path so probably not worth it. */
87 base -= sstride[n] * extent[n];
91 /* Break out of the loop. */
101 while (count[n] == extent[n]);
105 define(START_MASKED_FOREACH_FUNCTION,
107 extern void `m'name`'rtype_qual`_'atype_code (rtype * const restrict,
108 atype * const restrict, gfc_array_l1 * const restrict,
110 export_proto(`m'name`'rtype_qual`_'atype_code);
113 `m'name`'rtype_qual`_'atype_code (rtype * const restrict retarray,
114 atype * const restrict array,
115 gfc_array_l1 * const restrict mask, GFC_LOGICAL_4 back)
117 index_type count[GFC_MAX_DIMENSIONS];
118 index_type extent[GFC_MAX_DIMENSIONS];
119 index_type sstride[GFC_MAX_DIMENSIONS];
120 index_type mstride[GFC_MAX_DIMENSIONS];
123 const atype_name *base;
124 GFC_LOGICAL_1 *mbase;
130 rank = GFC_DESCRIPTOR_RANK (array);
132 runtime_error ("Rank of array needs to be > 0");
134 if (retarray->base_addr == NULL)
136 GFC_DIMENSION_SET(retarray->dim[0], 0, rank - 1, 1);
137 GFC_DTYPE_COPY_SETRANK(retarray,retarray,1);
138 retarray->offset = 0;
139 retarray->base_addr = xmallocarray (rank, sizeof (rtype_name));
143 if (unlikely (compile_options.bounds_check))
146 bounds_iforeach_return ((array_t *) retarray, (array_t *) array,
148 bounds_equal_extents ((array_t *) mask, (array_t *) array,
149 "MASK argument", "u_name");
153 mask_kind = GFC_DESCRIPTOR_SIZE (mask);
155 mbase = mask->base_addr;
157 if (mask_kind == 1 || mask_kind == 2 || mask_kind == 4 || mask_kind == 8
158 #ifdef HAVE_GFC_LOGICAL_16
162 mbase = GFOR_POINTER_TO_L1 (mbase, mask_kind);
164 runtime_error ("Funny sized logical array");
166 dstride = GFC_DESCRIPTOR_STRIDE(retarray,0);
167 dest = retarray->base_addr;
168 for (n = 0; n < rank; n++)
170 sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n);
171 mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask,n);
172 extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
176 /* Set the return value. */
177 for (n = 0; n < rank; n++)
178 dest[n * dstride] = 0;
183 base = array->base_addr;
185 /* Initialize the return value. */
186 for (n = 0; n < rank; n++)
187 dest[n * dstride] = 0;
190 define(START_MASKED_FOREACH_BLOCK, `START_FOREACH_BLOCK')dnl
191 define(FINISH_MASKED_FOREACH_FUNCTION,
192 ` /* Implementation end. */
193 /* Advance to the next element. */
197 while (++count[0] != extent[0]);
201 /* When we get to the end of a dimension, reset it and increment
202 the next dimension. */
204 /* We could precalculate these products, but this is a less
205 frequently used path so probably not worth it. */
206 base -= sstride[n] * extent[n];
207 mbase -= mstride[n] * extent[n];
211 /* Break out of the loop. */
222 while (count[n] == extent[n]);
226 define(FOREACH_FUNCTION,
227 `START_FOREACH_FUNCTION
231 FINISH_FOREACH_FUNCTION')dnl
232 define(MASKED_FOREACH_FUNCTION,
233 `START_MASKED_FOREACH_FUNCTION
235 START_MASKED_FOREACH_BLOCK
237 FINISH_MASKED_FOREACH_FUNCTION')dnl
238 define(SCALAR_FOREACH_FUNCTION,
240 extern void `s'name`'rtype_qual`_'atype_code (rtype * const restrict,
241 atype * const restrict, GFC_LOGICAL_4 *, GFC_LOGICAL_4);
242 export_proto(`s'name`'rtype_qual`_'atype_code);
245 `s'name`'rtype_qual`_'atype_code (rtype * const restrict retarray,
246 atype * const restrict array,
247 GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back)
256 name`'rtype_qual`_'atype_code (retarray, array, back);
260 rank = GFC_DESCRIPTOR_RANK (array);
263 runtime_error ("Rank of array needs to be > 0");
265 if (retarray->base_addr == NULL)
267 GFC_DIMENSION_SET(retarray->dim[0], 0, rank-1, 1);
268 GFC_DTYPE_COPY_SETRANK(retarray,retarray,1);
269 retarray->offset = 0;
270 retarray->base_addr = xmallocarray (rank, sizeof (rtype_name));
272 else if (unlikely (compile_options.bounds_check))
274 bounds_iforeach_return ((array_t *) retarray, (array_t *) array,
278 dstride = GFC_DESCRIPTOR_STRIDE(retarray,0);
279 dest = retarray->base_addr;
280 for (n = 0; n<rank; n++)
281 dest[n * dstride] = $1 ;