]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgfortran/generated/eoshift3_4.c
Update copyright years.
[thirdparty/gcc.git] / libgfortran / generated / eoshift3_4.c
CommitLineData
6de9cd9a 1/* Implementation of the EOSHIFT intrinsic
a945c346 2 Copyright (C) 2002-2024 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"
6de9cd9a 27#include <string.h>
36ae8a61 28
6de9cd9a 29
644cb69f
FXC
30#if defined (HAVE_GFC_INTEGER_4)
31
7823229b 32static void
64acfd99
JB
33eoshift3 (gfc_array_char * const restrict ret,
34 const gfc_array_char * const restrict array,
35 const gfc_array_i4 * const restrict h,
36 const gfc_array_char * const restrict bound,
37 const GFC_INTEGER_4 * const restrict pwhich,
dfb55fdc 38 const char * filler, index_type filler_len)
6de9cd9a
DN
39{
40 /* r.* indicates the return array. */
e33e218b 41 index_type rstride[GFC_MAX_DIMENSIONS];
6de9cd9a
DN
42 index_type rstride0;
43 index_type roffset;
44 char *rptr;
5863aacf 45 char * restrict dest;
6de9cd9a 46 /* s.* indicates the source array. */
e33e218b 47 index_type sstride[GFC_MAX_DIMENSIONS];
6de9cd9a
DN
48 index_type sstride0;
49 index_type soffset;
50 const char *sptr;
51 const char *src;
52 /* h.* indicates the shift array. */
e33e218b 53 index_type hstride[GFC_MAX_DIMENSIONS];
6de9cd9a
DN
54 index_type hstride0;
55 const GFC_INTEGER_4 *hptr;
56 /* b.* indicates the bound array. */
e33e218b 57 index_type bstride[GFC_MAX_DIMENSIONS];
6de9cd9a
DN
58 index_type bstride0;
59 const char *bptr;
60
e33e218b
TK
61 index_type count[GFC_MAX_DIMENSIONS];
62 index_type extent[GFC_MAX_DIMENSIONS];
6de9cd9a 63 index_type dim;
6de9cd9a
DN
64 index_type len;
65 index_type n;
dfb55fdc 66 index_type size;
16bff921 67 index_type arraysize;
6de9cd9a
DN
68 int which;
69 GFC_INTEGER_4 sh;
70 GFC_INTEGER_4 delta;
71
7672ae20
AJ
72 /* The compiler cannot figure out that these are set, initialize
73 them to avoid warnings. */
74 len = 0;
75 soffset = 0;
76 roffset = 0;
77
16bff921 78 arraysize = size0 ((array_t *) array);
dfb55fdc
TK
79 size = GFC_DESCRIPTOR_SIZE(array);
80
6de9cd9a
DN
81 if (pwhich)
82 which = *pwhich - 1;
83 else
84 which = 0;
85
21d1335b 86 if (ret->base_addr == NULL)
0e6d033b 87 {
92e6f3a4 88 ret->base_addr = xmallocarray (arraysize, size);
efd4dc1a 89 ret->offset = 0;
fa3c4d47 90 GFC_DTYPE_COPY(ret,array);
7a157266 91 for (index_type i = 0; i < GFC_DESCRIPTOR_RANK (array); i++)
0e6d033b 92 {
dfb55fdc
TK
93 index_type ub, str;
94
95 ub = GFC_DESCRIPTOR_EXTENT(array,i) - 1;
0e6d033b
TK
96
97 if (i == 0)
dfb55fdc 98 str = 1;
0e6d033b 99 else
dfb55fdc
TK
100 str = GFC_DESCRIPTOR_EXTENT(ret,i-1)
101 * GFC_DESCRIPTOR_STRIDE(ret,i-1);
102
103 GFC_DIMENSION_SET(ret->dim[i], 0, ub, str);
104
0e6d033b 105 }
92e6f3a4
JB
106 /* xmallocarray allocates a single byte for zero size. */
107 ret->base_addr = xmallocarray (arraysize, size);
16bff921 108
0e6d033b 109 }
16bff921
TK
110 else if (unlikely (compile_options.bounds_check))
111 {
112 bounds_equal_extents ((array_t *) ret, (array_t *) array,
113 "return value", "EOSHIFT");
114 }
115
116 if (unlikely (compile_options.bounds_check))
c44109aa 117 {
16bff921
TK
118 bounds_reduced_extents ((array_t *) h, (array_t *) array, which,
119 "SHIFT argument", "EOSHIFT");
c44109aa 120 }
0e6d033b 121
16bff921
TK
122 if (arraysize == 0)
123 return;
6de9cd9a
DN
124
125 extent[0] = 1;
126 count[0] = 0;
6de9cd9a
DN
127 n = 0;
128 for (dim = 0; dim < GFC_DESCRIPTOR_RANK (array); dim++)
129 {
130 if (dim == which)
131 {
dfb55fdc 132 roffset = GFC_DESCRIPTOR_STRIDE_BYTES(ret,dim);
6de9cd9a
DN
133 if (roffset == 0)
134 roffset = size;
dfb55fdc 135 soffset = GFC_DESCRIPTOR_STRIDE_BYTES(array,dim);
6de9cd9a
DN
136 if (soffset == 0)
137 soffset = size;
dfb55fdc 138 len = GFC_DESCRIPTOR_EXTENT(array,dim);
6de9cd9a
DN
139 }
140 else
141 {
142 count[n] = 0;
dfb55fdc
TK
143 extent[n] = GFC_DESCRIPTOR_EXTENT(array,dim);
144 rstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(ret,dim);
145 sstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(array,dim);
6de9cd9a 146
dfb55fdc 147 hstride[n] = GFC_DESCRIPTOR_STRIDE(h,n);
6de9cd9a 148 if (bound)
dfb55fdc 149 bstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(bound,n);
6de9cd9a
DN
150 else
151 bstride[n] = 0;
152 n++;
153 }
154 }
155 if (sstride[0] == 0)
156 sstride[0] = size;
157 if (rstride[0] == 0)
158 rstride[0] = size;
159 if (hstride[0] == 0)
160 hstride[0] = 1;
161 if (bound && bstride[0] == 0)
162 bstride[0] = size;
163
164 dim = GFC_DESCRIPTOR_RANK (array);
165 rstride0 = rstride[0];
166 sstride0 = sstride[0];
167 hstride0 = hstride[0];
168 bstride0 = bstride[0];
21d1335b
TB
169 rptr = ret->base_addr;
170 sptr = array->base_addr;
171 hptr = h->base_addr;
6de9cd9a 172 if (bound)
21d1335b 173 bptr = bound->base_addr;
6de9cd9a 174 else
7823229b 175 bptr = NULL;
6de9cd9a
DN
176
177 while (rptr)
178 {
179 /* Do the shift for this dimension. */
180 sh = *hptr;
47b3a403
TK
181 if (( sh >= 0 ? sh : -sh ) > len)
182 {
183 delta = len;
184 sh = len;
185 }
186 else
187 delta = (sh >= 0) ? sh: -sh;
188
6de9cd9a
DN
189 if (sh > 0)
190 {
191 src = &sptr[delta * soffset];
192 dest = rptr;
193 }
194 else
195 {
196 src = sptr;
197 dest = &rptr[delta * roffset];
198 }
ba71a2a6
TK
199
200 /* If the elements are contiguous, perform a single block move. */
201 if (soffset == size && roffset == size)
202 {
203 size_t chunk = size * (len - delta);
204 memcpy (dest, src, chunk);
205 dest += chunk;
206 }
207 else
208 {
209 for (n = 0; n < len - delta; n++)
210 {
211 memcpy (dest, src, size);
212 dest += roffset;
213 src += soffset;
214 }
215 }
216
6de9cd9a
DN
217 if (sh < 0)
218 dest = rptr;
219 n = delta;
220
7823229b
RS
221 if (bptr)
222 while (n--)
223 {
224 memcpy (dest, bptr, size);
225 dest += roffset;
226 }
227 else
228 while (n--)
229 {
691da334
FXC
230 index_type i;
231
232 if (filler_len == 1)
233 memset (dest, filler[0], size);
234 else
235 for (i = 0; i < size; i += filler_len)
236 memcpy (&dest[i], filler, filler_len);
237
7823229b
RS
238 dest += roffset;
239 }
6de9cd9a
DN
240
241 /* Advance to the next section. */
242 rptr += rstride0;
243 sptr += sstride0;
244 hptr += hstride0;
245 bptr += bstride0;
246 count[0]++;
247 n = 0;
248 while (count[n] == extent[n])
249 {
250 /* When we get to the end of a dimension, reset it and increment
251 the next dimension. */
252 count[n] = 0;
253 /* We could precalculate these products, but this is a less
5d7adf7a 254 frequently used path so probably not worth it. */
6de9cd9a
DN
255 rptr -= rstride[n] * extent[n];
256 sptr -= sstride[n] * extent[n];
257 hptr -= hstride[n] * extent[n];
258 bptr -= bstride[n] * extent[n];
259 n++;
260 if (n >= dim - 1)
261 {
262 /* Break out of the loop. */
263 rptr = NULL;
264 break;
265 }
266 else
267 {
268 count[n]++;
269 rptr += rstride[n];
270 sptr += sstride[n];
271 hptr += hstride[n];
272 bptr += bstride[n];
273 }
274 }
275 }
276}
7823229b 277
64acfd99
JB
278extern void eoshift3_4 (gfc_array_char * const restrict,
279 const gfc_array_char * const restrict,
280 const gfc_array_i4 * const restrict,
281 const gfc_array_char * const restrict,
282 const GFC_INTEGER_4 *);
7823229b
RS
283export_proto(eoshift3_4);
284
285void
64acfd99
JB
286eoshift3_4 (gfc_array_char * const restrict ret,
287 const gfc_array_char * const restrict array,
288 const gfc_array_i4 * const restrict h,
289 const gfc_array_char * const restrict bound,
290 const GFC_INTEGER_4 * const restrict pwhich)
7823229b 291{
dfb55fdc 292 eoshift3 (ret, array, h, bound, pwhich, "\0", 1);
7823229b
RS
293}
294
691da334 295
64acfd99
JB
296extern void eoshift3_4_char (gfc_array_char * const restrict,
297 GFC_INTEGER_4,
298 const gfc_array_char * const restrict,
299 const gfc_array_i4 * const restrict,
300 const gfc_array_char * const restrict,
301 const GFC_INTEGER_4 * const restrict,
302 GFC_INTEGER_4, GFC_INTEGER_4);
7823229b
RS
303export_proto(eoshift3_4_char);
304
305void
64acfd99
JB
306eoshift3_4_char (gfc_array_char * const restrict ret,
307 GFC_INTEGER_4 ret_length __attribute__((unused)),
308 const gfc_array_char * const restrict array,
309 const gfc_array_i4 * const restrict h,
310 const gfc_array_char * const restrict bound,
311 const GFC_INTEGER_4 * const restrict pwhich,
dfb55fdc 312 GFC_INTEGER_4 array_length __attribute__((unused)),
64acfd99 313 GFC_INTEGER_4 bound_length __attribute__((unused)))
7823229b 314{
dfb55fdc 315 eoshift3 (ret, array, h, bound, pwhich, " ", 1);
691da334
FXC
316}
317
318
319extern void eoshift3_4_char4 (gfc_array_char * const restrict,
320 GFC_INTEGER_4,
321 const gfc_array_char * const restrict,
322 const gfc_array_i4 * const restrict,
323 const gfc_array_char * const restrict,
324 const GFC_INTEGER_4 * const restrict,
325 GFC_INTEGER_4, GFC_INTEGER_4);
326export_proto(eoshift3_4_char4);
327
328void
329eoshift3_4_char4 (gfc_array_char * const restrict ret,
330 GFC_INTEGER_4 ret_length __attribute__((unused)),
331 const gfc_array_char * const restrict array,
332 const gfc_array_i4 * const restrict h,
333 const gfc_array_char * const restrict bound,
334 const GFC_INTEGER_4 * const restrict pwhich,
dfb55fdc 335 GFC_INTEGER_4 array_length __attribute__((unused)),
691da334
FXC
336 GFC_INTEGER_4 bound_length __attribute__((unused)))
337{
338 static const gfc_char4_t space = (unsigned char) ' ';
dfb55fdc 339 eoshift3 (ret, array, h, bound, pwhich,
691da334 340 (const char *) &space, sizeof (gfc_char4_t));
7823229b 341}
644cb69f
FXC
342
343#endif