]> gcc.gnu.org Git - gcc.git/blame - libgfortran/m4/eoshift1.m4
re PR fortran/37577 ([meta-bug] change internal array descriptor format for better...
[gcc.git] / libgfortran / m4 / eoshift1.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
36eoshift1 (gfc_array_char * const restrict ret,
37 const gfc_array_char * const restrict array,
adea5e16 38 const 'atype` * const restrict h,
64acfd99 39 const char * const restrict pbound,
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
e33e218b
TK
60 index_type count[GFC_MAX_DIMENSIONS];
61 index_type extent[GFC_MAX_DIMENSIONS];
6de9cd9a 62 index_type dim;
6de9cd9a
DN
63 index_type len;
64 index_type n;
dfb55fdc 65 index_type size;
6de9cd9a 66 int which;
adea5e16
TK
67 'atype_name` sh;
68 'atype_name` delta;
6de9cd9a 69
7672ae20
AJ
70 /* The compiler cannot figure out that these are set, initialize
71 them to avoid warnings. */
72 len = 0;
73 soffset = 0;
74 roffset = 0;
75
dfb55fdc
TK
76 size = GFC_DESCRIPTOR_SIZE(array);
77
6de9cd9a
DN
78 if (pwhich)
79 which = *pwhich - 1;
80 else
81 which = 0;
82
6de9cd9a
DN
83 extent[0] = 1;
84 count[0] = 0;
0e6d033b
TK
85
86 if (ret->data == NULL)
87 {
88 int i;
89
90 ret->data = internal_malloc_size (size * size0 ((array_t *)array));
efd4dc1a 91 ret->offset = 0;
0e6d033b
TK
92 ret->dtype = array->dtype;
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
TK
107 }
108 }
c44109aa
TK
109 else
110 {
111 if (size0 ((array_t *) ret) == 0)
112 return;
113 }
0e6d033b 114
6de9cd9a
DN
115 n = 0;
116 for (dim = 0; dim < GFC_DESCRIPTOR_RANK (array); dim++)
117 {
118 if (dim == which)
119 {
dfb55fdc 120 roffset = GFC_DESCRIPTOR_STRIDE_BYTES(ret,dim);
6de9cd9a
DN
121 if (roffset == 0)
122 roffset = size;
dfb55fdc 123 soffset = GFC_DESCRIPTOR_STRIDE_BYTES(array,dim);
6de9cd9a
DN
124 if (soffset == 0)
125 soffset = size;
dfb55fdc 126 len = GFC_DESCRIPTOR_EXTENT(array,dim);
6de9cd9a
DN
127 }
128 else
129 {
130 count[n] = 0;
dfb55fdc
TK
131 extent[n] = GFC_DESCRIPTOR_EXTENT(array,dim);
132 rstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(ret,dim);
133 sstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(array,dim);
6de9cd9a 134
dfb55fdc 135 hstride[n] = GFC_DESCRIPTOR_STRIDE(h,n);
6de9cd9a
DN
136 n++;
137 }
138 }
139 if (sstride[0] == 0)
140 sstride[0] = size;
141 if (rstride[0] == 0)
142 rstride[0] = size;
143 if (hstride[0] == 0)
144 hstride[0] = 1;
145
146 dim = GFC_DESCRIPTOR_RANK (array);
147 rstride0 = rstride[0];
148 sstride0 = sstride[0];
149 hstride0 = hstride[0];
150 rptr = ret->data;
151 sptr = array->data;
152 hptr = h->data;
153
154 while (rptr)
155 {
adea5e16 156 /* Do the shift for this dimension. */
6de9cd9a 157 sh = *hptr;
47b3a403
TK
158 if (( sh >= 0 ? sh : -sh ) > len)
159 {
160 delta = len;
161 sh = len;
162 }
163 else
164 delta = (sh >= 0) ? sh: -sh;
165
6de9cd9a
DN
166 if (sh > 0)
167 {
168 src = &sptr[delta * soffset];
169 dest = rptr;
170 }
171 else
172 {
173 src = sptr;
174 dest = &rptr[delta * roffset];
175 }
176 for (n = 0; n < len - delta; n++)
177 {
178 memcpy (dest, src, size);
179 dest += roffset;
180 src += soffset;
181 }
182 if (sh < 0)
183 dest = rptr;
184 n = delta;
185
7823229b
RS
186 if (pbound)
187 while (n--)
188 {
189 memcpy (dest, pbound, size);
190 dest += roffset;
191 }
192 else
193 while (n--)
194 {
691da334
FXC
195 index_type i;
196
197 if (filler_len == 1)
198 memset (dest, filler[0], size);
199 else
200 for (i = 0; i < size; i += filler_len)
201 memcpy (&dest[i], filler, filler_len);
202
7823229b
RS
203 dest += roffset;
204 }
6de9cd9a
DN
205
206 /* Advance to the next section. */
207 rptr += rstride0;
208 sptr += sstride0;
209 hptr += hstride0;
210 count[0]++;
211 n = 0;
212 while (count[n] == extent[n])
213 {
214 /* When we get to the end of a dimension, reset it and increment
215 the next dimension. */
216 count[n] = 0;
217 /* We could precalculate these products, but this is a less
8b6dba81 218 frequently used path so probably not worth it. */
6de9cd9a
DN
219 rptr -= rstride[n] * extent[n];
220 sptr -= sstride[n] * extent[n];
221 hptr -= hstride[n] * extent[n];
222 n++;
223 if (n >= dim - 1)
224 {
225 /* Break out of the loop. */
226 rptr = NULL;
227 break;
228 }
229 else
230 {
231 count[n]++;
232 rptr += rstride[n];
233 sptr += sstride[n];
234 hptr += hstride[n];
235 }
236 }
237 }
238}
7823229b 239
adea5e16 240void eoshift1_'atype_kind` (gfc_array_char * const restrict,
64acfd99 241 const gfc_array_char * const restrict,
adea5e16
TK
242 const 'atype` * const restrict, const char * const restrict,
243 const 'atype_name` * const restrict);
244export_proto(eoshift1_'atype_kind`);
7823229b
RS
245
246void
adea5e16 247eoshift1_'atype_kind` (gfc_array_char * const restrict ret,
64acfd99 248 const gfc_array_char * const restrict array,
adea5e16 249 const 'atype` * const restrict h,
64acfd99 250 const char * const restrict pbound,
adea5e16 251 const 'atype_name` * const restrict pwhich)
7823229b 252{
dfb55fdc 253 eoshift1 (ret, array, h, pbound, pwhich, "\0", 1);
7823229b
RS
254}
255
691da334 256
adea5e16 257void eoshift1_'atype_kind`_char (gfc_array_char * const restrict,
64acfd99
JB
258 GFC_INTEGER_4,
259 const gfc_array_char * const restrict,
adea5e16 260 const 'atype` * const restrict,
64acfd99 261 const char * const restrict,
adea5e16 262 const 'atype_name` * const restrict,
64acfd99 263 GFC_INTEGER_4, GFC_INTEGER_4);
adea5e16 264export_proto(eoshift1_'atype_kind`_char);
7823229b
RS
265
266void
adea5e16 267eoshift1_'atype_kind`_char (gfc_array_char * const restrict ret,
64acfd99
JB
268 GFC_INTEGER_4 ret_length __attribute__((unused)),
269 const gfc_array_char * const restrict array,
adea5e16 270 const 'atype` * const restrict h,
64acfd99 271 const char * const restrict pbound,
adea5e16 272 const 'atype_name` * const restrict pwhich,
dfb55fdc 273 GFC_INTEGER_4 array_length __attribute__((unused)),
64acfd99 274 GFC_INTEGER_4 bound_length __attribute__((unused)))
7823229b 275{
dfb55fdc 276 eoshift1 (ret, array, h, pbound, pwhich, " ", 1);
691da334
FXC
277}
278
279
280void eoshift1_'atype_kind`_char4 (gfc_array_char * const restrict,
281 GFC_INTEGER_4,
282 const gfc_array_char * const restrict,
283 const 'atype` * const restrict,
284 const char * const restrict,
285 const 'atype_name` * const restrict,
286 GFC_INTEGER_4, GFC_INTEGER_4);
287export_proto(eoshift1_'atype_kind`_char4);
288
289void
290eoshift1_'atype_kind`_char4 (gfc_array_char * const restrict ret,
291 GFC_INTEGER_4 ret_length __attribute__((unused)),
292 const gfc_array_char * const restrict array,
293 const 'atype` * const restrict h,
294 const char * const restrict pbound,
295 const 'atype_name` * const restrict pwhich,
dfb55fdc 296 GFC_INTEGER_4 array_length __attribute__((unused)),
691da334
FXC
297 GFC_INTEGER_4 bound_length __attribute__((unused)))
298{
299 static const gfc_char4_t space = (unsigned char) ''` ''`;
dfb55fdc 300 eoshift1 (ret, array, h, pbound, pwhich,
691da334 301 (const char *) &space, sizeof (gfc_char4_t));
7823229b 302}
644cb69f 303
adea5e16 304#endif'
This page took 0.512501 seconds and 5 git commands to generate.