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 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 gfc_array_l1 * 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 gfc_array_l1 * 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 GFC_LOGICAL_1 * restrict base;
36 rtype_name * restrict dest;
45 /* Make dim zero based to avoid confusion. */
47 rank = GFC_DESCRIPTOR_RANK (array) - 1;
49 src_kind = GFC_DESCRIPTOR_SIZE (array);
51 len = GFC_DESCRIPTOR_EXTENT(array,dim);
55 delta = GFC_DESCRIPTOR_STRIDE_BYTES(array,dim);
57 for (n = 0; n < dim; n++)
59 sstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(array,n);
60 extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
65 for (n = dim; n < rank; n++)
67 sstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(array,n + 1);
68 extent[n] = GFC_DESCRIPTOR_EXTENT(array,n + 1);
74 if (retarray->base_addr == NULL)
76 size_t alloc_size, str;
78 for (n = 0; n < rank; n++)
83 str = GFC_DESCRIPTOR_STRIDE(retarray,n-1) * extent[n-1];
85 GFC_DIMENSION_SET(retarray->dim[n], 0, extent[n] - 1, str);
90 retarray->dtype.rank = rank;
92 alloc_size = GFC_DESCRIPTOR_STRIDE(retarray,rank-1) * extent[rank-1];
96 /* Make sure we have a zero-sized array. */
97 GFC_DIMENSION_SET(retarray->dim[0], 0, -1, 1);
101 retarray->base_addr = xmallocarray (alloc_size, sizeof (rtype_name));
105 if (rank != GFC_DESCRIPTOR_RANK (retarray))
106 runtime_error ("rank of return array incorrect in"
107 " u_name intrinsic: is %ld, should be %ld",
108 (long int) GFC_DESCRIPTOR_RANK (retarray),
111 if (unlikely (compile_options.bounds_check))
113 for (n=0; n < rank; n++)
115 index_type ret_extent;
117 ret_extent = GFC_DESCRIPTOR_EXTENT(retarray,n);
118 if (extent[n] != ret_extent)
119 runtime_error ("Incorrect extent in return value of"
120 " u_name intrinsic in dimension %d:"
121 " is %ld, should be %ld", (int) n + 1,
122 (long int) ret_extent, (long int) extent[n]);
127 for (n = 0; n < rank; n++)
130 dstride[n] = GFC_DESCRIPTOR_STRIDE(retarray,n);
135 base = array->base_addr;
137 if (src_kind == 1 || src_kind == 2 || src_kind == 4 || src_kind == 8
138 #ifdef HAVE_GFC_LOGICAL_16
144 base = GFOR_POINTER_TO_L1 (base, src_kind);
147 internal_error (NULL, "Funny sized logical array in u_name intrinsic");
149 dest = retarray->base_addr;
152 while (continue_loop)
154 const GFC_LOGICAL_1 * restrict src;
159 define(START_ARRAY_BLOCK,
164 for (n = 0; n < len; n++, src += delta)
167 define(FINISH_ARRAY_FUNCTION,
172 /* Advance to the next element. */
177 while (count[n] == extent[n])
179 /* When we get to the end of a dimension, reset it and increment
180 the next dimension. */
182 /* We could precalculate these products, but this is a less
183 frequently used path so probably not worth it. */
184 base -= sstride[n] * extent[n];
185 dest -= dstride[n] * extent[n];
189 /* Break out of the loop. */
202 define(ARRAY_FUNCTION,
203 `START_ARRAY_FUNCTION
205 START_ARRAY_BLOCK($1)
207 FINISH_ARRAY_FUNCTION')dnl