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