/* Generic implementation of the PACK intrinsic
   Copyright (C) 2002-2022 Free Software Foundation, Inc.
   Contributed by Paul Brook <paul@nowt.org>

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

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

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

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/>.  */

#include "libgfortran.h"
#include <string.h>

/* PACK is specified as follows:

   13.14.80 PACK (ARRAY, MASK, [VECTOR])

   Description: Pack an array into an array of rank one under the
   control of a mask.

   Class: Transformational function.

   Arguments:
      ARRAY   may be of any type. It shall not be scalar.
      MASK    shall be of type LOGICAL. It shall be conformable with ARRAY.
      VECTOR  (optional) shall be of the same type and type parameters
              as ARRAY. VECTOR shall have at least as many elements as
              there are true elements in MASK. If MASK is a scalar
              with the value true, VECTOR shall have at least as many
              elements as there are in ARRAY.

   Result Characteristics: The result is an array of rank one with the
   same type and type parameters as ARRAY. If VECTOR is present, the
   result size is that of VECTOR; otherwise, the result size is the
   number /t/ of true elements in MASK unless MASK is scalar with the
   value true, in which case the result size is the size of ARRAY.

   Result Value: Element /i/ of the result is the element of ARRAY
   that corresponds to the /i/th true element of MASK, taking elements
   in array element order, for /i/ = 1, 2, ..., /t/. If VECTOR is
   present and has size /n/ > /t/, element /i/ of the result has the
   value VECTOR(/i/), for /i/ = /t/ + 1, ..., /n/.

   Examples: The nonzero elements of an array M with the value
   | 0 0 0 |
   | 9 0 0 | may be "gathered" by the function PACK. The result of
   | 0 0 7 |
   PACK (M, MASK = M.NE.0) is [9,7] and the result of PACK (M, M.NE.0,
   VECTOR = (/ 2,4,6,8,10,12 /)) is [9,7,6,8,10,12].

There are two variants of the PACK intrinsic: one, where MASK is
array valued, and the other one where MASK is scalar.  */

