From 6a4917ac6ff0993f69e7e60c864804916e34f88e Mon Sep 17 00:00:00 2001
From: Sabrina Ni <sabrina@andestech.com>
Date: Tue, 25 Jun 2013 17:09:16 +0800
Subject: [PATCH 3/3] Add machine specific code for nds32 port.

[newlib]
  * 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.
---

diff --git a/newlib/libc/machine/nds32/Makefile.am b/newlib/libc/machine/nds32/Makefile.am
index 329e2ce..fa96ccd 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
** omitted **

diff --git a/newlib/libc/machine/nds32/abort.c b/newlib/libc/machine/nds32/abort.c
new file mode 100644
index 0000000..724562a
--- /dev/null
+++ b/newlib/libc/machine/nds32/abort.c
@@ -0,0 +1,42 @@
+/*
+FUNCTION
+<<abort>>---abnormal termination of a program
+
+INDEX
+	abort
+
+ANSI_SYNOPSIS
+	#include <stdlib.h>
+	void abort(void);
+
+TRAD_SYNOPSIS
+	#include <stdlib.h>
+	void abort();
+
+DESCRIPTION
+Use <<abort>> to signal that your program has detected a condition it
+cannot deal with.  Normally, <<abort>> ends your program's execution.
+
+In general implementation, <<abort>> raises the exception <<SIGABRT>>.
+But for nds32 target, currently it is not necessary for MCU platform.
+We can just call <<_exit>> to terminate program.
+
+RETURNS
+<<abort>> does not return to its caller.
+
+PORTABILITY
+ANSI C requires <<abort>>.
+
+Supporting OS subroutines required: <<_exit>>.
+*/
+
+#include <unistd.h>
+
+_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 0000000..f27858c
--- /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 0000000..51e5ff2
--- /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 0000000..f3f37fb
--- /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 0000000..6d94396
--- /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
-- 
1.7.9.5

