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 LGPL. See COPYING for details.
5 define(START_FOREACH_FUNCTION,
7 `__'name`'rtype_qual`_'atype_code (rtype * retarray, atype *array)
9 index_type count[GFC_MAX_DIMENSIONS];
10 index_type extent[GFC_MAX_DIMENSIONS];
11 index_type sstride[GFC_MAX_DIMENSIONS];
18 rank = GFC_DESCRIPTOR_RANK (array);
20 assert (GFC_DESCRIPTOR_RANK (retarray) == 1);
21 assert (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound == rank);
22 if (array->dim[0].stride == 0)
23 array->dim[0].stride = 1;
24 if (retarray->dim[0].stride == 0)
25 retarray->dim[0].stride = 1;
27 dstride = retarray->dim[0].stride;
28 dest = retarray->data;
29 for (n = 0; n < rank; n++)
31 sstride[n] = array->dim[n].stride;
32 extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
36 /* Set the return value. */
37 for (n = 0; n < rank; n++)
38 dest[n * dstride] = 0;
45 /* Initialize the return value. */
46 for (n = 0; n < rank; n++)
47 dest[n * dstride] = 1;
50 define(START_FOREACH_BLOCK,
54 /* Implementation start. */
56 define(FINISH_FOREACH_FUNCTION,
57 ` /* Implementation end. */
59 /* Advance to the next element. */
63 while (count[n] == extent[n])
65 /* When we get to the end of a dimension, reset it and increment
66 the next dimension. */
68 /* We could precalculate these products, but this is a less
69 frequently used path so proabably not worth it. */
70 base -= sstride[n] * extent[n];
74 /* Break out of the loop. */
87 define(START_MASKED_FOREACH_FUNCTION,
89 `__m'name`'rtype_qual`_'atype_code (rtype * retarray, atype *array, gfc_array_l4 * mask)
91 index_type count[GFC_MAX_DIMENSIONS];
92 index_type extent[GFC_MAX_DIMENSIONS];
93 index_type sstride[GFC_MAX_DIMENSIONS];
94 index_type mstride[GFC_MAX_DIMENSIONS];
102 rank = GFC_DESCRIPTOR_RANK (array);
104 assert (GFC_DESCRIPTOR_RANK (retarray) == 1);
105 assert (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound == rank);
106 assert (GFC_DESCRIPTOR_RANK (mask) == rank);
108 if (array->dim[0].stride == 0)
109 array->dim[0].stride = 1;
110 if (retarray->dim[0].stride == 0)
111 retarray->dim[0].stride = 1;
112 if (retarray->dim[0].stride == 0)
113 retarray->dim[0].stride = 1;
115 dstride = retarray->dim[0].stride;
116 dest = retarray->data;
117 for (n = 0; n < rank; n++)
119 sstride[n] = array->dim[n].stride;
120 mstride[n] = mask->dim[n].stride;
121 extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
125 /* Set the return value. */
126 for (n = 0; n < rank; n++)
127 dest[n * dstride] = 0;
135 if (GFC_DESCRIPTOR_SIZE (mask) != 4)
137 /* This allows the same loop to be used for all logical types. */
138 assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
139 for (n = 0; n < rank; n++)
141 mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
145 /* Initialize the return value. */
146 for (n = 0; n < rank; n++)
147 dest[n * dstride] = 1;
150 define(START_MASKED_FOREACH_BLOCK, `START_FOREACH_BLOCK')dnl
151 define(FINISH_MASKED_FOREACH_FUNCTION,
152 ` /* Implementation end. */
154 /* Advance to the next element. */
159 while (count[n] == extent[n])
161 /* When we get to the end of a dimension, reset it and increment
162 the next dimension. */
164 /* We could precalculate these products, but this is a less
165 frequently used path so proabably not worth it. */
166 base -= sstride[n] * extent[n];
167 mbase -= mstride[n] * extent[n];
171 /* Break out of the loop. */
185 define(FOREACH_FUNCTION,
186 `START_FOREACH_FUNCTION
190 FINISH_FOREACH_FUNCTION')dnl
191 define(MASKED_FOREACH_FUNCTION,
192 `START_MASKED_FOREACH_FUNCTION
194 START_MASKED_FOREACH_BLOCK
196 FINISH_MASKED_FOREACH_FUNCTION')dnl