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