/* Generic implementation of the EOSHIFT intrinsic
   Copyright 2002 Free Software Foundation, Inc.
   Contributed by Paul Brook <paul@nowt.org>

This file is part of the GNU Fortran 95 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 2 of the License, or (at your option) any later version.

In addition to the permissions in the GNU General Public License, the
Free Software Foundation gives you unlimited permission to link the
compiled version of this file into combinations with other programs,
and to distribute those combinations without any restriction coming
from the use of this file.  (The General Public License restrictions
do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)

Libgfortran 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.

You should have received a copy of the GNU General Public
License along with libgfortran; see the file COPYING.  If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.  */

#include "config.h"
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include "libgfortran.h"

static const char zeros[16] =
  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

/* TODO: make this work for large shifts when
   sizeof(int) < sizeof (index_type).  */

static void
eoshift0 (gfc_array_char * ret, const gfc_array_char * array,
	  int shift, const char * pbound, int which)
{
  /* r.* indicates the return array.  */
  index_type rstride[GFC_MAX_DIMENSIONS];
  index_type rstride0;
  index_type roffset;
  char *rptr;
  char *dest;
  /* s.* indicates the source array.  */
  index_type sstride[GFC_MAX_DIMENSIONS];
  index_type sstride0;
  index_type soffset;
  const char *sptr;
  const char *src;

  index_type count[GFC_MAX_DIMENSIONS];
  index_type extent[GFC_MAX_DIMENSIONS];
  index_type dim;
  index_type size;
  index_type len;
  index_type n;

  if (!pbound)
    pbound = zeros;

  size = GFC_DESCRIPTOR_SIZE (ret);

  if (ret->data == NULL)
    {
      int i;

      ret->data = internal_malloc_size (size * size0 ((array_t *)array));
      ret->base = 0;
      ret->dtype = array->dtype;
      for (i = 0; i < GFC_DESCRIPTOR_RANK (array); i++)
        {
          ret->dim[i].lbound = 0;
          ret->dim[i].ubound = array->dim[i].ubound - array->dim[i].lbound;

          if (i == 0)
            ret->dim[i].stride = 1;
          else
            ret->dim[i].stride = (ret->dim[i-1].ubound + 1) * ret->dim[i-1].stride;
        }
    }

  which = which - 1;

  extent[0] = 1;
  count[0] = 0;
  size = GFC_DESCRIPTOR_SIZE (array);
  n = 0;
  for (dim = 0; dim < GFC_DESCRIPTOR_RANK (array); dim++)
    {
      if (dim == which)
        {
          roffset = ret->dim[dim].stride * size;
          if (roffset == 0)
            roffset = size;
          soffset = array->dim[dim].stride * size;
          if (soffset == 0)
            soffset = size;
          len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
        }
      else
        {
          count[n] = 0;
          extent[n] = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
          rstride[n] = ret->dim[dim].stride * size;
          sstride[n] = array->dim[dim].stride * size;
          n++;
        }
    }
  if (sstride[0] == 0)
    sstride[0] = size;
  if (rstride[0] == 0)
    rstride[0] = size;

  dim = GFC_DESCRIPTOR_RANK (array);
  rstride0 = rstride[0];
  sstride0 = sstride[0];
  rptr = ret->data;
  sptr = array->data;
  if (shift > 0)
    len = len - shift;
  else
    len = len + shift;

  while (rptr)
    {
      /* Do the shift for this dimension.  */
      if (shift > 0)
        {
          src = &sptr[shift * soffset];
          dest = rptr;
        }
      else
        {
          src = sptr;
          dest = &rptr[-shift * roffset];
        }
      for (n = 0; n < len; n++)
        {
          memcpy (dest, src, size);
          dest += roffset;
          src += soffset;
        }
      if (shift >= 0)
        {
          n = shift;
        }
      else
        {
          dest = rptr;
          n = -shift;
        }

      while (n--)
        {
          memcpy (dest, pbound, size);
          dest += roffset;
        }

      /* Advance to the next section.  */
      rptr += rstride0;
      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 proabably not worth it.  */
          rptr -= rstride[n] * extent[n];
          sptr -= sstride[n] * extent[n];
          n++;
          if (n >= dim - 1)
            {
              /* Break out of the loop.  */
              rptr = NULL;
              break;
            }
          else
            {
              count[n]++;
              rptr += rstride[n];
              sptr += sstride[n];
            }
        }
    }
}


extern void eoshift0_1 (gfc_array_char *, const gfc_array_char *,
			const GFC_INTEGER_1 *, const char *,
			const GFC_INTEGER_1 *);
export_proto(eoshift0_1);

void
eoshift0_1 (gfc_array_char *ret, const gfc_array_char *array,
	    const GFC_INTEGER_1 *pshift, const char *pbound,
	    const GFC_INTEGER_1 *pdim)
{
  eoshift0 (ret, array, *pshift, pbound, pdim ? *pdim : 1);
}


extern void eoshift0_2 (gfc_array_char *, const gfc_array_char *,
			const GFC_INTEGER_2 *, const char *,
			const GFC_INTEGER_2 *);
export_proto(eoshift0_2);

void
eoshift0_2 (gfc_array_char *ret, const gfc_array_char *array,
	    const GFC_INTEGER_2 *pshift, const char *pbound,
	    const GFC_INTEGER_2 *pdim)
{
  eoshift0 (ret, array, *pshift, pbound, pdim ? *pdim : 1);
}


extern void eoshift0_4 (gfc_array_char *, const gfc_array_char *,
			const GFC_INTEGER_4 *, const char *,
			const GFC_INTEGER_4 *);
export_proto(eoshift0_4);

void
eoshift0_4 (gfc_array_char *ret, const gfc_array_char *array,
	    const GFC_INTEGER_4 *pshift, const char *pbound,
	    const GFC_INTEGER_4 *pdim)
{
  eoshift0 (ret, array, *pshift, pbound, pdim ? *pdim : 1);
}


extern void eoshift0_8 (gfc_array_char *, const gfc_array_char *,
			const GFC_INTEGER_8 *, const char *,
			const GFC_INTEGER_8 *);
export_proto(eoshift0_8);

void
eoshift0_8 (gfc_array_char *ret, const gfc_array_char *array,
	    const GFC_INTEGER_8 *pshift, const char *pbound,
	    const GFC_INTEGER_8 *pdim)
{
  eoshift0 (ret, array, *pshift, pbound, pdim ? *pdim : 1);
}

