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 compare_fcn (const atype_name *a, const atype_name *b, gfc_charlen_type n)
9 if (sizeof ('atype_name`) == 1)
10 return memcmp (a, b, n);
12 return memcmp_char4 (a, b, n);
16 extern void name`'rtype_qual`_'atype_code` ('rtype` * const restrict retarray,
17 'atype` * const restrict array'back_arg`, gfc_charlen_type len);
18 export_proto('name`'rtype_qual`_'atype_code);
21 name`'rtype_qual`_'atype_code` ('rtype` * const restrict retarray,
22 'atype` * const restrict array'back_arg`, gfc_charlen_type len)
24 index_type count[GFC_MAX_DIMENSIONS];
25 index_type extent[GFC_MAX_DIMENSIONS];
26 index_type sstride[GFC_MAX_DIMENSIONS];
28 const 'atype_name *base;
29 rtype_name * restrict dest;
33 rank = GFC_DESCRIPTOR_RANK (array);
35 runtime_error ("Rank of array needs to be > 0");
37 if (retarray->base_addr == NULL)
39 GFC_DIMENSION_SET(retarray->dim[0], 0, rank-1, 1);
40 retarray->dtype.rank = 1;
42 retarray->base_addr = xmallocarray (rank, sizeof (rtype_name));
46 if (unlikely (compile_options.bounds_check))
47 bounds_iforeach_return ((array_t *) retarray, (array_t *) array,
51 dstride = GFC_DESCRIPTOR_STRIDE(retarray,0);
52 dest = retarray->base_addr;
53 for (n = 0; n < rank; n++)
55 sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n) * len;
56 extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
60 /* Set the return value. */
61 for (n = 0; n < rank; n++)
62 dest[n * dstride] = 0;
67 base = array->base_addr;
69 /* Initialize the return value. */
70 for (n = 0; n < rank; n++)
71 dest[n * dstride] = 1;
74 define(START_FOREACH_BLOCK,
79 /* Implementation start. */
81 define(FINISH_FOREACH_FUNCTION,
82 ` /* Implementation end. */
83 /* Advance to the next element. */
86 while (++count[0] != extent[0]);
90 /* When we get to the end of a dimension, reset it and increment
91 the next dimension. */
93 /* We could precalculate these products, but this is a less
94 frequently used path so probably not worth it. */
95 base -= sstride[n] * extent[n];
99 /* Break out of the loop. */
109 while (count[n] == extent[n]);
113 define(START_MASKED_FOREACH_FUNCTION,
115 extern void `m'name`'rtype_qual`_'atype_code` ('rtype` * const restrict,
116 'atype` * const restrict, gfc_array_l1 * const restrict 'back_arg`,
117 gfc_charlen_type len);
118 export_proto(m'name`'rtype_qual`_'atype_code`);
121 m'name`'rtype_qual`_'atype_code` ('rtype` * const restrict retarray,
122 'atype` * const restrict array,
123 gfc_array_l1 * const restrict mask'back_arg`,
124 gfc_charlen_type len)
126 index_type count[GFC_MAX_DIMENSIONS];
127 index_type extent[GFC_MAX_DIMENSIONS];
128 index_type sstride[GFC_MAX_DIMENSIONS];
129 index_type mstride[GFC_MAX_DIMENSIONS];
132 const atype_name *base;
133 GFC_LOGICAL_1 *mbase;
141 name`'rtype_qual`_'atype_code (retarray, array, back, len);
143 name`'rtype_qual`_'atype_code (retarray, array, len);
148 rank = GFC_DESCRIPTOR_RANK (array);
150 runtime_error ("Rank of array needs to be > 0");
152 if (retarray->base_addr == NULL)
154 GFC_DIMENSION_SET(retarray->dim[0], 0, rank - 1, 1);
155 retarray->dtype.rank = 1;
156 retarray->offset = 0;
157 retarray->base_addr = xmallocarray (rank, sizeof (rtype_name));
161 if (unlikely (compile_options.bounds_check))
164 bounds_iforeach_return ((array_t *) retarray, (array_t *) array,
166 bounds_equal_extents ((array_t *) mask, (array_t *) array,
167 "MASK argument", "u_name");
171 mask_kind = GFC_DESCRIPTOR_SIZE (mask);
173 mbase = mask->base_addr;
175 if (mask_kind == 1 || mask_kind == 2 || mask_kind == 4 || mask_kind == 8
176 #ifdef HAVE_GFC_LOGICAL_16
180 mbase = GFOR_POINTER_TO_L1 (mbase, mask_kind);
182 runtime_error ("Funny sized logical array");
184 dstride = GFC_DESCRIPTOR_STRIDE(retarray,0);
185 dest = retarray->base_addr;
186 for (n = 0; n < rank; n++)
188 sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n) * len;
189 mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask,n);
190 extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
194 /* Set the return value. */
195 for (n = 0; n < rank; n++)
196 dest[n * dstride] = 0;
201 base = array->base_addr;
203 /* Initialize the return value. */
204 for (n = 0; n < rank; n++)
205 dest[n * dstride] = 0;
208 define(START_MASKED_FOREACH_BLOCK, `START_FOREACH_BLOCK')dnl
209 define(FINISH_MASKED_FOREACH_FUNCTION,
210 ` /* Implementation end. */
211 /* Advance to the next element. */
215 while (++count[0] != extent[0]);
219 /* When we get to the end of a dimension, reset it and increment
220 the next dimension. */
222 /* We could precalculate these products, but this is a less
223 frequently used path so probably not worth it. */
224 base -= sstride[n] * extent[n];
225 mbase -= mstride[n] * extent[n];
229 /* Break out of the loop. */
240 while (count[n] == extent[n]);
244 define(FOREACH_FUNCTION,
245 `START_FOREACH_FUNCTION
249 FINISH_FOREACH_FUNCTION')dnl
250 define(MASKED_FOREACH_FUNCTION,
251 `START_MASKED_FOREACH_FUNCTION
253 START_MASKED_FOREACH_BLOCK
255 FINISH_MASKED_FOREACH_FUNCTION')dnl
256 define(SCALAR_FOREACH_FUNCTION,
258 extern void `s'name`'rtype_qual`_'atype_code` ('rtype` * const restrict,
259 'atype` * const restrict, GFC_LOGICAL_4 *'back_arg`,
260 gfc_charlen_type len);
261 export_proto(s'name`'rtype_qual`_'atype_code);
264 `s'name`'rtype_qual`_'atype_code` ('rtype` * const restrict retarray,
265 'atype` * const restrict array,
266 GFC_LOGICAL_4 * mask'back_arg`,
267 gfc_charlen_type len)
274 if (mask == NULL || *mask)
277 name`'rtype_qual`_'atype_code (retarray, array, back, len);
279 name`'rtype_qual`_'atype_code (retarray, array, len);
284 rank = GFC_DESCRIPTOR_RANK (array);
287 runtime_error ("Rank of array needs to be > 0");
289 if (retarray->base_addr == NULL)
291 GFC_DIMENSION_SET(retarray->dim[0], 0, rank-1, 1);
292 retarray->dtype.rank = 1;
293 retarray->offset = 0;
294 retarray->base_addr = xmallocarray (rank, sizeof (rtype_name));
296 else if (unlikely (compile_options.bounds_check))
298 bounds_iforeach_return ((array_t *) retarray, (array_t *) array,
302 dstride = GFC_DESCRIPTOR_STRIDE(retarray,0);
303 dest = retarray->base_addr;
304 for (n = 0; n<rank; n++)
305 dest[n * dstride] = $1 ;