]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgfortran/m4/iforeach.m4
[multiple changes]
[thirdparty/gcc.git] / libgfortran / m4 / iforeach.m4
CommitLineData
6de9cd9a
DN
1dnl Support macro file for intrinsic functions.
2dnl Contains the generic sections of the array functions.
3dnl This file is part of the GNU Fortran 95 Runtime Library (libgfortran)
57dea9f6 4dnl Distributed under the GNU GPL with exception. See COPYING for details.
6de9cd9a 5define(START_FOREACH_FUNCTION,
7d7b8bfe 6`
64acfd99
JB
7extern void name`'rtype_qual`_'atype_code (rtype * const restrict retarray,
8 atype * const restrict array);
7f68c75f 9export_proto(name`'rtype_qual`_'atype_code);
7d7b8bfe
RH
10
11void
64acfd99
JB
12name`'rtype_qual`_'atype_code (rtype * const restrict retarray,
13 atype * const restrict array)
6de9cd9a
DN
14{
15 index_type count[GFC_MAX_DIMENSIONS];
16 index_type extent[GFC_MAX_DIMENSIONS];
17 index_type sstride[GFC_MAX_DIMENSIONS];
18 index_type dstride;
64acfd99 19 const atype_name *base;
5863aacf 20 rtype_name * restrict dest;
6de9cd9a
DN
21 index_type rank;
22 index_type n;
23
24 rank = GFC_DESCRIPTOR_RANK (array);
50dd63a9
TK
25 if (rank <= 0)
26 runtime_error ("Rank of array needs to be > 0");
27
28 if (retarray->data == NULL)
29 {
dfb55fdc 30 GFC_DIMENSION_SET(retarray->dim[0], 0, rank-1, 1);
50dd63a9 31 retarray->dtype = (retarray->dtype & ~GFC_DTYPE_RANK_MASK) | 1;
efd4dc1a 32 retarray->offset = 0;
50dd63a9
TK
33 retarray->data = internal_malloc_size (sizeof (rtype_name) * rank);
34 }
35 else
36 {
9731c4a3 37 if (unlikely (compile_options.bounds_check))
16bff921
TK
38 bounds_iforeach_return ((array_t *) retarray, (array_t *) array,
39 "u_name");
50dd63a9 40 }
c6abe94d 41
dfb55fdc 42 dstride = GFC_DESCRIPTOR_STRIDE(retarray,0);
6de9cd9a
DN
43 dest = retarray->data;
44 for (n = 0; n < rank; n++)
45 {
dfb55fdc
TK
46 sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n);
47 extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
6de9cd9a
DN
48 count[n] = 0;
49 if (extent[n] <= 0)
50 {
51 /* Set the return value. */
52 for (n = 0; n < rank; n++)
53 dest[n * dstride] = 0;
54 return;
55 }
56 }
57
58 base = array->data;
59
60 /* Initialize the return value. */
61 for (n = 0; n < rank; n++)
a4b9e93e 62 dest[n * dstride] = 0;
6de9cd9a
DN
63 {
64')dnl
65define(START_FOREACH_BLOCK,
66` while (base)
67 {
68 {
69 /* Implementation start. */
70')dnl
71define(FINISH_FOREACH_FUNCTION,
72` /* Implementation end. */
73 }
74 /* Advance to the next element. */
75 count[0]++;
76 base += sstride[0];
77 n = 0;
78 while (count[n] == extent[n])
79 {
80 /* When we get to the end of a dimension, reset it and increment
81 the next dimension. */
82 count[n] = 0;
83 /* We could precalculate these products, but this is a less
8b6dba81 84 frequently used path so probably not worth it. */
6de9cd9a
DN
85 base -= sstride[n] * extent[n];
86 n++;
87 if (n == rank)
88 {
89 /* Break out of the loop. */
90 base = NULL;
91 break;
92 }
93 else
94 {
95 count[n]++;
96 base += sstride[n];
97 }
98 }
99 }
100 }
101}')dnl
102define(START_MASKED_FOREACH_FUNCTION,
7d7b8bfe 103`
64acfd99 104extern void `m'name`'rtype_qual`_'atype_code (rtype * const restrict,
28dc6b33 105 atype * const restrict, gfc_array_l1 * const restrict);
7f68c75f 106export_proto(`m'name`'rtype_qual`_'atype_code);
7d7b8bfe
RH
107
108void
64acfd99
JB
109`m'name`'rtype_qual`_'atype_code (rtype * const restrict retarray,
110 atype * const restrict array,
28dc6b33 111 gfc_array_l1 * const restrict mask)
6de9cd9a
DN
112{
113 index_type count[GFC_MAX_DIMENSIONS];
114 index_type extent[GFC_MAX_DIMENSIONS];
115 index_type sstride[GFC_MAX_DIMENSIONS];
116 index_type mstride[GFC_MAX_DIMENSIONS];
117 index_type dstride;
118 rtype_name *dest;
64acfd99 119 const atype_name *base;
28dc6b33 120 GFC_LOGICAL_1 *mbase;
6de9cd9a
DN
121 int rank;
122 index_type n;
28dc6b33 123 int mask_kind;
6de9cd9a
DN
124
125 rank = GFC_DESCRIPTOR_RANK (array);
50dd63a9
TK
126 if (rank <= 0)
127 runtime_error ("Rank of array needs to be > 0");
128
129 if (retarray->data == NULL)
130 {
dfb55fdc 131 GFC_DIMENSION_SET(retarray->dim[0], 0, rank - 1, 1);
50dd63a9 132 retarray->dtype = (retarray->dtype & ~GFC_DTYPE_RANK_MASK) | 1;
efd4dc1a 133 retarray->offset = 0;
50dd63a9
TK
134 retarray->data = internal_malloc_size (sizeof (rtype_name) * rank);
135 }
136 else
137 {
9731c4a3 138 if (unlikely (compile_options.bounds_check))
fd6590f8 139 {
fd6590f8 140
16bff921
TK
141 bounds_iforeach_return ((array_t *) retarray, (array_t *) array,
142 "u_name");
143 bounds_equal_extents ((array_t *) mask, (array_t *) array,
144 "MASK argument", "u_name");
fd6590f8 145 }
50dd63a9 146 }
6de9cd9a 147
28dc6b33
TK
148 mask_kind = GFC_DESCRIPTOR_SIZE (mask);
149
150 mbase = mask->data;
151
152 if (mask_kind == 1 || mask_kind == 2 || mask_kind == 4 || mask_kind == 8
153#ifdef HAVE_GFC_LOGICAL_16
154 || mask_kind == 16
155#endif
156 )
157 mbase = GFOR_POINTER_TO_L1 (mbase, mask_kind);
158 else
159 runtime_error ("Funny sized logical array");
160
dfb55fdc 161 dstride = GFC_DESCRIPTOR_STRIDE(retarray,0);
6de9cd9a
DN
162 dest = retarray->data;
163 for (n = 0; n < rank; n++)
164 {
dfb55fdc
TK
165 sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n);
166 mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask,n);
167 extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
6de9cd9a
DN
168 count[n] = 0;
169 if (extent[n] <= 0)
170 {
171 /* Set the return value. */
172 for (n = 0; n < rank; n++)
173 dest[n * dstride] = 0;
174 return;
175 }
176 }
177
178 base = array->data;
6de9cd9a
DN
179
180 /* Initialize the return value. */
181 for (n = 0; n < rank; n++)
a4b9e93e 182 dest[n * dstride] = 0;
6de9cd9a
DN
183 {
184')dnl
185define(START_MASKED_FOREACH_BLOCK, `START_FOREACH_BLOCK')dnl
186define(FINISH_MASKED_FOREACH_FUNCTION,
187` /* Implementation end. */
188 }
189 /* Advance to the next element. */
190 count[0]++;
191 base += sstride[0];
192 mbase += mstride[0];
193 n = 0;
194 while (count[n] == extent[n])
195 {
196 /* When we get to the end of a dimension, reset it and increment
197 the next dimension. */
198 count[n] = 0;
199 /* We could precalculate these products, but this is a less
8b6dba81 200 frequently used path so probably not worth it. */
6de9cd9a
DN
201 base -= sstride[n] * extent[n];
202 mbase -= mstride[n] * extent[n];
203 n++;
204 if (n == rank)
205 {
206 /* Break out of the loop. */
207 base = NULL;
208 break;
209 }
210 else
211 {
212 count[n]++;
213 base += sstride[n];
214 mbase += mstride[n];
215 }
216 }
217 }
218 }
219}')dnl
220define(FOREACH_FUNCTION,
221`START_FOREACH_FUNCTION
222$1
223START_FOREACH_BLOCK
224$2
225FINISH_FOREACH_FUNCTION')dnl
226define(MASKED_FOREACH_FUNCTION,
227`START_MASKED_FOREACH_FUNCTION
228$1
229START_MASKED_FOREACH_BLOCK
230$2
231FINISH_MASKED_FOREACH_FUNCTION')dnl
97a62038
TK
232define(SCALAR_FOREACH_FUNCTION,
233`
234extern void `s'name`'rtype_qual`_'atype_code (rtype * const restrict,
235 atype * const restrict, GFC_LOGICAL_4 *);
236export_proto(`s'name`'rtype_qual`_'atype_code);
237
238void
239`s'name`'rtype_qual`_'atype_code (rtype * const restrict retarray,
240 atype * const restrict array,
241 GFC_LOGICAL_4 * mask)
242{
243 index_type rank;
244 index_type dstride;
245 index_type n;
246 rtype_name *dest;
247
248 if (*mask)
249 {
250 name`'rtype_qual`_'atype_code (retarray, array);
251 return;
252 }
253
254 rank = GFC_DESCRIPTOR_RANK (array);
255
256 if (rank <= 0)
257 runtime_error ("Rank of array needs to be > 0");
258
259 if (retarray->data == NULL)
260 {
dfb55fdc 261 GFC_DIMENSION_SET(retarray->dim[0], 0, rank-1, 1);
97a62038
TK
262 retarray->dtype = (retarray->dtype & ~GFC_DTYPE_RANK_MASK) | 1;
263 retarray->offset = 0;
264 retarray->data = internal_malloc_size (sizeof (rtype_name) * rank);
265 }
16bff921 266 else if (unlikely (compile_options.bounds_check))
97a62038 267 {
16bff921
TK
268 bounds_iforeach_return ((array_t *) retarray, (array_t *) array,
269 "u_name");
97a62038
TK
270 }
271
dfb55fdc 272 dstride = GFC_DESCRIPTOR_STRIDE(retarray,0);
97a62038
TK
273 dest = retarray->data;
274 for (n = 0; n<rank; n++)
275 dest[n * dstride] = $1 ;
276}')dnl