]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgfortran/m4/cshift1.m4
Update copyright years.
[thirdparty/gcc.git] / libgfortran / m4 / cshift1.m4
CommitLineData
4ee9c684 1`/* Implementation of the CSHIFT intrinsic
f1717362 2 Copyright (C) 2003-2016 Free Software Foundation, Inc.
4ee9c684 3 Contributed by Feng Wang <wf_cs@yahoo.com>
4
553877d9 5This file is part of the GNU Fortran runtime library (libgfortran).
4ee9c684 6
7Libgfortran is free software; you can redistribute it and/or
b417ea8c 8modify it under the terms of the GNU General Public
4ee9c684 9License as published by the Free Software Foundation; either
6bc9506f 10version 3 of the License, or (at your option) any later version.
b417ea8c 11
12Ligbfortran is distributed in the hope that it will be useful,
4ee9c684 13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
b417ea8c 15GNU General Public License for more details.
4ee9c684 16
6bc9506f 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/>. */
4ee9c684 25
41f2d5e8 26#include "libgfortran.h"
4ee9c684 27#include <stdlib.h>
28#include <assert.h>
41f2d5e8 29#include <string.h>'
30
cdafa1f6 31include(iparm.m4)dnl
4ee9c684 32
0a6b5f6b 33`#if defined (HAVE_'atype_name`)
920e54ef 34
1a9a4a12 35static void
b4cafd67 36cshift1 (gfc_array_char * const restrict ret,
37 const gfc_array_char * const restrict array,
0a6b5f6b 38 const 'atype` * const restrict h,
827aef63 39 const 'atype_name` * const restrict pwhich)
4ee9c684 40{
41 /* r.* indicates the return array. */
9130521e 42 index_type rstride[GFC_MAX_DIMENSIONS];
4ee9c684 43 index_type rstride0;
44 index_type roffset;
45 char *rptr;
46 char *dest;
47 /* s.* indicates the source array. */
9130521e 48 index_type sstride[GFC_MAX_DIMENSIONS];
4ee9c684 49 index_type sstride0;
50 index_type soffset;
51 const char *sptr;
52 const char *src;
7b6cb5bd 53 /* h.* indicates the shift array. */
9130521e 54 index_type hstride[GFC_MAX_DIMENSIONS];
4ee9c684 55 index_type hstride0;
0a6b5f6b 56 const 'atype_name` *hptr;
4ee9c684 57
9130521e 58 index_type count[GFC_MAX_DIMENSIONS];
59 index_type extent[GFC_MAX_DIMENSIONS];
4ee9c684 60 index_type dim;
4ee9c684 61 index_type len;
62 index_type n;
63 int which;
0a6b5f6b 64 'atype_name` sh;
74a175c1 65 index_type arraysize;
827aef63 66 index_type size;
4ee9c684 67
68 if (pwhich)
69 which = *pwhich - 1;
70 else
71 which = 0;
72
73 if (which < 0 || (which + 1) > GFC_DESCRIPTOR_RANK (array))
0a6b5f6b 74 runtime_error ("Argument ''`DIM''` is out of range in call to ''`CSHIFT''`");
4ee9c684 75
827aef63 76 size = GFC_DESCRIPTOR_SIZE(array);
77
74a175c1 78 arraysize = size0 ((array_t *)array);
79
553877d9 80 if (ret->base_addr == NULL)
71a8a4b3 81 {
82 int i;
83
af1e9051 84 ret->base_addr = xmallocarray (arraysize, size);
93830de1 85 ret->offset = 0;
71a8a4b3 86 ret->dtype = array->dtype;
87 for (i = 0; i < GFC_DESCRIPTOR_RANK (array); i++)
88 {
827aef63 89 index_type ub, str;
90
91 ub = GFC_DESCRIPTOR_EXTENT(array,i) - 1;
71a8a4b3 92
93 if (i == 0)
827aef63 94 str = 1;
71a8a4b3 95 else
827aef63 96 str = GFC_DESCRIPTOR_EXTENT(ret,i-1) *
97 GFC_DESCRIPTOR_STRIDE(ret,i-1);
98
99 GFC_DIMENSION_SET(ret->dim[i], 0, ub, str);
71a8a4b3 100 }
101 }
5d04d450 102 else if (unlikely (compile_options.bounds_check))
103 {
104 bounds_equal_extents ((array_t *) ret, (array_t *) array,
105 "return value", "CSHIFT");
106 }
107
108 if (unlikely (compile_options.bounds_check))
109 {
110 bounds_reduced_extents ((array_t *) h, (array_t *) array, which,
111 "SHIFT argument", "CSHIFT");
112 }
71a8a4b3 113
74a175c1 114 if (arraysize == 0)
115 return;
116
4ee9c684 117 extent[0] = 1;
118 count[0] = 0;
4ee9c684 119 n = 0;
120
7b6cb5bd 121 /* Initialized for avoiding compiler warnings. */
4ee9c684 122 roffset = size;
123 soffset = size;
124 len = 0;
125
126 for (dim = 0; dim < GFC_DESCRIPTOR_RANK (array); dim++)
127 {
128 if (dim == which)
129 {
827aef63 130 roffset = GFC_DESCRIPTOR_STRIDE_BYTES(ret,dim);
4ee9c684 131 if (roffset == 0)
132 roffset = size;
827aef63 133 soffset = GFC_DESCRIPTOR_STRIDE_BYTES(array,dim);
4ee9c684 134 if (soffset == 0)
135 soffset = size;
827aef63 136 len = GFC_DESCRIPTOR_EXTENT(array,dim);
4ee9c684 137 }
138 else
139 {
140 count[n] = 0;
827aef63 141 extent[n] = GFC_DESCRIPTOR_EXTENT(array,dim);
142 rstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(ret,dim);
143 sstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(array,dim);
4ee9c684 144
827aef63 145 hstride[n] = GFC_DESCRIPTOR_STRIDE(h,n);
4ee9c684 146 n++;
147 }
148 }
149 if (sstride[0] == 0)
150 sstride[0] = size;
151 if (rstride[0] == 0)
152 rstride[0] = size;
153 if (hstride[0] == 0)
154 hstride[0] = 1;
155
156 dim = GFC_DESCRIPTOR_RANK (array);
157 rstride0 = rstride[0];
158 sstride0 = sstride[0];
159 hstride0 = hstride[0];
553877d9 160 rptr = ret->base_addr;
161 sptr = array->base_addr;
162 hptr = h->base_addr;
4ee9c684 163
164 while (rptr)
165 {
7b6cb5bd 166 /* Do the shift for this dimension. */
4ee9c684 167 sh = *hptr;
168 sh = (div (sh, len)).rem;
169 if (sh < 0)
170 sh += len;
171
172 src = &sptr[sh * soffset];
173 dest = rptr;
174
175 for (n = 0; n < len; n++)
176 {
177 memcpy (dest, src, size);
178 dest += roffset;
179 if (n == len - sh - 1)
180 src = sptr;
181 else
182 src += soffset;
183 }
184
185 /* Advance to the next section. */
186 rptr += rstride0;
187 sptr += sstride0;
188 hptr += hstride0;
189 count[0]++;
190 n = 0;
191 while (count[n] == extent[n])
192 {
193 /* When we get to the end of a dimension, reset it and increment
194 the next dimension. */
195 count[n] = 0;
196 /* We could precalculate these products, but this is a less
a2ffc2c4 197 frequently used path so probably not worth it. */
4ee9c684 198 rptr -= rstride[n] * extent[n];
199 sptr -= sstride[n] * extent[n];
200 hptr -= hstride[n] * extent[n];
201 n++;
202 if (n >= dim - 1)
203 {
204 /* Break out of the loop. */
205 rptr = NULL;
206 break;
207 }
208 else
209 {
210 count[n]++;
211 rptr += rstride[n];
212 sptr += sstride[n];
213 hptr += hstride[n];
214 }
215 }
216 }
217}
1a9a4a12 218
0a6b5f6b 219void cshift1_'atype_kind` (gfc_array_char * const restrict,
b4cafd67 220 const gfc_array_char * const restrict,
0a6b5f6b 221 const 'atype` * const restrict,
222 const 'atype_name` * const restrict);
223export_proto(cshift1_'atype_kind`);
1a9a4a12 224
225void
0a6b5f6b 226cshift1_'atype_kind` (gfc_array_char * const restrict ret,
b4cafd67 227 const gfc_array_char * const restrict array,
0a6b5f6b 228 const 'atype` * const restrict h,
229 const 'atype_name` * const restrict pwhich)
1a9a4a12 230{
827aef63 231 cshift1 (ret, array, h, pwhich);
1a9a4a12 232}
233
329f13ad 234
0a6b5f6b 235void cshift1_'atype_kind`_char (gfc_array_char * const restrict ret,
b4cafd67 236 GFC_INTEGER_4,
237 const gfc_array_char * const restrict array,
0a6b5f6b 238 const 'atype` * const restrict h,
239 const 'atype_name` * const restrict pwhich,
b4cafd67 240 GFC_INTEGER_4);
0a6b5f6b 241export_proto(cshift1_'atype_kind`_char);
1a9a4a12 242
243void
0a6b5f6b 244cshift1_'atype_kind`_char (gfc_array_char * const restrict ret,
b4cafd67 245 GFC_INTEGER_4 ret_length __attribute__((unused)),
246 const gfc_array_char * const restrict array,
0a6b5f6b 247 const 'atype` * const restrict h,
248 const 'atype_name` * const restrict pwhich,
827aef63 249 GFC_INTEGER_4 array_length __attribute__((unused)))
1a9a4a12 250{
827aef63 251 cshift1 (ret, array, h, pwhich);
1a9a4a12 252}
920e54ef 253
329f13ad 254
255void cshift1_'atype_kind`_char4 (gfc_array_char * const restrict ret,
256 GFC_INTEGER_4,
257 const gfc_array_char * const restrict array,
258 const 'atype` * const restrict h,
259 const 'atype_name` * const restrict pwhich,
260 GFC_INTEGER_4);
261export_proto(cshift1_'atype_kind`_char4);
262
263void
264cshift1_'atype_kind`_char4 (gfc_array_char * const restrict ret,
265 GFC_INTEGER_4 ret_length __attribute__((unused)),
266 const gfc_array_char * const restrict array,
267 const 'atype` * const restrict h,
268 const 'atype_name` * const restrict pwhich,
827aef63 269 GFC_INTEGER_4 array_length __attribute__((unused)))
329f13ad 270{
827aef63 271 cshift1 (ret, array, h, pwhich);
329f13ad 272}
273
0a6b5f6b 274#endif'