]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgfortran/generated/cshift1_8.c
iresolve.c (gfc_resolve_all, [...]): Use PREFIX.
[thirdparty/gcc.git] / libgfortran / generated / cshift1_8.c
CommitLineData
6de9cd9a
DN
1/* Implementation of the CSHIFT intrinsic
2 Copyright 2003 Free Software Foundation, Inc.
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
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
7f68c75f
RH
28void cshift1_8 (const gfc_array_char * ret,
29 const gfc_array_char * array,
30 const gfc_array_i8 * h, const GFC_INTEGER_8 * pwhich);
31export_proto(cshift1_8);
7d7b8bfe 32
6de9cd9a 33void
7f68c75f
RH
34cshift1_8 (const gfc_array_char * ret,
35 const gfc_array_char * array,
36 const gfc_array_i8 * h, const GFC_INTEGER_8 * pwhich)
6de9cd9a
DN
37{
38 /* r.* indicates the return array. */
39 index_type rstride[GFC_MAX_DIMENSIONS - 1];
40 index_type rstride0;
41 index_type roffset;
42 char *rptr;
43 char *dest;
44 /* s.* indicates the source array. */
45 index_type sstride[GFC_MAX_DIMENSIONS - 1];
46 index_type sstride0;
47 index_type soffset;
48 const char *sptr;
49 const char *src;
7d7b8bfe 50 /* h.* indicates the array. */
6de9cd9a
DN
51 index_type hstride[GFC_MAX_DIMENSIONS - 1];
52 index_type hstride0;
53 const GFC_INTEGER_8 *hptr;
54
55 index_type count[GFC_MAX_DIMENSIONS - 1];
56 index_type extent[GFC_MAX_DIMENSIONS - 1];
57 index_type dim;
58 index_type size;
59 index_type len;
60 index_type n;
61 int which;
62 GFC_INTEGER_8 sh;
63
64 if (pwhich)
65 which = *pwhich - 1;
66 else
67 which = 0;
68
69 if (which < 0 || (which + 1) > GFC_DESCRIPTOR_RANK (array))
70 runtime_error ("Argument 'DIM' is out of range in call to 'CSHIFT'");
71
72 size = GFC_DESCRIPTOR_SIZE (ret);
73
74 extent[0] = 1;
75 count[0] = 0;
76 size = GFC_DESCRIPTOR_SIZE (array);
77 n = 0;
78
7d7b8bfe 79 /* Initialized for avoiding compiler warnings. */
6de9cd9a
DN
80 roffset = size;
81 soffset = size;
82 len = 0;
83
84 for (dim = 0; dim < GFC_DESCRIPTOR_RANK (array); dim++)
85 {
86 if (dim == which)
87 {
88 roffset = ret->dim[dim].stride * size;
89 if (roffset == 0)
90 roffset = size;
91 soffset = array->dim[dim].stride * size;
92 if (soffset == 0)
93 soffset = size;
94 len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
95 }
96 else
97 {
98 count[n] = 0;
99 extent[n] = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
100 rstride[n] = ret->dim[dim].stride * size;
101 sstride[n] = array->dim[dim].stride * size;
102
103 hstride[n] = h->dim[n].stride;
104 n++;
105 }
106 }
107 if (sstride[0] == 0)
108 sstride[0] = size;
109 if (rstride[0] == 0)
110 rstride[0] = size;
111 if (hstride[0] == 0)
112 hstride[0] = 1;
113
114 dim = GFC_DESCRIPTOR_RANK (array);
115 rstride0 = rstride[0];
116 sstride0 = sstride[0];
117 hstride0 = hstride[0];
118 rptr = ret->data;
119 sptr = array->data;
120 hptr = h->data;
121
122 while (rptr)
123 {
7d7b8bfe 124 /* Do the for this dimension. */
6de9cd9a
DN
125 sh = *hptr;
126 sh = (div (sh, len)).rem;
127 if (sh < 0)
128 sh += len;
129
130 src = &sptr[sh * soffset];
131 dest = rptr;
132
133 for (n = 0; n < len; n++)
134 {
135 memcpy (dest, src, size);
136 dest += roffset;
137 if (n == len - sh - 1)
138 src = sptr;
139 else
140 src += soffset;
141 }
142
143 /* Advance to the next section. */
144 rptr += rstride0;
145 sptr += sstride0;
146 hptr += hstride0;
147 count[0]++;
148 n = 0;
149 while (count[n] == extent[n])
150 {
151 /* When we get to the end of a dimension, reset it and increment
152 the next dimension. */
153 count[n] = 0;
154 /* We could precalculate these products, but this is a less
155 frequently used path so proabably not worth it. */
156 rptr -= rstride[n] * extent[n];
157 sptr -= sstride[n] * extent[n];
158 hptr -= hstride[n] * extent[n];
159 n++;
160 if (n >= dim - 1)
161 {
162 /* Break out of the loop. */
163 rptr = NULL;
164 break;
165 }
166 else
167 {
168 count[n]++;
169 rptr += rstride[n];
170 sptr += sstride[n];
171 hptr += hstride[n];
172 }
173 }
174 }
175}