[PATCH] cell spu accelerated string functions

Jeff Johnston jjohnstn@redhat.com
Sat Oct 28 08:04:00 GMT 2006


Patch checked in.

-- Jeff J.

jschopp wrote:
> <snip>
>  > Also the curly
>> brace style
>> is not optional by the Cell C/C++ Language extension document so you 
>> can use that style
>> always for literals.
> 
> Refreshed patch below.
> 
> This patch is ready to check in to cvs.  It is string code written 
> explicitly to take advantage of the spu being a vectorized processor.  
> All functions generate assembly on the spu that is smaller and faster 
> than the generic code, except memcpy and memmove which generate slightly 
> larger code that is faster.  As a bonus, the code should be fairly 
> trivial to port to other vectorized processors such as PowerPCs with 
> altivec.
> 
> We've been running with this code on our internal builds for the cell 
> SDK 2.0 for several cycles now and seem to have squashed all the bugs we 
> could find through our extensive testing.
> 
> 2006-10-26    <jschopp@austin.ibm.com>
> 
>     * libc/machine/spu/memcpy.c: Override generic function with vectorized
>     version optimized for the cell spu.
>     * libc/machine/spu/memmove.c: Ditto.
>     * libc/machine/spu/memset.c: Ditto.
>     * libc/machine/spu/strcat.c: Ditto.
>     * libc/machine/spu/strchr.c: Ditto.
>     * libc/machine/spu/strcmp.c: Ditto.
>     * libc/machine/spu/strcpy.c: Ditto.
>     * libc/machine/spu/strcspn.c: Ditto.
>     * libc/machine/spu/strlen.c: Ditto.
>     * libc/machine/spu/strncat.c: Ditto.
>     * libc/machine/spu/strncmp.c: Ditto.
>     * libc/machine/spu/strncpy.c: Ditto.
>     * libc/machine/spu/strpbrk.c: Ditto.
>     * libc/machine/spu/strrchr.c: Ditto.
>     * libc/machine/spu/strspn.c: Ditto.
>     * libc/machine/spu/strxfrm.c: Ditto.
>     * libc/machine/spu/vec_literal.h: Add abstraction of vector 
> literals, removing altivec style initializers.
>     * libc/machine/spu/Makefile.am: Add new files to list so they build
>     * libc/machine/spu/Makefile.in: Regenerate from new Makefile.am
> 
> 
> ------------------------------------------------------------------------
> 
> Index: src/newlib/libc/machine/spu/strcmp.c
> ===================================================================
> --- /dev/null
> +++ src/newlib/libc/machine/spu/strcmp.c
> @@ -0,0 +1,94 @@
> +/*
> +  (C) Copyright 2001,2006,
> +  International Business Machines Corporation,
> +  Sony Computer Entertainment, Incorporated,
> +  Toshiba Corporation,
> +
> +  All rights reserved.
> +
> +  Redistribution and use in source and binary forms, with or without
> +  modification, are permitted provided that the following conditions are met:
> +
> +    * Redistributions of source code must retain the above copyright notice,
> +  this list of conditions and the following disclaimer.
> +    * Redistributions in binary form must reproduce the above copyright
> +  notice, this list of conditions and the following disclaimer in the
> +  documentation and/or other materials provided with the distribution.
> +    * Neither the names of the copyright holders nor the names of their
> +  contributors may be used to endorse or promote products derived from this
> +  software without specific prior written permission.
> +
> +  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
> +  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> +  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> +  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
> +  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> +  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> +  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
> +  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> +  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> +  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> +  POSSIBILITY OF SUCH DAMAGE.
> +*/
> +#include <spu_intrinsics.h>
> +#include "vec_literal.h"
> +
> +/* Compare the two strings s1 and s2. Return an integer less than, equal
> + * to, or greater than zero if  s1 is found, respectively, to be less than,
> + * to match, or be greater than s2.
> + */
> +
> +int strcmp(const char *s1, const char *s2)
> +{
> +  unsigned int offset1, offset2;
> +  vec_uint4 gt_v, lt_v, mask_v;
> +  vec_uint4 cnt1_v, cnt2_v;
> +  vec_uint4 end1_v, end2_v, end_v, neq_v;
> +  vec_uchar16 shuffle1, shuffle2;
> +  vec_uchar16 data1A, data1B, data1, data2A, data2B, data2;
> +  vec_uchar16 *ptr1, *ptr2;
> +
> +  ptr1 = (vec_uchar16 *)s1;
> +  ptr2 = (vec_uchar16 *)s2;
> +
> +  offset1 = (unsigned int)(ptr1) & 15;
> +  offset2 = (unsigned int)(ptr2) & 15;
> +
> +  shuffle1 = (vec_uchar16)spu_add((vec_uint4)spu_splats((unsigned char)offset1),
> +				  VEC_LITERAL(vec_uint4, 0x00010203, 0x04050607, 0x08090A0B, 0x0C0D0E0F));
> +  shuffle2 = (vec_uchar16)spu_add((vec_uint4)spu_splats((unsigned char)offset2),
> +				  VEC_LITERAL(vec_uint4, 0x00010203, 0x04050607, 0x08090A0B, 0x0C0D0E0F));
> +
> +  data1A = *ptr1++;
> +  data2A = *ptr2++;
> +
> +  do {
> +    data1B = *ptr1++;
> +    data2B = *ptr2++;
> +
> +    data1 = spu_shuffle(data1A, data1B, shuffle1);
> +    data2 = spu_shuffle(data2A, data2B, shuffle2);
> +
> +    data1A = data1B;
> +    data2A = data2B;
> +
> +    neq_v = spu_gather(spu_xor(spu_cmpeq(data1, data2), -1));
> +
> +    end1_v = spu_gather(spu_cmpeq(data1, 0));
> +    end2_v = spu_gather(spu_cmpeq(data2, 0));
> +    end_v  = spu_or(end1_v, end2_v), 0;
> +  } while (spu_extract(spu_or(end_v, neq_v), 0) == 0);
> +
> +  cnt1_v = spu_cntlz(end1_v);
> +  cnt2_v = spu_cntlz(end2_v);
> +
> +  gt_v = spu_gather(spu_cmpgt(data1, data2));
> +  lt_v = spu_gather(spu_cmpgt(data2, data1));
> +
> +  mask_v = spu_and(spu_cmpeq(cnt1_v, cnt2_v),
> +		   spu_cmpeq(spu_rlmask(neq_v, (vec_int4)spu_add((vec_uint4)cnt1_v, -32)), 0));
> +
> +  gt_v = spu_sub(-1, spu_sl(spu_cmpgt(gt_v, lt_v), 1));
> +
> +  return (spu_extract(spu_andc(gt_v, mask_v), 0));
> +}
> Index: src/newlib/libc/machine/spu/vec_literal.h
> ===================================================================
> --- /dev/null
> +++ src/newlib/libc/machine/spu/vec_literal.h
> @@ -0,0 +1,75 @@
> +/*
> +  (C) Copyright 2001,2006,
> +  International Business Machines Corporation,
> +  Sony Computer Entertainment, Incorporated,
> +  Toshiba Corporation,
> +
> +  All rights reserved.
> +
> +  Redistribution and use in source and binary forms, with or without
> +  modification, are permitted provided that the following conditions are met:
> +
> +    * Redistributions of source code must retain the above copyright notice,
> +  this list of conditions and the following disclaimer.
> +    * Redistributions in binary form must reproduce the above copyright
> +  notice, this list of conditions and the following disclaimer in the
> +  documentation and/or other materials provided with the distribution.
> +    * Neither the names of the copyright holders nor the names of their
> +  contributors may be used to endorse or promote products derived from this
> +  software without specific prior written permission.
> +
> +  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
> +  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> +  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> +  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
> +  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> +  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> +  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
> +  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> +  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> +  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> +  POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#ifndef _VEC_LITERAL_H_
> +#define _VEC_LITERAL_H_
> +
> +/* This header files provides an abstraction for the various implementations
> + * of vector literal construction. The two formats are:
> + *
> + * 1) Altivec styled using parenthesis
> + * 2) C grammer friendly styled using curly braces
> + *
> + * The macro, VEC_LITERAL has been developed to provide some portability
> + * in these two styles. To achieve true portability, user must specify all
> + * elements of the vector being initialized. A single element can be provided
> + * but only the first element guarenteed across both construction styles.
> + *
> + * The VEC_SPLAT_* macros have been provided for portability of vector literal
> + * construction when all the elements of the vector contain the same value.
> + */
> +
> +#ifdef __SPU__
> +#include <spu_intrinsics.h>
> +#endif
> +
> +
> +/* Use curly brace style.
> + */
> +#define VEC_LITERAL(_type, ...)	((_type){__VA_ARGS__})
> +
> +#define VEC_SPLAT_U8(_val)	((vector unsigned char){_val, _val, _val, _val, _val, _val, _val, _val, _val, _val, _val, _val, _val, _val, _val, _val})
> +#define VEC_SPLAT_S8(_val)	((vector signed char){_val, _val, _val, _val, _val, _val, _val, _val, _val, _val, _val, _val, _val, _val, _val, _val})
> +
> +#define VEC_SPLAT_U16(_val)	((vector unsigned short){_val, _val, _val, _val, _val, _val, _val, _val})
> +#define VEC_SPLAT_S16(_val)	((vector signed short){_val, _val, _val, _val, _val, _val, _val, _val})
> +
> +#define VEC_SPLAT_U32(_val)	((vector unsigned int){_val, _val, _val, _val})
> +#define VEC_SPLAT_S32(_val)	((vector signed int){_val, _val, _val, _val})
> +#define VEC_SPLAT_F32(_val)	((vector float){_val, _val, _val, _val})
> +
> +#define VEC_SPLAT_U64(_val)	((vector unsigned long long){_val, _val})
> +#define VEC_SPLAT_S64(_val)	((vector signed long long){_val, _val})
> +#define VEC_SPLAT_F64(_val)	((vector double){_val, _val})
> +
> +#endif /* _VEC_LITERAL_H_ */
> Index: src/newlib/libc/machine/spu/memcpy.c
> ===================================================================
> --- src.orig/newlib/libc/machine/spu/memcpy.c
> +++ src/newlib/libc/machine/spu/memcpy.c
> @@ -1,48 +1,115 @@
>  /*
> -(C) Copyright IBM Corp. 2005, 2006
> -
> -All rights reserved.
> -
> -Redistribution and use in source and binary forms, with or without 
> -modification, are permitted provided that the following conditions are met:
> -
> -    * Redistributions of source code must retain the above copyright notice, 
> -this list of conditions and the following disclaimer.
> -    * Redistributions in binary form must reproduce the above copyright 
> -notice, this list of conditions and the following disclaimer in the 
> -documentation and/or other materials provided with the distribution.
> -    * Neither the name of IBM nor the names of its contributors may be 
> -used to endorse or promote products derived from this software without 
> -specific prior written permission.
> -
> -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
> -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
> -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
> -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
> -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
> -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
> -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
> -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
> -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
> -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
> -POSSIBILITY OF SUCH DAMAGE.
> -
> -Author: Andreas Neukoetter (ti95neuk@de.ibm.com)
> -*/
> -
> -#include <string.h>
> -
> -void * memcpy (void *dst, const void *src, size_t len)
> +  (C) Copyright 2001,2006,
> +  International Business Machines Corporation,
> +  Sony Computer Entertainment, Incorporated,
> +  Toshiba Corporation,
> +
> +  All rights reserved.
> +
> +  Redistribution and use in source and binary forms, with or without
> +  modification, are permitted provided that the following conditions are met:
> +
> +    * Redistributions of source code must retain the above copyright notice,
> +  this list of conditions and the following disclaimer.
> +    * Redistributions in binary form must reproduce the above copyright
> +  notice, this list of conditions and the following disclaimer in the
> +  documentation and/or other materials provided with the distribution.
> +    * Neither the names of the copyright holders nor the names of their
> +  contributors may be used to endorse or promote products derived from this
> +  software without specific prior written permission.
> +
> +  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
> +  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> +  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> +  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
> +  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> +  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> +  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
> +  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> +  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> +  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> +  POSSIBILITY OF SUCH DAMAGE.
> +  */
> +#include <spu_intrinsics.h>
> +#include <stddef.h>
> +#include <vec_literal.h>
> +
> +/* Copy n bytes from memory area src to memory area dest.
> + * The memory areas may not overlap. The memcpy subroutine
> + * returns a pointer to dest.
> + *
> + * Faster implemenation of this function can be implemented
> + * either with prior knowledge of the alignment or special
> + * casing specific optimal alignments.
> + */
> +void * memcpy(void * __restrict__ dest, const void * __restrict__ src, size_t n)
>  {
> -	/* TODO: copying byte by byte is far to inefficient */
> -	int	i = 0;
> -	char 	*d = ( char* )dst;
> -	char	*s = ( char* )src;
> -
> -	while( i< len ){
> -		*( d++ )= *( s++ );
> -		i++;
> -	}
> +  int adjust, delta;
> +  unsigned int soffset1, doffset1, doffset2;
> +  vec_uchar16 *vSrc, *vDst;
> +  vec_uchar16 sdata1, sdata2, sdata, ddata, shuffle;
> +  vec_uchar16 mask, mask1, mask2, mask3;
> +
> +  vSrc = (vec_uchar16 *)(src);
> +  vDst = (vec_uchar16 *)(dest);
> +
> +  /* Handle any leading destination partial quadwords as
> +   * well a very short copy (ie, such that the n characters
> +   * all reside in a single (destination) quadword.
> +   */
> +  soffset1 = (unsigned int)(src) & 15;
> +  doffset1 = (unsigned int)(dest) & 15;
> +  doffset2 = ((unsigned int)(dest) + n) & 15;
> +
> +  /* Compute a shuffle pattern used to align the source string
> +   * with the alignment of the destination string.
> +   */
> +
> +  adjust = (int)spu_extract(spu_cmpgt(spu_promote(doffset1, 0), spu_promote(soffset1, 0)), 0);
> +  delta  = (int)soffset1 - (int)doffset1;
> +  delta += adjust & 16;
> +
> +  shuffle = (vec_uchar16)spu_add((vec_uint4)spu_splats((unsigned char)delta),
> +				 VEC_LITERAL(vec_uint4, 0x00010203, 0x04050607, 0x08090A0B, 0x0C0D0E0F));
> +
> +  vSrc += adjust;
> +
> +  sdata1 = *vSrc++;
> +  sdata2 = *vSrc++;
> +
> +  ddata = *vDst;
> +  sdata = spu_shuffle(sdata1, sdata2, shuffle);
> +
> +  /* Construct a series of masks used to data insert. The masks
> +   * contain 0 when the destination word is unchanged, 1 when it
> +   * must be replaced by source bytes.
> +   *
> +   * mask1 = mask for leading unchanged bytes
> +   * mask2 = mask for trailing unchange bytes
> +   * mask3 = mask indicating the more than one qword is being changed.
> +   */
> +  mask  = VEC_SPLAT_U8(-1);
> +  mask1 = spu_rlmaskqwbyte(mask, -doffset1);
> +  mask2 = spu_slqwbyte(mask, 16-doffset2);
> +  mask3 = (vec_uchar16)spu_cmpgt(spu_splats(doffset1 + n), 15);
> +
> +  *vDst++ = spu_sel(ddata, sdata, spu_and(mask1, spu_or(mask2, mask3)));
> +
> +  n += doffset1;
> +
> +  /* Handle complete destination quadwords
> +   */
> +  while (n > 31) {
> +    sdata1 = sdata2;
> +    sdata2 = *vSrc++;
> +    *vDst++ = spu_shuffle(sdata1, sdata2, shuffle);
> +    n -= 16;
> +  }
> +
> +  /* Handle any trailing partial (destination) quadwords
> +   */
> +  mask = spu_and((vec_uchar16)spu_cmpgt(spu_splats(n), 16), mask2);
> +  *vDst = spu_sel(*vDst, spu_shuffle(sdata2, *vSrc, shuffle), mask);
>  
> -	return( dst );
> +  return (dest);
>  }
> Index: src/newlib/libc/machine/spu/memmove.c
> ===================================================================
> --- /dev/null
> +++ src/newlib/libc/machine/spu/memmove.c
> @@ -0,0 +1,216 @@
> +/*
> +  (C) Copyright 2001,2006,
> +  International Business Machines Corporation,
> +  Sony Computer Entertainment, Incorporated,
> +  Toshiba Corporation,
> +
> +  All rights reserved.
> +
> +  Redistribution and use in source and binary forms, with or without
> +  modification, are permitted provided that the following conditions are met:
> +
> +    * Redistributions of source code must retain the above copyright notice,
> +  this list of conditions and the following disclaimer.
> +    * Redistributions in binary form must reproduce the above copyright
> +  notice, this list of conditions and the following disclaimer in the
> +  documentation and/or other materials provided with the distribution.
> +    * Neither the names of the copyright holders nor the names of their
> +  contributors may be used to endorse or promote products derived from this
> +  software without specific prior written permission.
> +
> +  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
> +  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> +  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> +  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
> +  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> +  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> +  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
> +  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> +  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> +  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> +  POSSIBILITY OF SUCH DAMAGE.
> +*/
> +#include <spu_intrinsics.h>
> +#include <stddef.h>
> +#include "vec_literal.h"
> +
> +/* Copy n bytes from memory area src to memory area dest.
> + * Copying is performed as if the n characters pointed to
> + * by src are first copied into a temporary array that does
> + * not overlap the src and dest arrays. Then the n characters
> + * of the temporary array are copied into the destination
> + * array. The memmove subroutine returns a pointer to dest.
> + */
> +
> +void * memmove(void * __restrict__ dest, const void * __restrict__ src, size_t n)
> +{
> +  int adjust, delta;
> +  unsigned int soffset1, soffset2, doffset1, doffset2;
> +  vec_uchar16 *vSrc, *vDst;
> +  vec_uchar16 sdata1, sdata2, sdata, ddata, shuffle;
> +  vec_uchar16 mask, mask1, mask2, mask3;
> +
> +  soffset1  = (unsigned int)(src) & 15;
> +  doffset1 = (unsigned int)(dest) & 15;
> +  doffset2 = ((unsigned int)(dest) + n) & 15;
> +
> +  /* Construct a series of masks used to data insert. The masks
> +   * contains 0 bit when the destination word is unchanged, 1 when it
> +   * must be replaced by source bits.
> +   *
> +   * mask1 = mask for leading unchanged bytes
> +   * mask2 = mask for trailing unchange bytes
> +   * mask3 = mask indicating the more than one qword is being changed.
> +   */
> +  mask  = VEC_SPLAT_U8(-1);
> +  mask1 = spu_rlmaskqwbyte(mask, -doffset1);
> +  mask2 = spu_slqwbyte(mask, 16-doffset2);
> +  mask3 = (vec_uchar16)spu_cmpgt(spu_splats(doffset1 + n), 15);
> +
> +  vDst = (vec_uchar16 *)(dest);
> +
> +  delta  = (int)soffset1 - (int)doffset1;
> +
> +  /* The follow check only works if the SPU addresses are not
> +   * wrapped. No provisions have been made to correct for this
> +   * limitation.
> +   */
> +  if (((unsigned int)dest - (unsigned int)src) >= (unsigned int)n) {
> +    /* Forward copy. Perform a memcpy.
> +     *
> +     * Handle any leading destination partial quadwords as
> +     * well a very short copy (ie, such that the n characters
> +     * all reside in a single (destination) quadword.
> +     */
> +    vSrc = (vec_uchar16 *)(src);
> +    vDst = (vec_uchar16 *)(dest);
> +
> +    /* Handle any leading destination partial quadwords as
> +     * well a very short copy (ie, such that the n characters
> +     * all reside in a single (destination) quadword.
> +     */
> +    soffset1 = (unsigned int)(src) & 15;
> +    doffset1 = (unsigned int)(dest) & 15;
> +    doffset2 = ((unsigned int)(dest) + n) & 15;
> +
> +    /* Compute a shuffle pattern used to align the source string
> +     * with the alignment of the destination string.
> +     */
> +
> +    adjust = (int)spu_extract(spu_cmpgt(spu_promote(doffset1, 0), spu_promote(soffset1, 0)), 0);
> +    delta  = (int)soffset1 - (int)doffset1;
> +    delta += adjust & 16;
> +
> +    shuffle = (vec_uchar16)spu_add((vec_uint4)spu_splats((unsigned char)delta),
> +				   VEC_LITERAL(vec_uint4, 0x00010203, 0x04050607, 0x08090A0B, 0x0C0D0E0F));
> +
> +    vSrc += adjust;
> +
> +    sdata1 = *vSrc++;
> +    sdata2 = *vSrc++;
> +
> +    ddata = *vDst;
> +    sdata = spu_shuffle(sdata1, sdata2, shuffle);
> +
> +    /* Construct a series of masks used to data insert. The masks
> +     * contain 0 when the destination word is unchanged, 1 when it
> +     * must be replaced by source bytes.
> +     *
> +     * mask1 = mask for leading unchanged bytes
> +     * mask2 = mask for trailing unchange bytes
> +     * mask3 = mask indicating the more than one qword is being changed.
> +     */
> +    mask  = VEC_SPLAT_U8(-1);
> +    mask1 = spu_rlmaskqwbyte(mask, -doffset1);
> +    mask2 = spu_slqwbyte(mask, 16-doffset2);
> +    mask3 = (vec_uchar16)spu_cmpgt(spu_splats(doffset1 + n), 15);
> +
> +    *vDst++ = spu_sel(ddata, sdata, spu_and(mask1, spu_or(mask2, mask3)));
> +
> +    n += doffset1;
> +
> +    /* Handle complete destination quadwords
> +     */
> +    while (n > 31) {
> +      sdata1 = sdata2;
> +      sdata2 = *vSrc++;
> +      *vDst++ = spu_shuffle(sdata1, sdata2, shuffle);
> +      n -= 16;
> +    }
> +
> +    /* Handle any trailing partial (destination) quadwords
> +     */
> +    mask = spu_and((vec_uchar16)spu_cmpgt(spu_splats(n), 16), mask2);
> +    *vDst = spu_sel(*vDst, spu_shuffle(sdata2, *vSrc, shuffle), mask);
> +
> +  } else {
> +    /* Backward copy.
> +     *
> +     * Handle any leading destination partial quadwords as
> +     * well a very short copy (ie, such that the n characters
> +     * all reside in a single (destination) quadword.
> +     */
> +    vSrc = (vec_uchar16 *)((unsigned int)src  + n-1);
> +    vDst = (vec_uchar16 *)((unsigned int)dest + n-1);
> +
> +    /* Handle any leading destination partial quadwords as
> +     * well a very short copy (ie, such that the n characters
> +     * all reside in a single (destination) quadword.
> +     */
> +    soffset1 = (unsigned int)(src)  & 15;
> +    soffset2 = (unsigned int)(vSrc) & 15;
> +    doffset1 = (unsigned int)(dest) & 15;
> +    doffset2 = (unsigned int)(vDst) & 15;
> +
> +    /* Compute a shuffle pattern used to align the source string
> +     * with the alignment of the destination string.
> +     */
> +    adjust = (int)spu_extract(spu_cmpgt(spu_promote(soffset2, 0), spu_promote(doffset2, 0)), 0);
> +    delta  = (int)doffset2 - (int)soffset2;
> +    delta += adjust & 16;
> +
> +    shuffle = (vec_uchar16)spu_sub(VEC_LITERAL(vec_uint4, 0x10111213, 0x14151617, 0x18191A1B, 0x1C1D1E1F),
> +				   (vec_uint4)spu_splats((unsigned char)delta));
> +
> +    vSrc -= adjust;
> +
> +    sdata2 = *vSrc--;
> +    sdata1 = *vSrc--;
> +
> +    ddata = *vDst;
> +    sdata = spu_shuffle(sdata1, sdata2, shuffle);
> +
> +    /* Construct a series of masks used to data insert. The masks
> +     * contain 0 when the destination word is unchanged, 1 when it
> +     * must be replaced by source bytes.
> +     *
> +     * mask1 = mask for leading unchanged bytes
> +     * mask2 = mask for trailing unchange bytes
> +     * mask3 = mask indicating the more than one qword is being changed.
> +     */
> +    mask  = VEC_SPLAT_U8(-1);
> +    mask1 = spu_rlmaskqwbyte(mask, -doffset1);
> +    mask2 = spu_slqwbyte(mask, 15-doffset2);
> +    mask3 = (vec_uchar16)spu_cmpgt(spu_splats((int)(doffset2 - n)), -2);
> +
> +    *vDst-- = spu_sel(ddata, sdata, spu_and(mask2, spu_orc(mask1, mask3)));
> +
> +    n -= doffset2 + 1;
> +
> +    /* Handle complete destination quadwords
> +     */
> +    while ((int)n > 15) {
> +      sdata2 = sdata1;
> +      sdata1 = *vSrc--;
> +      *vDst-- = spu_shuffle(sdata1, sdata2, shuffle);
> +      n -= 16;
> +    }
> +
> +    /* Handle any trailing partial (destination) quadwords
> +     */
> +    mask = spu_and((vec_uchar16)spu_cmpgt(spu_splats((int)n), 0), mask1);
> +    *vDst = spu_sel(*vDst, spu_shuffle(*vSrc, sdata1, shuffle), mask);
> +  }
> +  return (dest);
> +}
> +
> Index: src/newlib/libc/machine/spu/memset.c
> ===================================================================
> --- /dev/null
> +++ src/newlib/libc/machine/spu/memset.c
> @@ -0,0 +1,90 @@
> +/*
> +  (C) Copyright 2001,2006,
> +  International Business Machines Corporation,
> +  Sony Computer Entertainment, Incorporated,
> +  Toshiba Corporation,
> +
> +  All rights reserved.
> +
> +  Redistribution and use in source and binary forms, with or without
> +  modification, are permitted provided that the following conditions are met:
> +
> +    * Redistributions of source code must retain the above copyright notice,
> +  this list of conditions and the following disclaimer.
> +    * Redistributions in binary form must reproduce the above copyright
> +  notice, this list of conditions and the following disclaimer in the
> +  documentation and/or other materials provided with the distribution.
> +    * Neither the names of the copyright holders nor the names of their
> +  contributors may be used to endorse or promote products derived from this
> +  software without specific prior written permission.
> +
> +  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
> +  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> +  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> +  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
> +  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> +  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> +  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
> +  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> +  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> +  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> +  POSSIBILITY OF SUCH DAMAGE.
> +*/
> +#include <spu_intrinsics.h>
> +#include <stddef.h>
> +
> +/* Fills the first n bytes of the memory area pointed to by s
> + * with the constant byte c. Returns a pointer to the memory area s.
> + */
> +void * memset(void *s, int c, size_t n)
> +{
> +  int skip, cnt, i;
> +  vec_uchar16 *vs;
> +  vec_uchar16 vc, mask;
> +
> +  vs = (vec_uchar16 *)(s);
> +  vc = spu_splats((unsigned char)c);
> +  cnt = (int)(n);
> +
> +  /* Handle any leading partial quadwords as well a
> +   * very short settings (ie, such that the n characters
> +   * all reside in a single quadword.
> +   */
> +  skip = (int)(s) & 15;
> +  if (skip) {
> +    mask = spu_rlmaskqwbyte((vec_uchar16)(-1), 0-skip);
> +    cnt -= 16 - skip;
> +    if (cnt < 0) {
> +      mask = spu_and(mask, spu_slqwbyte((vec_uchar16)(-1), (unsigned int)(-cnt)));
> +    }
> +    *vs = spu_sel(*vs, vc, mask);
> +    vs++;
> +  }
> +
> +  /* Handle 8 quadwords at a time
> +   */
> +  for (i=127; i<cnt; cnt-=8*16) {
> +    vs[0] = vc;
> +    vs[1] = vc;
> +    vs[2] = vc;
> +    vs[3] = vc;
> +    vs[4] = vc;
> +    vs[5] = vc;
> +    vs[6] = vc;
> +    vs[7] = vc;
> +    vs += 8;
> +  }
> +
> +  /* Finish all remaining complete quadwords
> +   */
> +  for (i=15; i<cnt; cnt-=16) *vs++ = vc;
> +
> +  /* Handle any trailing partial quadwords
> +   */
> +  if (cnt > 0) {
> +    mask = spu_slqwbyte((vec_uchar16)(-1), (unsigned int)(16-cnt));
> +    *vs = spu_sel(*vs, vc, mask);
> +  }
> +
> +  return (s);
> +}
> Index: src/newlib/libc/machine/spu/strcat.c
> ===================================================================
> --- /dev/null
> +++ src/newlib/libc/machine/spu/strcat.c
> @@ -0,0 +1,55 @@
> +/*
> +  (C) Copyright 2001,2006,
> +  International Business Machines Corporation,
> +  Sony Computer Entertainment, Incorporated,
> +  Toshiba Corporation,
> +
> +  All rights reserved.
> +
> +  Redistribution and use in source and binary forms, with or without
> +  modification, are permitted provided that the following conditions are met:
> +
> +    * Redistributions of source code must retain the above copyright notice,
> +  this list of conditions and the following disclaimer.
> +    * Redistributions in binary form must reproduce the above copyright
> +  notice, this list of conditions and the following disclaimer in the
> +  documentation and/or other materials provided with the distribution.
> +    * Neither the names of the copyright holders nor the names of their
> +  contributors may be used to endorse or promote products derived from this
> +  software without specific prior written permission.
> +
> +  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
> +  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> +  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> +  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
> +  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> +  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> +  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
> +  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> +  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> +  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> +  POSSIBILITY OF SUCH DAMAGE.
> +*/
> +#include <spu_intrinsics.h>
> +#include <stddef.h>
> +#include <string.h>
> +
> +/* Appends the string pointed to by src (up to and including the /0
> + * character) to the array pointed to by dest (overwriting the
> + * /0 character at the end of dest. The strings may not overlap and
> + * the dest string must have enough space for the result.
> + */
> +
> +char *strcat(char * __restrict__ dest, const char * __restrict__ src)
> +{
> +  size_t d_len, s_len;
> +
> +  /* Determine the length of the src and dest input arrays.
> +   */
> +  d_len = strlen(dest);
> +  s_len = strlen(src);
> +
> +  (void)memcpy((void *)(dest+d_len), (const void *)src, s_len + 1);
> +
> +  return ((char *)dest);
> +}
> Index: src/newlib/libc/machine/spu/strchr.c
> ===================================================================
> --- /dev/null
> +++ src/newlib/libc/machine/spu/strchr.c
> @@ -0,0 +1,82 @@
> +/*
> +  (C) Copyright 2001,2006,
> +  International Business Machines Corporation,
> +  Sony Computer Entertainment, Incorporated,
> +  Toshiba Corporation,
> +
> +  All rights reserved.
> +
> +  Redistribution and use in source and binary forms, with or without
> +  modification, are permitted provided that the following conditions are met:
> +
> +    * Redistributions of source code must retain the above copyright notice,
> +  this list of conditions and the following disclaimer.
> +    * Redistributions in binary form must reproduce the above copyright
> +  notice, this list of conditions and the following disclaimer in the
> +  documentation and/or other materials provided with the distribution.
> +    * Neither the names of the copyright holders nor the names of their
> +  contributors may be used to endorse or promote products derived from this
> +  software without specific prior written permission.
> +
> +  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
> +  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> +  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> +  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
> +  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> +  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> +  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
> +  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> +  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> +  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> +  POSSIBILITY OF SUCH DAMAGE.
> +*/
> +#include <spu_intrinsics.h>
> +#include <stddef.h>
> +
> +/* Scans the string pointed to by s for the character c and
> + * returns a pointer to the first occurance of c. If
> + * c is not found, then NULL is returned.
> + */
> +char *strchr(const char *s, int c)
> +{
> +  unsigned int cmp, skip;
> +  vec_uchar16 *ptr, data, vc;
> +  vec_uint4 cmp_c, cmp_0;
> +  vec_uint4 result;
> +  vec_uint4 mask;
> +
> +  /* Scan memory array a quadword at a time. Skip leading
> +   * mis-aligned bytes.
> +   */
> +  ptr = (vec_uchar16 *)s;
> +
> +  skip = (unsigned int)(ptr) & 15;
> +  mask = spu_rlmask((vec_uint4)(0xFFFF), -skip);
> +
> +  vc = spu_splats((unsigned char)(c));
> +
> +  data = *ptr++;
> +
> +  cmp_c = spu_and(spu_gather(spu_cmpeq(data, vc)), mask);
> +  cmp_0 = spu_and(spu_gather(spu_cmpeq(data, 0)), mask);
> +
> +  cmp = spu_extract(spu_or(cmp_c, cmp_0), 0);
> +
> +  while (cmp == 0) {
> +    data = *ptr++;
> +    cmp_c = spu_gather(spu_cmpeq(data, vc));
> +    cmp_0 = spu_gather(spu_cmpeq(data, 0));
> +
> +    cmp = spu_extract(spu_or(cmp_c, cmp_0), 0);
> +  }
> +
> +  /* Compute the location of the first character. If it is beyond
> +   * the end of the string, then return NULL.
> +   */
> +  result = spu_add(spu_promote((unsigned int)ptr - (skip+32), 0),
> +		   spu_cntlz(spu_promote(cmp, 0)));
> +
> +  result = spu_andc(result, spu_cmpgt(cmp_0, cmp_c));
> +
> +  return ((char *)spu_extract(result, 0));
> +}
> Index: src/newlib/libc/machine/spu/strcpy.c
> ===================================================================
> --- /dev/null
> +++ src/newlib/libc/machine/spu/strcpy.c
> @@ -0,0 +1,48 @@
> +/*
> +  (C) Copyright 2001,2006,
> +  International Business Machines Corporation,
> +  Sony Computer Entertainment, Incorporated,
> +  Toshiba Corporation,
> +
> +  All rights reserved.
> +
> +  Redistribution and use in source and binary forms, with or without
> +  modification, are permitted provided that the following conditions are met:
> +
> +    * Redistributions of source code must retain the above copyright notice,
> +  this list of conditions and the following disclaimer.
> +    * Redistributions in binary form must reproduce the above copyright
> +  notice, this list of conditions and the following disclaimer in the
> +  documentation and/or other materials provided with the distribution.
> +    * Neither the names of the copyright holders nor the names of their
> +  contributors may be used to endorse or promote products derived from this
> +  software without specific prior written permission.
> +
> +  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
> +  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> +  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> +  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
> +  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> +  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> +  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
> +  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> +  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> +  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> +  POSSIBILITY OF SUCH DAMAGE.
> +*/
> +#include <spu_intrinsics.h>
> +#include <stddef.h>
> +
> +/* Copy the string pointed to by src (up to and including the /0
> + * character) into the array pointed to by dest. If copy between
> + * two arrays that overlap, then behavior is undefined.
> + */
> +
> +char * strcpy(char * __restrict__ dest, const char * __restrict__ src)
> +{
> +  /* Due to the need to support all alignment variances, this
> +   * function can not easily be optimized. As a result, it is
> +   * serviced using strlen and memcpy.
> +   */
> +  return ((char *)memcpy((void *)dest, (const void *)src, strlen(src)+1));
> +}
> Index: src/newlib/libc/machine/spu/strcspn.c
> ===================================================================
> --- /dev/null
> +++ src/newlib/libc/machine/spu/strcspn.c
> @@ -0,0 +1,96 @@
> +/*
> +  (C) Copyright 2001,2006,
> +  International Business Machines Corporation,
> +  Sony Computer Entertainment, Incorporated,
> +  Toshiba Corporation,
> +
> +  All rights reserved.
> +
> +  Redistribution and use in source and binary forms, with or without
> +  modification, are permitted provided that the following conditions are met:
> +
> +    * Redistributions of source code must retain the above copyright notice,
> +  this list of conditions and the following disclaimer.
> +    * Redistributions in binary form must reproduce the above copyright
> +  notice, this list of conditions and the following disclaimer in the
> +  documentation and/or other materials provided with the distribution.
> +    * Neither the names of the copyright holders nor the names of their
> +  contributors may be used to endorse or promote products derived from this
> +  software without specific prior written permission.
> +
> +  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
> +  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> +  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> +  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
> +  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> +  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> +  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
> +  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> +  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> +  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> +  POSSIBILITY OF SUCH DAMAGE.
> +*/
> +#include <spu_intrinsics.h>
> +#include <stddef.h>
> +#include "vec_literal.h"
> +
> +/* Computes the length of the maximum initial segement
> + * of the string pointed to by s1 which consists entirely
> + * of characters not contained in the string pointed to by s2.
> + */
> +size_t strcspn(const char *s1, const char *s2)
> +{
> +  size_t len, cnt;
> +  unsigned int offset;
> +  vec_uchar16 shuffle, match, initial_splat, splat;
> +  vec_uchar16 data1, data2, dataA, dataB, *ptr1, *ptr2;
> +
> +  ptr1 = (vec_uchar16 *)s1;
> +
> +  offset = (unsigned int)(s1) & 15;
> +  shuffle = (vec_uchar16)spu_add((vec_uint4)spu_splats((unsigned char) offset),
> +				 VEC_LITERAL(vec_uint4, 0x0010203, 0x04050607, 0x08090A0B, 0x0C0D0E0F));
> +
> +  len = 0;
> +
> +  dataA = *ptr1++;
> +  dataB = *ptr1++;
> +
> +  initial_splat = spu_splats((unsigned char)((unsigned int)(s2) & 0xF));
> +
> +  /* For each quadword of the string s1.
> +   */
> +  do {
> +    data1 = spu_shuffle(dataA, dataB, shuffle);
> +
> +
> +    ptr2 = (vec_uchar16 *)s2;
> +    data2 = *ptr2;
> +    data2 = spu_shuffle(data2, data2, initial_splat);
> +    ptr2 = (vec_uchar16 *)((unsigned int)(ptr2) + 1);
> +    splat = initial_splat;
> +
> +    match = spu_cmpeq(data1, 0);
> +
> +    /* For each character of s2, compare agains a quadword of s1,
> +     * accumulating match success in the variable match.
> +     */
> +    while (spu_extract((vec_uint4)data2, 0)) {
> +      match = spu_or(match, spu_cmpeq(data1, data2));
> +
> +      splat = spu_and((vec_uchar16)(spu_add((vec_uint4)splat, VEC_SPLAT_U32(0x01010101))), 0xF);
> +
> +      data2 = *ptr2;
> +      data2 = spu_shuffle(data2, data2, splat);
> +      ptr2 = (vec_uchar16 *)((unsigned int)(ptr2) + 1);
> +    }
> +
> +    cnt = spu_extract(spu_cntlz(spu_gather(match)), 0);
> +    len = (len - 16) + cnt;
> +
> +    dataA = dataB;
> +    dataB = *ptr1++;
> +  } while (cnt == 32);
> +
> +  return (len);
> +}
> Index: src/newlib/libc/machine/spu/strlen.c
> ===================================================================
> --- /dev/null
> +++ src/newlib/libc/machine/spu/strlen.c
> @@ -0,0 +1,66 @@
> +/*
> +  (C) Copyright 2001,2006,
> +  International Business Machines Corporation,
> +  Sony Computer Entertainment, Incorporated,
> +  Toshiba Corporation,
> +
> +  All rights reserved.
> +
> +  Redistribution and use in source and binary forms, with or without
> +  modification, are permitted provided that the following conditions are met:
> +
> +    * Redistributions of source code must retain the above copyright notice,
> +  this list of conditions and the following disclaimer.
> +    * Redistributions in binary form must reproduce the above copyright
> +  notice, this list of conditions and the following disclaimer in the
> +  documentation and/or other materials provided with the distribution.
> +    * Neither the names of the copyright holders nor the names of their
> +  contributors may be used to endorse or promote products derived from this
> +  software without specific prior written permission.
> +
> +  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
> +  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> +  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> +  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
> +  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> +  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> +  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
> +  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> +  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> +  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> +  POSSIBILITY OF SUCH DAMAGE.
> +*/
> +#include <spu_intrinsics.h>
> +#include <stddef.h>
> +
> +/* Calculates  the  length  of  the string s, not including the terminating
> + * \0 character.
> + */
> +size_t strlen(const char *s)
> +{
> +  size_t len;
> +  unsigned int cnt, cmp, skip, mask;
> +  vec_uchar16 *ptr, data;
> +
> +  /* Compensate for initial mis-aligned string.
> +   */
> +  ptr = (vec_uchar16 *)s;
> +  skip = (unsigned int)(ptr) & 15;
> +  mask = 0xFFFF >> skip;
> +
> +  data = *ptr++;
> +  cmp = spu_extract(spu_gather(spu_cmpeq(data, 0)), 0);
> +  cmp &= mask;
> +
> +  cnt = spu_extract(spu_cntlz(spu_promote(cmp, 0)), 0);
> +  len = cnt - (skip + 16);
> +
> +  while (cnt == 32) {
> +    data = *ptr++;
> +    len -= 16;
> +    cnt = spu_extract(spu_cntlz(spu_gather(spu_cmpeq(data, 0))), 0);
> +    len += cnt;
> +  }
> +
> +  return (len);
> +}
> Index: src/newlib/libc/machine/spu/strncat.c
> ===================================================================
> --- /dev/null
> +++ src/newlib/libc/machine/spu/strncat.c
> @@ -0,0 +1,98 @@
> +/*
> +  (C) Copyright 2001,2006,
> +  International Business Machines Corporation,
> +  Sony Computer Entertainment, Incorporated,
> +  Toshiba Corporation,
> +
> +  All rights reserved.
> +
> +  Redistribution and use in source and binary forms, with or without
> +  modification, are permitted provided that the following conditions are met:
> +
> +    * Redistributions of source code must retain the above copyright notice,
> +  this list of conditions and the following disclaimer.
> +    * Redistributions in binary form must reproduce the above copyright
> +  notice, this list of conditions and the following disclaimer in the
> +  documentation and/or other materials provided with the distribution.
> +    * Neither the names of the copyright holders nor the names of their
> +  contributors may be used to endorse or promote products derived from this
> +  software without specific prior written permission.
> +
> +  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
> +  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> +  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> +  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
> +  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> +  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> +  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
> +  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> +  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> +  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> +  POSSIBILITY OF SUCH DAMAGE.
> +*/
> +#include <spu_intrinsics.h>
> +#include <stddef.h>
> +#include <string.h>
> +
> +/* Appends the string pointed to by src (up to and including the /0
> + * character) to the array pointed to by dest (overwriting the
> + * /0 character at the end of dest. The strings may not overlap and
> + * the dest string must have enough space for the result.
> + */
> +
> +char * strncat(char * __restrict__ dest, const char * __restrict__ src, size_t n)
> +{
> +  size_t len;
> +  unsigned int cmp, skip, mask;
> +  vec_uchar16 *ptr, data;
> +  vec_uint4 cnt, gt, N;
> +  char *dst;
> +
> +  /* Determine the starting location to begin concatenation.
> +   */
> +  dst = dest + strlen(dest);
> +
> +  /* Copy the src image until either the src string terminates
> +   * or n characters are copied.
> +   */
> +  N = spu_promote(n, 0);
> +
> +  /* Determine the string length, not including termination character,
> +   * clamped to n characters.
> +   */
> +  ptr = (vec_uchar16 *)src;
> +  skip = (unsigned int)(ptr) & 15;
> +  mask = 0xFFFF >> skip;
> +
> +  data = *ptr++;
> +  cmp = spu_extract(spu_gather(spu_cmpeq(data, 0)), 0);
> +  cmp &= mask;
> +
> +  cnt = spu_cntlz(spu_promote(cmp, 0));
> +  len = spu_extract(cnt, 0) - (skip + 16);
> +
> +  gt = spu_cmpgt(spu_promote(len, 0), N);
> +
> +  while (spu_extract(spu_andc(spu_cmpeq(cnt, 32), gt), 0)) {
> +    data = *ptr++;
> +    len -= 16;
> +    cnt  = spu_cntlz(spu_gather(spu_cmpeq(data, 0)));
> +    len += spu_extract(cnt, 0);
> +
> +    gt = spu_cmpgt(spu_promote(len, 0), N);
> +  }
> +
> +  /* len = MIN(len, n)
> +   */
> +  len = spu_extract(spu_sel(spu_promote(len, 0), N, gt), 0);
> +
> +  /* Perform a memcpy of the resulting length
> +   */
> +  (void)memcpy((void *)dst, (const void *)src, len);
> +
> +  /* Terminate the resulting concetenated string.
> +   */
> +  dst[len] = '\0';
> +
> +  return (dest);
> +}
> Index: src/newlib/libc/machine/spu/strncpy.c
> ===================================================================
> --- /dev/null
> +++ src/newlib/libc/machine/spu/strncpy.c
> @@ -0,0 +1,82 @@
> +/*
> +  (C) Copyright 2001,2006,
> +  International Business Machines Corporation,
> +  Sony Computer Entertainment, Incorporated,
> +  Toshiba Corporation,
> +
> +  All rights reserved.
> +
> +  Redistribution and use in source and binary forms, with or without
> +  modification, are permitted provided that the following conditions are met:
> +
> +    * Redistributions of source code must retain the above copyright notice,
> +  this list of conditions and the following disclaimer.
> +    * Redistributions in binary form must reproduce the above copyright
> +  notice, this list of conditions and the following disclaimer in the
> +  documentation and/or other materials provided with the distribution.
> +    * Neither the names of the copyright holders nor the names of their
> +  contributors may be used to endorse or promote products derived from this
> +  software without specific prior written permission.
> +
> +  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
> +  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> +  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> +  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
> +  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> +  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> +  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
> +  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> +  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> +  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> +  POSSIBILITY OF SUCH DAMAGE.
> +*/
> +#include <spu_intrinsics.h>
> +#include <stddef.h>
> +#include <string.h>
> +
> +/* Copy the string up to n character from memory area src to
> + * memory area dest. The memory areas may not overlap. The
> + * strncpy subroutine returns a pointer to dest.
> + */
> +char * strncpy(char * __restrict__ dest, const char * __restrict__ src, size_t n)
> +{
> +  size_t len;
> +  unsigned int cmp, skip, mask;
> +  vec_uchar16 *ptr, data;
> +  vec_uint4 cnt, gt, N;
> +
> +  N = spu_promote(n, 0);
> +
> +  /* Determine the string length, including termination character,
> +   * clamped to n characters.
> +   */
> +  ptr = (vec_uchar16 *)src;
> +  skip = (unsigned int)(ptr) & 15;
> +  mask = 0xFFFF >> skip;
> +
> +  data = *ptr++;
> +  cmp = spu_extract(spu_gather(spu_cmpeq(data, 0)), 0);
> +  cmp &= mask;
> +
> +  cnt = spu_cntlz(spu_promote(cmp, 0));
> +  len = spu_extract(cnt, 0) - (skip + 15);
> +
> +  gt = spu_cmpgt(spu_promote(len, 0), N);
> +
> +  while (spu_extract(spu_andc(spu_cmpeq(cnt, 32), gt), 0)) {
> +    data = *ptr++;
> +    len -= 16;
> +    cnt  = spu_cntlz(spu_gather(spu_cmpeq(data, 0)));
> +    len += spu_extract(cnt, 0);
> +
> +    gt = spu_cmpgt(spu_promote(len, 0), N);
> +  }
> +
> +  /* len = MIN(len, n)
> +   */
> +  len = spu_extract(spu_sel(spu_promote(len, 0), N, gt), 0);
> +
> +  /* Perform a memcpy of the resulting length
> +   */
> +  return ((char *)memcpy((void *)dest, (const void *)src, len));
> +}
> Index: src/newlib/libc/machine/spu/strpbrk.c
> ===================================================================
> --- /dev/null
> +++ src/newlib/libc/machine/spu/strpbrk.c
> @@ -0,0 +1,96 @@
> +/*
> +  (C) Copyright 2001,2006,
> +  International Business Machines Corporation,
> +  Sony Computer Entertainment, Incorporated,
> +  Toshiba Corporation,
> +
> +  All rights reserved.
> +
> +  Redistribution and use in source and binary forms, with or without
> +  modification, are permitted provided that the following conditions are met:
> +
> +    * Redistributions of source code must retain the above copyright notice,
> +  this list of conditions and the following disclaimer.
> +    * Redistributions in binary form must reproduce the above copyright
> +  notice, this list of conditions and the following disclaimer in the
> +  documentation and/or other materials provided with the distribution.
> +    * Neither the names of the copyright holders nor the names of their
> +  contributors may be used to endorse or promote products derived from this
> +  software without specific prior written permission.
> +
> +  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
> +  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> +  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> +  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
> +  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> +  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> +  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
> +  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> +  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> +  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> +  POSSIBILITY OF SUCH DAMAGE.
> +*/
> +#include <spu_intrinsics.h>
> +#include <stddef.h>
> +#include "vec_literal.h"
> +
> +/* Locates the first occurance in string pointed to by s1 of
> + * any character in the string pointed to by s2. A null pointer
> + * is returned if no character in s2 occurs in s1.
> + */
> +char * strpbrk(const char *s1, const char *s2)
> +{
> +  unsigned int offset;
> +  vec_uint4 cnt;
> +  vec_uchar16 shuffle, match, initial_splat, splat, eos;
> +  vec_uchar16 data1, data2, dataA, dataB, *ptr1, *ptr2;
> +
> +  ptr1 = (vec_uchar16 *)s1;
> +
> +  offset = (unsigned int)(s1) & 15;
> +  shuffle = (vec_uchar16)spu_add((vec_uint4)spu_splats((unsigned char) offset),
> +				 VEC_LITERAL(vec_uint4, 0x0010203, 0x04050607, 0x08090A0B, 0x0C0D0E0F));
> +
> +  dataA = *ptr1++;
> +  dataB = *ptr1++;
> +
> +  initial_splat = spu_splats((unsigned char)((unsigned int)(s2) & 0xF));
> +
> +  /* For each quadword of the string s1.
> +   */
> +  do {
> +    data1 = spu_shuffle(dataA, dataB, shuffle);
> +
> +    eos = match = spu_cmpeq(data1, 0);
> +
> +    ptr2 = (vec_uchar16 *)s2;
> +    data2 = *ptr2;
> +    data2 = spu_shuffle(data2, data2, initial_splat);
> +    ptr2 = (vec_uchar16 *)((unsigned int)(ptr2) + 1);
> +    splat = initial_splat;
> +
> +    /* For each character of s2, compare agains a quadword of s1,
> +     * accumulating match success in the variable match.
> +     */
> +    while (spu_extract((vec_uint4)data2, 0)) {
> +      match = spu_or(match, spu_cmpeq(data1, data2));
> +
> +      splat = spu_and((vec_uchar16)(spu_add((vec_uint4)splat, VEC_SPLAT_U32(0x01010101))), 0xF);
> +
> +      data2 = *ptr2;
> +      data2 = spu_shuffle(data2, data2, splat);
> +      ptr2 = (vec_uchar16 *)((unsigned int)(ptr2) + 1);
> +    }
> +
> +    cnt = spu_cntlz(spu_gather(match));
> +
> +    dataA = dataB;
> +    dataB = *ptr1++;
> +  } while (spu_extract(cnt, 0) == 32);
> +
> +  /* Compute the first match pointer, zeroing it (NIL) if it is the end of
> +   * string.
> +   */
> +  return ((char *)spu_extract(spu_andc(spu_add(spu_add(spu_promote((unsigned int)(ptr1), 0), -64), cnt),
> +				       spu_cmpeq(cnt, spu_cntlz(spu_gather(eos)))), 0));
> +}
> Index: src/newlib/libc/machine/spu/strrchr.c
> ===================================================================
> --- /dev/null
> +++ src/newlib/libc/machine/spu/strrchr.c
> @@ -0,0 +1,115 @@
> +/*
> +  (C) Copyright 2001,2006,
> +  International Business Machines Corporation,
> +  Sony Computer Entertainment, Incorporated,
> +  Toshiba Corporation,
> +
> +  All rights reserved.
> +
> +  Redistribution and use in source and binary forms, with or without
> +  modification, are permitted provided that the following conditions are met:
> +
> +    * Redistributions of source code must retain the above copyright notice,
> +  this list of conditions and the following disclaimer.
> +    * Redistributions in binary form must reproduce the above copyright
> +  notice, this list of conditions and the following disclaimer in the
> +  documentation and/or other materials provided with the distribution.
> +    * Neither the names of the copyright holders nor the names of their
> +  contributors may be used to endorse or promote products derived from this
> +  software without specific prior written permission.
> +
> +  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
> +  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> +  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> +  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
> +  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> +  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> +  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
> +  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> +  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> +  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> +  POSSIBILITY OF SUCH DAMAGE.
> +*/
> +#include <spu_intrinsics.h>
> +#include <stddef.h>
> +#include "vec_literal.h"
> +
> +/* Scans the string pointed to by s for the character c and
> + * returns a pointer to the last occurance of c. If
> + * c is not found, then NULL is returned.
> + */
> +char * strrchr(const char *s, int c)
> +{
> +  int nskip;
> +  vec_uchar16 *ptr, data, vc;
> +  vec_uint4 cmp_c, cmp_0, cmp;
> +  vec_uint4 res_ptr, res_cmp;
> +  vec_uint4 mask, result;
> +
> +  /* Scan memory array a quadword at a time. Skip leading
> +   * mis-aligned bytes.
> +   */
> +  ptr = (vec_uchar16 *)s;
> +
> +  nskip = -((unsigned int)(ptr) & 15);
> +  mask = spu_rlmask((vec_uint4)(0xFFFF), nskip);
> +
> +  vc = spu_splats((unsigned char)(c));
> +
> +  data = *ptr++;
> +  ptr = (vec_uchar16 *)((unsigned int)ptr & ~15);
> +
> +  cmp_c = spu_and(spu_gather(spu_cmpeq(data, vc)), mask);
> +  cmp_0 = spu_and(spu_gather(spu_cmpeq(data, 0)), mask);
> +
> +  res_ptr = VEC_SPLAT_U32(0);
> +  res_cmp = VEC_SPLAT_U32(0);
> +
> +  while (spu_extract(cmp_0, 0) == 0) {
> +    cmp = spu_cmpeq(cmp_c, 0);
> +
> +    res_ptr = spu_sel(spu_promote((unsigned int)(ptr), 0), res_ptr, cmp);
> +    res_cmp = spu_sel(cmp_c, res_cmp, cmp);
> +
> +    data = *ptr++;
> +
> +    cmp_c = spu_gather(spu_cmpeq(data, vc));
> +    cmp_0 = spu_gather(spu_cmpeq(data, 0));
> +
> +    cmp = spu_cmpeq(cmp_c, 0);
> +  }
> +
> +  /* Compute the location of the last character before termination
> +   * character.
> +   *
> +   * First mask off compare results following the first termination character.
> +   */
> +  mask = spu_sl(VEC_SPLAT_U32(-1), 31 - spu_extract(spu_cntlz(cmp_0), 0));
> +  cmp_c = spu_and(cmp_c, mask);
> +
> +  /* Conditionally update res_ptr and res_cmd if a match was found in the last
> +   * quadword.
> +   */
> +  cmp = spu_cmpeq(cmp_c, 0);
> +
> +  res_ptr = spu_sel(spu_promote((unsigned int)(ptr), 0), res_ptr, cmp);
> +  res_cmp = spu_sel(cmp_c, res_cmp, cmp);
> +
> +  /* Bit reserve res_cmp for locating last occurance.
> +   */
> +  mask = spu_cmpeq(res_cmp, 0);
> +
> +  res_cmp = (vec_uint4)spu_maskb(spu_extract(res_cmp, 0));
> +  res_cmp = spu_gather((vec_uchar16)spu_shuffle(res_cmp, res_cmp,
> +						VEC_LITERAL(vec_uchar16,
> +							    15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)));
> +
> +  /* Compute the location (ptr) of the last occurance of c. If no
> +   * occurance was found (ie, element 0 of res_cmp == 0, then return
> +   * NULL.
> +   */
> +  result = spu_sub(spu_add(res_ptr, 15), spu_cntlz(res_cmp));
> +  result = spu_andc(result, mask);
> +
> +  return ((char *)spu_extract(result, 0));
> +}
> Index: src/newlib/libc/machine/spu/strspn.c
> ===================================================================
> --- /dev/null
> +++ src/newlib/libc/machine/spu/strspn.c
> @@ -0,0 +1,95 @@
> +/*
> +  (C) Copyright 2001,2006,
> +  International Business Machines Corporation,
> +  Sony Computer Entertainment, Incorporated,
> +  Toshiba Corporation,
> +
> +  All rights reserved.
> +
> +  Redistribution and use in source and binary forms, with or without
> +  modification, are permitted provided that the following conditions are met:
> +
> +    * Redistributions of source code must retain the above copyright notice,
> +  this list of conditions and the following disclaimer.
> +    * Redistributions in binary form must reproduce the above copyright
> +  notice, this list of conditions and the following disclaimer in the
> +  documentation and/or other materials provided with the distribution.
> +    * Neither the names of the copyright holders nor the names of their
> +  contributors may be used to endorse or promote products derived from this
> +  software without specific prior written permission.
> +
> +  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
> +  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> +  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> +  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
> +  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> +  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> +  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
> +  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> +  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> +  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> +  POSSIBILITY OF SUCH DAMAGE.
> +*/
> +#include <spu_intrinsics.h>
> +#include <stddef.h>
> +#include "vec_literal.h"
> +
> +/* Computes the length of the maximum initial segement
> + * of the string pointed to by s1 which consists entirely
> + * of characters from the string pointed to by s2.
> + */
> +size_t strspn(const char *s1, const char *s2)
> +{
> +  size_t len, cnt;
> +  unsigned int offset;
> +  vec_uchar16 shuffle, match, initial_splat, splat;
> +  vec_uchar16 data1, data2, dataA, dataB, *ptr1, *ptr2;
> +
> +  ptr1 = (vec_uchar16 *)s1;
> +
> +  offset = (unsigned int)(s1) & 15;
> +  shuffle = (vec_uchar16)spu_add((vec_uint4)spu_splats((unsigned char) offset),
> +				 VEC_LITERAL(vec_uint4, 0x0010203, 0x04050607, 0x08090A0B, 0x0C0D0E0F));
> +
> +  len = 0;
> +
> +  dataA = *ptr1++;
> +  dataB = *ptr1++;
> +
> +  initial_splat = spu_splats((unsigned char)((unsigned int)(s2) & 0xF));
> +
> +  /* For each quadword of the string s1.
> +   */
> +  do {
> +    data1 = spu_shuffle(dataA, dataB, shuffle);
> +
> +    match = VEC_SPLAT_U8(0);
> +
> +    ptr2 = (vec_uchar16 *)s2;
> +    data2 = *ptr2;
> +    data2 = spu_shuffle(data2, data2, initial_splat);
> +    ptr2 = (vec_uchar16 *)((unsigned int)(ptr2) + 1);
> +    splat = initial_splat;
> +
> +    /* For each character of s2, compare agains a quadword of s1,
> +     * accumulating match success in the variable match.
> +     */
> +    while (spu_extract((vec_uint4)data2, 0)) {
> +      match = spu_or(match, spu_cmpeq(data1, data2));
> +
> +      splat = spu_and((vec_uchar16)(spu_add((vec_uint4)splat, VEC_SPLAT_U32(0x01010101))), 0xF);
> +
> +      data2 = *ptr2;
> +      data2 = spu_shuffle(data2, data2, splat);
> +      ptr2 = (vec_uchar16 *)((unsigned int)(ptr2) + 1);
> +    }
> +
> +    cnt = spu_extract(spu_cntlz(spu_gather(spu_xor(match, -1))), 0);
> +    len = (len - 16) + cnt;
> +
> +    dataA = dataB;
> +    dataB = *ptr1++;
> +  } while (cnt == 32);
> +
> +  return (len);
> +}
> Index: src/newlib/libc/machine/spu/strxfrm.c
> ===================================================================
> --- /dev/null
> +++ src/newlib/libc/machine/spu/strxfrm.c
> @@ -0,0 +1,66 @@
> +/*
> +  (C) Copyright 2001,2006,
> +  International Business Machines Corporation,
> +  Sony Computer Entertainment, Incorporated,
> +  Toshiba Corporation,
> +
> +  All rights reserved.
> +
> +  Redistribution and use in source and binary forms, with or without
> +  modification, are permitted provided that the following conditions are met:
> +
> +    * Redistributions of source code must retain the above copyright notice,
> +  this list of conditions and the following disclaimer.
> +    * Redistributions in binary form must reproduce the above copyright
> +  notice, this list of conditions and the following disclaimer in the
> +  documentation and/or other materials provided with the distribution.
> +    * Neither the names of the copyright holders nor the names of their
> +  contributors may be used to endorse or promote products derived from this
> +  software without specific prior written permission.
> +
> +  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
> +  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> +  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> +  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
> +  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> +  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> +  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
> +  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> +  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> +  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> +  POSSIBILITY OF SUCH DAMAGE.
> +*/
> +#include <spu_intrinsics.h>
> +#include <stddef.h>
> +#include <string.h>
> +
> +
> +/* The strxfrm() function transforms the src string into a form such that
> + * the result of strcmp() on two strings that have been transformed with
> + * strxfrm() is the same as the result of strcoll() on the two strings
> + * before their transformation. The first n characters of the transformed
> + * string are placed in dest.
> + *
> + * The strxfrm() function returns the number of bytes required to store
> + * the transformed string in dest excluding the terminating character
> + * If the value returned is n or more, the contents of dest are indeterminate.
> + *
> + * Note: Since this library/function only supports a single locale, no
> + * transformation is performed.
> + */
> +
> +size_t strxfrm(char * __restrict__ dest, const char * __restrict__ src, size_t n)
> +{
> +  size_t len;
> +
> +  len = strlen(src);
> +
> +  /* Since the destination is indeterminant if n is less than of equal
> +   * to the string length, we skip performing the copy (altogether) in
> +   * this case.
> +   */
> +  if (n > len) {
> +    (void)memcpy((void *)dest, (void *)src, n);
> +  }
> +  return (len);
> +}
> Index: src/newlib/libc/machine/spu/strncmp.c
> ===================================================================
> --- /dev/null
> +++ src/newlib/libc/machine/spu/strncmp.c
> @@ -0,0 +1,131 @@
> +/*
> +  (C) Copyright 2001,2006,
> +  International Business Machines Corporation,
> +  Sony Computer Entertainment, Incorporated,
> +  Toshiba Corporation,
> +
> +  All rights reserved.
> +
> +  Redistribution and use in source and binary forms, with or without
> +  modification, are permitted provided that the following conditions are met:
> +
> +    * Redistributions of source code must retain the above copyright notice,
> +  this list of conditions and the following disclaimer.
> +    * Redistributions in binary form must reproduce the above copyright
> +  notice, this list of conditions and the following disclaimer in the
> +  documentation and/or other materials provided with the distribution.
> +    * Neither the names of the copyright holders nor the names of their
> +  contributors may be used to endorse or promote products derived from this
> +  software without specific prior written permission.
> +
> +  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
> +  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> +  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> +  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
> +  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> +  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> +  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
> +  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> +  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> +  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> +  POSSIBILITY OF SUCH DAMAGE.
> +*/
> +#include <spu_intrinsics.h>
> +#include <stddef.h>
> +#include "vec_literal.h"
> +
> +/* Compare the two strings s1 and s2 of length n.  Returns an integer
> + * less than, equal to, or greater than zero if  s1  is  found, respectively,
> + * to be less than, to match, or be greater than s2.
> + */
> +
> +int strncmp(const char *s1, const char *s2, size_t n)
> +{
> +  unsigned int offset1, offset2;
> +  vec_int4 n_v;
> +  vec_uint4 cnt1_v, cnt2_v, max_cnt_v;
> +  vec_uint4 gt_v, lt_v, mask_v, end1_v, end2_v, end_v, neq_v;
> +  vec_uint4 shift_n_v, shift_eos_v, max_shift_v;
> +  vec_uchar16 shuffle1, shuffle2;
> +  vec_uchar16 data1A, data1B, data1, data2A, data2B, data2;
> +  vec_uchar16 *ptr1, *ptr2;
> +
> +  data1 = data2 = VEC_SPLAT_U8(0);
> +
> +  ptr1 = (vec_uchar16 *)s1;
> +  ptr2 = (vec_uchar16 *)s2;
> +
> +  offset1 = (unsigned int)(ptr1) & 15;
> +  offset2 = (unsigned int)(ptr2) & 15;
> +
> +  shuffle1 = (vec_uchar16)spu_add((vec_uint4)spu_splats((unsigned char)offset1),
> +				  VEC_LITERAL(vec_uint4, 0x00010203, 0x04050607, 0x08090A0B, 0x0C0D0E0F));
> +  shuffle2 = (vec_uchar16)spu_add((vec_uint4)spu_splats((unsigned char)offset2),
> +				  VEC_LITERAL(vec_uint4, 0x00010203, 0x04050607, 0x08090A0B, 0x0C0D0E0F));
> +  data1A = *ptr1++;
> +  data2A = *ptr2++;
> +
> +  n_v = spu_promote((int)n, 0);
> +
> +  do {
> +    data1B = *ptr1++;
> +    data2B = *ptr2++;
> +
> +    /* Quadword align each of the input strings so that
> +     * we operate on full quadwords.
> +     */
> +    data1 = spu_shuffle(data1A, data1B, shuffle1);
> +    data2 = spu_shuffle(data2A, data2B, shuffle2);
> +
> +    data1A = data1B;
> +    data2A = data2B;
> +
> +    neq_v = spu_gather(spu_xor(spu_cmpeq(data1, data2), -1));
> +
> +    end1_v = spu_gather(spu_cmpeq(data1, 0));
> +    end2_v = spu_gather(spu_cmpeq(data2, 0));
> +    end_v  = spu_or(end1_v, end2_v), 0;
> +
> +    n_v = spu_add(n_v, -16);
> +
> +    /* Repeat until either
> +     * 1) the character count expired,
> +     * 2) a null character is discovered in one of the input strings, or
> +     * 3) the strings do not compare equal.
> +     */
> +  } while (spu_extract(spu_and(spu_cmpeq(spu_or(end_v, neq_v), 0), spu_cmpgt(n_v, 0)), 0));
> +
> +  /* Construct a mask to eliminate characters that are not of interest
> +   * in the comparison. Theses include characters that are beyond the
> +   * n character count and beyond the first null character.
> +   */
> +  cnt1_v = spu_cntlz(end1_v);
> +  cnt2_v = spu_cntlz(end2_v);
> +
> +  max_cnt_v = spu_sel(cnt1_v, cnt2_v, spu_cmpgt(cnt2_v, cnt1_v));
> +
> +  mask_v = spu_splats((unsigned int)0xFFFF);
> +
> +  shift_n_v = spu_andc((vector unsigned int)spu_sub(0, n_v), spu_cmpgt(n_v, -1));
> +  shift_eos_v = spu_sub(32, max_cnt_v);
> +
> +  max_shift_v = spu_sel(shift_n_v, shift_eos_v, spu_cmpgt(shift_eos_v, shift_n_v));
> +
> +  mask_v = spu_and(spu_sl(mask_v, spu_extract(max_shift_v, 0)), mask_v);
> +
> +  /* Determine if greater then or less then in the case that they are
> +   * not equal. gt_v is either 1 (in the case s1 is greater then s2), or
> +   * -1 (in the case that s2 is greater then s1).
> +   */
> +  gt_v = spu_gather(spu_cmpgt(data1, data2));
> +  lt_v = spu_gather(spu_cmpgt(data2, data1));
> +
> +  gt_v = spu_sub(-1, spu_sl(spu_cmpgt(gt_v, lt_v), 1));
> +
> +  /* Construct a mask to be applied to gt_v if the strings are discovered
> +   * to be equal.
> +   */
> +  mask_v = spu_cmpeq(spu_and(neq_v, mask_v), 0);
> +
> +  return (spu_extract(spu_andc(gt_v, mask_v), 0));
> +}
> Index: src/newlib/libc/machine/spu/Makefile.am
> ===================================================================
> --- src.orig/newlib/libc/machine/spu/Makefile.am
> +++ src/newlib/libc/machine/spu/Makefile.am
> @@ -8,7 +8,7 @@ noinst_LIBRARIES = lib.a
>  
>  AM_CCASFLAGS = $(INCLUDES)
>  
> -lib_a_SOURCES = setjmp.S memcpy.c
> +lib_a_SOURCES = setjmp.S memcpy.c memmove.c memset.c strcat.c strchr.c strcmp.c strcpy.c strcspn.c strlen.c strncat.c strncmp.c strncpy.c strpbrk.c strrchr.c strspn.c strxfrm.c
>  
>  lib_a_CCASFLAGS = $(AM_CCASFLAGS)
>  lib_a_CFLAGS = $(AM_CFLAGS)
> Index: src/newlib/libc/machine/spu/Makefile.in
> ===================================================================
> --- src.orig/newlib/libc/machine/spu/Makefile.in
> +++ src/newlib/libc/machine/spu/Makefile.in
> @@ -42,7 +42,14 @@ DIST_COMMON = $(srcdir)/../../../../conf
>  	$(srcdir)/../../../../config.sub $(srcdir)/Makefile.in \
>  	$(srcdir)/Makefile.am $(top_srcdir)/configure \
>  	$(am__configure_deps) $(srcdir)/../../../../mkinstalldirs \
> -	$(srcdir)/../../../../compile
> +	$(srcdir)/../../../../compile $(srcdir)/../../../../compile \
> +	$(srcdir)/../../../../compile $(srcdir)/../../../../compile \
> +	$(srcdir)/../../../../compile $(srcdir)/../../../../compile \
> +	$(srcdir)/../../../../compile $(srcdir)/../../../../compile \
> +	$(srcdir)/../../../../compile $(srcdir)/../../../../compile \
> +	$(srcdir)/../../../../compile $(srcdir)/../../../../compile \
> +	$(srcdir)/../../../../compile $(srcdir)/../../../../compile \
> +	$(srcdir)/../../../../compile $(srcdir)/../../../../compile
>  subdir = .
>  ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
>  am__aclocal_m4_deps = $(top_srcdir)/../../../acinclude.m4 \
> @@ -57,7 +64,15 @@ LIBRARIES = $(noinst_LIBRARIES)
>  ARFLAGS = cru
>  lib_a_AR = $(AR) $(ARFLAGS)
>  lib_a_LIBADD =
> -am_lib_a_OBJECTS = lib_a-setjmp.$(OBJEXT) lib_a-memcpy.$(OBJEXT)
> +am_lib_a_OBJECTS = lib_a-setjmp.$(OBJEXT) lib_a-memcpy.$(OBJEXT) \
> +	lib_a-memmove.$(OBJEXT) lib_a-memset.$(OBJEXT) \
> +	lib_a-strcat.$(OBJEXT) lib_a-strchr.$(OBJEXT) \
> +	lib_a-strcmp.$(OBJEXT) lib_a-strcpy.$(OBJEXT) \
> +	lib_a-strcspn.$(OBJEXT) lib_a-strlen.$(OBJEXT) \
> +	lib_a-strncat.$(OBJEXT) lib_a-strncmp.$(OBJEXT) \
> +	lib_a-strncpy.$(OBJEXT) lib_a-strpbrk.$(OBJEXT) \
> +	lib_a-strrchr.$(OBJEXT) lib_a-strspn.$(OBJEXT) \
> +	lib_a-strxfrm.$(OBJEXT)
>  lib_a_OBJECTS = $(am_lib_a_OBJECTS)
>  DEFAULT_INCLUDES = -I. -I$(srcdir)
>  depcomp =
> @@ -182,7 +197,7 @@ AUTOMAKE_OPTIONS = cygnus
>  INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
>  noinst_LIBRARIES = lib.a
>  AM_CCASFLAGS = $(INCLUDES)
> -lib_a_SOURCES = setjmp.S memcpy.c
> +lib_a_SOURCES = setjmp.S memcpy.c memmove.c memset.c strcat.c strchr.c strcmp.c strcpy.c strcspn.c strlen.c strncat.c strncmp.c strncpy.c strpbrk.c strrchr.c strspn.c strxfrm.c
>  lib_a_CCASFLAGS = $(AM_CCASFLAGS)
>  lib_a_CFLAGS = $(AM_CFLAGS)
>  ACLOCAL_AMFLAGS = -I ../../.. 
> @@ -262,6 +277,96 @@ lib_a-memcpy.o: memcpy.c
>  
>  lib_a-memcpy.obj: memcpy.c
>  	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-memcpy.obj `if test -f 'memcpy.c'; then $(CYGPATH_W) 'memcpy.c'; else $(CYGPATH_W) '$(srcdir)/memcpy.c'; fi`
> +
> +lib_a-memmove.o: memmove.c
> +	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-memmove.o `test -f 'memmove.c' || echo '$(srcdir)/'`memmove.c
> +
> +lib_a-memmove.obj: memmove.c
> +	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-memmove.obj `if test -f 'memmove.c'; then $(CYGPATH_W) 'memmove.c'; else $(CYGPATH_W) '$(srcdir)/memmove.c'; fi`
> +
> +lib_a-memset.o: memset.c
> +	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-memset.o `test -f 'memset.c' || echo '$(srcdir)/'`memset.c
> +
> +lib_a-memset.obj: memset.c
> +	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-memset.obj `if test -f 'memset.c'; then $(CYGPATH_W) 'memset.c'; else $(CYGPATH_W) '$(srcdir)/memset.c'; fi`
> +
> +lib_a-strcat.o: strcat.c
> +	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strcat.o `test -f 'strcat.c' || echo '$(srcdir)/'`strcat.c
> +
> +lib_a-strcat.obj: strcat.c
> +	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strcat.obj `if test -f 'strcat.c'; then $(CYGPATH_W) 'strcat.c'; else $(CYGPATH_W) '$(srcdir)/strcat.c'; fi`
> +
> +lib_a-strchr.o: strchr.c
> +	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strchr.o `test -f 'strchr.c' || echo '$(srcdir)/'`strchr.c
> +
> +lib_a-strchr.obj: strchr.c
> +	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strchr.obj `if test -f 'strchr.c'; then $(CYGPATH_W) 'strchr.c'; else $(CYGPATH_W) '$(srcdir)/strchr.c'; fi`
> +
> +lib_a-strcmp.o: strcmp.c
> +	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strcmp.o `test -f 'strcmp.c' || echo '$(srcdir)/'`strcmp.c
> +
> +lib_a-strcmp.obj: strcmp.c
> +	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strcmp.obj `if test -f 'strcmp.c'; then $(CYGPATH_W) 'strcmp.c'; else $(CYGPATH_W) '$(srcdir)/strcmp.c'; fi`
> +
> +lib_a-strcpy.o: strcpy.c
> +	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strcpy.o `test -f 'strcpy.c' || echo '$(srcdir)/'`strcpy.c
> +
> +lib_a-strcpy.obj: strcpy.c
> +	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strcpy.obj `if test -f 'strcpy.c'; then $(CYGPATH_W) 'strcpy.c'; else $(CYGPATH_W) '$(srcdir)/strcpy.c'; fi`
> +
> +lib_a-strcspn.o: strcspn.c
> +	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strcspn.o `test -f 'strcspn.c' || echo '$(srcdir)/'`strcspn.c
> +
> +lib_a-strcspn.obj: strcspn.c
> +	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strcspn.obj `if test -f 'strcspn.c'; then $(CYGPATH_W) 'strcspn.c'; else $(CYGPATH_W) '$(srcdir)/strcspn.c'; fi`
> +
> +lib_a-strlen.o: strlen.c
> +	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strlen.o `test -f 'strlen.c' || echo '$(srcdir)/'`strlen.c
> +
> +lib_a-strlen.obj: strlen.c
> +	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strlen.obj `if test -f 'strlen.c'; then $(CYGPATH_W) 'strlen.c'; else $(CYGPATH_W) '$(srcdir)/strlen.c'; fi`
> +
> +lib_a-strncat.o: strncat.c
> +	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strncat.o `test -f 'strncat.c' || echo '$(srcdir)/'`strncat.c
> +
> +lib_a-strncat.obj: strncat.c
> +	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strncat.obj `if test -f 'strncat.c'; then $(CYGPATH_W) 'strncat.c'; else $(CYGPATH_W) '$(srcdir)/strncat.c'; fi`
> +
> +lib_a-strncmp.o: strncmp.c
> +	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strncmp.o `test -f 'strncmp.c' || echo '$(srcdir)/'`strncmp.c
> +
> +lib_a-strncmp.obj: strncmp.c
> +	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strncmp.obj `if test -f 'strncmp.c'; then $(CYGPATH_W) 'strncmp.c'; else $(CYGPATH_W) '$(srcdir)/strncmp.c'; fi`
> +
> +lib_a-strncpy.o: strncpy.c
> +	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strncpy.o `test -f 'strncpy.c' || echo '$(srcdir)/'`strncpy.c
> +
> +lib_a-strncpy.obj: strncpy.c
> +	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strncpy.obj `if test -f 'strncpy.c'; then $(CYGPATH_W) 'strncpy.c'; else $(CYGPATH_W) '$(srcdir)/strncpy.c'; fi`
> +
> +lib_a-strpbrk.o: strpbrk.c
> +	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strpbrk.o `test -f 'strpbrk.c' || echo '$(srcdir)/'`strpbrk.c
> +
> +lib_a-strpbrk.obj: strpbrk.c
> +	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strpbrk.obj `if test -f 'strpbrk.c'; then $(CYGPATH_W) 'strpbrk.c'; else $(CYGPATH_W) '$(srcdir)/strpbrk.c'; fi`
> +
> +lib_a-strrchr.o: strrchr.c
> +	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strrchr.o `test -f 'strrchr.c' || echo '$(srcdir)/'`strrchr.c
> +
> +lib_a-strrchr.obj: strrchr.c
> +	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strrchr.obj `if test -f 'strrchr.c'; then $(CYGPATH_W) 'strrchr.c'; else $(CYGPATH_W) '$(srcdir)/strrchr.c'; fi`
> +
> +lib_a-strspn.o: strspn.c
> +	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strspn.o `test -f 'strspn.c' || echo '$(srcdir)/'`strspn.c
> +
> +lib_a-strspn.obj: strspn.c
> +	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strspn.obj `if test -f 'strspn.c'; then $(CYGPATH_W) 'strspn.c'; else $(CYGPATH_W) '$(srcdir)/strspn.c'; fi`
> +
> +lib_a-strxfrm.o: strxfrm.c
> +	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strxfrm.o `test -f 'strxfrm.c' || echo '$(srcdir)/'`strxfrm.c
> +
> +lib_a-strxfrm.obj: strxfrm.c
> +	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strxfrm.obj `if test -f 'strxfrm.c'; then $(CYGPATH_W) 'strxfrm.c'; else $(CYGPATH_W) '$(srcdir)/strxfrm.c'; fi`
>  uninstall-info-am:
>  
>  ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)



More information about the Newlib mailing list