static void
pack_internal (gfc_array_char *ret, const gfc_array_char *array,
	       const gfc_array_l1 *mask, const gfc_array_char *vector,
	       index_type size)
{
  /* r.* indicates the return array.  */
  index_type rstride0;
  char * restrict rptr;
  /* s.* indicates the source array.  */
  index_type sstride[GFC_MAX_DIMENSIONS];
  index_type sstride0;
  const char *sptr;
  /* m.* indicates the mask array.  */
  index_type mstride[GFC_MAX_DIMENSIONS];
  index_type mstride0;
  const GFC_LOGICAL_1 *mptr;

  index_type count[GFC_MAX_DIMENSIONS];
  index_type extent[GFC_MAX_DIMENSIONS];
  bool zero_sized;
  index_type n;
  index_type dim;
  index_type nelem;
  index_type total;
  int mask_kind;

  dim = GFC_DESCRIPTOR_RANK (array);

  sptr = array->base_addr;
  mptr = mask->base_addr;

  /* Use the same loop for all logical types, by using GFC_LOGICAL_1
     and using shifting to address size and endian issues.  */

  mask_kind = GFC_DESCRIPTOR_SIZE (mask);

  if (mask_kind == 1 || mask_kind == 2 || mask_kind == 4 || mask_kind == 8
#ifdef HAVE_GFC_LOGICAL_16
      || mask_kind == 16
#endif
      )
    {
      /*  Don't convert a NULL pointer as we use test for NULL below.  */
      if (mptr)
	mptr = GFOR_POINTER_TO_L1 (mptr, mask_kind);
    }
  else
    runtime_error ("Funny sized logical array");

  zero_sized = false;
  for (n = 0; n < dim; n++)
    {
      count[n] = 0;
      extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
      if (extent[n] <= 0)
	zero_sized = true;
      sstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(array,n);
      mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask,n);
    }
  if (sstride[0] == 0)
    sstride[0] = size;
  if (mstride[0] == 0)
    mstride[0] = mask_kind;

  if (zero_sized)
    sptr = NULL;
  else
    sptr = array->base_addr;

  if (ret->base_addr == NULL || unlikely (compile_options.bounds_check))
    {
      /* Count the elements, either for allocating memory or
	 for bounds checking.  */

      if (vector != NULL)
	{
	  /* The return array will have as many
	     elements as there are in VECTOR.  */
	  total = GFC_DESCRIPTOR_EXTENT(vector,0);
	}
      else
	{
	  /* We have to count the true elements in MASK.  */

	  total = count_0 (mask);
	}

      if (ret->base_addr == NULL)
	{
	  /* Setup the array descriptor.  */
	  GFC_DIMENSION_SET(ret->dim[0], 0, total-1, 1);

	  ret->offset = 0;
	  /* xmallocarray allocates a single byte for zero size.  */
	  ret->base_addr = xmallocarray (total, size);

	  if (total == 0)
	    return;      /* In this case, nothing remains to be done.  */
	}
      else 
	{
	  /* We come here because of range checking.  */
	  index_type ret_extent;

	  ret_extent = GFC_DESCRIPTOR_EXTENT(ret,0);
	  if (total != ret_extent)
	    runtime_error ("Incorrect extent in return value of PACK intrinsic;"
			   " is %ld, should be %ld", (long int) total,
			   (long int) ret_extent);
	}
    }

  rstride0 = GFC_DESCRIPTOR_STRIDE_BYTES(ret,0);
  if (rstride0 == 0)
    rstride0 = size;
  sstride0 = sstride[0];
  mstride0 = mstride[0];
  rptr = ret->base_addr;

  while (sptr && mptr)
    {
      /* Test this element.  */
      if (*mptr)
        {
          /* Add it.  */
          memcpy (rptr, sptr, size);
          rptr += rstride0;
        }
      /* Advance to the next element.  */
      sptr += sstride0;
      mptr += mstride0;
      count[0]++;
      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
             frequently used path so probably not worth it.  */
          sptr -= sstride[n] * extent[n];
          mptr -= mstride[n] * extent[n];
          n++;
          if (n >= dim)
            {
              /* Break out of the loop.  */
              sptr = NULL;
              break;
            }
          else
            {
              count[n]++;
              sptr += sstride[n];
              mptr += mstride[n];
            }
        }
    }

  /* Add any remaining elements from VECTOR.  */
  if (vector)
    {
      n = GFC_DESCRIPTOR_EXTENT(vector,0);
      nelem = ((rptr - ret->base_addr) / rstride0);
      if (n > nelem)
        {
          sstride0 = GFC_DESCRIPTOR_STRIDE_BYTES(vector,0);
          if (sstride0 == 0)
            sstride0 = size;

          sptr = vector->base_addr + sstride0 * nelem;
          n -= nelem;
          while (n--)
            {
              memcpy (rptr, sptr, size);
              rptr += rstride0;
              sptr += sstride0;
            }
        }
    }
}

extern void pack (gfc_array_char *, const gfc_array_char *,
		  const gfc_array_l1 *, const gfc_array_char *);
export_proto(pack);

