ifunction.m4 revision 1.1.1.1 1 1.1 mrg dnl Support macro file for intrinsic functions.
2 1.1 mrg dnl Contains the generic sections of the array functions.
3 1.1 mrg dnl This file is part of the GNU Fortran Runtime Library (libgfortran)
4 1.1 mrg dnl Distributed under the GNU GPL with exception. See COPYING for details.
5 1.1 mrg dnl
6 1.1 mrg dnl Pass the implementation for a single section as the parameter to
7 1.1 mrg dnl {MASK_}ARRAY_FUNCTION.
8 1.1 mrg dnl The variables base, delta, and len describe the input section.
9 1.1 mrg dnl For masked section the mask is described by mbase and mdelta.
10 1.1 mrg dnl These should not be modified. The result should be stored in *dest.
11 1.1 mrg dnl The names count, extent, sstride, dstride, base, dest, rank, dim
12 1.1 mrg dnl retarray, array, pdim and mstride should not be used.
13 1.1 mrg dnl The variable n is declared as index_type and may be used.
14 1.1 mrg dnl Other variable declarations may be placed at the start of the code,
15 1.1 mrg dnl The types of the array parameter and the return value are
16 1.1 mrg dnl atype_name and rtype_name respectively.
17 1.1 mrg dnl Execution should be allowed to continue to the end of the block.
18 1.1 mrg dnl You should not return or break from the inner loop of the implementation.
19 1.1 mrg dnl Care should also be taken to avoid using the names defined in iparm.m4
20 1.1 mrg define(START_ARRAY_FUNCTION,
21 1.1 mrg `
22 1.1 mrg extern void name`'rtype_qual`_'atype_code (rtype * const restrict,
23 1.1 mrg atype` * const restrict, const 'index_type` * const restrict'back_arg`);
24 1.1 mrg export_proto('name`'rtype_qual`_'atype_code);
25 1.1 mrg
26 1.1 mrg void
27 1.1 mrg name`'rtype_qual`_'atype_code` ('rtype` * const restrict retarray,
28 1.1 mrg 'atype` * const restrict array,
29 1.1 mrg const index_type * const restrict pdim'back_arg`)
30 1.1 mrg {
31 1.1 mrg index_type count[GFC_MAX_DIMENSIONS];
32 1.1 mrg index_type extent[GFC_MAX_DIMENSIONS];
33 1.1 mrg index_type sstride[GFC_MAX_DIMENSIONS];
34 1.1 mrg index_type dstride[GFC_MAX_DIMENSIONS];
35 1.1 mrg const 'atype_name * restrict base;
36 1.1 mrg rtype_name * restrict dest;
37 1.1 mrg index_type rank;
38 1.1 mrg index_type n;
39 1.1 mrg index_type len;
40 1.1 mrg index_type delta;
41 1.1 mrg index_type dim;
42 1.1 mrg int continue_loop;
43 1.1 mrg
44 1.1 mrg /* Make dim zero based to avoid confusion. */
45 1.1 mrg rank = GFC_DESCRIPTOR_RANK (array) - 1;
46 1.1 mrg dim = (*pdim) - 1;
47 1.1 mrg
48 1.1 mrg if (unlikely (dim < 0 || dim > rank))
49 1.1 mrg {
50 1.1 mrg runtime_error ("Dim argument incorrect in u_name intrinsic: "
51 1.1 mrg "is %ld, should be between 1 and %ld",
52 1.1 mrg (long int) dim + 1, (long int) rank + 1);
53 1.1 mrg }
54 1.1 mrg
55 1.1 mrg len = GFC_DESCRIPTOR_EXTENT(array,dim);
56 1.1 mrg if (len < 0)
57 1.1 mrg len = 0;
58 1.1 mrg delta = GFC_DESCRIPTOR_STRIDE(array,dim);
59 1.1 mrg
60 1.1 mrg for (n = 0; n < dim; n++)
61 1.1 mrg {
62 1.1 mrg sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n);
63 1.1 mrg extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
64 1.1 mrg
65 1.1 mrg if (extent[n] < 0)
66 1.1 mrg extent[n] = 0;
67 1.1 mrg }
68 1.1 mrg for (n = dim; n < rank; n++)
69 1.1 mrg {
70 1.1 mrg sstride[n] = GFC_DESCRIPTOR_STRIDE(array, n + 1);
71 1.1 mrg extent[n] = GFC_DESCRIPTOR_EXTENT(array, n + 1);
72 1.1 mrg
73 1.1 mrg if (extent[n] < 0)
74 1.1 mrg extent[n] = 0;
75 1.1 mrg }
76 1.1 mrg
77 1.1 mrg if (retarray->base_addr == NULL)
78 1.1 mrg {
79 1.1 mrg size_t alloc_size, str;
80 1.1 mrg
81 1.1 mrg for (n = 0; n < rank; n++)
82 1.1 mrg {
83 1.1 mrg if (n == 0)
84 1.1 mrg str = 1;
85 1.1 mrg else
86 1.1 mrg str = GFC_DESCRIPTOR_STRIDE(retarray,n-1) * extent[n-1];
87 1.1 mrg
88 1.1 mrg GFC_DIMENSION_SET(retarray->dim[n], 0, extent[n] - 1, str);
89 1.1 mrg
90 1.1 mrg }
91 1.1 mrg
92 1.1 mrg retarray->offset = 0;
93 1.1 mrg retarray->dtype.rank = rank;
94 1.1 mrg
95 1.1 mrg alloc_size = GFC_DESCRIPTOR_STRIDE(retarray,rank-1) * extent[rank-1];
96 1.1 mrg
97 1.1 mrg retarray->base_addr = xmallocarray (alloc_size, sizeof (rtype_name));
98 1.1 mrg if (alloc_size == 0)
99 1.1 mrg {
100 1.1 mrg /* Make sure we have a zero-sized array. */
101 1.1 mrg GFC_DIMENSION_SET(retarray->dim[0], 0, -1, 1);
102 1.1 mrg return;
103 1.1 mrg
104 1.1 mrg }
105 1.1 mrg }
106 1.1 mrg else
107 1.1 mrg {
108 1.1 mrg if (rank != GFC_DESCRIPTOR_RANK (retarray))
109 1.1 mrg runtime_error ("rank of return array incorrect in"
110 1.1 mrg " u_name intrinsic: is %ld, should be %ld",
111 1.1 mrg (long int) (GFC_DESCRIPTOR_RANK (retarray)),
112 1.1 mrg (long int) rank);
113 1.1 mrg
114 1.1 mrg if (unlikely (compile_options.bounds_check))
115 1.1 mrg bounds_ifunction_return ((array_t *) retarray, extent,
116 1.1 mrg "return value", "u_name");
117 1.1 mrg }
118 1.1 mrg
119 1.1 mrg for (n = 0; n < rank; n++)
120 1.1 mrg {
121 1.1 mrg count[n] = 0;
122 1.1 mrg dstride[n] = GFC_DESCRIPTOR_STRIDE(retarray,n);
123 1.1 mrg if (extent[n] <= 0)
124 1.1 mrg return;
125 1.1 mrg }
126 1.1 mrg
127 1.1 mrg base = array->base_addr;
128 1.1 mrg dest = retarray->base_addr;
129 1.1 mrg
130 1.1 mrg continue_loop = 1;
131 1.1 mrg while (continue_loop)
132 1.1 mrg {
133 1.1 mrg const atype_name * restrict src;
134 1.1 mrg rtype_name result;
135 1.1 mrg src = base;
136 1.1 mrg {
137 1.1 mrg ')dnl
138 1.1 mrg define(START_ARRAY_BLOCK,
139 1.1 mrg ` if (len <= 0)
140 1.1 mrg *dest = '$1`;
141 1.1 mrg else
142 1.1 mrg {
143 1.1 mrg #if ! defined HAVE_BACK_ARG
144 1.1 mrg for (n = 0; n < len; n++, src += delta)
145 1.1 mrg {
146 1.1 mrg #endif
147 1.1 mrg ')dnl
148 1.1 mrg define(FINISH_ARRAY_FUNCTION,
149 1.1 mrg ` }
150 1.1 mrg '$1`
151 1.1 mrg *dest = result;
152 1.1 mrg }
153 1.1 mrg }
154 1.1 mrg /* Advance to the next element. */
155 1.1 mrg count[0]++;
156 1.1 mrg base += sstride[0];
157 1.1 mrg dest += dstride[0];
158 1.1 mrg n = 0;
159 1.1 mrg while (count[n] == extent[n])
160 1.1 mrg {
161 1.1 mrg /* When we get to the end of a dimension, reset it and increment
162 1.1 mrg the next dimension. */
163 1.1 mrg count[n] = 0;
164 1.1 mrg /* We could precalculate these products, but this is a less
165 1.1 mrg frequently used path so probably not worth it. */
166 1.1 mrg base -= sstride[n] * extent[n];
167 1.1 mrg dest -= dstride[n] * extent[n];
168 1.1 mrg n++;
169 1.1 mrg if (n >= rank)
170 1.1 mrg {
171 1.1 mrg /* Break out of the loop. */
172 1.1 mrg continue_loop = 0;
173 1.1 mrg break;
174 1.1 mrg }
175 1.1 mrg else
176 1.1 mrg {
177 1.1 mrg count[n]++;
178 1.1 mrg base += sstride[n];
179 1.1 mrg dest += dstride[n];
180 1.1 mrg }
181 1.1 mrg }
182 1.1 mrg }
183 1.1 mrg }')dnl
184 1.1 mrg define(START_MASKED_ARRAY_FUNCTION,
185 1.1 mrg `
186 1.1 mrg extern void `m'name`'rtype_qual`_'atype_code` ('rtype` * const restrict,
187 1.1 mrg 'atype` * const restrict, const 'index_type` * const restrict,
188 1.1 mrg gfc_array_l1 * const restrict'back_arg`);
189 1.1 mrg export_proto(m'name`'rtype_qual`_'atype_code`);
190 1.1 mrg
191 1.1 mrg void
192 1.1 mrg m'name`'rtype_qual`_'atype_code` ('rtype` * const restrict retarray,
193 1.1 mrg 'atype` * const restrict array,
194 1.1 mrg const index_type * const restrict pdim,
195 1.1 mrg gfc_array_l1 * const restrict mask'back_arg`)
196 1.1 mrg {
197 1.1 mrg index_type count[GFC_MAX_DIMENSIONS];
198 1.1 mrg index_type extent[GFC_MAX_DIMENSIONS];
199 1.1 mrg index_type sstride[GFC_MAX_DIMENSIONS];
200 1.1 mrg index_type dstride[GFC_MAX_DIMENSIONS];
201 1.1 mrg index_type mstride[GFC_MAX_DIMENSIONS];
202 1.1 mrg 'rtype_name * restrict dest;
203 1.1 mrg const atype_name * restrict base;
204 1.1 mrg const GFC_LOGICAL_1 * restrict mbase;
205 1.1 mrg index_type rank;
206 1.1 mrg index_type dim;
207 1.1 mrg index_type n;
208 1.1 mrg index_type len;
209 1.1 mrg index_type delta;
210 1.1 mrg index_type mdelta;
211 1.1 mrg int mask_kind;
212 1.1 mrg
213 1.1 mrg if (mask == NULL)
214 1.1 mrg {
215 1.1 mrg #ifdef HAVE_BACK_ARG
216 1.1 mrg name`'rtype_qual`_'atype_code (retarray, array, pdim, back);
217 1.1 mrg #else
218 1.1 mrg name`'rtype_qual`_'atype_code (retarray, array, pdim);
219 1.1 mrg #endif
220 1.1 mrg return;
221 1.1 mrg }
222 1.1 mrg
223 1.1 mrg dim = (*pdim) - 1;
224 1.1 mrg rank = GFC_DESCRIPTOR_RANK (array) - 1;
225 1.1 mrg
226 1.1 mrg
227 1.1 mrg if (unlikely (dim < 0 || dim > rank))
228 1.1 mrg {
229 1.1 mrg runtime_error ("Dim argument incorrect in u_name intrinsic: "
230 1.1 mrg "is %ld, should be between 1 and %ld",
231 1.1 mrg (long int) dim + 1, (long int) rank + 1);
232 1.1 mrg }
233 1.1 mrg
234 1.1 mrg len = GFC_DESCRIPTOR_EXTENT(array,dim);
235 1.1 mrg if (len <= 0)
236 1.1 mrg return;
237 1.1 mrg
238 1.1 mrg mbase = mask->base_addr;
239 1.1 mrg
240 1.1 mrg mask_kind = GFC_DESCRIPTOR_SIZE (mask);
241 1.1 mrg
242 1.1 mrg if (mask_kind == 1 || mask_kind == 2 || mask_kind == 4 || mask_kind == 8
243 1.1 mrg #ifdef HAVE_GFC_LOGICAL_16
244 1.1 mrg || mask_kind == 16
245 1.1 mrg #endif
246 1.1 mrg )
247 1.1 mrg mbase = GFOR_POINTER_TO_L1 (mbase, mask_kind);
248 1.1 mrg else
249 1.1 mrg runtime_error ("Funny sized logical array");
250 1.1 mrg
251 1.1 mrg delta = GFC_DESCRIPTOR_STRIDE(array,dim);
252 1.1 mrg mdelta = GFC_DESCRIPTOR_STRIDE_BYTES(mask,dim);
253 1.1 mrg
254 1.1 mrg for (n = 0; n < dim; n++)
255 1.1 mrg {
256 1.1 mrg sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n);
257 1.1 mrg mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask,n);
258 1.1 mrg extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
259 1.1 mrg
260 1.1 mrg if (extent[n] < 0)
261 1.1 mrg extent[n] = 0;
262 1.1 mrg
263 1.1 mrg }
264 1.1 mrg for (n = dim; n < rank; n++)
265 1.1 mrg {
266 1.1 mrg sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n + 1);
267 1.1 mrg mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask, n + 1);
268 1.1 mrg extent[n] = GFC_DESCRIPTOR_EXTENT(array, n + 1);
269 1.1 mrg
270 1.1 mrg if (extent[n] < 0)
271 1.1 mrg extent[n] = 0;
272 1.1 mrg }
273 1.1 mrg
274 1.1 mrg if (retarray->base_addr == NULL)
275 1.1 mrg {
276 1.1 mrg size_t alloc_size, str;
277 1.1 mrg
278 1.1 mrg for (n = 0; n < rank; n++)
279 1.1 mrg {
280 1.1 mrg if (n == 0)
281 1.1 mrg str = 1;
282 1.1 mrg else
283 1.1 mrg str= GFC_DESCRIPTOR_STRIDE(retarray,n-1) * extent[n-1];
284 1.1 mrg
285 1.1 mrg GFC_DIMENSION_SET(retarray->dim[n], 0, extent[n] - 1, str);
286 1.1 mrg
287 1.1 mrg }
288 1.1 mrg
289 1.1 mrg alloc_size = GFC_DESCRIPTOR_STRIDE(retarray,rank-1) * extent[rank-1];
290 1.1 mrg
291 1.1 mrg retarray->offset = 0;
292 1.1 mrg retarray->dtype.rank = rank;
293 1.1 mrg
294 1.1 mrg if (alloc_size == 0)
295 1.1 mrg {
296 1.1 mrg /* Make sure we have a zero-sized array. */
297 1.1 mrg GFC_DIMENSION_SET(retarray->dim[0], 0, -1, 1);
298 1.1 mrg return;
299 1.1 mrg }
300 1.1 mrg else
301 1.1 mrg retarray->base_addr = xmallocarray (alloc_size, sizeof (rtype_name));
302 1.1 mrg
303 1.1 mrg }
304 1.1 mrg else
305 1.1 mrg {
306 1.1 mrg if (rank != GFC_DESCRIPTOR_RANK (retarray))
307 1.1 mrg runtime_error ("rank of return array incorrect in u_name intrinsic");
308 1.1 mrg
309 1.1 mrg if (unlikely (compile_options.bounds_check))
310 1.1 mrg {
311 1.1 mrg bounds_ifunction_return ((array_t *) retarray, extent,
312 1.1 mrg "return value", "u_name");
313 1.1 mrg bounds_equal_extents ((array_t *) mask, (array_t *) array,
314 1.1 mrg "MASK argument", "u_name");
315 1.1 mrg }
316 1.1 mrg }
317 1.1 mrg
318 1.1 mrg for (n = 0; n < rank; n++)
319 1.1 mrg {
320 1.1 mrg count[n] = 0;
321 1.1 mrg dstride[n] = GFC_DESCRIPTOR_STRIDE(retarray,n);
322 1.1 mrg if (extent[n] <= 0)
323 1.1 mrg return;
324 1.1 mrg }
325 1.1 mrg
326 1.1 mrg dest = retarray->base_addr;
327 1.1 mrg base = array->base_addr;
328 1.1 mrg
329 1.1 mrg while (base)
330 1.1 mrg {
331 1.1 mrg const atype_name * restrict src;
332 1.1 mrg const GFC_LOGICAL_1 * restrict msrc;
333 1.1 mrg rtype_name result;
334 1.1 mrg src = base;
335 1.1 mrg msrc = mbase;
336 1.1 mrg {
337 1.1 mrg ')dnl
338 1.1 mrg define(START_MASKED_ARRAY_BLOCK,
339 1.1 mrg ` for (n = 0; n < len; n++, src += delta, msrc += mdelta)
340 1.1 mrg {
341 1.1 mrg ')dnl
342 1.1 mrg define(FINISH_MASKED_ARRAY_FUNCTION,
343 1.1 mrg ` }
344 1.1 mrg *dest = result;
345 1.1 mrg }
346 1.1 mrg /* Advance to the next element. */
347 1.1 mrg count[0]++;
348 1.1 mrg base += sstride[0];
349 1.1 mrg mbase += mstride[0];
350 1.1 mrg dest += dstride[0];
351 1.1 mrg n = 0;
352 1.1 mrg while (count[n] == extent[n])
353 1.1 mrg {
354 1.1 mrg /* When we get to the end of a dimension, reset it and increment
355 1.1 mrg the next dimension. */
356 1.1 mrg count[n] = 0;
357 1.1 mrg /* We could precalculate these products, but this is a less
358 1.1 mrg frequently used path so probably not worth it. */
359 1.1 mrg base -= sstride[n] * extent[n];
360 1.1 mrg mbase -= mstride[n] * extent[n];
361 1.1 mrg dest -= dstride[n] * extent[n];
362 1.1 mrg n++;
363 1.1 mrg if (n >= rank)
364 1.1 mrg {
365 1.1 mrg /* Break out of the loop. */
366 1.1 mrg base = NULL;
367 1.1 mrg break;
368 1.1 mrg }
369 1.1 mrg else
370 1.1 mrg {
371 1.1 mrg count[n]++;
372 1.1 mrg base += sstride[n];
373 1.1 mrg mbase += mstride[n];
374 1.1 mrg dest += dstride[n];
375 1.1 mrg }
376 1.1 mrg }
377 1.1 mrg }
378 1.1 mrg }')dnl
379 1.1 mrg define(SCALAR_ARRAY_FUNCTION,
380 1.1 mrg `
381 1.1 mrg extern void `s'name`'rtype_qual`_'atype_code` ('rtype` * const restrict,
382 1.1 mrg 'atype` * const restrict, const index_type * const restrict,
383 1.1 mrg GFC_LOGICAL_4 *'back_arg`);
384 1.1 mrg export_proto(s'name`'rtype_qual`_'atype_code);
385 1.1 mrg
386 1.1 mrg void
387 1.1 mrg `s'name`'rtype_qual`_'atype_code` ('rtype` * const restrict retarray,
388 1.1 mrg 'atype` * const restrict array,
389 1.1 mrg const index_type * const restrict pdim,
390 1.1 mrg GFC_LOGICAL_4 * mask'back_arg`)
391 1.1 mrg {
392 1.1 mrg index_type count[GFC_MAX_DIMENSIONS];
393 1.1 mrg index_type extent[GFC_MAX_DIMENSIONS];
394 1.1 mrg index_type dstride[GFC_MAX_DIMENSIONS];
395 1.1 mrg 'rtype_name * restrict dest;
396 1.1 mrg index_type rank;
397 1.1 mrg index_type n;
398 1.1 mrg index_type dim;
399 1.1 mrg
400 1.1 mrg
401 1.1 mrg if (mask == NULL || *mask)
402 1.1 mrg {
403 1.1 mrg #ifdef HAVE_BACK_ARG
404 1.1 mrg name`'rtype_qual`_'atype_code (retarray, array, pdim, back);
405 1.1 mrg #else
406 1.1 mrg name`'rtype_qual`_'atype_code (retarray, array, pdim);
407 1.1 mrg #endif
408 1.1 mrg return;
409 1.1 mrg }
410 1.1 mrg /* Make dim zero based to avoid confusion. */
411 1.1 mrg dim = (*pdim) - 1;
412 1.1 mrg rank = GFC_DESCRIPTOR_RANK (array) - 1;
413 1.1 mrg
414 1.1 mrg if (unlikely (dim < 0 || dim > rank))
415 1.1 mrg {
416 1.1 mrg runtime_error ("Dim argument incorrect in u_name intrinsic: "
417 1.1 mrg "is %ld, should be between 1 and %ld",
418 1.1 mrg (long int) dim + 1, (long int) rank + 1);
419 1.1 mrg }
420 1.1 mrg
421 1.1 mrg for (n = 0; n < dim; n++)
422 1.1 mrg {
423 1.1 mrg extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
424 1.1 mrg
425 1.1 mrg if (extent[n] <= 0)
426 1.1 mrg extent[n] = 0;
427 1.1 mrg }
428 1.1 mrg
429 1.1 mrg for (n = dim; n < rank; n++)
430 1.1 mrg {
431 1.1 mrg extent[n] =
432 1.1 mrg GFC_DESCRIPTOR_EXTENT(array,n + 1);
433 1.1 mrg
434 1.1 mrg if (extent[n] <= 0)
435 1.1 mrg extent[n] = 0;
436 1.1 mrg }
437 1.1 mrg
438 1.1 mrg if (retarray->base_addr == NULL)
439 1.1 mrg {
440 1.1 mrg size_t alloc_size, str;
441 1.1 mrg
442 1.1 mrg for (n = 0; n < rank; n++)
443 1.1 mrg {
444 1.1 mrg if (n == 0)
445 1.1 mrg str = 1;
446 1.1 mrg else
447 1.1 mrg str = GFC_DESCRIPTOR_STRIDE(retarray,n-1) * extent[n-1];
448 1.1 mrg
449 1.1 mrg GFC_DIMENSION_SET(retarray->dim[n], 0, extent[n] - 1, str);
450 1.1 mrg
451 1.1 mrg }
452 1.1 mrg
453 1.1 mrg retarray->offset = 0;
454 1.1 mrg retarray->dtype.rank = rank;
455 1.1 mrg
456 1.1 mrg alloc_size = GFC_DESCRIPTOR_STRIDE(retarray,rank-1) * extent[rank-1];
457 1.1 mrg
458 1.1 mrg if (alloc_size == 0)
459 1.1 mrg {
460 1.1 mrg /* Make sure we have a zero-sized array. */
461 1.1 mrg GFC_DIMENSION_SET(retarray->dim[0], 0, -1, 1);
462 1.1 mrg return;
463 1.1 mrg }
464 1.1 mrg else
465 1.1 mrg retarray->base_addr = xmallocarray (alloc_size, sizeof (rtype_name));
466 1.1 mrg }
467 1.1 mrg else
468 1.1 mrg {
469 1.1 mrg if (rank != GFC_DESCRIPTOR_RANK (retarray))
470 1.1 mrg runtime_error ("rank of return array incorrect in"
471 1.1 mrg " u_name intrinsic: is %ld, should be %ld",
472 1.1 mrg (long int) (GFC_DESCRIPTOR_RANK (retarray)),
473 1.1 mrg (long int) rank);
474 1.1 mrg
475 1.1 mrg if (unlikely (compile_options.bounds_check))
476 1.1 mrg {
477 1.1 mrg for (n=0; n < rank; n++)
478 1.1 mrg {
479 1.1 mrg index_type ret_extent;
480 1.1 mrg
481 1.1 mrg ret_extent = GFC_DESCRIPTOR_EXTENT(retarray,n);
482 1.1 mrg if (extent[n] != ret_extent)
483 1.1 mrg runtime_error ("Incorrect extent in return value of"
484 1.1 mrg " u_name intrinsic in dimension %ld:"
485 1.1 mrg " is %ld, should be %ld", (long int) n + 1,
486 1.1 mrg (long int) ret_extent, (long int) extent[n]);
487 1.1 mrg }
488 1.1 mrg }
489 1.1 mrg }
490 1.1 mrg
491 1.1 mrg for (n = 0; n < rank; n++)
492 1.1 mrg {
493 1.1 mrg count[n] = 0;
494 1.1 mrg dstride[n] = GFC_DESCRIPTOR_STRIDE(retarray,n);
495 1.1 mrg }
496 1.1 mrg
497 1.1 mrg dest = retarray->base_addr;
498 1.1 mrg
499 1.1 mrg while(1)
500 1.1 mrg {
501 1.1 mrg *dest = '$1`;
502 1.1 mrg count[0]++;
503 1.1 mrg dest += dstride[0];
504 1.1 mrg n = 0;
505 1.1 mrg while (count[n] == extent[n])
506 1.1 mrg {
507 1.1 mrg /* When we get to the end of a dimension, reset it and increment
508 1.1 mrg the next dimension. */
509 1.1 mrg count[n] = 0;
510 1.1 mrg /* We could precalculate these products, but this is a less
511 1.1 mrg frequently used path so probably not worth it. */
512 1.1 mrg dest -= dstride[n] * extent[n];
513 1.1 mrg n++;
514 1.1 mrg if (n >= rank)
515 1.1 mrg return;
516 1.1 mrg else
517 1.1 mrg {
518 1.1 mrg count[n]++;
519 1.1 mrg dest += dstride[n];
520 1.1 mrg }
521 1.1 mrg }
522 1.1 mrg }
523 1.1 mrg }')dnl
524 1.1 mrg define(ARRAY_FUNCTION,
525 1.1 mrg `START_ARRAY_FUNCTION
526 1.1 mrg $2
527 1.1 mrg START_ARRAY_BLOCK($1)
528 1.1 mrg $3
529 1.1 mrg FINISH_ARRAY_FUNCTION($4)')dnl
530 1.1 mrg define(MASKED_ARRAY_FUNCTION,
531 1.1 mrg `START_MASKED_ARRAY_FUNCTION
532 1.1 mrg $2
533 1.1 mrg START_MASKED_ARRAY_BLOCK
534 1.1 mrg $3
535 1.1 mrg FINISH_MASKED_ARRAY_FUNCTION')dnl
536