]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgfortran/generated/cshift1_4.c
Licensing changes to GPLv3 resp. GPLv3 with GCC Runtime Exception.
[thirdparty/gcc.git] / libgfortran / generated / cshift1_4.c
CommitLineData
6de9cd9a 1/* Implementation of the CSHIFT intrinsic
748086b7 2 Copyright 2003, 2007, 2009 Free Software Foundation, Inc.
6de9cd9a
DN
3 Contributed by Feng Wang <wf_cs@yahoo.com>
4
5This file is part of the GNU Fortran 95 runtime library (libgfortran).
6
7Libgfortran is free software; you can redistribute it and/or
57dea9f6 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
12Ligbfortran 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>
29#include <string.h>
36ae8a61 30
6de9cd9a 31
644cb69f
FXC
32#if defined (HAVE_GFC_INTEGER_4)
33
7823229b 34static void
64acfd99
JB
35cshift1 (gfc_array_char * const restrict ret,
36 const gfc_array_char * const restrict array,
37 const gfc_array_i4 * const restrict h,
38 const GFC_INTEGER_4 * const restrict pwhich,
39 index_type size)
6de9cd9a
DN
40{
41 /* r.* indicates the return array. */
e33e218b 42 index_type rstride[GFC_MAX_DIMENSIONS];
6de9cd9a
DN
43 index_type rstride0;
44 index_type roffset;
45 char *rptr;
46 char *dest;
47 /* s.* indicates the source array. */
e33e218b 48 index_type sstride[GFC_MAX_DIMENSIONS];
6de9cd9a
DN
49 index_type sstride0;
50 index_type soffset;
51 const char *sptr;
52 const char *src;
80ee04b9 53 /* h.* indicates the shift array. */
e33e218b 54 index_type hstride[GFC_MAX_DIMENSIONS];
6de9cd9a
DN
55 index_type hstride0;
56 const GFC_INTEGER_4 *hptr;
57
e33e218b
TK
58 index_type count[GFC_MAX_DIMENSIONS];
59 index_type extent[GFC_MAX_DIMENSIONS];
6de9cd9a 60 index_type dim;
6de9cd9a
DN
61 index_type len;
62 index_type n;
63 int which;
64 GFC_INTEGER_4 sh;
c44109aa 65 index_type arraysize;
6de9cd9a
DN
66
67 if (pwhich)
68 which = *pwhich - 1;
69 else
70 which = 0;
71
72 if (which < 0 || (which + 1) > GFC_DESCRIPTOR_RANK (array))
73 runtime_error ("Argument 'DIM' is out of range in call to 'CSHIFT'");
74
c44109aa
TK
75 arraysize = size0 ((array_t *)array);
76
0e6d033b
TK
77 if (ret->data == NULL)
78 {
79 int i;
80
c44109aa 81 ret->data = internal_malloc_size (size * arraysize);
efd4dc1a 82 ret->offset = 0;
0e6d033b
TK
83 ret->dtype = array->dtype;
84 for (i = 0; i < GFC_DESCRIPTOR_RANK (array); i++)
85 {
86 ret->dim[i].lbound = 0;
87 ret->dim[i].ubound = array->dim[i].ubound - array->dim[i].lbound;
88
89 if (i == 0)
90 ret->dim[i].stride = 1;
91 else
92 ret->dim[i].stride = (ret->dim[i-1].ubound + 1) * ret->dim[i-1].stride;
93 }
94 }
95
c44109aa
TK
96 if (arraysize == 0)
97 return;
98
6de9cd9a
DN
99 extent[0] = 1;
100 count[0] = 0;
6de9cd9a
DN
101 n = 0;
102
7d7b8bfe 103 /* Initialized for avoiding compiler warnings. */
6de9cd9a
DN
104 roffset = size;
105 soffset = size;
106 len = 0;
107
108 for (dim = 0; dim < GFC_DESCRIPTOR_RANK (array); dim++)
109 {
110 if (dim == which)
111 {
112 roffset = ret->dim[dim].stride * size;
113 if (roffset == 0)
114 roffset = size;
115 soffset = array->dim[dim].stride * size;
116 if (soffset == 0)
117 soffset = size;
118 len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
119 }
120 else
121 {
122 count[n] = 0;
123 extent[n] = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
124 rstride[n] = ret->dim[dim].stride * size;
125 sstride[n] = array->dim[dim].stride * size;
126
127 hstride[n] = h->dim[n].stride;
128 n++;
129 }
130 }
131 if (sstride[0] == 0)
132 sstride[0] = size;
133 if (rstride[0] == 0)
134 rstride[0] = size;
135 if (hstride[0] == 0)
136 hstride[0] = 1;
137
138 dim = GFC_DESCRIPTOR_RANK (array);
139 rstride0 = rstride[0];
140 sstride0 = sstride[0];
141 hstride0 = hstride[0];
142 rptr = ret->data;
143 sptr = array->data;
144 hptr = h->data;
145
146 while (rptr)
147 {
80ee04b9 148 /* Do the shift for this dimension. */
6de9cd9a
DN
149 sh = *hptr;
150 sh = (div (sh, len)).rem;
151 if (sh < 0)
152 sh += len;
153
154 src = &sptr[sh * soffset];
155 dest = rptr;
156
157 for (n = 0; n < len; n++)
158 {
159 memcpy (dest, src, size);
160 dest += roffset;
161 if (n == len - sh - 1)
162 src = sptr;
163 else
164 src += soffset;
165 }
166
167 /* Advance to the next section. */
168 rptr += rstride0;
169 sptr += sstride0;
170 hptr += hstride0;
171 count[0]++;
172 n = 0;
173 while (count[n] == extent[n])
174 {
175 /* When we get to the end of a dimension, reset it and increment
176 the next dimension. */
177 count[n] = 0;
178 /* We could precalculate these products, but this is a less
5d7adf7a 179 frequently used path so probably not worth it. */
6de9cd9a
DN
180 rptr -= rstride[n] * extent[n];
181 sptr -= sstride[n] * extent[n];
182 hptr -= hstride[n] * extent[n];
183 n++;
184 if (n >= dim - 1)
185 {
186 /* Break out of the loop. */
187 rptr = NULL;
188 break;
189 }
190 else
191 {
192 count[n]++;
193 rptr += rstride[n];
194 sptr += sstride[n];
195 hptr += hstride[n];
196 }
197 }
198 }
199}
7823229b 200
64acfd99
JB
201void cshift1_4 (gfc_array_char * const restrict,
202 const gfc_array_char * const restrict,
203 const gfc_array_i4 * const restrict,
204 const GFC_INTEGER_4 * const restrict);
7823229b
RS
205export_proto(cshift1_4);
206
207void
64acfd99
JB
208cshift1_4 (gfc_array_char * const restrict ret,
209 const gfc_array_char * const restrict array,
210 const gfc_array_i4 * const restrict h,
211 const GFC_INTEGER_4 * const restrict pwhich)
7823229b
RS
212{
213 cshift1 (ret, array, h, pwhich, GFC_DESCRIPTOR_SIZE (array));
214}
215
691da334 216
64acfd99
JB
217void cshift1_4_char (gfc_array_char * const restrict ret,
218 GFC_INTEGER_4,
219 const gfc_array_char * const restrict array,
220 const gfc_array_i4 * const restrict h,
221 const GFC_INTEGER_4 * const restrict pwhich,
222 GFC_INTEGER_4);
7823229b
RS
223export_proto(cshift1_4_char);
224
225void
64acfd99
JB
226cshift1_4_char (gfc_array_char * const restrict ret,
227 GFC_INTEGER_4 ret_length __attribute__((unused)),
228 const gfc_array_char * const restrict array,
229 const gfc_array_i4 * const restrict h,
230 const GFC_INTEGER_4 * const restrict pwhich,
231 GFC_INTEGER_4 array_length)
7823229b
RS
232{
233 cshift1 (ret, array, h, pwhich, array_length);
234}
644cb69f 235
691da334
FXC
236
237void cshift1_4_char4 (gfc_array_char * const restrict ret,
238 GFC_INTEGER_4,
239 const gfc_array_char * const restrict array,
240 const gfc_array_i4 * const restrict h,
241 const GFC_INTEGER_4 * const restrict pwhich,
242 GFC_INTEGER_4);
243export_proto(cshift1_4_char4);
244
245void
246cshift1_4_char4 (gfc_array_char * const restrict ret,
247 GFC_INTEGER_4 ret_length __attribute__((unused)),
248 const gfc_array_char * const restrict array,
249 const gfc_array_i4 * const restrict h,
250 const GFC_INTEGER_4 * const restrict pwhich,
251 GFC_INTEGER_4 array_length)
252{
253 cshift1 (ret, array, h, pwhich, array_length * sizeof (gfc_char4_t));
254}
255
644cb69f 256#endif