void
pack (gfc_array_char *ret, const gfc_array_char *array,
      const gfc_array_l1 *mask, const gfc_array_char *vector)
{
  index_type type_size;
  index_type size;

  type_size = GFC_DTYPE_TYPE_SIZE(array);

  switch(type_size)
    {
    case GFC_DTYPE_LOGICAL_1:
    case GFC_DTYPE_INTEGER_1:
      pack_i1 ((gfc_array_i1 *) ret, (gfc_array_i1 *) array,
	       (gfc_array_l1 *) mask, (gfc_array_i1 *) vector);
      return;

    case GFC_DTYPE_LOGICAL_2:
    case GFC_DTYPE_INTEGER_2:
      pack_i2 ((gfc_array_i2 *) ret, (gfc_array_i2 *) array,
	       (gfc_array_l1 *) mask, (gfc_array_i2 *) vector);
      return;

    case GFC_DTYPE_LOGICAL_4:
    case GFC_DTYPE_INTEGER_4:
      pack_i4 ((gfc_array_i4 *) ret, (gfc_array_i4 *) array,
	       (gfc_array_l1 *) mask, (gfc_array_i4 *) vector);
      return;

    case GFC_DTYPE_LOGICAL_8:
    case GFC_DTYPE_INTEGER_8:
      pack_i8 ((gfc_array_i8 *) ret, (gfc_array_i8 *) array,
	       (gfc_array_l1 *) mask, (gfc_array_i8 *) vector);
      return;

#ifdef HAVE_GFC_INTEGER_16
    case GFC_DTYPE_LOGICAL_16:
    case GFC_DTYPE_INTEGER_16:
      pack_i16 ((gfc_array_i16 *) ret, (gfc_array_i16 *) array,
		(gfc_array_l1 *) mask, (gfc_array_i16 *) vector);
      return;
#endif

    case GFC_DTYPE_REAL_4:
      pack_r4 ((gfc_array_r4 *) ret, (gfc_array_r4 *) array,
	       (gfc_array_l1 *) mask, (gfc_array_r4 *) vector);
      return;

    case GFC_DTYPE_REAL_8:
      pack_r8 ((gfc_array_r8 *) ret, (gfc_array_r8 *) array,
	       (gfc_array_l1 *) mask, (gfc_array_r8 *) vector);
      return;

/* FIXME: This here is a hack, which will have to be removed when
   the array descriptor is reworked.  Currently, we don't store the
   kind value for the type, but only the size.  Because on targets with
   _Float128, we have sizeof(long double) == sizeof(_Float128),
   we cannot discriminate here and have to fall back to the generic
   handling (which is suboptimal).  */
#if !defined(GFC_REAL_16_IS_FLOAT128)
# ifdef HAVE_GFC_REAL_10
    case GFC_DTYPE_REAL_10:
      pack_r10 ((gfc_array_r10 *) ret, (gfc_array_r10 *) array,
		(gfc_array_l1 *) mask, (gfc_array_r10 *) vector);
      return;
# endif

# ifdef HAVE_GFC_REAL_16
    case GFC_DTYPE_REAL_16:
      pack_r16 ((gfc_array_r16 *) ret, (gfc_array_r16 *) array,
		(gfc_array_l1 *) mask, (gfc_array_r16 *) vector);
      return;
# endif
#endif

    case GFC_DTYPE_COMPLEX_4:
      pack_c4 ((gfc_array_c4 *) ret, (gfc_array_c4 *) array,
	       (gfc_array_l1 *) mask, (gfc_array_c4 *) vector);
      return;

    case GFC_DTYPE_COMPLEX_8:
      pack_c8 ((gfc_array_c8 *) ret, (gfc_array_c8 *) array,
	       (gfc_array_l1 *) mask, (gfc_array_c8 *) vector);
      return;

/* FIXME: This here is a hack, which will have to be removed when
   the array descriptor is reworked.  Currently, we don't store the
   kind value for the type, but only the size.  Because on targets with
   _Float128, we have sizeof(long double) == sizeof(_Float128),
   we cannot discriminate here and have to fall back to the generic
   handling (which is suboptimal).  */
#if !defined(GFC_REAL_16_IS_FLOAT128)
# ifdef HAVE_GFC_COMPLEX_10
    case GFC_DTYPE_COMPLEX_10:
      pack_c10 ((gfc_array_c10 *) ret, (gfc_array_c10 *) array,
		(gfc_array_l1 *) mask, (gfc_array_c10 *) vector);
      return;
# endif

# ifdef HAVE_GFC_COMPLEX_16
    case GFC_DTYPE_COMPLEX_16:
      pack_c16 ((gfc_array_c16 *) ret, (gfc_array_c16 *) array,
		(gfc_array_l1 *) mask, (gfc_array_c16 *) vector);
      return;
# endif
#endif
    }
  
  /* For other types, let's check the actual alignment of the data pointers.
     If they are aligned, we can safely call the unpack functions.  */

  switch (GFC_DESCRIPTOR_SIZE (array))
    {
    case 1:
      pack_i1 ((gfc_array_i1 *) ret, (gfc_array_i1 *) array,
	       (gfc_array_l1 *) mask, (gfc_array_i1 *) vector);
      return;

    case 2:
      if (GFC_UNALIGNED_2(ret->base_addr) || GFC_UNALIGNED_2(array->base_addr)
	  || (vector && GFC_UNALIGNED_2(vector->base_addr)))
	break;
      else
	{
	  pack_i2 ((gfc_array_i2 *) ret, (gfc_array_i2 *) array,
		   (gfc_array_l1 *) mask, (gfc_array_i2 *) vector);
	  return;
	}
	      
    case 4:
      if (GFC_UNALIGNED_4(ret->base_addr) || GFC_UNALIGNED_4(array->base_addr)
	  || (vector && GFC_UNALIGNED_4(vector->base_addr)))
	break;
      else
	{
	  pack_i4 ((gfc_array_i4 *) ret, (gfc_array_i4 *) array,
		   (gfc_array_l1 *) mask, (gfc_array_i4 *) vector);
	  return;
	}

    case 8:
      if (GFC_UNALIGNED_8(ret->base_addr) || GFC_UNALIGNED_8(array->base_addr)
	  || (vector && GFC_UNALIGNED_8(vector->base_addr)))
	break;
      else
	{
	  pack_i8 ((gfc_array_i8 *) ret, (gfc_array_i8 *) array,
		   (gfc_array_l1 *) mask, (gfc_array_i8 *) vector);
	  return;
	}

#ifdef HAVE_GFC_INTEGER_16	      
    case 16:
      if (GFC_UNALIGNED_16(ret->base_addr) || GFC_UNALIGNED_16(array->base_addr)
	  || (vector && GFC_UNALIGNED_16(vector->base_addr)))
	break;
      else
	{
	  pack_i16 ((gfc_array_i16 *) ret, (gfc_array_i16 *) array,
		    (gfc_array_l1 *) mask, (gfc_array_i16 *) vector);
	  return;
	}
#endif
    default:
      break;
    }

  size = GFC_DESCRIPTOR_SIZE (array);
  pack_internal (ret, array, mask, vector, size);
}


