]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgfortran/m4/eoshift3.m4
eoshift1.m4: Initialize variables to avoid warnings.
[thirdparty/gcc.git] / libgfortran / m4 / eoshift3.m4
CommitLineData
6de9cd9a 1`/* Implementation of the EOSHIFT intrinsic
7672ae20 2 Copyright 2002, 2005 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
57dea9f6 10version 2 of the License, or (at your option) any later version.
6de9cd9a 11
57dea9f6
TM
12In addition to the permissions in the GNU General Public License, the
13Free Software Foundation gives you unlimited permission to link the
14compiled version of this file into combinations with other programs,
15and to distribute those combinations without any restriction coming
16from the use of this file. (The General Public License restrictions
17do apply in other respects; for example, they cover modification of
18the file, and distribution when not linked into a combine
19executable.)
20
21Libgfortran is distributed in the hope that it will be useful,
6de9cd9a
DN
22but WITHOUT ANY WARRANTY; without even the implied warranty of
23MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
57dea9f6 24GNU General Public License for more details.
6de9cd9a 25
57dea9f6
TM
26You should have received a copy of the GNU General Public
27License along with libgfortran; see the file COPYING. If not,
6de9cd9a
DN
28write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
29Boston, MA 02111-1307, USA. */
30
31#include "config.h"
32#include <stdlib.h>
33#include <assert.h>
34#include <string.h>
35#include "libgfortran.h"'
c9e66eda 36include(iparm.m4)dnl
6de9cd9a
DN
37
38static const char zeros[16] =
39 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
40
7f68c75f 41extern void eoshift3_`'atype_kind (gfc_array_char *, gfc_array_char *,
7d7b8bfe
RH
42 atype *, const gfc_array_char *,
43 atype_name *);
7f68c75f 44export_proto(eoshift3_`'atype_kind);
7d7b8bfe 45
6de9cd9a 46void
7f68c75f
RH
47eoshift3_`'atype_kind (gfc_array_char *ret, gfc_array_char *array,
48 atype *h, const gfc_array_char *bound,
49 atype_name *pwhich)
6de9cd9a
DN
50{
51 /* r.* indicates the return array. */
e33e218b 52 index_type rstride[GFC_MAX_DIMENSIONS];
6de9cd9a
DN
53 index_type rstride0;
54 index_type roffset;
55 char *rptr;
56 char *dest;
57 /* s.* indicates the source array. */
e33e218b 58 index_type sstride[GFC_MAX_DIMENSIONS];
6de9cd9a
DN
59 index_type sstride0;
60 index_type soffset;
61 const char *sptr;
62 const char *src;
63` /* h.* indicates the shift array. */'
e33e218b 64 index_type hstride[GFC_MAX_DIMENSIONS];
6de9cd9a 65 index_type hstride0;
c9e66eda 66 const atype_name *hptr;
6de9cd9a 67 /* b.* indicates the bound array. */
e33e218b 68 index_type bstride[GFC_MAX_DIMENSIONS];
6de9cd9a
DN
69 index_type bstride0;
70 const char *bptr;
71
e33e218b
TK
72 index_type count[GFC_MAX_DIMENSIONS];
73 index_type extent[GFC_MAX_DIMENSIONS];
6de9cd9a
DN
74 index_type dim;
75 index_type size;
76 index_type len;
77 index_type n;
78 int which;
c9e66eda
PB
79 atype_name sh;
80 atype_name delta;
6de9cd9a 81
7672ae20
AJ
82 /* The compiler cannot figure out that these are set, initialize
83 them to avoid warnings. */
84 len = 0;
85 soffset = 0;
86 roffset = 0;
87
6de9cd9a
DN
88 if (pwhich)
89 which = *pwhich - 1;
90 else
91 which = 0;
92
93 size = GFC_DESCRIPTOR_SIZE (ret);
94
95 extent[0] = 1;
96 count[0] = 0;
97 size = GFC_DESCRIPTOR_SIZE (array);
98 n = 0;
99 for (dim = 0; dim < GFC_DESCRIPTOR_RANK (array); dim++)
100 {
101 if (dim == which)
102 {
103 roffset = ret->dim[dim].stride * size;
104 if (roffset == 0)
105 roffset = size;
106 soffset = array->dim[dim].stride * size;
107 if (soffset == 0)
108 soffset = size;
109 len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
110 }
111 else
112 {
113 count[n] = 0;
114 extent[n] = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
115 rstride[n] = ret->dim[dim].stride * size;
116 sstride[n] = array->dim[dim].stride * size;
117
118 hstride[n] = h->dim[n].stride;
119 if (bound)
120 bstride[n] = bound->dim[n].stride;
121 else
122 bstride[n] = 0;
123 n++;
124 }
125 }
126 if (sstride[0] == 0)
127 sstride[0] = size;
128 if (rstride[0] == 0)
129 rstride[0] = size;
130 if (hstride[0] == 0)
131 hstride[0] = 1;
132 if (bound && bstride[0] == 0)
133 bstride[0] = size;
134
135 dim = GFC_DESCRIPTOR_RANK (array);
136 rstride0 = rstride[0];
137 sstride0 = sstride[0];
138 hstride0 = hstride[0];
139 bstride0 = bstride[0];
140 rptr = ret->data;
141 sptr = array->data;
142 hptr = h->data;
143 if (bound)
144 bptr = bound->data;
145 else
146 bptr = zeros;
147
148 while (rptr)
149 {
150` /* Do the shift for this dimension. */'
151 sh = *hptr;
152 delta = (sh >= 0) ? sh: -sh;
153 if (sh > 0)
154 {
155 src = &sptr[delta * soffset];
156 dest = rptr;
157 }
158 else
159 {
160 src = sptr;
161 dest = &rptr[delta * roffset];
162 }
163 for (n = 0; n < len - delta; n++)
164 {
165 memcpy (dest, src, size);
166 dest += roffset;
167 src += soffset;
168 }
169 if (sh < 0)
170 dest = rptr;
171 n = delta;
172
173 while (n--)
174 {
175 memcpy (dest, bptr, size);
176 dest += roffset;
177 }
178
179 /* Advance to the next section. */
180 rptr += rstride0;
181 sptr += sstride0;
182 hptr += hstride0;
183 bptr += bstride0;
184 count[0]++;
185 n = 0;
186 while (count[n] == extent[n])
187 {
188 /* When we get to the end of a dimension, reset it and increment
189 the next dimension. */
190 count[n] = 0;
191 /* We could precalculate these products, but this is a less
192 frequently used path so proabably not worth it. */
193 rptr -= rstride[n] * extent[n];
194 sptr -= sstride[n] * extent[n];
195 hptr -= hstride[n] * extent[n];
196 bptr -= bstride[n] * extent[n];
197 n++;
198 if (n >= dim - 1)
199 {
200 /* Break out of the loop. */
201 rptr = NULL;
202 break;
203 }
204 else
205 {
206 count[n]++;
207 rptr += rstride[n];
208 sptr += sstride[n];
209 hptr += hstride[n];
210 bptr += bstride[n];
211 }
212 }
213 }
214}