OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [tags/] [gnu-dev/] [fsf-gcc-snapshot-1-mar-12/] [or1k-gcc/] [libgfortran/] [m4/] [reshape.m4] - Diff between revs 733 and 783

Only display areas with differences | Details | Blame | View Log

Rev 733 Rev 783
`/* Implementation of the RESHAPE intrinsic
`/* Implementation of the RESHAPE intrinsic
   Copyright 2002, 2006, 2007, 2009 Free Software Foundation, Inc.
   Copyright 2002, 2006, 2007, 2009 Free Software Foundation, Inc.
   Contributed by Paul Brook <paul@nowt.org>
   Contributed by Paul Brook <paul@nowt.org>
 
 
This file is part of the GNU Fortran 95 runtime library (libgfortran).
This file is part of the GNU Fortran 95 runtime library (libgfortran).
 
 
Libgfortran is free software; you can redistribute it and/or
Libgfortran is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
version 3 of the License, or (at your option) any later version.
 
 
Libgfortran is distributed in the hope that it will be useful,
Libgfortran is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
GNU General Public License for more details.
 
 
Under Section 7 of GPL version 3, you are granted additional
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
3.1, as published by the Free Software Foundation.
 
 
You should have received a copy of the GNU General Public License and
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;
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
<http://www.gnu.org/licenses/>.  */
<http://www.gnu.org/licenses/>.  */
 
 
#include "libgfortran.h"
#include "libgfortran.h"
#include <stdlib.h>
#include <stdlib.h>
#include <assert.h>'
#include <assert.h>'
 
 
include(iparm.m4)dnl
include(iparm.m4)dnl
 
 
`#if defined (HAVE_'rtype_name`)
`#if defined (HAVE_'rtype_name`)
 
 
typedef GFC_ARRAY_DESCRIPTOR(1, 'index_type`) 'shape_type`;'
typedef GFC_ARRAY_DESCRIPTOR(1, 'index_type`) 'shape_type`;'
 
 
dnl For integer routines, only the kind (ie size) is used to name the
dnl For integer routines, only the kind (ie size) is used to name the
dnl function.  The same function will be used for integer and logical
dnl function.  The same function will be used for integer and logical
dnl arrays of the same kind.
dnl arrays of the same kind.
 
 
`extern void reshape_'rtype_ccode` ('rtype` * const restrict,
`extern void reshape_'rtype_ccode` ('rtype` * const restrict,
        'rtype` * const restrict,
        'rtype` * const restrict,
        'shape_type` * const restrict,
        'shape_type` * const restrict,
        'rtype` * const restrict,
        'rtype` * const restrict,
        'shape_type` * const restrict);
        'shape_type` * const restrict);
export_proto(reshape_'rtype_ccode`);
export_proto(reshape_'rtype_ccode`);
 
 
void
void
reshape_'rtype_ccode` ('rtype` * const restrict ret,
reshape_'rtype_ccode` ('rtype` * const restrict ret,
        'rtype` * const restrict source,
        'rtype` * const restrict source,
        'shape_type` * const restrict shape,
        'shape_type` * const restrict shape,
        'rtype` * const restrict pad,
        'rtype` * const restrict pad,
        'shape_type` * const restrict order)
        'shape_type` * const restrict order)
{
{
  /* r.* indicates the return array.  */
  /* r.* indicates the return array.  */
  index_type rcount[GFC_MAX_DIMENSIONS];
  index_type rcount[GFC_MAX_DIMENSIONS];
  index_type rextent[GFC_MAX_DIMENSIONS];
  index_type rextent[GFC_MAX_DIMENSIONS];
  index_type rstride[GFC_MAX_DIMENSIONS];
  index_type rstride[GFC_MAX_DIMENSIONS];
  index_type rstride0;
  index_type rstride0;
  index_type rdim;
  index_type rdim;
  index_type rsize;
  index_type rsize;
  index_type rs;
  index_type rs;
  index_type rex;
  index_type rex;
  'rtype_name` *rptr;
  'rtype_name` *rptr;
  /* s.* indicates the source array.  */
  /* s.* indicates the source array.  */
  index_type scount[GFC_MAX_DIMENSIONS];
  index_type scount[GFC_MAX_DIMENSIONS];
  index_type sextent[GFC_MAX_DIMENSIONS];
  index_type sextent[GFC_MAX_DIMENSIONS];
  index_type sstride[GFC_MAX_DIMENSIONS];
  index_type sstride[GFC_MAX_DIMENSIONS];
  index_type sstride0;
  index_type sstride0;
  index_type sdim;
  index_type sdim;
  index_type ssize;
  index_type ssize;
  const 'rtype_name` *sptr;
  const 'rtype_name` *sptr;
  /* p.* indicates the pad array.  */
  /* p.* indicates the pad array.  */
  index_type pcount[GFC_MAX_DIMENSIONS];
  index_type pcount[GFC_MAX_DIMENSIONS];
  index_type pextent[GFC_MAX_DIMENSIONS];
  index_type pextent[GFC_MAX_DIMENSIONS];
  index_type pstride[GFC_MAX_DIMENSIONS];
  index_type pstride[GFC_MAX_DIMENSIONS];
  index_type pdim;
  index_type pdim;
  index_type psize;
  index_type psize;
  const 'rtype_name` *pptr;
  const 'rtype_name` *pptr;
 
 
  const 'rtype_name` *src;
  const 'rtype_name` *src;
  int n;
  int n;
  int dim;
  int dim;
  int sempty, pempty, shape_empty;
  int sempty, pempty, shape_empty;
  index_type shape_data[GFC_MAX_DIMENSIONS];
  index_type shape_data[GFC_MAX_DIMENSIONS];
 
 
  rdim = GFC_DESCRIPTOR_EXTENT(shape,0);
  rdim = GFC_DESCRIPTOR_EXTENT(shape,0);
  if (rdim != GFC_DESCRIPTOR_RANK(ret))
  if (rdim != GFC_DESCRIPTOR_RANK(ret))
    runtime_error("rank of return array incorrect in RESHAPE intrinsic");
    runtime_error("rank of return array incorrect in RESHAPE intrinsic");
 
 
  shape_empty = 0;
  shape_empty = 0;
 
 
  for (n = 0; n < rdim; n++)
  for (n = 0; n < rdim; n++)
    {
    {
      shape_data[n] = shape->data[n * GFC_DESCRIPTOR_STRIDE(shape,0)];
      shape_data[n] = shape->data[n * GFC_DESCRIPTOR_STRIDE(shape,0)];
      if (shape_data[n] <= 0)
      if (shape_data[n] <= 0)
      {
      {
        shape_data[n] = 0;
        shape_data[n] = 0;
        shape_empty = 1;
        shape_empty = 1;
      }
      }
    }
    }
 
 
  if (ret->data == NULL)
  if (ret->data == NULL)
    {
    {
      index_type alloc_size;
      index_type alloc_size;
 
 
      rs = 1;
      rs = 1;
      for (n = 0; n < rdim; n++)
      for (n = 0; n < rdim; n++)
        {
        {
          rex = shape_data[n];
          rex = shape_data[n];
 
 
          GFC_DIMENSION_SET(ret->dim[n], 0, rex - 1, rs);
          GFC_DIMENSION_SET(ret->dim[n], 0, rex - 1, rs);
 
 
          rs *= rex;
          rs *= rex;
        }
        }
      ret->offset = 0;
      ret->offset = 0;
 
 
      if (unlikely (rs < 1))
      if (unlikely (rs < 1))
        alloc_size = 1;
        alloc_size = 1;
      else
      else
        alloc_size = rs * sizeof ('rtype_name`);
        alloc_size = rs * sizeof ('rtype_name`);
 
 
      ret->data = internal_malloc_size (alloc_size);
      ret->data = internal_malloc_size (alloc_size);
      ret->dtype = (source->dtype & ~GFC_DTYPE_RANK_MASK) | rdim;
      ret->dtype = (source->dtype & ~GFC_DTYPE_RANK_MASK) | rdim;
    }
    }
 
 
  if (shape_empty)
  if (shape_empty)
    return;
    return;
 
 
  if (pad)
  if (pad)
    {
    {
      pdim = GFC_DESCRIPTOR_RANK (pad);
      pdim = GFC_DESCRIPTOR_RANK (pad);
      psize = 1;
      psize = 1;
      pempty = 0;
      pempty = 0;
      for (n = 0; n < pdim; n++)
      for (n = 0; n < pdim; n++)
        {
        {
          pcount[n] = 0;
          pcount[n] = 0;
          pstride[n] = GFC_DESCRIPTOR_STRIDE(pad,n);
          pstride[n] = GFC_DESCRIPTOR_STRIDE(pad,n);
          pextent[n] = GFC_DESCRIPTOR_EXTENT(pad,n);
          pextent[n] = GFC_DESCRIPTOR_EXTENT(pad,n);
          if (pextent[n] <= 0)
          if (pextent[n] <= 0)
            {
            {
              pempty = 1;
              pempty = 1;
              pextent[n] = 0;
              pextent[n] = 0;
            }
            }
 
 
          if (psize == pstride[n])
          if (psize == pstride[n])
            psize *= pextent[n];
            psize *= pextent[n];
          else
          else
            psize = 0;
            psize = 0;
        }
        }
      pptr = pad->data;
      pptr = pad->data;
    }
    }
  else
  else
    {
    {
      pdim = 0;
      pdim = 0;
      psize = 1;
      psize = 1;
      pempty = 1;
      pempty = 1;
      pptr = NULL;
      pptr = NULL;
    }
    }
 
 
  if (unlikely (compile_options.bounds_check))
  if (unlikely (compile_options.bounds_check))
    {
    {
      index_type ret_extent, source_extent;
      index_type ret_extent, source_extent;
 
 
      rs = 1;
      rs = 1;
      for (n = 0; n < rdim; n++)
      for (n = 0; n < rdim; n++)
        {
        {
          rs *= shape_data[n];
          rs *= shape_data[n];
          ret_extent = GFC_DESCRIPTOR_EXTENT(ret,n);
          ret_extent = GFC_DESCRIPTOR_EXTENT(ret,n);
          if (ret_extent != shape_data[n])
          if (ret_extent != shape_data[n])
            runtime_error("Incorrect extent in return value of RESHAPE"
            runtime_error("Incorrect extent in return value of RESHAPE"
                          " intrinsic in dimension %ld: is %ld,"
                          " intrinsic in dimension %ld: is %ld,"
                          " should be %ld", (long int) n+1,
                          " should be %ld", (long int) n+1,
                          (long int) ret_extent, (long int) shape_data[n]);
                          (long int) ret_extent, (long int) shape_data[n]);
        }
        }
 
 
      source_extent = 1;
      source_extent = 1;
      sdim = GFC_DESCRIPTOR_RANK (source);
      sdim = GFC_DESCRIPTOR_RANK (source);
      for (n = 0; n < sdim; n++)
      for (n = 0; n < sdim; n++)
        {
        {
          index_type se;
          index_type se;
          se = GFC_DESCRIPTOR_EXTENT(source,n);
          se = GFC_DESCRIPTOR_EXTENT(source,n);
          source_extent *= se > 0 ? se : 0;
          source_extent *= se > 0 ? se : 0;
        }
        }
 
 
      if (rs > source_extent && (!pad || pempty))
      if (rs > source_extent && (!pad || pempty))
        runtime_error("Incorrect size in SOURCE argument to RESHAPE"
        runtime_error("Incorrect size in SOURCE argument to RESHAPE"
                      " intrinsic: is %ld, should be %ld",
                      " intrinsic: is %ld, should be %ld",
                      (long int) source_extent, (long int) rs);
                      (long int) source_extent, (long int) rs);
 
 
      if (order)
      if (order)
        {
        {
          int seen[GFC_MAX_DIMENSIONS];
          int seen[GFC_MAX_DIMENSIONS];
          index_type v;
          index_type v;
 
 
          for (n = 0; n < rdim; n++)
          for (n = 0; n < rdim; n++)
            seen[n] = 0;
            seen[n] = 0;
 
 
          for (n = 0; n < rdim; n++)
          for (n = 0; n < rdim; n++)
            {
            {
              v = order->data[n * GFC_DESCRIPTOR_STRIDE(order,0)] - 1;
              v = order->data[n * GFC_DESCRIPTOR_STRIDE(order,0)] - 1;
 
 
              if (v < 0 || v >= rdim)
              if (v < 0 || v >= rdim)
                runtime_error("Value %ld out of range in ORDER argument"
                runtime_error("Value %ld out of range in ORDER argument"
                              " to RESHAPE intrinsic", (long int) v + 1);
                              " to RESHAPE intrinsic", (long int) v + 1);
 
 
              if (seen[v] != 0)
              if (seen[v] != 0)
                runtime_error("Duplicate value %ld in ORDER argument to"
                runtime_error("Duplicate value %ld in ORDER argument to"
                              " RESHAPE intrinsic", (long int) v + 1);
                              " RESHAPE intrinsic", (long int) v + 1);
 
 
              seen[v] = 1;
              seen[v] = 1;
            }
            }
        }
        }
    }
    }
 
 
  rsize = 1;
  rsize = 1;
  for (n = 0; n < rdim; n++)
  for (n = 0; n < rdim; n++)
    {
    {
      if (order)
      if (order)
        dim = order->data[n * GFC_DESCRIPTOR_STRIDE(order,0)] - 1;
        dim = order->data[n * GFC_DESCRIPTOR_STRIDE(order,0)] - 1;
      else
      else
        dim = n;
        dim = n;
 
 
      rcount[n] = 0;
      rcount[n] = 0;
      rstride[n] = GFC_DESCRIPTOR_STRIDE(ret,dim);
      rstride[n] = GFC_DESCRIPTOR_STRIDE(ret,dim);
      rextent[n] = GFC_DESCRIPTOR_EXTENT(ret,dim);
      rextent[n] = GFC_DESCRIPTOR_EXTENT(ret,dim);
      if (rextent[n] < 0)
      if (rextent[n] < 0)
        rextent[n] = 0;
        rextent[n] = 0;
 
 
      if (rextent[n] != shape_data[dim])
      if (rextent[n] != shape_data[dim])
        runtime_error ("shape and target do not conform");
        runtime_error ("shape and target do not conform");
 
 
      if (rsize == rstride[n])
      if (rsize == rstride[n])
        rsize *= rextent[n];
        rsize *= rextent[n];
      else
      else
        rsize = 0;
        rsize = 0;
      if (rextent[n] <= 0)
      if (rextent[n] <= 0)
        return;
        return;
    }
    }
 
 
  sdim = GFC_DESCRIPTOR_RANK (source);
  sdim = GFC_DESCRIPTOR_RANK (source);
  ssize = 1;
  ssize = 1;
  sempty = 0;
  sempty = 0;
  for (n = 0; n < sdim; n++)
  for (n = 0; n < sdim; n++)
    {
    {
      scount[n] = 0;
      scount[n] = 0;
      sstride[n] = GFC_DESCRIPTOR_STRIDE(source,n);
      sstride[n] = GFC_DESCRIPTOR_STRIDE(source,n);
      sextent[n] = GFC_DESCRIPTOR_EXTENT(source,n);
      sextent[n] = GFC_DESCRIPTOR_EXTENT(source,n);
      if (sextent[n] <= 0)
      if (sextent[n] <= 0)
        {
        {
          sempty = 1;
          sempty = 1;
          sextent[n] = 0;
          sextent[n] = 0;
        }
        }
 
 
      if (ssize == sstride[n])
      if (ssize == sstride[n])
        ssize *= sextent[n];
        ssize *= sextent[n];
      else
      else
        ssize = 0;
        ssize = 0;
    }
    }
 
 
  if (rsize != 0 && ssize != 0 && psize != 0)
  if (rsize != 0 && ssize != 0 && psize != 0)
    {
    {
      rsize *= sizeof ('rtype_name`);
      rsize *= sizeof ('rtype_name`);
      ssize *= sizeof ('rtype_name`);
      ssize *= sizeof ('rtype_name`);
      psize *= sizeof ('rtype_name`);
      psize *= sizeof ('rtype_name`);
      reshape_packed ((char *)ret->data, rsize, (char *)source->data,
      reshape_packed ((char *)ret->data, rsize, (char *)source->data,
                      ssize, pad ? (char *)pad->data : NULL, psize);
                      ssize, pad ? (char *)pad->data : NULL, psize);
      return;
      return;
    }
    }
  rptr = ret->data;
  rptr = ret->data;
  src = sptr = source->data;
  src = sptr = source->data;
  rstride0 = rstride[0];
  rstride0 = rstride[0];
  sstride0 = sstride[0];
  sstride0 = sstride[0];
 
 
  if (sempty && pempty)
  if (sempty && pempty)
    abort ();
    abort ();
 
 
  if (sempty)
  if (sempty)
    {
    {
      /* Pretend we are using the pad array the first time around, too.  */
      /* Pretend we are using the pad array the first time around, too.  */
      src = pptr;
      src = pptr;
      sptr = pptr;
      sptr = pptr;
      sdim = pdim;
      sdim = pdim;
      for (dim = 0; dim < pdim; dim++)
      for (dim = 0; dim < pdim; dim++)
        {
        {
          scount[dim] = pcount[dim];
          scount[dim] = pcount[dim];
          sextent[dim] = pextent[dim];
          sextent[dim] = pextent[dim];
          sstride[dim] = pstride[dim];
          sstride[dim] = pstride[dim];
          sstride0 = pstride[0];
          sstride0 = pstride[0];
        }
        }
    }
    }
 
 
  while (rptr)
  while (rptr)
    {
    {
      /* Select between the source and pad arrays.  */
      /* Select between the source and pad arrays.  */
      *rptr = *src;
      *rptr = *src;
      /* Advance to the next element.  */
      /* Advance to the next element.  */
      rptr += rstride0;
      rptr += rstride0;
      src += sstride0;
      src += sstride0;
      rcount[0]++;
      rcount[0]++;
      scount[0]++;
      scount[0]++;
 
 
      /* Advance to the next destination element.  */
      /* Advance to the next destination element.  */
      n = 0;
      n = 0;
      while (rcount[n] == rextent[n])
      while (rcount[n] == rextent[n])
        {
        {
          /* When we get to the end of a dimension, reset it and increment
          /* When we get to the end of a dimension, reset it and increment
             the next dimension.  */
             the next dimension.  */
          rcount[n] = 0;
          rcount[n] = 0;
          /* We could precalculate these products, but this is a less
          /* We could precalculate these products, but this is a less
             frequently used path so probably not worth it.  */
             frequently used path so probably not worth it.  */
          rptr -= rstride[n] * rextent[n];
          rptr -= rstride[n] * rextent[n];
          n++;
          n++;
          if (n == rdim)
          if (n == rdim)
            {
            {
              /* Break out of the loop.  */
              /* Break out of the loop.  */
              rptr = NULL;
              rptr = NULL;
              break;
              break;
            }
            }
          else
          else
            {
            {
              rcount[n]++;
              rcount[n]++;
              rptr += rstride[n];
              rptr += rstride[n];
            }
            }
        }
        }
      /* Advance to the next source element.  */
      /* Advance to the next source element.  */
      n = 0;
      n = 0;
      while (scount[n] == sextent[n])
      while (scount[n] == sextent[n])
        {
        {
          /* When we get to the end of a dimension, reset it and increment
          /* When we get to the end of a dimension, reset it and increment
             the next dimension.  */
             the next dimension.  */
          scount[n] = 0;
          scount[n] = 0;
          /* We could precalculate these products, but this is a less
          /* We could precalculate these products, but this is a less
             frequently used path so probably not worth it.  */
             frequently used path so probably not worth it.  */
          src -= sstride[n] * sextent[n];
          src -= sstride[n] * sextent[n];
          n++;
          n++;
          if (n == sdim)
          if (n == sdim)
            {
            {
              if (sptr && pad)
              if (sptr && pad)
                {
                {
                  /* Switch to the pad array.  */
                  /* Switch to the pad array.  */
                  sptr = NULL;
                  sptr = NULL;
                  sdim = pdim;
                  sdim = pdim;
                  for (dim = 0; dim < pdim; dim++)
                  for (dim = 0; dim < pdim; dim++)
                    {
                    {
                      scount[dim] = pcount[dim];
                      scount[dim] = pcount[dim];
                      sextent[dim] = pextent[dim];
                      sextent[dim] = pextent[dim];
                      sstride[dim] = pstride[dim];
                      sstride[dim] = pstride[dim];
                      sstride0 = sstride[0];
                      sstride0 = sstride[0];
                    }
                    }
                }
                }
              /* We now start again from the beginning of the pad array.  */
              /* We now start again from the beginning of the pad array.  */
              src = pptr;
              src = pptr;
              break;
              break;
            }
            }
          else
          else
            {
            {
              scount[n]++;
              scount[n]++;
              src += sstride[n];
              src += sstride[n];
            }
            }
        }
        }
    }
    }
}
}
 
 
#endif'
#endif'
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.