extern void pack_char (gfc_array_char *, GFC_INTEGER_4, const gfc_array_char *,
		       const gfc_array_l1 *, const gfc_array_char *,
		       GFC_INTEGER_4, GFC_INTEGER_4);
export_proto(pack_char);

void
pack_char (gfc_array_char *ret,
	   GFC_INTEGER_4 ret_length __attribute__((unused)),
	   const gfc_array_char *array, const gfc_array_l1 *mask,
	   const gfc_array_char *vector, GFC_INTEGER_4 array_length,
	   GFC_INTEGER_4 vector_length __attribute__((unused)))
{
  pack_internal (ret, array, mask, vector, array_length);
}


extern void pack_char4 (gfc_array_char *, GFC_INTEGER_4, const gfc_array_char *,
			const gfc_array_l1 *, const gfc_array_char *,
			GFC_INTEGER_4, GFC_INTEGER_4);
export_proto(pack_char4);

void
pack_char4 (gfc_array_char *ret,
	    GFC_INTEGER_4 ret_length __attribute__((unused)),
	    const gfc_array_char *array, const gfc_array_l1 *mask,
	    const gfc_array_char *vector, GFC_INTEGER_4 array_length,
	    GFC_INTEGER_4 vector_length __attribute__((unused)))
{
  pack_internal (ret, array, mask, vector, array_length * sizeof (gfc_char4_t));
}


