annotate libgfortran/generated/cshift0_r10.c @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* Helper function for cshift functions.
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2 Copyright (C) 2008-2020 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
3 Contributed by Thomas Koenig <tkoenig@gcc.gnu.org>
kono
parents:
diff changeset
4
kono
parents:
diff changeset
5 This file is part of the GNU Fortran runtime library (libgfortran).
kono
parents:
diff changeset
6
kono
parents:
diff changeset
7 Libgfortran is free software; you can redistribute it and/or
kono
parents:
diff changeset
8 modify it under the terms of the GNU General Public
kono
parents:
diff changeset
9 License as published by the Free Software Foundation; either
kono
parents:
diff changeset
10 version 3 of the License, or (at your option) any later version.
kono
parents:
diff changeset
11
kono
parents:
diff changeset
12 Libgfortran is distributed in the hope that it will be useful,
kono
parents:
diff changeset
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
kono
parents:
diff changeset
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
kono
parents:
diff changeset
15 GNU General Public License for more details.
kono
parents:
diff changeset
16
kono
parents:
diff changeset
17 Under Section 7 of GPL version 3, you are granted additional
kono
parents:
diff changeset
18 permissions described in the GCC Runtime Library Exception, version
kono
parents:
diff changeset
19 3.1, as published by the Free Software Foundation.
kono
parents:
diff changeset
20
kono
parents:
diff changeset
21 You should have received a copy of the GNU General Public License and
kono
parents:
diff changeset
22 a copy of the GCC Runtime Library Exception along with this program;
kono
parents:
diff changeset
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
kono
parents:
diff changeset
24 <http://www.gnu.org/licenses/>. */
kono
parents:
diff changeset
25
kono
parents:
diff changeset
26 #include "libgfortran.h"
kono
parents:
diff changeset
27 #include <string.h>
kono
parents:
diff changeset
28
kono
parents:
diff changeset
29
kono
parents:
diff changeset
30 #if defined (HAVE_GFC_REAL_10)
kono
parents:
diff changeset
31
kono
parents:
diff changeset
32 void
kono
parents:
diff changeset
33 cshift0_r10 (gfc_array_r10 *ret, const gfc_array_r10 *array, ptrdiff_t shift,
kono
parents:
diff changeset
34 int which)
kono
parents:
diff changeset
35 {
kono
parents:
diff changeset
36 /* r.* indicates the return array. */
kono
parents:
diff changeset
37 index_type rstride[GFC_MAX_DIMENSIONS];
kono
parents:
diff changeset
38 index_type rstride0;
kono
parents:
diff changeset
39 index_type roffset;
kono
parents:
diff changeset
40 GFC_REAL_10 *rptr;
kono
parents:
diff changeset
41
kono
parents:
diff changeset
42 /* s.* indicates the source array. */
kono
parents:
diff changeset
43 index_type sstride[GFC_MAX_DIMENSIONS];
kono
parents:
diff changeset
44 index_type sstride0;
kono
parents:
diff changeset
45 index_type soffset;
kono
parents:
diff changeset
46 const GFC_REAL_10 *sptr;
kono
parents:
diff changeset
47
kono
parents:
diff changeset
48 index_type count[GFC_MAX_DIMENSIONS];
kono
parents:
diff changeset
49 index_type extent[GFC_MAX_DIMENSIONS];
kono
parents:
diff changeset
50 index_type dim;
kono
parents:
diff changeset
51 index_type len;
kono
parents:
diff changeset
52 index_type n;
kono
parents:
diff changeset
53
kono
parents:
diff changeset
54 bool do_blocked;
kono
parents:
diff changeset
55 index_type r_ex, a_ex;
kono
parents:
diff changeset
56
kono
parents:
diff changeset
57 which = which - 1;
kono
parents:
diff changeset
58 sstride[0] = 0;
kono
parents:
diff changeset
59 rstride[0] = 0;
kono
parents:
diff changeset
60
kono
parents:
diff changeset
61 extent[0] = 1;
kono
parents:
diff changeset
62 count[0] = 0;
kono
parents:
diff changeset
63 n = 0;
kono
parents:
diff changeset
64 /* Initialized for avoiding compiler warnings. */
kono
parents:
diff changeset
65 roffset = 1;
kono
parents:
diff changeset
66 soffset = 1;
kono
parents:
diff changeset
67 len = 0;
kono
parents:
diff changeset
68
kono
parents:
diff changeset
69 r_ex = 1;
kono
parents:
diff changeset
70 a_ex = 1;
kono
parents:
diff changeset
71
kono
parents:
diff changeset
72 if (which > 0)
kono
parents:
diff changeset
73 {
kono
parents:
diff changeset
74 /* Test if both ret and array are contiguous. */
kono
parents:
diff changeset
75 do_blocked = true;
kono
parents:
diff changeset
76 dim = GFC_DESCRIPTOR_RANK (array);
kono
parents:
diff changeset
77 for (n = 0; n < dim; n ++)
kono
parents:
diff changeset
78 {
kono
parents:
diff changeset
79 index_type rs, as;
kono
parents:
diff changeset
80 rs = GFC_DESCRIPTOR_STRIDE (ret, n);
kono
parents:
diff changeset
81 if (rs != r_ex)
kono
parents:
diff changeset
82 {
kono
parents:
diff changeset
83 do_blocked = false;
kono
parents:
diff changeset
84 break;
kono
parents:
diff changeset
85 }
kono
parents:
diff changeset
86 as = GFC_DESCRIPTOR_STRIDE (array, n);
kono
parents:
diff changeset
87 if (as != a_ex)
kono
parents:
diff changeset
88 {
kono
parents:
diff changeset
89 do_blocked = false;
kono
parents:
diff changeset
90 break;
kono
parents:
diff changeset
91 }
kono
parents:
diff changeset
92 r_ex *= GFC_DESCRIPTOR_EXTENT (ret, n);
kono
parents:
diff changeset
93 a_ex *= GFC_DESCRIPTOR_EXTENT (array, n);
kono
parents:
diff changeset
94 }
kono
parents:
diff changeset
95 }
kono
parents:
diff changeset
96 else
kono
parents:
diff changeset
97 do_blocked = false;
kono
parents:
diff changeset
98
kono
parents:
diff changeset
99 n = 0;
kono
parents:
diff changeset
100
kono
parents:
diff changeset
101 if (do_blocked)
kono
parents:
diff changeset
102 {
kono
parents:
diff changeset
103 /* For contiguous arrays, use the relationship that
kono
parents:
diff changeset
104
kono
parents:
diff changeset
105 dimension(n1,n2,n3) :: a, b
kono
parents:
diff changeset
106 b = cshift(a,sh,3)
kono
parents:
diff changeset
107
kono
parents:
diff changeset
108 can be dealt with as if
kono
parents:
diff changeset
109
kono
parents:
diff changeset
110 dimension(n1*n2*n3) :: an, bn
kono
parents:
diff changeset
111 bn = cshift(a,sh*n1*n2,1)
kono
parents:
diff changeset
112
kono
parents:
diff changeset
113 we can used a more blocked algorithm for dim>1. */
kono
parents:
diff changeset
114 sstride[0] = 1;
kono
parents:
diff changeset
115 rstride[0] = 1;
kono
parents:
diff changeset
116 roffset = 1;
kono
parents:
diff changeset
117 soffset = 1;
kono
parents:
diff changeset
118 len = GFC_DESCRIPTOR_STRIDE(array, which)
kono
parents:
diff changeset
119 * GFC_DESCRIPTOR_EXTENT(array, which);
kono
parents:
diff changeset
120 shift *= GFC_DESCRIPTOR_STRIDE(array, which);
kono
parents:
diff changeset
121 for (dim = which + 1; dim < GFC_DESCRIPTOR_RANK (array); dim++)
kono
parents:
diff changeset
122 {
kono
parents:
diff changeset
123 count[n] = 0;
kono
parents:
diff changeset
124 extent[n] = GFC_DESCRIPTOR_EXTENT(array,dim);
kono
parents:
diff changeset
125 rstride[n] = GFC_DESCRIPTOR_STRIDE(ret,dim);
kono
parents:
diff changeset
126 sstride[n] = GFC_DESCRIPTOR_STRIDE(array,dim);
kono
parents:
diff changeset
127 n++;
kono
parents:
diff changeset
128 }
kono
parents:
diff changeset
129 dim = GFC_DESCRIPTOR_RANK (array) - which;
kono
parents:
diff changeset
130 }
kono
parents:
diff changeset
131 else
kono
parents:
diff changeset
132 {
kono
parents:
diff changeset
133 for (dim = 0; dim < GFC_DESCRIPTOR_RANK (array); dim++)
kono
parents:
diff changeset
134 {
kono
parents:
diff changeset
135 if (dim == which)
kono
parents:
diff changeset
136 {
kono
parents:
diff changeset
137 roffset = GFC_DESCRIPTOR_STRIDE(ret,dim);
kono
parents:
diff changeset
138 if (roffset == 0)
kono
parents:
diff changeset
139 roffset = 1;
kono
parents:
diff changeset
140 soffset = GFC_DESCRIPTOR_STRIDE(array,dim);
kono
parents:
diff changeset
141 if (soffset == 0)
kono
parents:
diff changeset
142 soffset = 1;
kono
parents:
diff changeset
143 len = GFC_DESCRIPTOR_EXTENT(array,dim);
kono
parents:
diff changeset
144 }
kono
parents:
diff changeset
145 else
kono
parents:
diff changeset
146 {
kono
parents:
diff changeset
147 count[n] = 0;
kono
parents:
diff changeset
148 extent[n] = GFC_DESCRIPTOR_EXTENT(array,dim);
kono
parents:
diff changeset
149 rstride[n] = GFC_DESCRIPTOR_STRIDE(ret,dim);
kono
parents:
diff changeset
150 sstride[n] = GFC_DESCRIPTOR_STRIDE(array,dim);
kono
parents:
diff changeset
151 n++;
kono
parents:
diff changeset
152 }
kono
parents:
diff changeset
153 }
kono
parents:
diff changeset
154 if (sstride[0] == 0)
kono
parents:
diff changeset
155 sstride[0] = 1;
kono
parents:
diff changeset
156 if (rstride[0] == 0)
kono
parents:
diff changeset
157 rstride[0] = 1;
kono
parents:
diff changeset
158
kono
parents:
diff changeset
159 dim = GFC_DESCRIPTOR_RANK (array);
kono
parents:
diff changeset
160 }
kono
parents:
diff changeset
161
kono
parents:
diff changeset
162 rstride0 = rstride[0];
kono
parents:
diff changeset
163 sstride0 = sstride[0];
kono
parents:
diff changeset
164 rptr = ret->base_addr;
kono
parents:
diff changeset
165 sptr = array->base_addr;
kono
parents:
diff changeset
166
kono
parents:
diff changeset
167 /* Avoid the costly modulo for trivially in-bound shifts. */
kono
parents:
diff changeset
168 if (shift < 0 || shift >= len)
kono
parents:
diff changeset
169 {
kono
parents:
diff changeset
170 shift = len == 0 ? 0 : shift % (ptrdiff_t)len;
kono
parents:
diff changeset
171 if (shift < 0)
kono
parents:
diff changeset
172 shift += len;
kono
parents:
diff changeset
173 }
kono
parents:
diff changeset
174
kono
parents:
diff changeset
175 while (rptr)
kono
parents:
diff changeset
176 {
kono
parents:
diff changeset
177 /* Do the shift for this dimension. */
kono
parents:
diff changeset
178
kono
parents:
diff changeset
179 /* If elements are contiguous, perform the operation
kono
parents:
diff changeset
180 in two block moves. */
kono
parents:
diff changeset
181 if (soffset == 1 && roffset == 1)
kono
parents:
diff changeset
182 {
kono
parents:
diff changeset
183 size_t len1 = shift * sizeof (GFC_REAL_10);
kono
parents:
diff changeset
184 size_t len2 = (len - shift) * sizeof (GFC_REAL_10);
kono
parents:
diff changeset
185 memcpy (rptr, sptr + shift, len2);
kono
parents:
diff changeset
186 memcpy (rptr + (len - shift), sptr, len1);
kono
parents:
diff changeset
187 }
kono
parents:
diff changeset
188 else
kono
parents:
diff changeset
189 {
kono
parents:
diff changeset
190 /* Otherwise, we will have to perform the copy one element at
kono
parents:
diff changeset
191 a time. */
kono
parents:
diff changeset
192 GFC_REAL_10 *dest = rptr;
kono
parents:
diff changeset
193 const GFC_REAL_10 *src = &sptr[shift * soffset];
kono
parents:
diff changeset
194
kono
parents:
diff changeset
195 for (n = 0; n < len - shift; n++)
kono
parents:
diff changeset
196 {
kono
parents:
diff changeset
197 *dest = *src;
kono
parents:
diff changeset
198 dest += roffset;
kono
parents:
diff changeset
199 src += soffset;
kono
parents:
diff changeset
200 }
kono
parents:
diff changeset
201 for (src = sptr, n = 0; n < shift; n++)
kono
parents:
diff changeset
202 {
kono
parents:
diff changeset
203 *dest = *src;
kono
parents:
diff changeset
204 dest += roffset;
kono
parents:
diff changeset
205 src += soffset;
kono
parents:
diff changeset
206 }
kono
parents:
diff changeset
207 }
kono
parents:
diff changeset
208
kono
parents:
diff changeset
209 /* Advance to the next section. */
kono
parents:
diff changeset
210 rptr += rstride0;
kono
parents:
diff changeset
211 sptr += sstride0;
kono
parents:
diff changeset
212 count[0]++;
kono
parents:
diff changeset
213 n = 0;
kono
parents:
diff changeset
214 while (count[n] == extent[n])
kono
parents:
diff changeset
215 {
kono
parents:
diff changeset
216 /* When we get to the end of a dimension, reset it and increment
kono
parents:
diff changeset
217 the next dimension. */
kono
parents:
diff changeset
218 count[n] = 0;
kono
parents:
diff changeset
219 /* We could precalculate these products, but this is a less
kono
parents:
diff changeset
220 frequently used path so probably not worth it. */
kono
parents:
diff changeset
221 rptr -= rstride[n] * extent[n];
kono
parents:
diff changeset
222 sptr -= sstride[n] * extent[n];
kono
parents:
diff changeset
223 n++;
kono
parents:
diff changeset
224 if (n >= dim - 1)
kono
parents:
diff changeset
225 {
kono
parents:
diff changeset
226 /* Break out of the loop. */
kono
parents:
diff changeset
227 rptr = NULL;
kono
parents:
diff changeset
228 break;
kono
parents:
diff changeset
229 }
kono
parents:
diff changeset
230 else
kono
parents:
diff changeset
231 {
kono
parents:
diff changeset
232 count[n]++;
kono
parents:
diff changeset
233 rptr += rstride[n];
kono
parents:
diff changeset
234 sptr += sstride[n];
kono
parents:
diff changeset
235 }
kono
parents:
diff changeset
236 }
kono
parents:
diff changeset
237 }
kono
parents:
diff changeset
238
kono
parents:
diff changeset
239 return;
kono
parents:
diff changeset
240 }
kono
parents:
diff changeset
241
kono
parents:
diff changeset
242 #endif