OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [tags/] [gnu-src/] [newlib-1.18.0/] [newlib-1.18.0-or32-1.0rc1/] [newlib/] [libc/] [string/] [memccpy.c] - Diff between revs 207 and 345

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

Rev 207 Rev 345
/*
/*
FUNCTION
FUNCTION
        <<memccpy>>---copy memory regions with end-token check
        <<memccpy>>---copy memory regions with end-token check
 
 
ANSI_SYNOPSIS
ANSI_SYNOPSIS
        #include <string.h>
        #include <string.h>
        void* memccpy(void *<[out]>, const void *<[in]>,
        void* memccpy(void *<[out]>, const void *<[in]>,
                      int <[endchar]>, size_t <[n]>);
                      int <[endchar]>, size_t <[n]>);
 
 
TRAD_SYNOPSIS
TRAD_SYNOPSIS
        void *memccpy(<[out]>, <[in]>, <[endchar]>, <[n]>
        void *memccpy(<[out]>, <[in]>, <[endchar]>, <[n]>
        void *<[out]>;
        void *<[out]>;
        void *<[in]>;
        void *<[in]>;
        int <[endchar]>;
        int <[endchar]>;
        size_t <[n]>;
        size_t <[n]>;
 
 
DESCRIPTION
DESCRIPTION
        This function copies up to <[n]> bytes from the memory region
        This function copies up to <[n]> bytes from the memory region
        pointed to by <[in]> to the memory region pointed to by
        pointed to by <[in]> to the memory region pointed to by
        <[out]>.  If a byte matching the <[endchar]> is encountered,
        <[out]>.  If a byte matching the <[endchar]> is encountered,
        the byte is copied and copying stops.
        the byte is copied and copying stops.
 
 
        If the regions overlap, the behavior is undefined.
        If the regions overlap, the behavior is undefined.
 
 
RETURNS
RETURNS
        <<memccpy>> returns a pointer to the first byte following the
        <<memccpy>> returns a pointer to the first byte following the
        <[endchar]> in the <[out]> region.  If no byte matching
        <[endchar]> in the <[out]> region.  If no byte matching
        <[endchar]> was copied, then <<NULL>> is returned.
        <[endchar]> was copied, then <<NULL>> is returned.
 
 
PORTABILITY
PORTABILITY
<<memccpy>> is a GNU extension.
<<memccpy>> is a GNU extension.
 
 
<<memccpy>> requires no supporting OS subroutines.
<<memccpy>> requires no supporting OS subroutines.
 
 
        */
        */
 
 
#include <_ansi.h>
#include <_ansi.h>
#include <stddef.h>
#include <stddef.h>
#include <string.h>
#include <string.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 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) < LITTLEBLOCKSIZE)
#define TOO_SMALL(LEN)  ((LEN) < LITTLEBLOCKSIZE)
 
 
/* Macros for detecting endchar */
/* Macros for detecting endchar */
#if LONG_MAX == 2147483647L
#if LONG_MAX == 2147483647L
#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
#else
#else
#if LONG_MAX == 9223372036854775807L
#if LONG_MAX == 9223372036854775807L
/* Nonzero if X (a long int) contains a NULL byte. */
/* Nonzero if X (a long int) contains a NULL byte. */
#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
#else
#else
#error long int is not a 32bit or 64bit type.
#error long int is not a 32bit or 64bit type.
#endif
#endif
#endif
#endif
 
 
 
 
_PTR
_PTR
_DEFUN (memccpy, (dst0, src0, endchar, len0),
_DEFUN (memccpy, (dst0, src0, endchar, len0),
        _PTR dst0 _AND
        _PTR dst0 _AND
        _CONST _PTR src0 _AND
        _CONST _PTR src0 _AND
        int endchar0 _AND
        int endchar0 _AND
        size_t len0)
        size_t len0)
{
{
 
 
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
  _PTR ptr = NULL;
  _PTR ptr = NULL;
  char *dst = (char *) dst0;
  char *dst = (char *) dst0;
  char *src = (char *) src0;
  char *src = (char *) src0;
  char endchar = endchar0 & 0xff;
  char endchar = endchar0 & 0xff;
 
 
  while (len0--)
  while (len0--)
    {
    {
      if ((*dst++ = *src++) == endchar)
      if ((*dst++ = *src++) == endchar)
        {
        {
          ptr = dst;
          ptr = dst;
          break;
          break;
        }
        }
    }
    }
 
 
  return ptr;
  return ptr;
#else
#else
  _PTR ptr = NULL;
  _PTR ptr = NULL;
  char *dst = dst0;
  char *dst = dst0;
  _CONST char *src = src0;
  _CONST char *src = src0;
  long *aligned_dst;
  long *aligned_dst;
  _CONST long *aligned_src;
  _CONST long *aligned_src;
  int   len =  len0;
  int   len =  len0;
  char endchar = endchar0 & 0xff;
  char endchar = endchar0 & 0xff;
 
 
  /* If the size is small, or either SRC or DST is unaligned,
  /* 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))
    {
    {
      int i;
      int i;
      unsigned long mask = 0;
      unsigned long mask = 0;
 
 
      aligned_dst = (long*)dst;
      aligned_dst = (long*)dst;
      aligned_src = (long*)src;
      aligned_src = (long*)src;
 
 
      /* The fast code reads the ASCII one word at a time and only
      /* The fast code reads the ASCII one word at a time and only
         performs the bytewise search on word-sized segments if they
         performs the bytewise search on word-sized segments if they
         contain the search character, which is detected by XORing
         contain the search character, which is detected by XORing
         the word-sized segment with a word-sized block of the search
         the word-sized segment with a word-sized block of the search
         character and then detecting for the presence of NULL in the
         character and then detecting for the presence of NULL in the
         result.  */
         result.  */
      for (i = 0; i < LITTLEBLOCKSIZE; i++)
      for (i = 0; i < LITTLEBLOCKSIZE; i++)
        mask = (mask << 8) + endchar;
        mask = (mask << 8) + endchar;
 
 
 
 
      /* Copy one long word at a time if possible.  */
      /* Copy one long word at a time if possible.  */
      while (len >= LITTLEBLOCKSIZE)
      while (len >= LITTLEBLOCKSIZE)
        {
        {
          unsigned long buffer = (unsigned long)(*aligned_src);
          unsigned long buffer = (unsigned long)(*aligned_src);
          buffer ^=  mask;
          buffer ^=  mask;
          if (DETECTNULL (buffer))
          if (DETECTNULL (buffer))
            break; /* endchar is found, go byte by byte from here */
            break; /* endchar is found, go byte by byte from here */
          *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--)
    {
    {
      if ((*dst++ = *src++) == endchar)
      if ((*dst++ = *src++) == endchar)
        {
        {
          ptr = dst;
          ptr = dst;
          break;
          break;
        }
        }
    }
    }
 
 
  return ptr;
  return ptr;
#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.