static void
pack_s_internal (gfc_array_char *ret, const gfc_array_char *array,
		 const GFC_LOGICAL_4 *mask, const gfc_array_char *vector,
		 index_type size)
{
  /* r.* indicates the return array.  */
  index_type rstride0;
  char *rptr;
  /* s.* indicates the source array.  */
  index_type sstride[GFC_MAX_DIMENSIONS];
  index_type sstride0;
  const char *sptr;

  index_type count[GFC_MAX_DIMENSIONS];
  index_type extent[GFC_MAX_DIMENSIONS];
  index_type n;
  index_type dim;
  index_type ssize;
  index_type nelem;
  index_type total;

  dim = GFC_DESCRIPTOR_RANK (array);
  /* Initialize sstride[0] to avoid -Wmaybe-uninitialized
     complaints.  */
  sstride[0] = size;
  ssize = 1;
  for (n = 0; n < dim; n++)
    {
      count[n] = 0;
      extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
      if (extent[n] < 0)
	extent[n] = 0;

      sstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(array,n);
      ssize *= extent[n];
    }
  if (sstride[0] == 0)
    sstride[0] = size;

  sstride0 = sstride[0];

  if (ssize != 0)
    sptr = array->base_addr;
  else
    sptr = NULL;

  if (ret->base_addr == NULL)
    {
      /* Allocate the memory for the result.  */

      if (vector != NULL)
	{
	  /* The return array will have as many elements as there are
	     in vector.  */
	  total = GFC_DESCRIPTOR_EXTENT(vector,0);
	  if (total <= 0)
	    {
	      total = 0;
	      vector = NULL;
	    }
	}
      else
	{
	  if (*mask)
	    {
	      /* The result array will have as many elements as the input
		 array.  */
	      total = extent[0];
	      for (n = 1; n < dim; n++)
		total *= extent[n];
	    }
	  else
	    /* The result array will be empty.  */
	    total = 0;
	}

      /* Setup the array descriptor.  */
      GFC_DIMENSION_SET(ret->dim[0],0,total-1,1);

      ret->offset = 0;

      ret->base_addr = xmallocarray (total, size);

      if (total == 0)
	return;
    }

  rstride0 = GFC_DESCRIPTOR_STRIDE_BYTES(ret,0);
  if (rstride0 == 0)
    rstride0 = size;
  rptr = ret->base_addr;

  /* The remaining possibilities are now:
       If MASK is .TRUE., we have to copy the source array into the
     result array. We then have to fill it up with elements from VECTOR.
       If MASK is .FALSE., we have to copy VECTOR into the result
     array. If VECTOR were not present we would have already returned.  */

  if (*mask && ssize != 0)
    {
      while (sptr)
	{
	  /* Add this element.  */
	  memcpy (rptr, sptr, size);
	  rptr += rstride0;

	  /* Advance to the next element.  */
	  sptr += sstride0;
	  count[0]++;
	  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 frequently used path so probably not worth it.  */
	      sptr -= sstride[n] * extent[n];
	      n++;
	      if (n >= dim)
		{
		  /* Break out of the loop.  */
		  sptr = NULL;
		  break;
		}
	      else
		{
		  count[n]++;
		  sptr += sstride[n];
		}
	    }
	}
    }

  /* Add any remaining elements from VECTOR.  */
  if (vector)
    {
      n = GFC_DESCRIPTOR_EXTENT(vector,0);
      nelem = ((rptr - ret->base_addr) / rstride0);
      if (n > nelem)
        {
          sstride0 = GFC_DESCRIPTOR_STRIDE_BYTES(vector,0);
          if (sstride0 == 0)
            sstride0 = size;

          sptr = vector->base_addr + sstride0 * nelem;
          n -= nelem;
          while (n--)
            {
              memcpy (rptr, sptr, size);
              rptr += rstride0;
              sptr += sstride0;
            }
        }
    }
}

extern void pack_s (gfc_array_char *ret, const gfc_array_char *array,
		    const GFC_LOGICAL_4 *, const gfc_array_char *);
export_proto(pack_s);

void
pack_s (gfc_array_char *ret, const gfc_array_char *array,
	const GFC_LOGICAL_4 *mask, const gfc_array_char *vector)
{
  pack_s_internal (ret, array, mask, vector, GFC_DESCRIPTOR_SIZE (array));
}


extern void pack_s_char (gfc_array_char *ret, GFC_INTEGER_4,
			 const gfc_array_char *array, const GFC_LOGICAL_4 *,
			 const gfc_array_char *, GFC_INTEGER_4,
			 GFC_INTEGER_4);
export_proto(pack_s_char);

void
pack_s_char (gfc_array_char *ret,
	     GFC_INTEGER_4 ret_length __attribute__((unused)),
	     const gfc_array_char *array, const GFC_LOGICAL_4 *mask,
	     const gfc_array_char *vector, GFC_INTEGER_4 array_length,
	     GFC_INTEGER_4 vector_length __attribute__((unused)))
{
  pack_s_internal (ret, array, mask, vector, array_length);
}


extern void pack_s_char4 (gfc_array_char *ret, GFC_INTEGER_4,
			  const gfc_array_char *array, const GFC_LOGICAL_4 *,
			  const gfc_array_char *, GFC_INTEGER_4,
			  GFC_INTEGER_4);
export_proto(pack_s_char4);

void
pack_s_char4 (gfc_array_char *ret,
	      GFC_INTEGER_4 ret_length __attribute__((unused)),
	      const gfc_array_char *array, const GFC_LOGICAL_4 *mask,
	      const gfc_array_char *vector, GFC_INTEGER_4 array_length,
	      GFC_INTEGER_4 vector_length __attribute__((unused)))
{
  pack_s_internal (ret, array, mask, vector,
		   array_length * sizeof (gfc_char4_t));
}
