[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