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.
6 dnl Pass the implementation for a single section as the parameter to
7 dnl {MASK_}ARRAY_FUNCTION.
8 dnl The variables base, delta, and len describe the input section.
9 dnl For masked section the mask is described by mbase and mdelta.
10 dnl These should not be modified. The result should be stored in *dest.
11 dnl The names count, extent, sstride, dstride, base, dest, rank, dim
12 dnl retarray, array, pdim and mstride should not be used.
13 dnl The variable n is declared as index_type and may be used.
14 dnl Other variable declarations may be placed at the start of the code,
15 dnl The types of the array parameter and the return value are
16 dnl atype_name and rtype_name respectively.
17 dnl Execution should be allowed to continue to the end of the block.
18 dnl You should not return or break from the inner loop of the implementation.
19 dnl Care should also be taken to avoid using the names defined in iparm.m4
20 define(START_ARRAY_FUNCTION,
22 extern void name`'rtype_qual`_'atype_code (rtype * const restrict,
23 atype * const restrict, const index_type * const restrict);
24 export_proto(name`'rtype_qual`_'atype_code);
27 name`'rtype_qual`_'atype_code (rtype * const restrict retarray,
28 atype * const restrict array,
29 const index_type * const restrict pdim)
31 index_type count[GFC_MAX_DIMENSIONS];
32 index_type extent[GFC_MAX_DIMENSIONS];
33 index_type sstride[GFC_MAX_DIMENSIONS];
34 index_type dstride[GFC_MAX_DIMENSIONS];
35 const atype_name * restrict base;
36 rtype_name * restrict dest;
44 /* Make dim zero based to avoid confusion. */
46 rank = GFC_DESCRIPTOR_RANK (array) - 1;
48 len = GFC_DESCRIPTOR_EXTENT(array,dim);
51 delta = GFC_DESCRIPTOR_STRIDE(array,dim);
53 for (n = 0; n < dim; n++)
55 sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n);
56 extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
61 for (n = dim; n < rank; n++)
63 sstride[n] = GFC_DESCRIPTOR_STRIDE(array, n + 1);
64 extent[n] = GFC_DESCRIPTOR_EXTENT(array, n + 1);
70 if (retarray->data == NULL)
72 size_t alloc_size, str;
74 for (n = 0; n < rank; n++)
79 str = GFC_DESCRIPTOR_STRIDE(retarray,n-1) * extent[n-1];
81 GFC_DIMENSION_SET(retarray->dim[n], 0, extent[n] - 1, str);
86 retarray->dtype = (array->dtype & ~GFC_DTYPE_RANK_MASK) | rank;
88 alloc_size = sizeof (rtype_name) * GFC_DESCRIPTOR_STRIDE(retarray,rank-1)
93 /* Make sure we have a zero-sized array. */
94 GFC_DIMENSION_SET(retarray->dim[0], 0, -1, 1);
99 retarray->data = internal_malloc_size (alloc_size);
103 if (rank != GFC_DESCRIPTOR_RANK (retarray))
104 runtime_error ("rank of return array incorrect in"
105 " u_name intrinsic: is %ld, should be %ld",
106 (long int) (GFC_DESCRIPTOR_RANK (retarray)),
109 if (unlikely (compile_options.bounds_check))
111 for (n=0; n < rank; n++)
113 index_type ret_extent;
115 ret_extent = GFC_DESCRIPTOR_EXTENT(retarray,n);
116 if (extent[n] != ret_extent)
117 runtime_error ("Incorrect extent in return value of"
118 " u_name intrinsic in dimension %ld:"
119 " is %ld, should be %ld", (long int) n + 1,
120 (long int) ret_extent, (long int) extent[n]);
125 for (n = 0; n < rank; n++)
128 dstride[n] = GFC_DESCRIPTOR_STRIDE(retarray,n);
134 dest = retarray->data;
137 while (continue_loop)
139 const atype_name * restrict src;
144 define(START_ARRAY_BLOCK,
149 for (n = 0; n < len; n++, src += delta)
152 define(FINISH_ARRAY_FUNCTION,
157 /* Advance to the next element. */
162 while (count[n] == extent[n])
164 /* When we get to the end of a dimension, reset it and increment
165 the next dimension. */
167 /* We could precalculate these products, but this is a less
168 frequently used path so probably not worth it. */
169 base -= sstride[n] * extent[n];
170 dest -= dstride[n] * extent[n];
174 /* Break out of the look. */
187 define(START_MASKED_ARRAY_FUNCTION,
189 extern void `m'name`'rtype_qual`_'atype_code (rtype * const restrict,
190 atype * const restrict, const index_type * const restrict,
191 gfc_array_l1 * const restrict);
192 export_proto(`m'name`'rtype_qual`_'atype_code);
195 `m'name`'rtype_qual`_'atype_code (rtype * const restrict retarray,
196 atype * const restrict array,
197 const index_type * const restrict pdim,
198 gfc_array_l1 * const restrict mask)
200 index_type count[GFC_MAX_DIMENSIONS];
201 index_type extent[GFC_MAX_DIMENSIONS];
202 index_type sstride[GFC_MAX_DIMENSIONS];
203 index_type dstride[GFC_MAX_DIMENSIONS];
204 index_type mstride[GFC_MAX_DIMENSIONS];
205 rtype_name * restrict dest;
206 const atype_name * restrict base;
207 const GFC_LOGICAL_1 * restrict mbase;
217 rank = GFC_DESCRIPTOR_RANK (array) - 1;
219 len = GFC_DESCRIPTOR_EXTENT(array,dim);
225 mask_kind = GFC_DESCRIPTOR_SIZE (mask);
227 if (mask_kind == 1 || mask_kind == 2 || mask_kind == 4 || mask_kind == 8
228 #ifdef HAVE_GFC_LOGICAL_16
232 mbase = GFOR_POINTER_TO_L1 (mbase, mask_kind);
234 runtime_error ("Funny sized logical array");
236 delta = GFC_DESCRIPTOR_STRIDE(array,dim);
237 mdelta = GFC_DESCRIPTOR_STRIDE_BYTES(mask,dim);
239 for (n = 0; n < dim; n++)
241 sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n);
242 mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask,n);
243 extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
249 for (n = dim; n < rank; n++)
251 sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n + 1);
252 mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask, n + 1);
253 extent[n] = GFC_DESCRIPTOR_EXTENT(array, n + 1);
259 if (retarray->data == NULL)
261 size_t alloc_size, str;
263 for (n = 0; n < rank; n++)
268 str= GFC_DESCRIPTOR_STRIDE(retarray,n-1) * extent[n-1];
270 GFC_DIMENSION_SET(retarray->dim[n], 0, extent[n] - 1, str);
274 alloc_size = sizeof (rtype_name) * GFC_DESCRIPTOR_STRIDE(retarray,rank-1)
277 retarray->offset = 0;
278 retarray->dtype = (array->dtype & ~GFC_DTYPE_RANK_MASK) | rank;
282 /* Make sure we have a zero-sized array. */
283 GFC_DIMENSION_SET(retarray->dim[0], 0, -1, 1);
287 retarray->data = internal_malloc_size (alloc_size);
292 if (rank != GFC_DESCRIPTOR_RANK (retarray))
293 runtime_error ("rank of return array incorrect in u_name intrinsic");
295 if (unlikely (compile_options.bounds_check))
297 for (n=0; n < rank; n++)
299 index_type ret_extent;
301 ret_extent = GFC_DESCRIPTOR_EXTENT(retarray,n);
302 if (extent[n] != ret_extent)
303 runtime_error ("Incorrect extent in return value of"
304 " u_name intrinsic in dimension %ld:"
305 " is %ld, should be %ld", (long int) n + 1,
306 (long int) ret_extent, (long int) extent[n]);
308 for (n=0; n<= rank; n++)
310 index_type mask_extent, array_extent;
312 array_extent = GFC_DESCRIPTOR_EXTENT(array,n);
313 mask_extent = GFC_DESCRIPTOR_EXTENT(mask,n);
314 if (array_extent != mask_extent)
315 runtime_error ("Incorrect extent in MASK argument of"
316 " u_name intrinsic in dimension %ld:"
317 " is %ld, should be %ld", (long int) n + 1,
318 (long int) mask_extent, (long int) array_extent);
323 for (n = 0; n < rank; n++)
326 dstride[n] = GFC_DESCRIPTOR_STRIDE(retarray,n);
331 dest = retarray->data;
336 const atype_name * restrict src;
337 const GFC_LOGICAL_1 * restrict msrc;
343 define(START_MASKED_ARRAY_BLOCK,
348 for (n = 0; n < len; n++, src += delta, msrc += mdelta)
351 define(FINISH_MASKED_ARRAY_FUNCTION,
356 /* Advance to the next element. */
362 while (count[n] == extent[n])
364 /* When we get to the end of a dimension, reset it and increment
365 the next dimension. */
367 /* We could precalculate these products, but this is a less
368 frequently used path so probably not worth it. */
369 base -= sstride[n] * extent[n];
370 mbase -= mstride[n] * extent[n];
371 dest -= dstride[n] * extent[n];
375 /* Break out of the look. */
389 define(SCALAR_ARRAY_FUNCTION,
391 extern void `s'name`'rtype_qual`_'atype_code (rtype * const restrict,
392 atype * const restrict, const index_type * const restrict,
394 export_proto(`s'name`'rtype_qual`_'atype_code);
397 `s'name`'rtype_qual`_'atype_code (rtype * const restrict retarray,
398 atype * const restrict array,
399 const index_type * const restrict pdim,
400 GFC_LOGICAL_4 * mask)
402 index_type count[GFC_MAX_DIMENSIONS];
403 index_type extent[GFC_MAX_DIMENSIONS];
404 index_type sstride[GFC_MAX_DIMENSIONS];
405 index_type dstride[GFC_MAX_DIMENSIONS];
406 rtype_name * restrict dest;
414 name`'rtype_qual`_'atype_code (retarray, array, pdim);
417 /* Make dim zero based to avoid confusion. */
419 rank = GFC_DESCRIPTOR_RANK (array) - 1;
421 for (n = 0; n < dim; n++)
423 sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n);
424 extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
430 for (n = dim; n < rank; n++)
432 sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n + 1);
434 GFC_DESCRIPTOR_EXTENT(array,n + 1);
440 if (retarray->data == NULL)
442 size_t alloc_size, str;
444 for (n = 0; n < rank; n++)
449 str = GFC_DESCRIPTOR_STRIDE(retarray,n-1) * extent[n-1];
451 GFC_DIMENSION_SET(retarray->dim[n], 0, extent[n] - 1, str);
455 retarray->offset = 0;
456 retarray->dtype = (array->dtype & ~GFC_DTYPE_RANK_MASK) | rank;
458 alloc_size = sizeof (rtype_name) * GFC_DESCRIPTOR_STRIDE(retarray,rank-1)
463 /* Make sure we have a zero-sized array. */
464 GFC_DIMENSION_SET(retarray->dim[0], 0, -1, 1);
468 retarray->data = internal_malloc_size (alloc_size);
472 if (rank != GFC_DESCRIPTOR_RANK (retarray))
473 runtime_error ("rank of return array incorrect in"
474 " u_name intrinsic: is %ld, should be %ld",
475 (long int) (GFC_DESCRIPTOR_RANK (retarray)),
478 if (unlikely (compile_options.bounds_check))
480 for (n=0; n < rank; n++)
482 index_type ret_extent;
484 ret_extent = GFC_DESCRIPTOR_EXTENT(retarray,n);
485 if (extent[n] != ret_extent)
486 runtime_error ("Incorrect extent in return value of"
487 " u_name intrinsic in dimension %ld:"
488 " is %ld, should be %ld", (long int) n + 1,
489 (long int) ret_extent, (long int) extent[n]);
494 for (n = 0; n < rank; n++)
497 dstride[n] = GFC_DESCRIPTOR_STRIDE(retarray,n);
500 dest = retarray->data;
508 while (count[n] == extent[n])
510 /* When we get to the end of a dimension, reset it and increment
511 the next dimension. */
513 /* We could precalculate these products, but this is a less
514 frequently used path so probably not worth it. */
515 dest -= dstride[n] * extent[n];
527 define(ARRAY_FUNCTION,
528 `START_ARRAY_FUNCTION
530 START_ARRAY_BLOCK($1)
532 FINISH_ARRAY_FUNCTION')dnl
533 define(MASKED_ARRAY_FUNCTION,
534 `START_MASKED_ARRAY_FUNCTION
536 START_MASKED_ARRAY_BLOCK($1)
538 FINISH_MASKED_ARRAY_FUNCTION')dnl