1/* Helper function for repacking arrays. 2 Copyright (C) 2003-2020 Free Software Foundation, Inc. 3 Contributed by Paul Brook <paul@nowt.org> 4 5This file is part of the GNU Fortran runtime library (libgfortran). 6 7Libgfortran is free software; you can redistribute it and/or 8modify it under the terms of the GNU General Public 9License as published by the Free Software Foundation; either 10version 3 of the License, or (at your option) any later version. 11 12Libgfortran 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 General Public License for more details. 16 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/>. */ 25 26#include "libgfortran.h" 27#include <string.h> 28 29 30#if defined (HAVE_GFC_INTEGER_4) 31 32void 33internal_unpack_4 (gfc_array_i4 * d, const GFC_INTEGER_4 * src) 34{ 35 index_type count[GFC_MAX_DIMENSIONS]; 36 index_type extent[GFC_MAX_DIMENSIONS]; 37 index_type stride[GFC_MAX_DIMENSIONS]; 38 index_type stride0; 39 index_type dim; 40 index_type dsize; 41 GFC_INTEGER_4 * restrict dest; 42 43 dest = d->base_addr; 44 if (src == dest || !src) 45 return; 46 47 dim = GFC_DESCRIPTOR_RANK (d); 48 dsize = 1; 49 for (index_type n = 0; n < dim; n++) 50 { 51 count[n] = 0; 52 stride[n] = GFC_DESCRIPTOR_STRIDE(d,n); 53 extent[n] = GFC_DESCRIPTOR_EXTENT(d,n); 54 if (extent[n] <= 0) 55 return; 56 57 if (dsize == stride[n]) 58 dsize *= extent[n]; 59 else 60 dsize = 0; 61 } 62 63 if (dsize != 0) 64 { 65 memcpy (dest, src, dsize * sizeof (GFC_INTEGER_4)); 66 return; 67 } 68 69 stride0 = stride[0]; 70 71 while (dest) 72 { 73 /* Copy the data. */ 74 *dest = *(src++); 75 /* Advance to the next element. */ 76 dest += stride0; 77 count[0]++; 78 /* Advance to the next source element. */ 79 index_type n = 0; 80 while (count[n] == extent[n]) 81 { 82 /* When we get to the end of a dimension, reset it and increment 83 the next dimension. */ 84 count[n] = 0; 85 /* We could precalculate these products, but this is a less 86 frequently used path so probably not worth it. */ 87 dest -= stride[n] * extent[n]; 88 n++; 89 if (n == dim) 90 { 91 dest = NULL; 92 break; 93 } 94 else 95 { 96 count[n]++; 97 dest += stride[n]; 98 } 99 } 100 } 101} 102 103#endif 104 105