#include "config.h"
#include <stdlib.h>
#include <assert.h>
#include "libgfortran.h"
#if defined (HAVE_GFC_INTEGER_8)
typedef GFC_ARRAY_DESCRIPTOR(1, index_type) shape_type;
extern void reshape_8 (gfc_array_i8 * const restrict,
gfc_array_i8 * const restrict,
shape_type * const restrict,
gfc_array_i8 * const restrict,
shape_type * const restrict);
export_proto(reshape_8);
void
reshape_8 (gfc_array_i8 * const restrict ret,
gfc_array_i8 * const restrict source,
shape_type * const restrict shape,
gfc_array_i8 * const restrict pad,
shape_type * const restrict order)
{
index_type rcount[GFC_MAX_DIMENSIONS];
index_type rextent[GFC_MAX_DIMENSIONS];
index_type rstride[GFC_MAX_DIMENSIONS];
index_type rstride0;
index_type rdim;
index_type rsize;
index_type rs;
index_type rex;
GFC_INTEGER_8 *rptr;
index_type scount[GFC_MAX_DIMENSIONS];
index_type sextent[GFC_MAX_DIMENSIONS];
index_type sstride[GFC_MAX_DIMENSIONS];
index_type sstride0;
index_type sdim;
index_type ssize;
const GFC_INTEGER_8 *sptr;
index_type pcount[GFC_MAX_DIMENSIONS];
index_type pextent[GFC_MAX_DIMENSIONS];
index_type pstride[GFC_MAX_DIMENSIONS];
index_type pdim;
index_type psize;
const GFC_INTEGER_8 *pptr;
const GFC_INTEGER_8 *src;
int n;
int dim;
int sempty, pempty;
if (ret->data == NULL)
{
rdim = shape->dim[0].ubound - shape->dim[0].lbound + 1;
rs = 1;
for (n = 0; n < rdim; n++)
{
ret->dim[n].lbound = 0;
rex = shape->data[n * shape->dim[0].stride];
ret->dim[n].ubound = rex - 1;
ret->dim[n].stride = rs;
rs *= rex;
}
ret->offset = 0;
ret->data = internal_malloc_size ( rs * sizeof (GFC_INTEGER_8));
ret->dtype = (source->dtype & ~GFC_DTYPE_RANK_MASK) | rdim;
}
else
{
rdim = GFC_DESCRIPTOR_RANK (ret);
}
rsize = 1;
for (n = 0; n < rdim; n++)
{
if (order)
dim = order->data[n * order->dim[0].stride] - 1;
else
dim = n;
rcount[n] = 0;
rstride[n] = ret->dim[dim].stride;
rextent[n] = ret->dim[dim].ubound + 1 - ret->dim[dim].lbound;
if (rextent[n] != shape->data[dim * shape->dim[0].stride])
runtime_error ("shape and target do not conform");
if (rsize == rstride[n])
rsize *= rextent[n];
else
rsize = 0;
if (rextent[n] <= 0)
return;
}
sdim = GFC_DESCRIPTOR_RANK (source);
ssize = 1;
sempty = 0;
for (n = 0; n < sdim; n++)
{
scount[n] = 0;
sstride[n] = source->dim[n].stride;
sextent[n] = source->dim[n].ubound + 1 - source->dim[n].lbound;
if (sextent[n] <= 0)
{
sempty = 1;
sextent[n] = 0;
}
if (ssize == sstride[n])
ssize *= sextent[n];
else
ssize = 0;
}
if (pad)
{
pdim = GFC_DESCRIPTOR_RANK (pad);
psize = 1;
pempty = 0;
for (n = 0; n < pdim; n++)
{
pcount[n] = 0;
pstride[n] = pad->dim[n].stride;
pextent[n] = pad->dim[n].ubound + 1 - pad->dim[n].lbound;
if (pextent[n] <= 0)
{
pempty = 1;
pextent[n] = 0;
}
if (psize == pstride[n])
psize *= pextent[n];
else
psize = 0;
}
pptr = pad->data;
}
else
{
pdim = 0;
psize = 1;
pempty = 1;
pptr = NULL;
}
if (rsize != 0 && ssize != 0 && psize != 0)
{
rsize *= sizeof (GFC_INTEGER_8);
ssize *= sizeof (GFC_INTEGER_8);
psize *= sizeof (GFC_INTEGER_8);
reshape_packed ((char *)ret->data, rsize, (char *)source->data,
ssize, pad ? (char *)pad->data : NULL, psize);
return;
}
rptr = ret->data;
src = sptr = source->data;
rstride0 = rstride[0];
sstride0 = sstride[0];
if (sempty && pempty)
abort ();
if (sempty)
{
src = pptr;
sptr = NULL;
sdim = pdim;
for (dim = 0; dim < pdim; dim++)
{
scount[dim] = pcount[dim];
sextent[dim] = pextent[dim];
sstride[dim] = pstride[dim];
sstride0 = sstride[0] * sizeof (GFC_INTEGER_8);
}
}
while (rptr)
{
*rptr = *src;
rptr += rstride0;
src += sstride0;
rcount[0]++;
scount[0]++;
n = 0;
while (rcount[n] == rextent[n])
{
rcount[n] = 0;
rptr -= rstride[n] * rextent[n];
n++;
if (n == rdim)
{
rptr = NULL;
break;
}
else
{
rcount[n]++;
rptr += rstride[n];
}
}
n = 0;
while (scount[n] == sextent[n])
{
scount[n] = 0;
src -= sstride[n] * sextent[n];
n++;
if (n == sdim)
{
if (sptr && pad)
{
sptr = NULL;
sdim = pdim;
for (dim = 0; dim < pdim; dim++)
{
scount[dim] = pcount[dim];
sextent[dim] = pextent[dim];
sstride[dim] = pstride[dim];
sstride0 = sstride[0];
}
}
src = pptr;
break;
}
else
{
scount[n]++;
src += sstride[n];
}
}
}
}
#endif