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;
37 rank = GFC_DESCRIPTOR_RANK (array);
39 runtime_error ("Rank of array needs to be > 0");
41 if (retarray->base_addr == NULL)
43 GFC_DIMENSION_SET(retarray->dim[0], 0, rank-1, 1);
44 GFC_DTYPE_COPY_SETRANK(retarray,retarray,1);
46 retarray->base_addr = xmallocarray (rank, sizeof (rtype_name));
50 if (unlikely (compile_options.bounds_check))
51 bounds_iforeach_return ((array_t *) retarray, (array_t *) array,
55 dstride = GFC_DESCRIPTOR_STRIDE(retarray,0);
56 dest = retarray->base_addr;
57 for (n = 0; n < rank; n++)
59 sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n) * len;
60 extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
64 /* Set the return value. */
65 for (n = 0; n < rank; n++)
66 dest[n * dstride] = 0;
71 base = array->base_addr;
73 /* Initialize the return value. */
74 for (n = 0; n < rank; n++)
75 dest[n * dstride] = 1;
78 define(START_FOREACH_BLOCK,
83 /* Implementation start. */
85 define(FINISH_FOREACH_FUNCTION,
86 ` /* Implementation end. */
87 /* Advance to the next element. */
90 while (++count[0] != extent[0]);
94 /* When we get to the end of a dimension, reset it and increment
95 the next dimension. */
97 /* We could precalculate these products, but this is a less
98 frequently used path so probably not worth it. */
99 base -= sstride[n] * extent[n];
103 /* Break out of the loop. */
113 while (count[n] == extent[n]);
117 define(START_MASKED_FOREACH_FUNCTION,
119 extern void `m'name`'rtype_qual`_'atype_code` ('rtype` * const restrict,
120 'atype` * const restrict, gfc_array_l1 * const restrict 'back_arg`,
121 gfc_charlen_type len);
122 export_proto(m'name`'rtype_qual`_'atype_code`);
125 m'name`'rtype_qual`_'atype_code` ('rtype` * const restrict retarray,
126 'atype` * const restrict array,
127 gfc_array_l1 * const restrict mask'back_arg`,
128 gfc_charlen_type len)
130 index_type count[GFC_MAX_DIMENSIONS];
131 index_type extent[GFC_MAX_DIMENSIONS];
132 index_type sstride[GFC_MAX_DIMENSIONS];
133 index_type mstride[GFC_MAX_DIMENSIONS];
136 const atype_name *base;
137 GFC_LOGICAL_1 *mbase;
145 rank = GFC_DESCRIPTOR_RANK (array);
147 runtime_error ("Rank of array needs to be > 0");
149 if (retarray->base_addr == NULL)
151 GFC_DIMENSION_SET(retarray->dim[0], 0, rank - 1, 1);
152 GFC_DTYPE_COPY_SETRANK(retarray,retarray,1);
153 retarray->offset = 0;
154 retarray->base_addr = xmallocarray (rank, sizeof (rtype_name));
158 if (unlikely (compile_options.bounds_check))
161 bounds_iforeach_return ((array_t *) retarray, (array_t *) array,
163 bounds_equal_extents ((array_t *) mask, (array_t *) array,
164 "MASK argument", "u_name");
168 mask_kind = GFC_DESCRIPTOR_SIZE (mask);
170 mbase = mask->base_addr;
172 if (mask_kind == 1 || mask_kind == 2 || mask_kind == 4 || mask_kind == 8
173 #ifdef HAVE_GFC_LOGICAL_16
177 mbase = GFOR_POINTER_TO_L1 (mbase, mask_kind);
179 runtime_error ("Funny sized logical array");
181 dstride = GFC_DESCRIPTOR_STRIDE(retarray,0);
182 dest = retarray->base_addr;
183 for (n = 0; n < rank; n++)
185 sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n) * len;
186 mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask,n);
187 extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
191 /* Set the return value. */
192 for (n = 0; n < rank; n++)
193 dest[n * dstride] = 0;
198 base = array->base_addr;
200 /* Initialize the return value. */
201 for (n = 0; n < rank; n++)
202 dest[n * dstride] = 0;
205 define(START_MASKED_FOREACH_BLOCK, `START_FOREACH_BLOCK')dnl
206 define(FINISH_MASKED_FOREACH_FUNCTION,
207 ` /* Implementation end. */
208 /* Advance to the next element. */
212 while (++count[0] != extent[0]);
216 /* When we get to the end of a dimension, reset it and increment
217 the next dimension. */
219 /* We could precalculate these products, but this is a less
220 frequently used path so probably not worth it. */
221 base -= sstride[n] * extent[n];
222 mbase -= mstride[n] * extent[n];
226 /* Break out of the loop. */
237 while (count[n] == extent[n]);
241 define(FOREACH_FUNCTION,
242 `START_FOREACH_FUNCTION
246 FINISH_FOREACH_FUNCTION')dnl
247 define(MASKED_FOREACH_FUNCTION,
248 `START_MASKED_FOREACH_FUNCTION
250 START_MASKED_FOREACH_BLOCK
252 FINISH_MASKED_FOREACH_FUNCTION')dnl
253 define(SCALAR_FOREACH_FUNCTION,
255 extern void `s'name`'rtype_qual`_'atype_code` ('rtype` * const restrict,
256 'atype` * const restrict, GFC_LOGICAL_4 *'back_arg`,
257 gfc_charlen_type len);
258 export_proto(s'name`'rtype_qual`_'atype_code);
261 `s'name`'rtype_qual`_'atype_code` ('rtype` * const restrict retarray,
262 'atype` * const restrict array,
263 GFC_LOGICAL_4 * mask'back_arg`,
264 gfc_charlen_type len)
274 name`'rtype_qual`_'atype_code (retarray, array, back, len);
276 name`'rtype_qual`_'atype_code (retarray, array, len);
281 rank = GFC_DESCRIPTOR_RANK (array);
284 runtime_error ("Rank of array needs to be > 0");
286 if (retarray->base_addr == NULL)
288 GFC_DIMENSION_SET(retarray->dim[0], 0, rank-1, 1);
289 GFC_DTYPE_COPY_SETRANK(retarray,retarray,1);
290 retarray->offset = 0;
291 retarray->base_addr = xmallocarray (rank, sizeof (rtype_name));
293 else if (unlikely (compile_options.bounds_check))
295 bounds_iforeach_return ((array_t *) retarray, (array_t *) array,
299 dstride = GFC_DESCRIPTOR_STRIDE(retarray,0);
300 dest = retarray->base_addr;
301 for (n = 0; n<rank; n++)
302 dest[n * dstride] = $1 ;