]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgfortran/generated/eoshift3_8.c
iresolve.c (gfc_resolve_all, [...]): Use PREFIX.
[thirdparty/gcc.git] / libgfortran / generated / eoshift3_8.c
CommitLineData
6de9cd9a
DN
1/* Implementation of the EOSHIFT intrinsic
2 Copyright 2002 Free Software Foundation, Inc.
3 Contributed by Paul Brook <paul@nowt.org>
4
5This file is part of the GNU Fortran 95 runtime library (libgfor).
6
7Libgfor is free software; you can redistribute it and/or
8modify it under the terms of the GNU Lesser General Public
9License as published by the Free Software Foundation; either
10version 2.1 of the License, or (at your option) any later version.
11
12Ligbfor is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU Lesser General Public License for more details.
16
17You should have received a copy of the GNU Lesser General Public
18License along with libgfor; see the file COPYING.LIB. If not,
19write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
21
22#include "config.h"
23#include <stdlib.h>
24#include <assert.h>
25#include <string.h>
26#include "libgfortran.h"
27
28static const char zeros[16] =
29 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
30
7f68c75f 31extern void eoshift3_8 (gfc_array_char *, gfc_array_char *,
7d7b8bfe
RH
32 gfc_array_i8 *, const gfc_array_char *,
33 GFC_INTEGER_8 *);
7f68c75f 34export_proto(eoshift3_8);
7d7b8bfe 35
6de9cd9a 36void
7f68c75f
RH
37eoshift3_8 (gfc_array_char *ret, gfc_array_char *array,
38 gfc_array_i8 *h, const gfc_array_char *bound,
39 GFC_INTEGER_8 *pwhich)
6de9cd9a
DN
40{
41 /* r.* indicates the return array. */
42 index_type rstride[GFC_MAX_DIMENSIONS - 1];
43 index_type rstride0;
44 index_type roffset;
45 char *rptr;
46 char *dest;
47 /* s.* indicates the source array. */
48 index_type sstride[GFC_MAX_DIMENSIONS - 1];
49 index_type sstride0;
50 index_type soffset;
51 const char *sptr;
52 const char *src;
53 /* h.* indicates the shift array. */
54 index_type hstride[GFC_MAX_DIMENSIONS - 1];
55 index_type hstride0;
56 const GFC_INTEGER_8 *hptr;
57 /* b.* indicates the bound array. */
58 index_type bstride[GFC_MAX_DIMENSIONS - 1];
59 index_type bstride0;
60 const char *bptr;
61
62 index_type count[GFC_MAX_DIMENSIONS - 1];
63 index_type extent[GFC_MAX_DIMENSIONS - 1];
64 index_type dim;
65 index_type size;
66 index_type len;
67 index_type n;
68 int which;
69 GFC_INTEGER_8 sh;
70 GFC_INTEGER_8 delta;
71
72 if (pwhich)
73 which = *pwhich - 1;
74 else
75 which = 0;
76
77 size = GFC_DESCRIPTOR_SIZE (ret);
78
79 extent[0] = 1;
80 count[0] = 0;
81 size = GFC_DESCRIPTOR_SIZE (array);
82 n = 0;
83 for (dim = 0; dim < GFC_DESCRIPTOR_RANK (array); dim++)
84 {
85 if (dim == which)
86 {
87 roffset = ret->dim[dim].stride * size;
88 if (roffset == 0)
89 roffset = size;
90 soffset = array->dim[dim].stride * size;
91 if (soffset == 0)
92 soffset = size;
93 len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
94 }
95 else
96 {
97 count[n] = 0;
98 extent[n] = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
99 rstride[n] = ret->dim[dim].stride * size;
100 sstride[n] = array->dim[dim].stride * size;
101
102 hstride[n] = h->dim[n].stride;
103 if (bound)
104 bstride[n] = bound->dim[n].stride;
105 else
106 bstride[n] = 0;
107 n++;
108 }
109 }
110 if (sstride[0] == 0)
111 sstride[0] = size;
112 if (rstride[0] == 0)
113 rstride[0] = size;
114 if (hstride[0] == 0)
115 hstride[0] = 1;
116 if (bound && bstride[0] == 0)
117 bstride[0] = size;
118
119 dim = GFC_DESCRIPTOR_RANK (array);
120 rstride0 = rstride[0];
121 sstride0 = sstride[0];
122 hstride0 = hstride[0];
123 bstride0 = bstride[0];
124 rptr = ret->data;
125 sptr = array->data;
126 hptr = h->data;
127 if (bound)
128 bptr = bound->data;
129 else
130 bptr = zeros;
131
132 while (rptr)
133 {
134 /* Do the shift for this dimension. */
135 sh = *hptr;
136 delta = (sh >= 0) ? sh: -sh;
137 if (sh > 0)
138 {
139 src = &sptr[delta * soffset];
140 dest = rptr;
141 }
142 else
143 {
144 src = sptr;
145 dest = &rptr[delta * roffset];
146 }
147 for (n = 0; n < len - delta; n++)
148 {
149 memcpy (dest, src, size);
150 dest += roffset;
151 src += soffset;
152 }
153 if (sh < 0)
154 dest = rptr;
155 n = delta;
156
157 while (n--)
158 {
159 memcpy (dest, bptr, size);
160 dest += roffset;
161 }
162
163 /* Advance to the next section. */
164 rptr += rstride0;
165 sptr += sstride0;
166 hptr += hstride0;
167 bptr += bstride0;
168 count[0]++;
169 n = 0;
170 while (count[n] == extent[n])
171 {
172 /* When we get to the end of a dimension, reset it and increment
173 the next dimension. */
174 count[n] = 0;
175 /* We could precalculate these products, but this is a less
176 frequently used path so proabably not worth it. */
177 rptr -= rstride[n] * extent[n];
178 sptr -= sstride[n] * extent[n];
179 hptr -= hstride[n] * extent[n];
180 bptr -= bstride[n] * extent[n];
181 n++;
182 if (n >= dim - 1)
183 {
184 /* Break out of the loop. */
185 rptr = NULL;
186 break;
187 }
188 else
189 {
190 count[n]++;
191 rptr += rstride[n];
192 sptr += sstride[n];
193 hptr += hstride[n];
194 bptr += bstride[n];
195 }
196 }
197 }
198}