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

Subversion Repositories openrisc

[/] [openrisc/] [tags/] [gnu-src/] [newlib-1.18.0/] [newlib-1.18.0-or32-1.0rc2/] [newlib/] [libc/] [string/] [memmove.c] - Diff between revs 207 and 520

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

Rev 207 Rev 520
/*
/*
FUNCTION
FUNCTION
        <<memmove>>---move possibly overlapping memory
        <<memmove>>---move possibly overlapping memory
 
 
INDEX
INDEX
        memmove
        memmove
 
 
ANSI_SYNOPSIS
ANSI_SYNOPSIS
        #include <string.h>
        #include <string.h>
        void *memmove(void *<[dst]>, const void *<[src]>, size_t <[length]>);
        void *memmove(void *<[dst]>, const void *<[src]>, size_t <[length]>);
 
 
TRAD_SYNOPSIS
TRAD_SYNOPSIS
        #include <string.h>
        #include <string.h>
        void *memmove(<[dst]>, <[src]>, <[length]>)
        void *memmove(<[dst]>, <[src]>, <[length]>)
        void *<[dst]>;
        void *<[dst]>;
        void *<[src]>;
        void *<[src]>;
        size_t <[length]>;
        size_t <[length]>;
 
 
DESCRIPTION
DESCRIPTION
        This function moves <[length]> characters from the block of
        This function moves <[length]> characters from the block of
        memory starting at <<*<[src]>>> to the memory starting at
        memory starting at <<*<[src]>>> to the memory starting at
        <<*<[dst]>>>. <<memmove>> reproduces the characters correctly
        <<*<[dst]>>>. <<memmove>> reproduces the characters correctly
        at <<*<[dst]>>> even if the two areas overlap.
        at <<*<[dst]>>> even if the two areas overlap.
 
 
 
 
RETURNS
RETURNS
        The function returns <[dst]> as passed.
        The function returns <[dst]> as passed.
 
 
PORTABILITY
PORTABILITY
<<memmove>> is ANSI C.
<<memmove>> is ANSI C.
 
 
<<memmove>> requires no supporting OS subroutines.
<<memmove>> requires no supporting OS subroutines.
 
 
QUICKREF
QUICKREF
        memmove ansi pure
        memmove ansi pure
*/
*/
 
 
#include <string.h>
#include <string.h>
#include <_ansi.h>
#include <_ansi.h>
#include <stddef.h>
#include <stddef.h>
#include <limits.h>
#include <limits.h>
 
 
/* Nonzero if either X or Y is not aligned on a "long" boundary.  */
/* Nonzero if either X or Y is not aligned on a "long" boundary.  */
#define UNALIGNED(X, Y) \
#define UNALIGNED(X, Y) \
  (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
  (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
 
 
/* How many bytes are copied each iteration of the 4X unrolled loop.  */
/* How many bytes are copied each iteration of the 4X unrolled loop.  */
#define BIGBLOCKSIZE    (sizeof (long) << 2)
#define BIGBLOCKSIZE    (sizeof (long) << 2)
 
 
/* How many bytes are copied each iteration of the word copy loop.  */
/* How many bytes are copied each iteration of the word copy loop.  */
#define LITTLEBLOCKSIZE (sizeof (long))
#define LITTLEBLOCKSIZE (sizeof (long))
 
 
/* Threshhold for punting to the byte copier.  */
/* Threshhold for punting to the byte copier.  */
#define TOO_SMALL(LEN)  ((LEN) < BIGBLOCKSIZE)
#define TOO_SMALL(LEN)  ((LEN) < BIGBLOCKSIZE)
 
 
/*SUPPRESS 20*/
/*SUPPRESS 20*/
_PTR
_PTR
_DEFUN (memmove, (dst_void, src_void, length),
_DEFUN (memmove, (dst_void, src_void, length),
        _PTR dst_void _AND
        _PTR dst_void _AND
        _CONST _PTR src_void _AND
        _CONST _PTR src_void _AND
        size_t length)
        size_t length)
{
{
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
  char *dst = dst_void;
  char *dst = dst_void;
  _CONST char *src = src_void;
  _CONST char *src = src_void;
 
 
  if (src < dst && dst < src + length)
  if (src < dst && dst < src + length)
    {
    {
      /* Have to copy backwards */
      /* Have to copy backwards */
      src += length;
      src += length;
      dst += length;
      dst += length;
      while (length--)
      while (length--)
        {
        {
          *--dst = *--src;
          *--dst = *--src;
        }
        }
    }
    }
  else
  else
    {
    {
      while (length--)
      while (length--)
        {
        {
          *dst++ = *src++;
          *dst++ = *src++;
        }
        }
    }
    }
 
 
  return dst_void;
  return dst_void;
#else
#else
  char *dst = dst_void;
  char *dst = dst_void;
  _CONST char *src = src_void;
  _CONST char *src = src_void;
  long *aligned_dst;
  long *aligned_dst;
  _CONST long *aligned_src;
  _CONST long *aligned_src;
  int   len =  length;
  int   len =  length;
 
 
  if (src < dst && dst < src + len)
  if (src < dst && dst < src + len)
    {
    {
      /* Destructive overlap...have to copy backwards */
      /* Destructive overlap...have to copy backwards */
      src += len;
      src += len;
      dst += len;
      dst += len;
      while (len--)
      while (len--)
        {
        {
          *--dst = *--src;
          *--dst = *--src;
        }
        }
    }
    }
  else
  else
    {
    {
      /* Use optimizing algorithm for a non-destructive copy to closely
      /* Use optimizing algorithm for a non-destructive copy to closely
         match memcpy. If the size is small or either SRC or DST is unaligned,
         match memcpy. If the size is small or either SRC or DST is unaligned,
         then punt into the byte copy loop.  This should be rare.  */
         then punt into the byte copy loop.  This should be rare.  */
      if (!TOO_SMALL(len) && !UNALIGNED (src, dst))
      if (!TOO_SMALL(len) && !UNALIGNED (src, dst))
        {
        {
          aligned_dst = (long*)dst;
          aligned_dst = (long*)dst;
          aligned_src = (long*)src;
          aligned_src = (long*)src;
 
 
          /* Copy 4X long words at a time if possible.  */
          /* Copy 4X long words at a time if possible.  */
          while (len >= BIGBLOCKSIZE)
          while (len >= BIGBLOCKSIZE)
            {
            {
              *aligned_dst++ = *aligned_src++;
              *aligned_dst++ = *aligned_src++;
              *aligned_dst++ = *aligned_src++;
              *aligned_dst++ = *aligned_src++;
              *aligned_dst++ = *aligned_src++;
              *aligned_dst++ = *aligned_src++;
              *aligned_dst++ = *aligned_src++;
              *aligned_dst++ = *aligned_src++;
              len -= BIGBLOCKSIZE;
              len -= BIGBLOCKSIZE;
            }
            }
 
 
          /* Copy one long word at a time if possible.  */
          /* Copy one long word at a time if possible.  */
          while (len >= LITTLEBLOCKSIZE)
          while (len >= LITTLEBLOCKSIZE)
            {
            {
              *aligned_dst++ = *aligned_src++;
              *aligned_dst++ = *aligned_src++;
              len -= LITTLEBLOCKSIZE;
              len -= LITTLEBLOCKSIZE;
            }
            }
 
 
          /* Pick up any residual with a byte copier.  */
          /* Pick up any residual with a byte copier.  */
          dst = (char*)aligned_dst;
          dst = (char*)aligned_dst;
          src = (char*)aligned_src;
          src = (char*)aligned_src;
        }
        }
 
 
      while (len--)
      while (len--)
        {
        {
          *dst++ = *src++;
          *dst++ = *src++;
        }
        }
    }
    }
 
 
  return dst_void;
  return dst_void;
#endif /* not PREFER_SIZE_OVER_SPEED */
#endif /* not PREFER_SIZE_OVER_SPEED */
}
}
 
 

powered by: WebSVN 2.1.0

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