annotate libgfortran/generated/unpack_i4.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 /* Specific implementation of the UNPACK intrinsic
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>, based on
kono
parents:
diff changeset
4 unpack_generic.c by Paul Brook <paul@nowt.org>.
kono
parents:
diff changeset
5
kono
parents:
diff changeset
6 This file is part of the GNU Fortran runtime library (libgfortran).
kono
parents:
diff changeset
7
kono
parents:
diff changeset
8 Libgfortran is free software; you can redistribute it and/or
kono
parents:
diff changeset
9 modify it under the terms of the GNU General Public
kono
parents:
diff changeset
10 License as published by the Free Software Foundation; either
kono
parents:
diff changeset
11 version 3 of the License, or (at your option) any later version.
kono
parents:
diff changeset
12
kono
parents:
diff changeset
13 Ligbfortran is distributed in the hope that it will be useful,
kono
parents:
diff changeset
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
kono
parents:
diff changeset
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
kono
parents:
diff changeset
16 GNU General Public License for more details.
kono
parents:
diff changeset
17
kono
parents:
diff changeset
18 Under Section 7 of GPL version 3, you are granted additional
kono
parents:
diff changeset
19 permissions described in the GCC Runtime Library Exception, version
kono
parents:
diff changeset
20 3.1, as published by the Free Software Foundation.
kono
parents:
diff changeset
21
kono
parents:
diff changeset
22 You should have received a copy of the GNU General Public License and
kono
parents:
diff changeset
23 a copy of the GCC Runtime Library Exception along with this program;
kono
parents:
diff changeset
24 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
kono
parents:
diff changeset
25 <http://www.gnu.org/licenses/>. */
kono
parents:
diff changeset
26
kono
parents:
diff changeset
27 #include "libgfortran.h"
kono
parents:
diff changeset
28 #include <string.h>
kono
parents:
diff changeset
29
kono
parents:
diff changeset
30
kono
parents:
diff changeset
31 #if defined (HAVE_GFC_INTEGER_4)
kono
parents:
diff changeset
32
kono
parents:
diff changeset
33 void
kono
parents:
diff changeset
34 unpack0_i4 (gfc_array_i4 *ret, const gfc_array_i4 *vector,
kono
parents:
diff changeset
35 const gfc_array_l1 *mask, const GFC_INTEGER_4 *fptr)
kono
parents:
diff changeset
36 {
kono
parents:
diff changeset
37 /* r.* indicates the return array. */
kono
parents:
diff changeset
38 index_type rstride[GFC_MAX_DIMENSIONS];
kono
parents:
diff changeset
39 index_type rstride0;
kono
parents:
diff changeset
40 index_type rs;
kono
parents:
diff changeset
41 GFC_INTEGER_4 * restrict rptr;
kono
parents:
diff changeset
42 /* v.* indicates the vector array. */
kono
parents:
diff changeset
43 index_type vstride0;
kono
parents:
diff changeset
44 GFC_INTEGER_4 *vptr;
kono
parents:
diff changeset
45 /* Value for field, this is constant. */
kono
parents:
diff changeset
46 const GFC_INTEGER_4 fval = *fptr;
kono
parents:
diff changeset
47 /* m.* indicates the mask array. */
kono
parents:
diff changeset
48 index_type mstride[GFC_MAX_DIMENSIONS];
kono
parents:
diff changeset
49 index_type mstride0;
kono
parents:
diff changeset
50 const GFC_LOGICAL_1 *mptr;
kono
parents:
diff changeset
51
kono
parents:
diff changeset
52 index_type count[GFC_MAX_DIMENSIONS];
kono
parents:
diff changeset
53 index_type extent[GFC_MAX_DIMENSIONS];
kono
parents:
diff changeset
54 index_type n;
kono
parents:
diff changeset
55 index_type dim;
kono
parents:
diff changeset
56
kono
parents:
diff changeset
57 int empty;
kono
parents:
diff changeset
58 int mask_kind;
kono
parents:
diff changeset
59
kono
parents:
diff changeset
60 empty = 0;
kono
parents:
diff changeset
61
kono
parents:
diff changeset
62 mptr = mask->base_addr;
kono
parents:
diff changeset
63
kono
parents:
diff changeset
64 /* Use the same loop for all logical types, by using GFC_LOGICAL_1
kono
parents:
diff changeset
65 and using shifting to address size and endian issues. */
kono
parents:
diff changeset
66
kono
parents:
diff changeset
67 mask_kind = GFC_DESCRIPTOR_SIZE (mask);
kono
parents:
diff changeset
68
kono
parents:
diff changeset
69 if (mask_kind == 1 || mask_kind == 2 || mask_kind == 4 || mask_kind == 8
kono
parents:
diff changeset
70 #ifdef HAVE_GFC_LOGICAL_16
kono
parents:
diff changeset
71 || mask_kind == 16
kono
parents:
diff changeset
72 #endif
kono
parents:
diff changeset
73 )
kono
parents:
diff changeset
74 {
kono
parents:
diff changeset
75 /* Do not convert a NULL pointer as we use test for NULL below. */
kono
parents:
diff changeset
76 if (mptr)
kono
parents:
diff changeset
77 mptr = GFOR_POINTER_TO_L1 (mptr, mask_kind);
kono
parents:
diff changeset
78 }
kono
parents:
diff changeset
79 else
kono
parents:
diff changeset
80 runtime_error ("Funny sized logical array");
kono
parents:
diff changeset
81
kono
parents:
diff changeset
82 if (ret->base_addr == NULL)
kono
parents:
diff changeset
83 {
kono
parents:
diff changeset
84 /* The front end has signalled that we need to populate the
kono
parents:
diff changeset
85 return array descriptor. */
kono
parents:
diff changeset
86 dim = GFC_DESCRIPTOR_RANK (mask);
kono
parents:
diff changeset
87 rs = 1;
kono
parents:
diff changeset
88 for (n = 0; n < dim; n++)
kono
parents:
diff changeset
89 {
kono
parents:
diff changeset
90 count[n] = 0;
kono
parents:
diff changeset
91 GFC_DIMENSION_SET(ret->dim[n], 0,
kono
parents:
diff changeset
92 GFC_DESCRIPTOR_EXTENT(mask,n) - 1, rs);
kono
parents:
diff changeset
93 extent[n] = GFC_DESCRIPTOR_EXTENT(ret,n);
kono
parents:
diff changeset
94 empty = empty || extent[n] <= 0;
kono
parents:
diff changeset
95 rstride[n] = GFC_DESCRIPTOR_STRIDE(ret,n);
kono
parents:
diff changeset
96 mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask,n);
kono
parents:
diff changeset
97 rs *= extent[n];
kono
parents:
diff changeset
98 }
kono
parents:
diff changeset
99 ret->offset = 0;
kono
parents:
diff changeset
100 ret->base_addr = xmallocarray (rs, sizeof (GFC_INTEGER_4));
kono
parents:
diff changeset
101 }
kono
parents:
diff changeset
102 else
kono
parents:
diff changeset
103 {
kono
parents:
diff changeset
104 dim = GFC_DESCRIPTOR_RANK (ret);
kono
parents:
diff changeset
105 /* Initialize to avoid -Wmaybe-uninitialized complaints. */
kono
parents:
diff changeset
106 rstride[0] = 1;
kono
parents:
diff changeset
107 for (n = 0; n < dim; n++)
kono
parents:
diff changeset
108 {
kono
parents:
diff changeset
109 count[n] = 0;
kono
parents:
diff changeset
110 extent[n] = GFC_DESCRIPTOR_EXTENT(ret,n);
kono
parents:
diff changeset
111 empty = empty || extent[n] <= 0;
kono
parents:
diff changeset
112 rstride[n] = GFC_DESCRIPTOR_STRIDE(ret,n);
kono
parents:
diff changeset
113 mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask,n);
kono
parents:
diff changeset
114 }
kono
parents:
diff changeset
115 if (rstride[0] == 0)
kono
parents:
diff changeset
116 rstride[0] = 1;
kono
parents:
diff changeset
117 }
kono
parents:
diff changeset
118
kono
parents:
diff changeset
119 if (empty)
kono
parents:
diff changeset
120 return;
kono
parents:
diff changeset
121
kono
parents:
diff changeset
122 if (mstride[0] == 0)
kono
parents:
diff changeset
123 mstride[0] = 1;
kono
parents:
diff changeset
124
kono
parents:
diff changeset
125 vstride0 = GFC_DESCRIPTOR_STRIDE(vector,0);
kono
parents:
diff changeset
126 if (vstride0 == 0)
kono
parents:
diff changeset
127 vstride0 = 1;
kono
parents:
diff changeset
128 rstride0 = rstride[0];
kono
parents:
diff changeset
129 mstride0 = mstride[0];
kono
parents:
diff changeset
130 rptr = ret->base_addr;
kono
parents:
diff changeset
131 vptr = vector->base_addr;
kono
parents:
diff changeset
132
kono
parents:
diff changeset
133 while (rptr)
kono
parents:
diff changeset
134 {
kono
parents:
diff changeset
135 if (*mptr)
kono
parents:
diff changeset
136 {
kono
parents:
diff changeset
137 /* From vector. */
kono
parents:
diff changeset
138 *rptr = *vptr;
kono
parents:
diff changeset
139 vptr += vstride0;
kono
parents:
diff changeset
140 }
kono
parents:
diff changeset
141 else
kono
parents:
diff changeset
142 {
kono
parents:
diff changeset
143 /* From field. */
kono
parents:
diff changeset
144 *rptr = fval;
kono
parents:
diff changeset
145 }
kono
parents:
diff changeset
146 /* Advance to the next element. */
kono
parents:
diff changeset
147 rptr += rstride0;
kono
parents:
diff changeset
148 mptr += mstride0;
kono
parents:
diff changeset
149 count[0]++;
kono
parents:
diff changeset
150 n = 0;
kono
parents:
diff changeset
151 while (count[n] == extent[n])
kono
parents:
diff changeset
152 {
kono
parents:
diff changeset
153 /* When we get to the end of a dimension, reset it and increment
kono
parents:
diff changeset
154 the next dimension. */
kono
parents:
diff changeset
155 count[n] = 0;
kono
parents:
diff changeset
156 /* We could precalculate these products, but this is a less
kono
parents:
diff changeset
157 frequently used path so probably not worth it. */
kono
parents:
diff changeset
158 rptr -= rstride[n] * extent[n];
kono
parents:
diff changeset
159 mptr -= mstride[n] * extent[n];
kono
parents:
diff changeset
160 n++;
kono
parents:
diff changeset
161 if (n >= dim)
kono
parents:
diff changeset
162 {
kono
parents:
diff changeset
163 /* Break out of the loop. */
kono
parents:
diff changeset
164 rptr = NULL;
kono
parents:
diff changeset
165 break;
kono
parents:
diff changeset
166 }
kono
parents:
diff changeset
167 else
kono
parents:
diff changeset
168 {
kono
parents:
diff changeset
169 count[n]++;
kono
parents:
diff changeset
170 rptr += rstride[n];
kono
parents:
diff changeset
171 mptr += mstride[n];
kono
parents:
diff changeset
172 }
kono
parents:
diff changeset
173 }
kono
parents:
diff changeset
174 }
kono
parents:
diff changeset
175 }
kono
parents:
diff changeset
176
kono
parents:
diff changeset
177 void
kono
parents:
diff changeset
178 unpack1_i4 (gfc_array_i4 *ret, const gfc_array_i4 *vector,
kono
parents:
diff changeset
179 const gfc_array_l1 *mask, const gfc_array_i4 *field)
kono
parents:
diff changeset
180 {
kono
parents:
diff changeset
181 /* r.* indicates the return array. */
kono
parents:
diff changeset
182 index_type rstride[GFC_MAX_DIMENSIONS];
kono
parents:
diff changeset
183 index_type rstride0;
kono
parents:
diff changeset
184 index_type rs;
kono
parents:
diff changeset
185 GFC_INTEGER_4 * restrict rptr;
kono
parents:
diff changeset
186 /* v.* indicates the vector array. */
kono
parents:
diff changeset
187 index_type vstride0;
kono
parents:
diff changeset
188 GFC_INTEGER_4 *vptr;
kono
parents:
diff changeset
189 /* f.* indicates the field array. */
kono
parents:
diff changeset
190 index_type fstride[GFC_MAX_DIMENSIONS];
kono
parents:
diff changeset
191 index_type fstride0;
kono
parents:
diff changeset
192 const GFC_INTEGER_4 *fptr;
kono
parents:
diff changeset
193 /* m.* indicates the mask array. */
kono
parents:
diff changeset
194 index_type mstride[GFC_MAX_DIMENSIONS];
kono
parents:
diff changeset
195 index_type mstride0;
kono
parents:
diff changeset
196 const GFC_LOGICAL_1 *mptr;
kono
parents:
diff changeset
197
kono
parents:
diff changeset
198 index_type count[GFC_MAX_DIMENSIONS];
kono
parents:
diff changeset
199 index_type extent[GFC_MAX_DIMENSIONS];
kono
parents:
diff changeset
200 index_type n;
kono
parents:
diff changeset
201 index_type dim;
kono
parents:
diff changeset
202
kono
parents:
diff changeset
203 int empty;
kono
parents:
diff changeset
204 int mask_kind;
kono
parents:
diff changeset
205
kono
parents:
diff changeset
206 empty = 0;
kono
parents:
diff changeset
207
kono
parents:
diff changeset
208 mptr = mask->base_addr;
kono
parents:
diff changeset
209
kono
parents:
diff changeset
210 /* Use the same loop for all logical types, by using GFC_LOGICAL_1
kono
parents:
diff changeset
211 and using shifting to address size and endian issues. */
kono
parents:
diff changeset
212
kono
parents:
diff changeset
213 mask_kind = GFC_DESCRIPTOR_SIZE (mask);
kono
parents:
diff changeset
214
kono
parents:
diff changeset
215 if (mask_kind == 1 || mask_kind == 2 || mask_kind == 4 || mask_kind == 8
kono
parents:
diff changeset
216 #ifdef HAVE_GFC_LOGICAL_16
kono
parents:
diff changeset
217 || mask_kind == 16
kono
parents:
diff changeset
218 #endif
kono
parents:
diff changeset
219 )
kono
parents:
diff changeset
220 {
kono
parents:
diff changeset
221 /* Do not convert a NULL pointer as we use test for NULL below. */
kono
parents:
diff changeset
222 if (mptr)
kono
parents:
diff changeset
223 mptr = GFOR_POINTER_TO_L1 (mptr, mask_kind);
kono
parents:
diff changeset
224 }
kono
parents:
diff changeset
225 else
kono
parents:
diff changeset
226 runtime_error ("Funny sized logical array");
kono
parents:
diff changeset
227
kono
parents:
diff changeset
228 if (ret->base_addr == NULL)
kono
parents:
diff changeset
229 {
kono
parents:
diff changeset
230 /* The front end has signalled that we need to populate the
kono
parents:
diff changeset
231 return array descriptor. */
kono
parents:
diff changeset
232 dim = GFC_DESCRIPTOR_RANK (mask);
kono
parents:
diff changeset
233 rs = 1;
kono
parents:
diff changeset
234 for (n = 0; n < dim; n++)
kono
parents:
diff changeset
235 {
kono
parents:
diff changeset
236 count[n] = 0;
kono
parents:
diff changeset
237 GFC_DIMENSION_SET(ret->dim[n], 0,
kono
parents:
diff changeset
238 GFC_DESCRIPTOR_EXTENT(mask,n) - 1, rs);
kono
parents:
diff changeset
239 extent[n] = GFC_DESCRIPTOR_EXTENT(ret,n);
kono
parents:
diff changeset
240 empty = empty || extent[n] <= 0;
kono
parents:
diff changeset
241 rstride[n] = GFC_DESCRIPTOR_STRIDE(ret,n);
kono
parents:
diff changeset
242 fstride[n] = GFC_DESCRIPTOR_STRIDE(field,n);
kono
parents:
diff changeset
243 mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask,n);
kono
parents:
diff changeset
244 rs *= extent[n];
kono
parents:
diff changeset
245 }
kono
parents:
diff changeset
246 ret->offset = 0;
kono
parents:
diff changeset
247 ret->base_addr = xmallocarray (rs, sizeof (GFC_INTEGER_4));
kono
parents:
diff changeset
248 }
kono
parents:
diff changeset
249 else
kono
parents:
diff changeset
250 {
kono
parents:
diff changeset
251 dim = GFC_DESCRIPTOR_RANK (ret);
kono
parents:
diff changeset
252 /* Initialize to avoid -Wmaybe-uninitialized complaints. */
kono
parents:
diff changeset
253 rstride[0] = 1;
kono
parents:
diff changeset
254 for (n = 0; n < dim; n++)
kono
parents:
diff changeset
255 {
kono
parents:
diff changeset
256 count[n] = 0;
kono
parents:
diff changeset
257 extent[n] = GFC_DESCRIPTOR_EXTENT(ret,n);
kono
parents:
diff changeset
258 empty = empty || extent[n] <= 0;
kono
parents:
diff changeset
259 rstride[n] = GFC_DESCRIPTOR_STRIDE(ret,n);
kono
parents:
diff changeset
260 fstride[n] = GFC_DESCRIPTOR_STRIDE(field,n);
kono
parents:
diff changeset
261 mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask,n);
kono
parents:
diff changeset
262 }
kono
parents:
diff changeset
263 if (rstride[0] == 0)
kono
parents:
diff changeset
264 rstride[0] = 1;
kono
parents:
diff changeset
265 }
kono
parents:
diff changeset
266
kono
parents:
diff changeset
267 if (empty)
kono
parents:
diff changeset
268 return;
kono
parents:
diff changeset
269
kono
parents:
diff changeset
270 if (fstride[0] == 0)
kono
parents:
diff changeset
271 fstride[0] = 1;
kono
parents:
diff changeset
272 if (mstride[0] == 0)
kono
parents:
diff changeset
273 mstride[0] = 1;
kono
parents:
diff changeset
274
kono
parents:
diff changeset
275 vstride0 = GFC_DESCRIPTOR_STRIDE(vector,0);
kono
parents:
diff changeset
276 if (vstride0 == 0)
kono
parents:
diff changeset
277 vstride0 = 1;
kono
parents:
diff changeset
278 rstride0 = rstride[0];
kono
parents:
diff changeset
279 fstride0 = fstride[0];
kono
parents:
diff changeset
280 mstride0 = mstride[0];
kono
parents:
diff changeset
281 rptr = ret->base_addr;
kono
parents:
diff changeset
282 fptr = field->base_addr;
kono
parents:
diff changeset
283 vptr = vector->base_addr;
kono
parents:
diff changeset
284
kono
parents:
diff changeset
285 while (rptr)
kono
parents:
diff changeset
286 {
kono
parents:
diff changeset
287 if (*mptr)
kono
parents:
diff changeset
288 {
kono
parents:
diff changeset
289 /* From vector. */
kono
parents:
diff changeset
290 *rptr = *vptr;
kono
parents:
diff changeset
291 vptr += vstride0;
kono
parents:
diff changeset
292 }
kono
parents:
diff changeset
293 else
kono
parents:
diff changeset
294 {
kono
parents:
diff changeset
295 /* From field. */
kono
parents:
diff changeset
296 *rptr = *fptr;
kono
parents:
diff changeset
297 }
kono
parents:
diff changeset
298 /* Advance to the next element. */
kono
parents:
diff changeset
299 rptr += rstride0;
kono
parents:
diff changeset
300 fptr += fstride0;
kono
parents:
diff changeset
301 mptr += mstride0;
kono
parents:
diff changeset
302 count[0]++;
kono
parents:
diff changeset
303 n = 0;
kono
parents:
diff changeset
304 while (count[n] == extent[n])
kono
parents:
diff changeset
305 {
kono
parents:
diff changeset
306 /* When we get to the end of a dimension, reset it and increment
kono
parents:
diff changeset
307 the next dimension. */
kono
parents:
diff changeset
308 count[n] = 0;
kono
parents:
diff changeset
309 /* We could precalculate these products, but this is a less
kono
parents:
diff changeset
310 frequently used path so probably not worth it. */
kono
parents:
diff changeset
311 rptr -= rstride[n] * extent[n];
kono
parents:
diff changeset
312 fptr -= fstride[n] * extent[n];
kono
parents:
diff changeset
313 mptr -= mstride[n] * extent[n];
kono
parents:
diff changeset
314 n++;
kono
parents:
diff changeset
315 if (n >= dim)
kono
parents:
diff changeset
316 {
kono
parents:
diff changeset
317 /* Break out of the loop. */
kono
parents:
diff changeset
318 rptr = NULL;
kono
parents:
diff changeset
319 break;
kono
parents:
diff changeset
320 }
kono
parents:
diff changeset
321 else
kono
parents:
diff changeset
322 {
kono
parents:
diff changeset
323 count[n]++;
kono
parents:
diff changeset
324 rptr += rstride[n];
kono
parents:
diff changeset
325 fptr += fstride[n];
kono
parents:
diff changeset
326 mptr += mstride[n];
kono
parents:
diff changeset
327 }
kono
parents:
diff changeset
328 }
kono
parents:
diff changeset
329 }
kono
parents:
diff changeset
330 }
kono
parents:
diff changeset
331
kono
parents:
diff changeset
332 #endif
kono
parents:
diff changeset
333