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