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