]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgfortran/intrinsics/unpack_generic.c
Update copyright years.
[thirdparty/gcc.git] / libgfortran / intrinsics / unpack_generic.c
CommitLineData
ba4a3d54 1/* Generic implementation of the UNPACK intrinsic
5624e564 2 Copyright (C) 2002-2015 Free Software Foundation, Inc.
6de9cd9a
DN
3 Contributed by Paul Brook <paul@nowt.org>
4
21d1335b 5This file is part of the GNU Fortran 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
748086b7 10version 3 of the License, or (at your option) any later version.
57dea9f6
TM
11
12Ligbfortran is distributed in the hope that it will be useful,
6de9cd9a
DN
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
57dea9f6 15GNU General Public License for more details.
6de9cd9a 16
748086b7
JJ
17Under Section 7 of GPL version 3, you are granted additional
18permissions described in the GCC Runtime Library Exception, version
193.1, as published by the Free Software Foundation.
20
21You should have received a copy of the GNU General Public License and
22a copy of the GCC Runtime Library Exception along with this program;
23see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24<http://www.gnu.org/licenses/>. */
6de9cd9a 25
36ae8a61 26#include "libgfortran.h"
6de9cd9a
DN
27#include <stdlib.h>
28#include <assert.h>
29#include <string.h>
6de9cd9a 30
8c39b987
TK
31/* All the bounds checking for unpack in one function. If field is NULL,
32 we don't check it, for the unpack0 functions. */
33
34static void
35unpack_bounds (gfc_array_char *ret, const gfc_array_char *vector,
36 const gfc_array_l1 *mask, const gfc_array_char *field)
37{
38 index_type vec_size, mask_count;
39 vec_size = size0 ((array_t *) vector);
40 mask_count = count_0 (mask);
41 if (vec_size < mask_count)
42 runtime_error ("Incorrect size of return value in UNPACK"
43 " intrinsic: should be at least %ld, is"
44 " %ld", (long int) mask_count,
45 (long int) vec_size);
46
47 if (field != NULL)
48 bounds_equal_extents ((array_t *) field, (array_t *) mask,
49 "FIELD", "UNPACK");
50
21d1335b 51 if (ret->base_addr != NULL)
8c39b987
TK
52 bounds_equal_extents ((array_t *) ret, (array_t *) mask,
53 "return value", "UNPACK");
54
55}
56
7823229b
RS
57static void
58unpack_internal (gfc_array_char *ret, const gfc_array_char *vector,
28dc6b33 59 const gfc_array_l1 *mask, const gfc_array_char *field,
23db9913 60 index_type size)
6de9cd9a
DN
61{
62 /* r.* indicates the return array. */
63 index_type rstride[GFC_MAX_DIMENSIONS];
64 index_type rstride0;
ba4a3d54 65 index_type rs;
5863aacf 66 char * restrict rptr;
6de9cd9a
DN
67 /* v.* indicates the vector array. */
68 index_type vstride0;
69 char *vptr;
70 /* f.* indicates the field array. */
71 index_type fstride[GFC_MAX_DIMENSIONS];
72 index_type fstride0;
73 const char *fptr;
74 /* m.* indicates the mask array. */
75 index_type mstride[GFC_MAX_DIMENSIONS];
76 index_type mstride0;
28dc6b33 77 const GFC_LOGICAL_1 *mptr;
6de9cd9a
DN
78
79 index_type count[GFC_MAX_DIMENSIONS];
80 index_type extent[GFC_MAX_DIMENSIONS];
81 index_type n;
82 index_type dim;
6de9cd9a 83
fb263f82 84 int empty;
28dc6b33 85 int mask_kind;
fb263f82
TK
86
87 empty = 0;
28dc6b33 88
21d1335b 89 mptr = mask->base_addr;
28dc6b33
TK
90
91 /* Use the same loop for all logical types, by using GFC_LOGICAL_1
92 and using shifting to address size and endian issues. */
93
94 mask_kind = GFC_DESCRIPTOR_SIZE (mask);
95
96 if (mask_kind == 1 || mask_kind == 2 || mask_kind == 4 || mask_kind == 8
97#ifdef HAVE_GFC_LOGICAL_16
98 || mask_kind == 16
99#endif
100 )
101 {
102 /* Don't convert a NULL pointer as we use test for NULL below. */
103 if (mptr)
104 mptr = GFOR_POINTER_TO_L1 (mptr, mask_kind);
105 }
106 else
107 runtime_error ("Funny sized logical array");
108
21d1335b 109 if (ret->base_addr == NULL)
6de9cd9a 110 {
ba4a3d54
TK
111 /* The front end has signalled that we need to populate the
112 return array descriptor. */
113 dim = GFC_DESCRIPTOR_RANK (mask);
114 rs = 1;
115 for (n = 0; n < dim; n++)
116 {
117 count[n] = 0;
dfb55fdc
TK
118 GFC_DIMENSION_SET(ret->dim[n], 0,
119 GFC_DESCRIPTOR_EXTENT(mask,n) - 1, rs);
120 extent[n] = GFC_DESCRIPTOR_EXTENT(ret,n);
fb263f82 121 empty = empty || extent[n] <= 0;
dfb55fdc
TK
122 rstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(ret, n);
123 fstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(field, n);
124 mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask, n);
ba4a3d54
TK
125 rs *= extent[n];
126 }
efd4dc1a 127 ret->offset = 0;
92e6f3a4 128 ret->base_addr = xmallocarray (rs, size);
ba4a3d54
TK
129 }
130 else
131 {
132 dim = GFC_DESCRIPTOR_RANK (ret);
133 for (n = 0; n < dim; n++)
134 {
135 count[n] = 0;
dfb55fdc 136 extent[n] = GFC_DESCRIPTOR_EXTENT(ret,n);
fb263f82 137 empty = empty || extent[n] <= 0;
dfb55fdc
TK
138 rstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(ret, n);
139 fstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(field, n);
140 mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask, n);
ba4a3d54 141 }
6de9cd9a 142 }
fb263f82
TK
143
144 if (empty)
145 return;
146
74bc175e
FXC
147 /* This assert makes sure GCC knows we can access *stride[0] later. */
148 assert (dim > 0);
149
dfb55fdc 150 vstride0 = GFC_DESCRIPTOR_STRIDE_BYTES(vector,0);
6de9cd9a
DN
151 rstride0 = rstride[0];
152 fstride0 = fstride[0];
153 mstride0 = mstride[0];
21d1335b
TB
154 rptr = ret->base_addr;
155 fptr = field->base_addr;
156 vptr = vector->base_addr;
6de9cd9a 157
6de9cd9a
DN
158 while (rptr)
159 {
160 if (*mptr)
161 {
162 /* From vector. */
163 memcpy (rptr, vptr, size);
164 vptr += vstride0;
165 }
166 else
167 {
168 /* From field. */
169 memcpy (rptr, fptr, size);
170 }
171 /* Advance to the next element. */
172 rptr += rstride0;
173 fptr += fstride0;
174 mptr += mstride0;
175 count[0]++;
176 n = 0;
177 while (count[n] == extent[n])
178 {
179 /* When we get to the end of a dimension, reset it and increment
180 the next dimension. */
181 count[n] = 0;
182 /* We could precalculate these products, but this is a less
8b6dba81 183 frequently used path so probably not worth it. */
6de9cd9a
DN
184 rptr -= rstride[n] * extent[n];
185 fptr -= fstride[n] * extent[n];
186 mptr -= mstride[n] * extent[n];
187 n++;
188 if (n >= dim)
189 {
190 /* Break out of the loop. */
191 rptr = NULL;
192 break;
193 }
194 else
195 {
196 count[n]++;
197 rptr += rstride[n];
198 fptr += fstride[n];
199 mptr += mstride[n];
200 }
201 }
202 }
203}
7823229b
RS
204
205extern void unpack1 (gfc_array_char *, const gfc_array_char *,
e6082041 206 const gfc_array_l1 *, const gfc_array_char *);
7823229b
RS
207export_proto(unpack1);
208
209void
210unpack1 (gfc_array_char *ret, const gfc_array_char *vector,
e6082041 211 const gfc_array_l1 *mask, const gfc_array_char *field)
7823229b 212{
c7d0f4d5 213 index_type type_size;
3478bba4
TK
214 index_type size;
215
8c39b987
TK
216 if (unlikely(compile_options.bounds_check))
217 unpack_bounds (ret, vector, mask, field);
218
c7d0f4d5 219 type_size = GFC_DTYPE_TYPE_SIZE (vector);
3478bba4
TK
220 size = GFC_DESCRIPTOR_SIZE (vector);
221
c7d0f4d5 222 switch(type_size)
3478bba4 223 {
c7d0f4d5
TK
224 case GFC_DTYPE_LOGICAL_1:
225 case GFC_DTYPE_INTEGER_1:
226 case GFC_DTYPE_DERIVED_1:
227 unpack1_i1 ((gfc_array_i1 *) ret, (gfc_array_i1 *) vector,
228 mask, (gfc_array_i1 *) field);
229 return;
230
231 case GFC_DTYPE_LOGICAL_2:
232 case GFC_DTYPE_INTEGER_2:
233 unpack1_i2 ((gfc_array_i2 *) ret, (gfc_array_i2 *) vector,
234 mask, (gfc_array_i2 *) field);
235 return;
236
237 case GFC_DTYPE_LOGICAL_4:
238 case GFC_DTYPE_INTEGER_4:
239 unpack1_i4 ((gfc_array_i4 *) ret, (gfc_array_i4 *) vector,
240 mask, (gfc_array_i4 *) field);
241 return;
242
243 case GFC_DTYPE_LOGICAL_8:
244 case GFC_DTYPE_INTEGER_8:
245 unpack1_i8 ((gfc_array_i8 *) ret, (gfc_array_i8 *) vector,
246 mask, (gfc_array_i8 *) field);
247 return;
3478bba4
TK
248
249#ifdef HAVE_GFC_INTEGER_16
c7d0f4d5
TK
250 case GFC_DTYPE_LOGICAL_16:
251 case GFC_DTYPE_INTEGER_16:
252 unpack1_i16 ((gfc_array_i16 *) ret, (gfc_array_i16 *) vector,
253 mask, (gfc_array_i16 *) field);
254 return;
3478bba4 255#endif
075abad5 256
c7d0f4d5
TK
257 case GFC_DTYPE_REAL_4:
258 unpack1_r4 ((gfc_array_r4 *) ret, (gfc_array_r4 *) vector,
259 mask, (gfc_array_r4 *) field);
260 return;
3478bba4 261
c7d0f4d5
TK
262 case GFC_DTYPE_REAL_8:
263 unpack1_r8 ((gfc_array_r8 *) ret, (gfc_array_r8 *) vector,
264 mask, (gfc_array_r8 *) field);
265 return;
3478bba4 266
1ec601bf
FXC
267/* FIXME: This here is a hack, which will have to be removed when
268 the array descriptor is reworked. Currently, we don't store the
269 kind value for the type, but only the size. Because on targets with
270 __float128, we have sizeof(logn double) == sizeof(__float128),
271 we cannot discriminate here and have to fall back to the generic
272 handling (which is suboptimal). */
273#if !defined(GFC_REAL_16_IS_FLOAT128)
274# ifdef HAVE_GFC_REAL_10
c7d0f4d5
TK
275 case GFC_DTYPE_REAL_10:
276 unpack1_r10 ((gfc_array_r10 *) ret, (gfc_array_r10 *) vector,
277 mask, (gfc_array_r10 *) field);
075abad5 278 return;
1ec601bf 279# endif
3478bba4 280
1ec601bf 281# ifdef HAVE_GFC_REAL_16
c7d0f4d5
TK
282 case GFC_DTYPE_REAL_16:
283 unpack1_r16 ((gfc_array_r16 *) ret, (gfc_array_r16 *) vector,
284 mask, (gfc_array_r16 *) field);
285 return;
1ec601bf 286# endif
3478bba4 287#endif
3478bba4 288
c7d0f4d5
TK
289 case GFC_DTYPE_COMPLEX_4:
290 unpack1_c4 ((gfc_array_c4 *) ret, (gfc_array_c4 *) vector,
291 mask, (gfc_array_c4 *) field);
292 return;
3478bba4 293
c7d0f4d5
TK
294 case GFC_DTYPE_COMPLEX_8:
295 unpack1_c8 ((gfc_array_c8 *) ret, (gfc_array_c8 *) vector,
296 mask, (gfc_array_c8 *) field);
297 return;
3478bba4 298
1ec601bf
FXC
299/* FIXME: This here is a hack, which will have to be removed when
300 the array descriptor is reworked. Currently, we don't store the
301 kind value for the type, but only the size. Because on targets with
302 __float128, we have sizeof(logn double) == sizeof(__float128),
303 we cannot discriminate here and have to fall back to the generic
304 handling (which is suboptimal). */
305#if !defined(GFC_REAL_16_IS_FLOAT128)
306# ifdef HAVE_GFC_COMPLEX_10
c7d0f4d5
TK
307 case GFC_DTYPE_COMPLEX_10:
308 unpack1_c10 ((gfc_array_c10 *) ret, (gfc_array_c10 *) vector,
309 mask, (gfc_array_c10 *) field);
310 return;
1ec601bf 311# endif
3478bba4 312
1ec601bf 313# ifdef HAVE_GFC_COMPLEX_16
c7d0f4d5
TK
314 case GFC_DTYPE_COMPLEX_16:
315 unpack1_c16 ((gfc_array_c16 *) ret, (gfc_array_c16 *) vector,
316 mask, (gfc_array_c16 *) field);
317 return;
1ec601bf 318# endif
3478bba4 319#endif
c7d0f4d5
TK
320
321 case GFC_DTYPE_DERIVED_2:
21d1335b
TB
322 if (GFC_UNALIGNED_2(ret->base_addr) || GFC_UNALIGNED_2(vector->base_addr)
323 || GFC_UNALIGNED_2(field->base_addr))
c7d0f4d5
TK
324 break;
325 else
326 {
327 unpack1_i2 ((gfc_array_i2 *) ret, (gfc_array_i2 *) vector,
328 mask, (gfc_array_i2 *) field);
329 return;
330 }
331
332 case GFC_DTYPE_DERIVED_4:
21d1335b
TB
333 if (GFC_UNALIGNED_4(ret->base_addr) || GFC_UNALIGNED_4(vector->base_addr)
334 || GFC_UNALIGNED_4(field->base_addr))
c7d0f4d5
TK
335 break;
336 else
337 {
338 unpack1_i4 ((gfc_array_i4 *) ret, (gfc_array_i4 *) vector,
339 mask, (gfc_array_i4 *) field);
340 return;
341 }
342
343 case GFC_DTYPE_DERIVED_8:
21d1335b
TB
344 if (GFC_UNALIGNED_8(ret->base_addr) || GFC_UNALIGNED_8(vector->base_addr)
345 || GFC_UNALIGNED_8(field->base_addr))
c7d0f4d5
TK
346 break;
347 else
348 {
349 unpack1_i8 ((gfc_array_i8 *) ret, (gfc_array_i8 *) vector,
350 mask, (gfc_array_i8 *) field);
351 return;
3478bba4
TK
352 }
353
c7d0f4d5
TK
354#ifdef HAVE_GFC_INTEGER_16
355 case GFC_DTYPE_DERIVED_16:
21d1335b
TB
356 if (GFC_UNALIGNED_16(ret->base_addr)
357 || GFC_UNALIGNED_16(vector->base_addr)
358 || GFC_UNALIGNED_16(field->base_addr))
c7d0f4d5
TK
359 break;
360 else
361 {
362 unpack1_i16 ((gfc_array_i16 *) ret, (gfc_array_i16 *) vector,
363 mask, (gfc_array_i16 *) field);
364 return;
365 }
366#endif
3478bba4 367 }
c7d0f4d5 368
23db9913 369 unpack_internal (ret, vector, mask, field, size);
7823229b
RS
370}
371
3571925e 372
7823229b 373extern void unpack1_char (gfc_array_char *, GFC_INTEGER_4,
e6082041 374 const gfc_array_char *, const gfc_array_l1 *,
7823229b
RS
375 const gfc_array_char *, GFC_INTEGER_4,
376 GFC_INTEGER_4);
377export_proto(unpack1_char);
378
379void
380unpack1_char (gfc_array_char *ret,
381 GFC_INTEGER_4 ret_length __attribute__((unused)),
e6082041 382 const gfc_array_char *vector, const gfc_array_l1 *mask,
7823229b 383 const gfc_array_char *field, GFC_INTEGER_4 vector_length,
23db9913 384 GFC_INTEGER_4 field_length __attribute__((unused)))
7823229b 385{
8c39b987
TK
386
387 if (unlikely(compile_options.bounds_check))
388 unpack_bounds (ret, vector, mask, field);
389
23db9913 390 unpack_internal (ret, vector, mask, field, vector_length);
7823229b 391}
6de9cd9a 392
3571925e
FXC
393
394extern void unpack1_char4 (gfc_array_char *, GFC_INTEGER_4,
395 const gfc_array_char *, const gfc_array_l1 *,
396 const gfc_array_char *, GFC_INTEGER_4,
397 GFC_INTEGER_4);
398export_proto(unpack1_char4);
399
400void
401unpack1_char4 (gfc_array_char *ret,
402 GFC_INTEGER_4 ret_length __attribute__((unused)),
403 const gfc_array_char *vector, const gfc_array_l1 *mask,
404 const gfc_array_char *field, GFC_INTEGER_4 vector_length,
23db9913 405 GFC_INTEGER_4 field_length __attribute__((unused)))
3571925e 406{
8c39b987
TK
407
408 if (unlikely(compile_options.bounds_check))
409 unpack_bounds (ret, vector, mask, field);
410
3571925e 411 unpack_internal (ret, vector, mask, field,
23db9913 412 vector_length * sizeof (gfc_char4_t));
3571925e
FXC
413}
414
415
a3b6aba2 416extern void unpack0 (gfc_array_char *, const gfc_array_char *,
e6082041 417 const gfc_array_l1 *, char *);
7f68c75f 418export_proto(unpack0);
7d7b8bfe 419
6de9cd9a 420void
a3b6aba2 421unpack0 (gfc_array_char *ret, const gfc_array_char *vector,
e6082041 422 const gfc_array_l1 *mask, char *field)
6de9cd9a
DN
423{
424 gfc_array_char tmp;
425
c7d0f4d5 426 index_type type_size;
3478bba4 427
8c39b987
TK
428 if (unlikely(compile_options.bounds_check))
429 unpack_bounds (ret, vector, mask, NULL);
430
c7d0f4d5 431 type_size = GFC_DTYPE_TYPE_SIZE (vector);
3478bba4 432
14ca4cf8 433 switch (type_size)
3478bba4 434 {
c7d0f4d5
TK
435 case GFC_DTYPE_LOGICAL_1:
436 case GFC_DTYPE_INTEGER_1:
437 case GFC_DTYPE_DERIVED_1:
438 unpack0_i1 ((gfc_array_i1 *) ret, (gfc_array_i1 *) vector,
439 mask, (GFC_INTEGER_1 *) field);
440 return;
441
442 case GFC_DTYPE_LOGICAL_2:
443 case GFC_DTYPE_INTEGER_2:
444 unpack0_i2 ((gfc_array_i2 *) ret, (gfc_array_i2 *) vector,
445 mask, (GFC_INTEGER_2 *) field);
446 return;
447
448 case GFC_DTYPE_LOGICAL_4:
449 case GFC_DTYPE_INTEGER_4:
450 unpack0_i4 ((gfc_array_i4 *) ret, (gfc_array_i4 *) vector,
451 mask, (GFC_INTEGER_4 *) field);
452 return;
453
454 case GFC_DTYPE_LOGICAL_8:
455 case GFC_DTYPE_INTEGER_8:
456 unpack0_i8 ((gfc_array_i8 *) ret, (gfc_array_i8 *) vector,
457 mask, (GFC_INTEGER_8 *) field);
458 return;
3478bba4
TK
459
460#ifdef HAVE_GFC_INTEGER_16
c7d0f4d5
TK
461 case GFC_DTYPE_LOGICAL_16:
462 case GFC_DTYPE_INTEGER_16:
463 unpack0_i16 ((gfc_array_i16 *) ret, (gfc_array_i16 *) vector,
464 mask, (GFC_INTEGER_16 *) field);
465 return;
3478bba4 466#endif
075abad5 467
c7d0f4d5
TK
468 case GFC_DTYPE_REAL_4:
469 unpack0_r4 ((gfc_array_r4 *) ret, (gfc_array_r4 *) vector,
470 mask, (GFC_REAL_4 *) field);
471 return;
3478bba4 472
c7d0f4d5
TK
473 case GFC_DTYPE_REAL_8:
474 unpack0_r8 ((gfc_array_r8 *) ret, (gfc_array_r8*) vector,
475 mask, (GFC_REAL_8 *) field);
476 return;
3478bba4 477
1ec601bf
FXC
478/* FIXME: This here is a hack, which will have to be removed when
479 the array descriptor is reworked. Currently, we don't store the
480 kind value for the type, but only the size. Because on targets with
481 __float128, we have sizeof(logn double) == sizeof(__float128),
482 we cannot discriminate here and have to fall back to the generic
483 handling (which is suboptimal). */
484#if !defined(GFC_REAL_16_IS_FLOAT128)
485# ifdef HAVE_GFC_REAL_10
c7d0f4d5
TK
486 case GFC_DTYPE_REAL_10:
487 unpack0_r10 ((gfc_array_r10 *) ret, (gfc_array_r10 *) vector,
488 mask, (GFC_REAL_10 *) field);
489 return;
1ec601bf 490# endif
3478bba4 491
1ec601bf 492# ifdef HAVE_GFC_REAL_16
c7d0f4d5
TK
493 case GFC_DTYPE_REAL_16:
494 unpack0_r16 ((gfc_array_r16 *) ret, (gfc_array_r16 *) vector,
495 mask, (GFC_REAL_16 *) field);
496 return;
1ec601bf 497# endif
3478bba4 498#endif
3478bba4 499
c7d0f4d5
TK
500 case GFC_DTYPE_COMPLEX_4:
501 unpack0_c4 ((gfc_array_c4 *) ret, (gfc_array_c4 *) vector,
502 mask, (GFC_COMPLEX_4 *) field);
503 return;
3478bba4 504
c7d0f4d5
TK
505 case GFC_DTYPE_COMPLEX_8:
506 unpack0_c8 ((gfc_array_c8 *) ret, (gfc_array_c8 *) vector,
507 mask, (GFC_COMPLEX_8 *) field);
508 return;
3478bba4 509
1ec601bf
FXC
510/* FIXME: This here is a hack, which will have to be removed when
511 the array descriptor is reworked. Currently, we don't store the
512 kind value for the type, but only the size. Because on targets with
513 __float128, we have sizeof(logn double) == sizeof(__float128),
514 we cannot discriminate here and have to fall back to the generic
515 handling (which is suboptimal). */
516#if !defined(GFC_REAL_16_IS_FLOAT128)
517# ifdef HAVE_GFC_COMPLEX_10
c7d0f4d5
TK
518 case GFC_DTYPE_COMPLEX_10:
519 unpack0_c10 ((gfc_array_c10 *) ret, (gfc_array_c10 *) vector,
520 mask, (GFC_COMPLEX_10 *) field);
521 return;
1ec601bf 522# endif
3478bba4 523
1ec601bf 524# ifdef HAVE_GFC_COMPLEX_16
c7d0f4d5
TK
525 case GFC_DTYPE_COMPLEX_16:
526 unpack0_c16 ((gfc_array_c16 *) ret, (gfc_array_c16 *) vector,
527 mask, (GFC_COMPLEX_16 *) field);
528 return;
1ec601bf 529# endif
3478bba4 530#endif
075abad5 531
c7d0f4d5 532 case GFC_DTYPE_DERIVED_2:
21d1335b 533 if (GFC_UNALIGNED_2(ret->base_addr) || GFC_UNALIGNED_2(vector->base_addr)
c7d0f4d5
TK
534 || GFC_UNALIGNED_2(field))
535 break;
536 else
537 {
538 unpack0_i2 ((gfc_array_i2 *) ret, (gfc_array_i2 *) vector,
539 mask, (GFC_INTEGER_2 *) field);
540 return;
541 }
542
543 case GFC_DTYPE_DERIVED_4:
21d1335b 544 if (GFC_UNALIGNED_4(ret->base_addr) || GFC_UNALIGNED_4(vector->base_addr)
c7d0f4d5
TK
545 || GFC_UNALIGNED_4(field))
546 break;
547 else
548 {
549 unpack0_i4 ((gfc_array_i4 *) ret, (gfc_array_i4 *) vector,
550 mask, (GFC_INTEGER_4 *) field);
551 return;
552 }
553
554 case GFC_DTYPE_DERIVED_8:
21d1335b 555 if (GFC_UNALIGNED_8(ret->base_addr) || GFC_UNALIGNED_8(vector->base_addr)
c7d0f4d5
TK
556 || GFC_UNALIGNED_8(field))
557 break;
558 else
559 {
560 unpack0_i8 ((gfc_array_i8 *) ret, (gfc_array_i8 *) vector,
561 mask, (GFC_INTEGER_8 *) field);
562 return;
563 }
075abad5 564
c7d0f4d5
TK
565#ifdef HAVE_GFC_INTEGER_16
566 case GFC_DTYPE_DERIVED_16:
21d1335b
TB
567 if (GFC_UNALIGNED_16(ret->base_addr)
568 || GFC_UNALIGNED_16(vector->base_addr)
c7d0f4d5
TK
569 || GFC_UNALIGNED_16(field))
570 break;
571 else
572 {
573 unpack0_i16 ((gfc_array_i16 *) ret, (gfc_array_i16 *) vector,
574 mask, (GFC_INTEGER_16 *) field);
575 return;
3478bba4 576 }
c7d0f4d5 577#endif
075abad5 578
3478bba4 579 }
c7d0f4d5 580
c6e75626 581 memset (&tmp, 0, sizeof (tmp));
6de9cd9a 582 tmp.dtype = 0;
21d1335b 583 tmp.base_addr = field;
23db9913 584 unpack_internal (ret, vector, mask, &tmp, GFC_DESCRIPTOR_SIZE (vector));
7823229b
RS
585}
586
3571925e 587
7823229b 588extern void unpack0_char (gfc_array_char *, GFC_INTEGER_4,
e6082041 589 const gfc_array_char *, const gfc_array_l1 *,
7823229b
RS
590 char *, GFC_INTEGER_4, GFC_INTEGER_4);
591export_proto(unpack0_char);
592
593void
594unpack0_char (gfc_array_char *ret,
595 GFC_INTEGER_4 ret_length __attribute__((unused)),
e6082041 596 const gfc_array_char *vector, const gfc_array_l1 *mask,
7823229b
RS
597 char *field, GFC_INTEGER_4 vector_length,
598 GFC_INTEGER_4 field_length __attribute__((unused)))
599{
600 gfc_array_char tmp;
601
8c39b987
TK
602 if (unlikely(compile_options.bounds_check))
603 unpack_bounds (ret, vector, mask, NULL);
604
c6e75626 605 memset (&tmp, 0, sizeof (tmp));
7823229b 606 tmp.dtype = 0;
21d1335b 607 tmp.base_addr = field;
23db9913 608 unpack_internal (ret, vector, mask, &tmp, vector_length);
6de9cd9a 609}
3571925e
FXC
610
611
612extern void unpack0_char4 (gfc_array_char *, GFC_INTEGER_4,
613 const gfc_array_char *, const gfc_array_l1 *,
614 char *, GFC_INTEGER_4, GFC_INTEGER_4);
615export_proto(unpack0_char4);
616
617void
618unpack0_char4 (gfc_array_char *ret,
619 GFC_INTEGER_4 ret_length __attribute__((unused)),
620 const gfc_array_char *vector, const gfc_array_l1 *mask,
621 char *field, GFC_INTEGER_4 vector_length,
622 GFC_INTEGER_4 field_length __attribute__((unused)))
623{
624 gfc_array_char tmp;
625
8c39b987
TK
626 if (unlikely(compile_options.bounds_check))
627 unpack_bounds (ret, vector, mask, NULL);
628
3571925e
FXC
629 memset (&tmp, 0, sizeof (tmp));
630 tmp.dtype = 0;
21d1335b 631 tmp.base_addr = field;
3571925e 632 unpack_internal (ret, vector, mask, &tmp,
23db9913 633 vector_length * sizeof (gfc_char4_t));
3571925e 634}