]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgfortran/m4/eoshift1.m4
Update copyright years.
[thirdparty/gcc.git] / libgfortran / m4 / eoshift1.m4
CommitLineData
6de9cd9a 1`/* Implementation of the EOSHIFT intrinsic
83ffe9cd 2 Copyright (C) 2002-2023 Free Software Foundation, Inc.
6de9cd9a
DN
3 Contributed by Paul Brook <paul@nowt.org>
4
21d1335b 5This file is part of the GNU Fortran runtime library (libgfortran).
6de9cd9a 6
57dea9f6
TM
7Libgfortran is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public
6de9cd9a 9License as published by the Free Software Foundation; either
748086b7 10version 3 of the License, or (at your option) any later version.
57dea9f6
TM
11
12Libgfortran is distributed in the hope that it will be useful,
6de9cd9a
DN
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
57dea9f6 15GNU General Public License for more details.
6de9cd9a 16
748086b7
JJ
17Under Section 7 of GPL version 3, you are granted additional
18permissions described in the GCC Runtime Library Exception, version
193.1, as published by the Free Software Foundation.
20
21You should have received a copy of the GNU General Public License and
22a copy of the GCC Runtime Library Exception along with this program;
23see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24<http://www.gnu.org/licenses/>. */
6de9cd9a 25
36ae8a61 26#include "libgfortran.h"
36ae8a61
FXC
27#include <string.h>'
28
c9e66eda 29include(iparm.m4)dnl
6de9cd9a 30
adea5e16 31`#if defined (HAVE_'atype_name`)
644cb69f 32
7823229b 33static void
64acfd99
JB
34eoshift1 (gfc_array_char * const restrict ret,
35 const gfc_array_char * const restrict array,
adea5e16 36 const 'atype` * const restrict h,
64acfd99 37 const char * const restrict pbound,
adea5e16 38 const 'atype_name` * const restrict pwhich,
dfb55fdc 39 const char * filler, index_type filler_len)
6de9cd9a
DN
40{
41 /* r.* indicates the return array. */
e33e218b 42 index_type rstride[GFC_MAX_DIMENSIONS];
6de9cd9a
DN
43 index_type rstride0;
44 index_type roffset;
45 char *rptr;
5863aacf 46 char * restrict dest;
6de9cd9a 47 /* s.* indicates the source array. */
e33e218b 48 index_type sstride[GFC_MAX_DIMENSIONS];
6de9cd9a
DN
49 index_type sstride0;
50 index_type soffset;
51 const char *sptr;
52 const char *src;
adea5e16 53 /* h.* indicates the shift array. */
e33e218b 54 index_type hstride[GFC_MAX_DIMENSIONS];
6de9cd9a 55 index_type hstride0;
adea5e16 56 const 'atype_name` *hptr;
6de9cd9a 57
e33e218b
TK
58 index_type count[GFC_MAX_DIMENSIONS];
59 index_type extent[GFC_MAX_DIMENSIONS];
6de9cd9a 60 index_type dim;
6de9cd9a
DN
61 index_type len;
62 index_type n;
dfb55fdc 63 index_type size;
16bff921 64 index_type arraysize;
6de9cd9a 65 int which;
adea5e16
TK
66 'atype_name` sh;
67 'atype_name` delta;
6de9cd9a 68
7672ae20
AJ
69 /* The compiler cannot figure out that these are set, initialize
70 them to avoid warnings. */
71 len = 0;
72 soffset = 0;
73 roffset = 0;
74
dfb55fdc
TK
75 size = GFC_DESCRIPTOR_SIZE(array);
76
6de9cd9a
DN
77 if (pwhich)
78 which = *pwhich - 1;
79 else
80 which = 0;
81
6de9cd9a
DN
82 extent[0] = 1;
83 count[0] = 0;
0e6d033b 84
16bff921 85 arraysize = size0 ((array_t *) array);
21d1335b 86 if (ret->base_addr == NULL)
0e6d033b 87 {
efd4dc1a 88 ret->offset = 0;
fa3c4d47 89 GFC_DTYPE_COPY(ret,array);
7a157266 90 for (index_type i = 0; i < GFC_DESCRIPTOR_RANK (array); i++)
0e6d033b 91 {
dfb55fdc
TK
92 index_type ub, str;
93
94 ub = GFC_DESCRIPTOR_EXTENT(array,i) - 1;
0e6d033b
TK
95
96 if (i == 0)
dfb55fdc 97 str = 1;
0e6d033b 98 else
dfb55fdc
TK
99 str = GFC_DESCRIPTOR_EXTENT(ret,i-1)
100 * GFC_DESCRIPTOR_STRIDE(ret,i-1);
101
102 GFC_DIMENSION_SET(ret->dim[i], 0, ub, str);
103
0e6d033b 104 }
92e6f3a4
JB
105 /* xmallocarray allocates a single byte for zero size. */
106 ret->base_addr = xmallocarray (arraysize, size);
16bff921 107
0e6d033b 108 }
16bff921 109 else if (unlikely (compile_options.bounds_check))
c44109aa 110 {
16bff921
TK
111 bounds_equal_extents ((array_t *) ret, (array_t *) array,
112 "return value", "EOSHIFT");
c44109aa 113 }
0e6d033b 114
16bff921
TK
115 if (unlikely (compile_options.bounds_check))
116 {
117 bounds_reduced_extents ((array_t *) h, (array_t *) array, which,
118 "SHIFT argument", "EOSHIFT");
119 }
120
121 if (arraysize == 0)
122 return;
123
6de9cd9a
DN
124 n = 0;
125 for (dim = 0; dim < GFC_DESCRIPTOR_RANK (array); dim++)
126 {
127 if (dim == which)
128 {
dfb55fdc 129 roffset = GFC_DESCRIPTOR_STRIDE_BYTES(ret,dim);
6de9cd9a
DN
130 if (roffset == 0)
131 roffset = size;
dfb55fdc 132 soffset = GFC_DESCRIPTOR_STRIDE_BYTES(array,dim);
6de9cd9a
DN
133 if (soffset == 0)
134 soffset = size;
dfb55fdc 135 len = GFC_DESCRIPTOR_EXTENT(array,dim);
6de9cd9a
DN
136 }
137 else
138 {
139 count[n] = 0;
dfb55fdc
TK
140 extent[n] = GFC_DESCRIPTOR_EXTENT(array,dim);
141 rstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(ret,dim);
142 sstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(array,dim);
6de9cd9a 143
dfb55fdc 144 hstride[n] = GFC_DESCRIPTOR_STRIDE(h,n);
6de9cd9a
DN
145 n++;
146 }
147 }
148 if (sstride[0] == 0)
149 sstride[0] = size;
150 if (rstride[0] == 0)
151 rstride[0] = size;
152 if (hstride[0] == 0)
153 hstride[0] = 1;
154
155 dim = GFC_DESCRIPTOR_RANK (array);
156 rstride0 = rstride[0];
157 sstride0 = sstride[0];
158 hstride0 = hstride[0];
21d1335b
TB
159 rptr = ret->base_addr;
160 sptr = array->base_addr;
161 hptr = h->base_addr;
6de9cd9a
DN
162
163 while (rptr)
164 {
adea5e16 165 /* Do the shift for this dimension. */
6de9cd9a 166 sh = *hptr;
47b3a403
TK
167 if (( sh >= 0 ? sh : -sh ) > len)
168 {
169 delta = len;
170 sh = len;
171 }
172 else
173 delta = (sh >= 0) ? sh: -sh;
174
6de9cd9a
DN
175 if (sh > 0)
176 {
177 src = &sptr[delta * soffset];
178 dest = rptr;
179 }
180 else
181 {
182 src = sptr;
183 dest = &rptr[delta * roffset];
184 }
ba71a2a6
TK
185
186 /* If the elements are contiguous, perform a single block move. */
187 if (soffset == size && roffset == size)
188 {
189 size_t chunk = size * (len - delta);
190 memcpy (dest, src, chunk);
191 dest += chunk;
192 }
193 else
194 {
195 for (n = 0; n < len - delta; n++)
196 {
197 memcpy (dest, src, size);
198 dest += roffset;
199 src += soffset;
200 }
201 }
6de9cd9a
DN
202 if (sh < 0)
203 dest = rptr;
204 n = delta;
205
7823229b
RS
206 if (pbound)
207 while (n--)
208 {
209 memcpy (dest, pbound, size);
210 dest += roffset;
211 }
212 else
213 while (n--)
214 {
691da334
FXC
215 index_type i;
216
217 if (filler_len == 1)
218 memset (dest, filler[0], size);
219 else
220 for (i = 0; i < size; i += filler_len)
221 memcpy (&dest[i], filler, filler_len);
222
7823229b
RS
223 dest += roffset;
224 }
6de9cd9a
DN
225
226 /* Advance to the next section. */
227 rptr += rstride0;
228 sptr += sstride0;
229 hptr += hstride0;
230 count[0]++;
231 n = 0;
232 while (count[n] == extent[n])
233 {
234 /* When we get to the end of a dimension, reset it and increment
235 the next dimension. */
236 count[n] = 0;
237 /* We could precalculate these products, but this is a less
8b6dba81 238 frequently used path so probably not worth it. */
6de9cd9a
DN
239 rptr -= rstride[n] * extent[n];
240 sptr -= sstride[n] * extent[n];
241 hptr -= hstride[n] * extent[n];
242 n++;
243 if (n >= dim - 1)
244 {
245 /* Break out of the loop. */
246 rptr = NULL;
247 break;
248 }
249 else
250 {
251 count[n]++;
252 rptr += rstride[n];
253 sptr += sstride[n];
254 hptr += hstride[n];
255 }
256 }
257 }
258}
7823229b 259
adea5e16 260void eoshift1_'atype_kind` (gfc_array_char * const restrict,
64acfd99 261 const gfc_array_char * const restrict,
adea5e16
TK
262 const 'atype` * const restrict, const char * const restrict,
263 const 'atype_name` * const restrict);
264export_proto(eoshift1_'atype_kind`);
7823229b
RS
265
266void
adea5e16 267eoshift1_'atype_kind` (gfc_array_char * const restrict ret,
64acfd99 268 const gfc_array_char * const restrict array,
adea5e16 269 const 'atype` * const restrict h,
64acfd99 270 const char * const restrict pbound,
adea5e16 271 const 'atype_name` * const restrict pwhich)
7823229b 272{
dfb55fdc 273 eoshift1 (ret, array, h, pbound, pwhich, "\0", 1);
7823229b
RS
274}
275
691da334 276
adea5e16 277void eoshift1_'atype_kind`_char (gfc_array_char * const restrict,
64acfd99
JB
278 GFC_INTEGER_4,
279 const gfc_array_char * const restrict,
adea5e16 280 const 'atype` * const restrict,
64acfd99 281 const char * const restrict,
adea5e16 282 const 'atype_name` * const restrict,
64acfd99 283 GFC_INTEGER_4, GFC_INTEGER_4);
adea5e16 284export_proto(eoshift1_'atype_kind`_char);
7823229b
RS
285
286void
adea5e16 287eoshift1_'atype_kind`_char (gfc_array_char * const restrict ret,
64acfd99
JB
288 GFC_INTEGER_4 ret_length __attribute__((unused)),
289 const gfc_array_char * const restrict array,
adea5e16 290 const 'atype` * const restrict h,
64acfd99 291 const char * const restrict pbound,
adea5e16 292 const 'atype_name` * const restrict pwhich,
dfb55fdc 293 GFC_INTEGER_4 array_length __attribute__((unused)),
64acfd99 294 GFC_INTEGER_4 bound_length __attribute__((unused)))
7823229b 295{
dfb55fdc 296 eoshift1 (ret, array, h, pbound, pwhich, " ", 1);
691da334
FXC
297}
298
299
300void eoshift1_'atype_kind`_char4 (gfc_array_char * const restrict,
301 GFC_INTEGER_4,
302 const gfc_array_char * const restrict,
303 const 'atype` * const restrict,
304 const char * const restrict,
305 const 'atype_name` * const restrict,
306 GFC_INTEGER_4, GFC_INTEGER_4);
307export_proto(eoshift1_'atype_kind`_char4);
308
309void
310eoshift1_'atype_kind`_char4 (gfc_array_char * const restrict ret,
311 GFC_INTEGER_4 ret_length __attribute__((unused)),
312 const gfc_array_char * const restrict array,
313 const 'atype` * const restrict h,
314 const char * const restrict pbound,
315 const 'atype_name` * const restrict pwhich,
dfb55fdc 316 GFC_INTEGER_4 array_length __attribute__((unused)),
691da334
FXC
317 GFC_INTEGER_4 bound_length __attribute__((unused)))
318{
319 static const gfc_char4_t space = (unsigned char) ''` ''`;
dfb55fdc 320 eoshift1 (ret, array, h, pbound, pwhich,
691da334 321 (const char *) &space, sizeof (gfc_char4_t));
7823229b 322}
644cb69f 323
adea5e16 324#endif'