From f9a17f68c4413c028666bb43ec79ab0a53fa173d Mon Sep 17 00:00:00 2001 From: Jeff Johnston Date: Tue, 9 Jul 2013 19:19:35 +0000 Subject: [PATCH] 2013-07-09 Sabrina Ni * libc/machine/nds32/Makefile.am (lib_a_SOURCES): Add abort.c, memcpy.S, memset.S, strcmp.S, and strcpy.S. * libc/machine/nds32/Makefile.in: Regenerated. * libc/machine/nds32/{abort.c, memcpy.S, memset.S, strcmp.S, strcpy.S}: New. --- newlib/ChangeLog | 8 +++ newlib/libc/machine/nds32/Makefile.am | 2 +- newlib/libc/machine/nds32/Makefile.in | 44 +++++++++++- newlib/libc/machine/nds32/abort.c | 42 ++++++++++++ newlib/libc/machine/nds32/memcpy.S | 77 +++++++++++++++++++++ newlib/libc/machine/nds32/memset.S | 80 ++++++++++++++++++++++ newlib/libc/machine/nds32/strcmp.S | 96 +++++++++++++++++++++++++++ newlib/libc/machine/nds32/strcpy.S | 76 +++++++++++++++++++++ 8 files changed, 421 insertions(+), 4 deletions(-) create mode 100644 newlib/libc/machine/nds32/abort.c create mode 100644 newlib/libc/machine/nds32/memcpy.S create mode 100644 newlib/libc/machine/nds32/memset.S create mode 100644 newlib/libc/machine/nds32/strcmp.S create mode 100644 newlib/libc/machine/nds32/strcpy.S diff --git a/newlib/ChangeLog b/newlib/ChangeLog index e29696dbc..870c10a00 100644 --- a/newlib/ChangeLog +++ b/newlib/ChangeLog @@ -1,3 +1,11 @@ +2013-07-09 Sabrina Ni + + * libc/machine/nds32/Makefile.am (lib_a_SOURCES): Add abort.c, memcpy.S, + memset.S, strcmp.S, and strcpy.S. + * libc/machine/nds32/Makefile.in: Regenerated. + * libc/machine/nds32/{abort.c, memcpy.S, memset.S, strcmp.S, strcpy.S}: + New. + 2013-07-09 Sabrina Ni * configure.host (machine_dir, syscall_dir, newlib_cflags): diff --git a/newlib/libc/machine/nds32/Makefile.am b/newlib/libc/machine/nds32/Makefile.am index 329e2ceca..fa96ccd07 100644 --- a/newlib/libc/machine/nds32/Makefile.am +++ b/newlib/libc/machine/nds32/Makefile.am @@ -8,7 +8,7 @@ AM_CCASFLAGS = $(INCLUDES) noinst_LIBRARIES = lib.a -lib_a_SOURCES = setjmp.S +lib_a_SOURCES = abort.c memcpy.S memset.S setjmp.S strcmp.S strcpy.S lib_a_CCASFLAGS=$(AM_CCASFLAGS) lib_a_CFLAGS = $(AM_CFLAGS) diff --git a/newlib/libc/machine/nds32/Makefile.in b/newlib/libc/machine/nds32/Makefile.in index 465fb7f65..a70705caa 100644 --- a/newlib/libc/machine/nds32/Makefile.in +++ b/newlib/libc/machine/nds32/Makefile.in @@ -69,7 +69,9 @@ LIBRARIES = $(noinst_LIBRARIES) ARFLAGS = cru lib_a_AR = $(AR) $(ARFLAGS) lib_a_LIBADD = -am_lib_a_OBJECTS = lib_a-setjmp.$(OBJEXT) +am_lib_a_OBJECTS = lib_a-abort.$(OBJEXT) lib_a-memcpy.$(OBJEXT) \ + lib_a-memset.$(OBJEXT) lib_a-setjmp.$(OBJEXT) \ + lib_a-strcmp.$(OBJEXT) lib_a-strcpy.$(OBJEXT) lib_a_OBJECTS = $(am_lib_a_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = @@ -195,7 +197,7 @@ AUTOMAKE_OPTIONS = cygnus INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) AM_CCASFLAGS = $(INCLUDES) noinst_LIBRARIES = lib.a -lib_a_SOURCES = setjmp.S +lib_a_SOURCES = abort.c memcpy.S memset.S setjmp.S strcmp.S strcpy.S lib_a_CCASFLAGS = $(AM_CCASFLAGS) lib_a_CFLAGS = $(AM_CFLAGS) ACLOCAL_AMFLAGS = -I ../../.. -I ../../../.. @@ -203,7 +205,7 @@ CONFIG_STATUS_DEPENDENCIES = $(newlib_basedir)/configure.host all: all-am .SUFFIXES: -.SUFFIXES: .S .o .obj +.SUFFIXES: .S .c .o .obj am--refresh: Makefile @: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @@ -258,12 +260,48 @@ distclean-compile: .S.obj: $(CPPASCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` +lib_a-memcpy.o: memcpy.S + $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CCASFLAGS) $(CCASFLAGS) -c -o lib_a-memcpy.o `test -f 'memcpy.S' || echo '$(srcdir)/'`memcpy.S + +lib_a-memcpy.obj: memcpy.S + $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CCASFLAGS) $(CCASFLAGS) -c -o lib_a-memcpy.obj `if test -f 'memcpy.S'; then $(CYGPATH_W) 'memcpy.S'; else $(CYGPATH_W) '$(srcdir)/memcpy.S'; fi` + +lib_a-memset.o: memset.S + $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CCASFLAGS) $(CCASFLAGS) -c -o lib_a-memset.o `test -f 'memset.S' || echo '$(srcdir)/'`memset.S + +lib_a-memset.obj: memset.S + $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CCASFLAGS) $(CCASFLAGS) -c -o lib_a-memset.obj `if test -f 'memset.S'; then $(CYGPATH_W) 'memset.S'; else $(CYGPATH_W) '$(srcdir)/memset.S'; fi` + lib_a-setjmp.o: setjmp.S $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CCASFLAGS) $(CCASFLAGS) -c -o lib_a-setjmp.o `test -f 'setjmp.S' || echo '$(srcdir)/'`setjmp.S lib_a-setjmp.obj: setjmp.S $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CCASFLAGS) $(CCASFLAGS) -c -o lib_a-setjmp.obj `if test -f 'setjmp.S'; then $(CYGPATH_W) 'setjmp.S'; else $(CYGPATH_W) '$(srcdir)/setjmp.S'; fi` +lib_a-strcmp.o: strcmp.S + $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CCASFLAGS) $(CCASFLAGS) -c -o lib_a-strcmp.o `test -f 'strcmp.S' || echo '$(srcdir)/'`strcmp.S + +lib_a-strcmp.obj: strcmp.S + $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CCASFLAGS) $(CCASFLAGS) -c -o lib_a-strcmp.obj `if test -f 'strcmp.S'; then $(CYGPATH_W) 'strcmp.S'; else $(CYGPATH_W) '$(srcdir)/strcmp.S'; fi` + +lib_a-strcpy.o: strcpy.S + $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CCASFLAGS) $(CCASFLAGS) -c -o lib_a-strcpy.o `test -f 'strcpy.S' || echo '$(srcdir)/'`strcpy.S + +lib_a-strcpy.obj: strcpy.S + $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CCASFLAGS) $(CCASFLAGS) -c -o lib_a-strcpy.obj `if test -f 'strcpy.S'; then $(CYGPATH_W) 'strcpy.S'; else $(CYGPATH_W) '$(srcdir)/strcpy.S'; fi` + +.c.o: + $(COMPILE) -c $< + +.c.obj: + $(COMPILE) -c `$(CYGPATH_W) '$<'` + +lib_a-abort.o: abort.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-abort.o `test -f 'abort.c' || echo '$(srcdir)/'`abort.c + +lib_a-abort.obj: abort.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-abort.obj `if test -f 'abort.c'; then $(CYGPATH_W) 'abort.c'; else $(CYGPATH_W) '$(srcdir)/abort.c'; fi` + ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ diff --git a/newlib/libc/machine/nds32/abort.c b/newlib/libc/machine/nds32/abort.c new file mode 100644 index 000000000..724562a84 --- /dev/null +++ b/newlib/libc/machine/nds32/abort.c @@ -0,0 +1,42 @@ +/* +FUNCTION +<>---abnormal termination of a program + +INDEX + abort + +ANSI_SYNOPSIS + #include + void abort(void); + +TRAD_SYNOPSIS + #include + void abort(); + +DESCRIPTION +Use <> to signal that your program has detected a condition it +cannot deal with. Normally, <> ends your program's execution. + +In general implementation, <> raises the exception <>. +But for nds32 target, currently it is not necessary for MCU platform. +We can just call <<_exit>> to terminate program. + +RETURNS +<> does not return to its caller. + +PORTABILITY +ANSI C requires <>. + +Supporting OS subroutines required: <<_exit>>. +*/ + +#include + +_VOID +_DEFUN_VOID (abort) +{ + while (1) + { + _exit (1); + } +} diff --git a/newlib/libc/machine/nds32/memcpy.S b/newlib/libc/machine/nds32/memcpy.S new file mode 100644 index 000000000..f27858c09 --- /dev/null +++ b/newlib/libc/machine/nds32/memcpy.S @@ -0,0 +1,77 @@ +/* +Copyright (c) 2013 Andes Technology 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. + + The name of the company may not 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 RED HAT INCORPORATED 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. + + + Function: + memcpy - copy memory regions + Syntax: + void *memcpy(void *s1, const void *s2, size_t n); + Description: + The memcpy function copies n characters from the object pointed to + by s2 into the object pointed to by s1. If copying takes place + between objects that overlap, the behavior is undeļ¬ned. + Return value: + The memcpy function returns the value of s1. +*/ + .text + .align 2 + .globl memcpy + .type memcpy, @function +memcpy: + /* Corner cases. If *s1 equals *s2 + or size_t is zero, just go return. */ + beq $r0, $r1, .Lend_memcpy + beqz $r2, .Lend_memcpy + + /* Keep *s1 as return value. + Set $r3 as how many words to copy. + Set $r2 as how many bytes are less than a word. */ + move $r5, $r0 + srli $r3, $r2, 2 + andi $r2, $r2, 3 + beqz $r3, .Lbyte_copy + +.Lword_copy: + /* Do the word copy $r3 times. Then, do the byte copy $r2 times. */ + lmw.bim $r4, [$r1], $r4, 0 + addi $r3, $r3, -1 + smw.bim $r4, [$r5], $r4, 0 + bnez $r3, .Lword_copy /* Loop again ? */ + beqz $r2, .Lend_memcpy /* Fall THRU or go return ? */ + +.Lbyte_copy: + /* Do the byte copy $r2 times. */ + lbi.bi $r4, [$r1], 1 + addi $r2, $r2, -1 + sbi.bi $r4, [$r5], 1 + bnez $r2, .Lbyte_copy /* Loop again ? */ + +.Lend_memcpy: + ret + .size memcpy, .-memcpy diff --git a/newlib/libc/machine/nds32/memset.S b/newlib/libc/machine/nds32/memset.S new file mode 100644 index 000000000..51e5ff2ae --- /dev/null +++ b/newlib/libc/machine/nds32/memset.S @@ -0,0 +1,80 @@ +/* +Copyright (c) 2013 Andes Technology 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. + + The name of the company may not 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 RED HAT INCORPORATED 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. + + + Function: + memset - fill memory with a constant byte + Syntax: + void *memset(void *s, int c, size_t n); + Description: + The memset function copies the value of c (converted to an unsigned char) + into each of the first n characters of the object pointed to by s. + Return value: + The memset function returns the value of s. +*/ + .text + .align 2 + .globl memset + .type memset, @function +memset: + /* Corner case. If n is zero, just go return. */ + beqz $r2, .Lend_memset + + /* Keep $r0 as return value. + Set $r4 as how many words to copy. + Set $r2 as how many bytes are less than a word. */ + move $r5, $r0 + srli $r4, $r2, 2 + andi $r2, $r2, 3 + beqz $r4, .Lbyte_set + + /* Set $r1 a word-size pattern composed of the value of c + (converted to an unsigned char). Convert ??????ab to abababab. */ + andi $r1, $r1, 0xff /* Set $r1 = 000000ab. */ + slli $r3, $r1, 8 /* Set $r3 = 0000ab00. */ + or $r1, $r1, $r3 /* Set $r1 = 0000abab. */ + slli $r3, $r1, 16 /* Set $r3 = abab0000. */ + or $r1, $r1, $r3 /* Set $r1 = abababab. */ + +.Lword_set: + /* Do the word set $r4 times. Then, do the byte set $r2 times. */ + addi $r4, $r4, -1 + smw.bim $r1, [$r5], $r1 /* Set a word-size. */ + bnez $r4, .Lword_set /* Loop again ? */ + beqz $r2, .Lend_memset /* Fall THRU or go return ? */ + +.Lbyte_set: + /* Do the byte set $r2 times. */ + addi $r2, $r2, -1 + sbi.p $r1, [$r5], 1 /* Set a byte-size. */ + bnez $r2, .Lbyte_set /* Loop again ? */ + +.Lend_memset: + ret + .size memset, .-memset diff --git a/newlib/libc/machine/nds32/strcmp.S b/newlib/libc/machine/nds32/strcmp.S new file mode 100644 index 000000000..f3f37fb3e --- /dev/null +++ b/newlib/libc/machine/nds32/strcmp.S @@ -0,0 +1,96 @@ +/* +Copyright (c) 2013 Andes Technology 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. + + The name of the company may not 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 RED HAT INCORPORATED 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. + + + Function: + strcmp - compare two strings. + Syntax: + int strcmp(const char *s1, const char *s2); + Description: + This function compares the two strings s1 and s2. It 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. + Return value: + strcmp returns an integer less than, equal to, or greater than + zero if s1 (or the first n bytes thereof) is found, respectively, + to be less than, to match, or be greater than s2. +*/ + .text + .align 2 + .globl strcmp + .type strcmp, @function +strcmp: + /* If s1 or s2 are unaligned, then compare bytes. */ + or $r5, $r1, $r0 + andi $r5, $r5, #3 + bnez $r5, .Lbyte_mode + + /* If s1 and s2 are word-aligned, compare them a word at a time. */ + lwi $r5, [$r0+(0)] + lwi $r3, [$r1+(0)] + bne $r5, $r3, .Lbyte_mode /* A difference was detected, so + search bytewise. */ + + /* It's more efficient to set bit mask outside the word_mode loop. */ + sethi $r4, hi20(0xFEFEFEFF) /* Set $r4 as -0x01010101. */ + ori $r4, $r4, lo12(0xFEFEFEFF) + sethi $r2, hi20(0x80808080) + ori $r2, $r2, lo12(0x80808080) + b .Ldetect_null + +.align 2 +.Lword_mode: + lmw.aim $r5, [$r0], $r5 + lmw.aim $r3, [$r1], $r3 + bne $r5, $r3, .Lbyte_mode + +.Ldetect_null: + /* #define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080) + DETECTNULL returns nonzero if (long)X contains a NULL byte. */ + nor $r3, $r5, $r5 /* r3 = ~(X) */ + add $r5, $r5, $r4 /* r2 = ((X) - 0x01010101) */ + and $r5, $r5, $r3 /* r2 = ~(X) & ((X) - 0x01010101) */ + and $r5, $r5, $r2 /* r2= r2 & 0x80808080 */ + beqz $r5, .Lword_mode /* No NULL byte, compare next word. */ + + /* To get here, *a1 == *a2, thus if we find a null in *a1, + then the strings must be equal, so return zero. */ + movi $r0, #0 + ret + +.Lbyte_mode: + /* Byte-mode compare. */ + lbi.bi $r5, [$r0], #1 + lbi.bi $r3, [$r1], #1 + bne $r5, $r3, 1f /* Mismatch, done. */ + bnez $r5, .Lbyte_mode +1: + sub $r0, $r5, $r3 + ret + .size strcmp, .-strcmp diff --git a/newlib/libc/machine/nds32/strcpy.S b/newlib/libc/machine/nds32/strcpy.S new file mode 100644 index 000000000..6d94396ac --- /dev/null +++ b/newlib/libc/machine/nds32/strcpy.S @@ -0,0 +1,76 @@ +/* +Copyright (c) 2013 Andes Technology 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. + + The name of the company may not 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 RED HAT INCORPORATED 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. + + + Function: + strcpy - copy a string. + Syntax: + char *strcpy(char *dest, const char *src); + Description: + This function copies the string pointed to by src into the array + point to by dest (include the teminating null character). + Return value: + strcpy returns the dest as given. +*/ + .text + .align 2 + .globl strcpy + .type strcpy, @function +strcpy: + move $r3, $r0 /* Keep r0 as reture value. */ + /* If SRC or DEST is unaligned, then copy bytes. */ + or $r2, $r1, $r0 + andi $r2, $r2, #3 + bnez $r2, .Lbyte_mode + +.Lword_mode: + /* SRC and DEST are both "long int" aligned, try to do "long int" + sized copies. */ + /* #define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080) + DETECTNULL returns nonzero if (long)X contains a NULL byte. */ + lwi $r2, [$r1+(0)] /* r2 is X */ + sethi $r4, hi20(0xFEFEFEFF) + ori $r4, $r4, lo12(0xFEFEFEFF) + add $r4, $r2, $r4 /* r4 = ((X) - 0x01010101) */ + nor $r5, $r2, $r2 /* r5 = ~(X) */ + and $r4, $r5, $r4 /* r4 = ~(X) & ((X) - 0x01010101) */ + sethi $r5, hi20(0x80808080) + ori $r5, $r5, lo12(0x80808080) + and $r4, $r4, $r5 /* r4 = r4 & 0x80808080 */ + bnez $r4, .Lbyte_mode /* Contains a NULL byte. */ + swi.bi $r2, [$r3], #4 + addi $r1, $r1, #4 + b .Lword_mode + +.Lbyte_mode: + lbi.bi $r4, [$r1], #1 /* r4 <- *src++ */ + sbi.bi $r4, [$r3], #1 /* r4 -> *dest++ */ + bnez $r4, .Lbyte_mode + ret + .size strcpy, .-strcpy