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 95 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);
9 export_proto(name`'rtype_qual`_'atype_code);
12 name`'rtype_qual`_'atype_code (rtype * const restrict retarray,
13 atype * const restrict array)
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;
24 rank = GFC_DESCRIPTOR_RANK (array);
26 runtime_error ("Rank of array needs to be > 0");
28 if (retarray->data == NULL)
30 retarray->dim[0].lbound = 0;
31 retarray->dim[0].ubound = rank-1;
32 retarray->dim[0].stride = 1;
33 retarray->dtype = (retarray->dtype & ~GFC_DTYPE_RANK_MASK) | 1;
35 retarray->data = internal_malloc_size (sizeof (rtype_name) * rank);
39 if (GFC_DESCRIPTOR_RANK (retarray) != 1)
40 runtime_error ("rank of return array does not equal 1");
42 if (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound != rank)
43 runtime_error ("dimension of return array incorrect");
46 dstride = retarray->dim[0].stride;
47 dest = retarray->data;
48 for (n = 0; n < rank; n++)
50 sstride[n] = array->dim[n].stride;
51 extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
55 /* Set the return value. */
56 for (n = 0; n < rank; n++)
57 dest[n * dstride] = 0;
64 /* Initialize the return value. */
65 for (n = 0; n < rank; n++)
66 dest[n * dstride] = 0;
69 define(START_FOREACH_BLOCK,
73 /* Implementation start. */
75 define(FINISH_FOREACH_FUNCTION,
76 ` /* Implementation end. */
78 /* Advance to the next element. */
82 while (count[n] == extent[n])
84 /* When we get to the end of a dimension, reset it and increment
85 the next dimension. */
87 /* We could precalculate these products, but this is a less
88 frequently used path so probably not worth it. */
89 base -= sstride[n] * extent[n];
93 /* Break out of the loop. */
106 define(START_MASKED_FOREACH_FUNCTION,
108 extern void `m'name`'rtype_qual`_'atype_code (rtype * const restrict,
109 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)
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;
129 rank = GFC_DESCRIPTOR_RANK (array);
131 runtime_error ("Rank of array needs to be > 0");
133 if (retarray->data == NULL)
135 retarray->dim[0].lbound = 0;
136 retarray->dim[0].ubound = rank-1;
137 retarray->dim[0].stride = 1;
138 retarray->dtype = (retarray->dtype & ~GFC_DTYPE_RANK_MASK) | 1;
139 retarray->offset = 0;
140 retarray->data = internal_malloc_size (sizeof (rtype_name) * rank);
144 if (GFC_DESCRIPTOR_RANK (retarray) != 1)
145 runtime_error ("rank of return array does not equal 1");
147 if (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound != rank)
148 runtime_error ("dimension of return array incorrect");
151 mask_kind = GFC_DESCRIPTOR_SIZE (mask);
155 if (mask_kind == 1 || mask_kind == 2 || mask_kind == 4 || mask_kind == 8
156 #ifdef HAVE_GFC_LOGICAL_16
160 mbase = GFOR_POINTER_TO_L1 (mbase, mask_kind);
162 runtime_error ("Funny sized logical array");
164 dstride = retarray->dim[0].stride;
165 dest = retarray->data;
166 for (n = 0; n < rank; n++)
168 sstride[n] = array->dim[n].stride;
169 mstride[n] = mask->dim[n].stride * mask_kind;
170 extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
174 /* Set the return value. */
175 for (n = 0; n < rank; n++)
176 dest[n * dstride] = 0;
183 /* Initialize the return value. */
184 for (n = 0; n < rank; n++)
185 dest[n * dstride] = 0;
188 define(START_MASKED_FOREACH_BLOCK, `START_FOREACH_BLOCK')dnl
189 define(FINISH_MASKED_FOREACH_FUNCTION,
190 ` /* Implementation end. */
192 /* Advance to the next element. */
197 while (count[n] == extent[n])
199 /* When we get to the end of a dimension, reset it and increment
200 the next dimension. */
202 /* We could precalculate these products, but this is a less
203 frequently used path so probably not worth it. */
204 base -= sstride[n] * extent[n];
205 mbase -= mstride[n] * extent[n];
209 /* Break out of the loop. */
223 define(FOREACH_FUNCTION,
224 `START_FOREACH_FUNCTION
228 FINISH_FOREACH_FUNCTION')dnl
229 define(MASKED_FOREACH_FUNCTION,
230 `START_MASKED_FOREACH_FUNCTION
232 START_MASKED_FOREACH_BLOCK
234 FINISH_MASKED_FOREACH_FUNCTION')dnl
235 define(SCALAR_FOREACH_FUNCTION,
237 extern void `s'name`'rtype_qual`_'atype_code (rtype * const restrict,
238 atype * const restrict, GFC_LOGICAL_4 *);
239 export_proto(`s'name`'rtype_qual`_'atype_code);
242 `s'name`'rtype_qual`_'atype_code (rtype * const restrict retarray,
243 atype * const restrict array,
244 GFC_LOGICAL_4 * mask)
253 name`'rtype_qual`_'atype_code (retarray, array);
257 rank = GFC_DESCRIPTOR_RANK (array);
260 runtime_error ("Rank of array needs to be > 0");
262 if (retarray->data == NULL)
264 retarray->dim[0].lbound = 0;
265 retarray->dim[0].ubound = rank-1;
266 retarray->dim[0].stride = 1;
267 retarray->dtype = (retarray->dtype & ~GFC_DTYPE_RANK_MASK) | 1;
268 retarray->offset = 0;
269 retarray->data = internal_malloc_size (sizeof (rtype_name) * rank);
273 if (GFC_DESCRIPTOR_RANK (retarray) != 1)
274 runtime_error ("rank of return array does not equal 1");
276 if (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound != rank)
277 runtime_error ("dimension of return array incorrect");
280 dstride = retarray->dim[0].stride;
281 dest = retarray->data;
282 for (n = 0; n<rank; n++)
283 dest[n * dstride] = $1 ;