in_unpack_i8.c 2.78 KB
Newer Older
1
/* Helper function for repacking arrays.
Jakub Jelinek committed
2
   Copyright (C) 2003-2015 Free Software Foundation, Inc.
3 4
   Contributed by Paul Brook <paul@nowt.org>

5
This file is part of the GNU Fortran runtime library (libgfortran).
6

7 8
Libgfortran is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
9
License as published by the Free Software Foundation; either
10
version 3 of the License, or (at your option) any later version.
11 12

Libgfortran is distributed in the hope that it will be useful,
13 14
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
GNU General Public License for more details.
16

17 18 19 20 21 22 23 24
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.

You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
<http://www.gnu.org/licenses/>.  */
25

26
#include "libgfortran.h"
27 28 29
#include <stdlib.h>
#include <assert.h>
#include <string.h>
30

31

32 33
#if defined (HAVE_GFC_INTEGER_8)

34 35 36
void
internal_unpack_8 (gfc_array_i8 * d, const GFC_INTEGER_8 * src)
{
37 38 39
  index_type count[GFC_MAX_DIMENSIONS];
  index_type extent[GFC_MAX_DIMENSIONS];
  index_type stride[GFC_MAX_DIMENSIONS];
40 41 42
  index_type stride0;
  index_type dim;
  index_type dsize;
43
  GFC_INTEGER_8 * restrict dest;
44 45
  int n;

46
  dest = d->base_addr;
47 48 49 50 51 52 53 54
  if (src == dest || !src)
    return;

  dim = GFC_DESCRIPTOR_RANK (d);
  dsize = 1;
  for (n = 0; n < dim; n++)
    {
      count[n] = 0;
55 56
      stride[n] = GFC_DESCRIPTOR_STRIDE(d,n);
      extent[n] = GFC_DESCRIPTOR_EXTENT(d,n);
57
      if (extent[n] <= 0)
58
	return;
59 60

      if (dsize == stride[n])
61
	dsize *= extent[n];
62
      else
63
	dsize = 0;
64 65 66 67
    }

  if (dsize != 0)
    {
Thomas Koenig committed
68
      memcpy (dest, src, dsize * sizeof (GFC_INTEGER_8));
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
      return;
    }

  stride0 = stride[0];

  while (dest)
    {
      /* Copy the data.  */
      *dest = *(src++);
      /* Advance to the next element.  */
      dest += stride0;
      count[0]++;
      /* Advance to the next source element.  */
      n = 0;
      while (count[n] == extent[n])
        {
          /* When we get to the end of a dimension, reset it and increment
             the next dimension.  */
          count[n] = 0;
          /* We could precalculate these products, but this is a less
89
             frequently used path so probably not worth it.  */
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
          dest -= stride[n] * extent[n];
          n++;
          if (n == dim)
            {
              dest = NULL;
              break;
            }
          else
            {
              count[n]++;
              dest += stride[n];
            }
        }
    }
}

106
#endif
107