[uclibc-ng-devel] uClibc-ng - small C library for embedded systems branch master updated. v1.0.21-28-g6af3332

wbx at helium.openadk.org wbx at helium.openadk.org
Sun Jan 22 10:06:37 CET 2017


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "uClibc-ng - small C library for embedded systems".

The branch, master has been updated
       via  6af3332a4cbd1ffbc81f74759ef7c5e1a87d2e10 (commit)
      from  82af21a60bc6e53dd92c1c140f20179d2ae4ad40 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 6af3332a4cbd1ffbc81f74759ef7c5e1a87d2e10
Author: Vincent Ren-Wei Chen <vincentc at andestech.com>
Date:   Tue Jan 17 07:31:24 2017 +0100

    nds32: add NPTL/TLS, *context function, libm changes and code cleanup
    
    This commit includes following features.
    1. Support NPTL/TLS
    2. Add libm function which is used to handle FP rounding and excpetions
       (ex: fclrexcpt,fedisblxcpti,feenablxcpt... )
    3. Add *context function for operating user context
       (ex: setcontext,getcontext,makecontext... )
    4. Change the return flow from signal handler
    5. Cleanup of old code
    
    The testsuite only has 2 errors, tst-cpuclock1 and tst-cputimer1,
    which are related to timing accuracy. (math and locale tests are disabled)
    
    Signed-off-by: Vincent Ren-Wei Chen <vincentc at andestech.com>

-----------------------------------------------------------------------

Summary of changes:
 extra/Configs/Config.in                            |   1 -
 extra/Configs/Config.nds32                         |   1 +
 extra/Configs/defconfigs/nds32/defconfig           | 167 ++++++++++
 include/elf.h                                      |   3 +
 ldso/ldso/nds32/dl-startup.h                       |  94 +-----
 ldso/ldso/nds32/dl-sysdep.h                        |   5 +-
 ldso/ldso/nds32/dl-tlsdesc.S                       | 100 ++++++
 ldso/ldso/nds32/elfinterp.c                        |  94 ++++--
 ldso/ldso/nds32/resolve.S                          |  24 --
 ldso/libdl/Makefile.in                             |   1 -
 libc/string/nds32/memcpy.S                         |  22 +-
 libc/string/nds32/memset.S                         |   2 +-
 libc/sysdeps/linux/common/posix_fadvise.c          |   2 +-
 libc/sysdeps/linux/common/posix_fadvise64.c        |   2 +-
 libc/sysdeps/linux/common/sync_file_range.c        |   2 +-
 libc/sysdeps/linux/nds32/Makefile                  |   6 +-
 libc/sysdeps/linux/nds32/Makefile.arch             |   6 +-
 libc/sysdeps/linux/nds32/__longjmp.S               |   2 +-
 libc/sysdeps/linux/nds32/bits/atomic.h             | 110 +++++++
 libc/sysdeps/linux/nds32/bits/fcntl.h              |   6 +-
 libc/sysdeps/linux/nds32/bits/fenv.h               |  79 +++++
 libc/sysdeps/linux/nds32/bits/mman.h               |   1 +
 libc/sysdeps/linux/nds32/bits/setjmp.h             |  18 +-
 libc/sysdeps/linux/nds32/bits/sigcontext.h         |  59 ----
 libc/sysdeps/linux/nds32/bits/sigcontextinfo.h     |  35 ++
 libc/sysdeps/linux/nds32/bits/syscalls.h           | 354 ++++++++++++++++-----
 .../linux/nds32/bits/uClibc_arch_features.h        |   2 +-
 libc/sysdeps/linux/nds32/bsd-_setjmp.S             |   5 +-
 libc/sysdeps/linux/nds32/bsd-setjmp.S              |   4 +-
 libc/sysdeps/linux/nds32/clone.S                   | 200 ++++++++----
 libc/sysdeps/linux/nds32/crt1.S                    |   7 -
 libc/sysdeps/linux/nds32/crti.S                    |  24 --
 libc/sysdeps/linux/nds32/fpu_control.h             |  77 +++++
 libc/sysdeps/linux/nds32/getcontext.S              | 106 ++++++
 libc/sysdeps/linux/nds32/jmpbuf-unwind.h           |  18 +-
 libc/sysdeps/linux/nds32/makecontext.c             |  77 +++++
 libc/sysdeps/linux/nds32/mmap.S                    | 101 ------
 libc/sysdeps/linux/nds32/mremap.c                  |  28 ++
 libc/sysdeps/linux/nds32/prctl.c                   |  23 ++
 libc/sysdeps/linux/nds32/setcontext.S              |  85 +++++
 libc/sysdeps/linux/nds32/setjmp.S                  |   2 +-
 libc/sysdeps/linux/nds32/sigaction.c               |  40 ---
 libc/sysdeps/linux/nds32/sigrestorer.S             |  42 ---
 libc/sysdeps/linux/nds32/swapcontext.c             |  38 +++
 libc/sysdeps/linux/nds32/sys/ucontext.h            | 117 ++-----
 libc/sysdeps/linux/nds32/syscall.S                 |  60 ----
 libc/sysdeps/linux/nds32/syscall.c                 |  28 ++
 libc/sysdeps/linux/nds32/sysdep.S                  |  39 ++-
 libc/sysdeps/linux/nds32/sysdep.h                  | 321 +++++++------------
 libc/sysdeps/linux/nds32/ucontext_i.sym            |  27 ++
 libc/sysdeps/linux/nds32/vfork.S                   | 114 +++++--
 libm/nds32/Makefile.arch                           |  16 +
 libm/nds32/e_sqrt.c                                |  34 ++
 libm/nds32/fclrexcpt.c                             |  52 +++
 libm/nds32/fedisblxcpt.c                           |  49 +++
 libm/nds32/feenablxcpt.c                           |  50 +++
 libm/nds32/fegetenv.c                              |  40 +++
 libm/nds32/fegetexcept.c                           |  41 +++
 libm/nds32/fegetround.c                            |  40 +++
 libm/nds32/feholdexcpt.c                           |  51 +++
 libm/nds32/fenv_libc.h                             |  33 ++
 libm/nds32/fesetenv.c                              |  51 +++
 libm/nds32/fesetround.c                            |  42 +++
 libm/nds32/feupdateenv.c                           |  48 +++
 libm/nds32/fgetexcptflg.c                          |  44 +++
 libm/nds32/fraiseexcpt.c                           | 104 ++++++
 libm/nds32/fsetexcptflg.c                          |  48 +++
 libm/nds32/ftestexcept.c                           |  40 +++
 libpthread/linuxthreads/sysdeps/nds32/pspinlock.c  |   2 +-
 libpthread/linuxthreads/sysdeps/nds32/pt-machine.h |   2 +-
 libpthread/nptl/sysdeps/nds32/Makefile.arch        |  16 +
 libpthread/nptl/sysdeps/nds32/dl-tls.h             |  59 ++++
 libpthread/nptl/sysdeps/nds32/libc-dl-tlsdesc.S    |   1 +
 libpthread/nptl/sysdeps/nds32/pthread_spin_lock.c  |  65 ++++
 .../nptl/sysdeps/nds32/pthread_spin_trylock.c      |  26 ++
 libpthread/nptl/sysdeps/nds32/pthreaddef.h         |  39 +++
 libpthread/nptl/sysdeps/nds32/tcb-offsets.sym      |  12 +
 libpthread/nptl/sysdeps/nds32/tls.h                | 178 +++++++++++
 libpthread/nptl/sysdeps/nds32/tlsdesc.sym          |  17 +
 .../nptl/sysdeps/unix/sysv/linux/nds32/Makefile    |   9 +
 .../sysdeps/unix/sysv/linux/nds32/Makefile.arch    |  12 +
 .../unix/sysv/linux/nds32/bits/pthreadtypes.h      | 177 +++++++++++
 .../sysdeps/unix/sysv/linux/nds32/bits/semaphore.h |  38 +++
 .../nptl/sysdeps/unix/sysv/linux/nds32/clone.S     |   4 +
 .../sysdeps/unix/sysv/linux/nds32/createthread.c   |  22 ++
 .../nptl/sysdeps/unix/sysv/linux/nds32/fork.c      |  27 ++
 .../sysdeps/unix/sysv/linux/nds32/lowlevellock.h   | 323 +++++++++++++++++++
 .../nptl/sysdeps/unix/sysv/linux/nds32/pt-raise.c  |  18 ++
 .../sysdeps/unix/sysv/linux/nds32/pthread_once.c   |  92 ++++++
 .../sysdeps/unix/sysv/linux/nds32/sysdep-cancel.h  | 273 ++++++++++++++++
 .../nptl/sysdeps/unix/sysv/linux/nds32/vfork.S     |  43 +++
 91 files changed, 4023 insertions(+), 996 deletions(-)
 create mode 100644 extra/Configs/defconfigs/nds32/defconfig
 create mode 100644 ldso/ldso/nds32/dl-tlsdesc.S
 create mode 100644 libc/sysdeps/linux/nds32/bits/atomic.h
 create mode 100644 libc/sysdeps/linux/nds32/bits/fenv.h
 delete mode 100644 libc/sysdeps/linux/nds32/bits/sigcontext.h
 create mode 100644 libc/sysdeps/linux/nds32/bits/sigcontextinfo.h
 create mode 100644 libc/sysdeps/linux/nds32/fpu_control.h
 create mode 100644 libc/sysdeps/linux/nds32/getcontext.S
 create mode 100644 libc/sysdeps/linux/nds32/makecontext.c
 delete mode 100644 libc/sysdeps/linux/nds32/mmap.S
 create mode 100644 libc/sysdeps/linux/nds32/mremap.c
 create mode 100644 libc/sysdeps/linux/nds32/prctl.c
 create mode 100644 libc/sysdeps/linux/nds32/setcontext.S
 delete mode 100644 libc/sysdeps/linux/nds32/sigaction.c
 delete mode 100644 libc/sysdeps/linux/nds32/sigrestorer.S
 create mode 100644 libc/sysdeps/linux/nds32/swapcontext.c
 delete mode 100644 libc/sysdeps/linux/nds32/syscall.S
 create mode 100644 libc/sysdeps/linux/nds32/syscall.c
 create mode 100644 libc/sysdeps/linux/nds32/ucontext_i.sym
 create mode 100644 libm/nds32/Makefile.arch
 create mode 100644 libm/nds32/e_sqrt.c
 create mode 100644 libm/nds32/fclrexcpt.c
 create mode 100644 libm/nds32/fedisblxcpt.c
 create mode 100644 libm/nds32/feenablxcpt.c
 create mode 100644 libm/nds32/fegetenv.c
 create mode 100644 libm/nds32/fegetexcept.c
 create mode 100644 libm/nds32/fegetround.c
 create mode 100644 libm/nds32/feholdexcpt.c
 create mode 100644 libm/nds32/fenv_libc.h
 create mode 100644 libm/nds32/fesetenv.c
 create mode 100644 libm/nds32/fesetround.c
 create mode 100644 libm/nds32/feupdateenv.c
 create mode 100644 libm/nds32/fgetexcptflg.c
 create mode 100644 libm/nds32/fraiseexcpt.c
 create mode 100644 libm/nds32/fsetexcptflg.c
 create mode 100644 libm/nds32/ftestexcept.c
 create mode 100644 libpthread/nptl/sysdeps/nds32/Makefile.arch
 create mode 100644 libpthread/nptl/sysdeps/nds32/dl-tls.h
 create mode 100644 libpthread/nptl/sysdeps/nds32/libc-dl-tlsdesc.S
 create mode 100644 libpthread/nptl/sysdeps/nds32/pthread_spin_lock.c
 create mode 100644 libpthread/nptl/sysdeps/nds32/pthread_spin_trylock.c
 create mode 100644 libpthread/nptl/sysdeps/nds32/pthreaddef.h
 create mode 100644 libpthread/nptl/sysdeps/nds32/tcb-offsets.sym
 create mode 100644 libpthread/nptl/sysdeps/nds32/tls.h
 create mode 100644 libpthread/nptl/sysdeps/nds32/tlsdesc.sym
 create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/nds32/Makefile
 create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/nds32/Makefile.arch
 create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/nds32/bits/pthreadtypes.h
 create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/nds32/bits/semaphore.h
 create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/nds32/clone.S
 create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/nds32/createthread.c
 create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/nds32/fork.c
 create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/nds32/lowlevellock.h
 create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/nds32/pt-raise.c
 create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/nds32/pthread_once.c
 create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/nds32/sysdep-cancel.h
 create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/nds32/vfork.S

diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in
index f312e7a..a9d62f5 100644
--- a/extra/Configs/Config.in
+++ b/extra/Configs/Config.in
@@ -521,7 +521,6 @@ config UCLIBC_HAS_THREADS_NATIVE
 		   !TARGET_hppa && \
 		   !TARGET_ia64 && \
 		   !TARGET_m68k && \
-		   !TARGET_nds32 && \
 		   !TARGET_or1k && \
 		   ARCH_USE_MMU
 	help
diff --git a/extra/Configs/Config.nds32 b/extra/Configs/Config.nds32
index a742499..2ed6a32 100644
--- a/extra/Configs/Config.nds32
+++ b/extra/Configs/Config.nds32
@@ -13,6 +13,7 @@ config FORCE_OPTIONS_FOR_ARCH
 	select ARCH_ANY_ENDIAN
 	select ARCH_HAS_DEPRECATED_SYSCALLS
 	select ARCH_HAS_MMU
+	select ARCH_HAS_UCONTEXT
 
 choice
 	prompt "MMU Page Size"
diff --git a/extra/Configs/defconfigs/nds32/defconfig b/extra/Configs/defconfigs/nds32/defconfig
new file mode 100644
index 0000000..d870ad7
--- /dev/null
+++ b/extra/Configs/defconfigs/nds32/defconfig
@@ -0,0 +1,167 @@
+TARGET_nds32=y
+#
+# Using ELF file format
+#
+ARCH_HAS_DEPRECATED_SYSCALLS=y
+ARCH_ANY_ENDIAN=y
+ARCH_LITTLE_ENDIAN=y
+# ARCH_WANTS_BIG_ENDIAN is not set
+ARCH_WANTS_LITTLE_ENDIAN=y
+ARCH_HAS_MMU=y
+ARCH_USE_MMU=y
+UCLIBC_HAS_FLOATS=y
+UCLIBC_HAS_FPU=y
+DO_C99_MATH=y
+DO_XSI_MATH=y
+UCLIBC_HAS_FENV=y
+KERNEL_HEADERS=""
+HAVE_DOT_CONFIG=y
+
+#
+# General Library Settings
+#
+DOPIC=y
+ARCH_HAS_UCONTEXT=y
+HAVE_SHARED=y
+# FORCE_SHAREABLE_TEXT_SEGMENTS is not set
+LDSO_LDD_SUPPORT=y
+LDSO_CACHE_SUPPORT=y
+# LDSO_PRELOAD_ENV_SUPPORT is not set
+# LDSO_PRELOAD_FILE_SUPPORT is not set
+LDSO_BASE_FILENAME="ld.so"
+# LDSO_STANDALONE_SUPPORT is not set
+# LDSO_PRELINK_SUPPORT is not set
+UCLIBC_STATIC_LDCONFIG=y
+LDSO_RUNPATH=y
+LDSO_RUNPATH_OF_EXECUTABLE=y
+LDSO_SAFE_RUNPATH=y
+LDSO_SEARCH_INTERP_PATH=y
+LDSO_LD_LIBRARY_PATH=y
+LDSO_NO_CLEANUP=y
+UCLIBC_CTOR_DTOR=y
+LDSO_GNU_HASH_SUPPORT=y
+# HAS_NO_THREADS is not set
+# UCLIBC_HAS_LINUXTHREADS is not set
+UCLIBC_HAS_THREADS_NATIVE=y
+UCLIBC_HAS_THREADS=y
+UCLIBC_HAS_TLS=y
+PTHREADS_DEBUG_SUPPORT=y
+UCLIBC_HAS_SYSLOG=y
+UCLIBC_HAS_LFS=y
+# MALLOC is not set
+# MALLOC_SIMPLE is not set
+MALLOC_STANDARD=y
+MALLOC_GLIBC_COMPAT=y
+# UCLIBC_HAS_OBSTACK is not set
+UCLIBC_DYNAMIC_ATEXIT=y
+COMPAT_ATEXIT=y
+UCLIBC_HAS_UTMPX=y
+UCLIBC_HAS_UTMP=y
+UCLIBC_SUSV2_LEGACY=y
+UCLIBC_SUSV3_LEGACY=y
+UCLIBC_HAS_CONTEXT_FUNCS=y
+UCLIBC_SUSV3_LEGACY_MACROS=y
+UCLIBC_SUSV4_LEGACY=y
+# UCLIBC_STRICT_HEADERS is not set
+# UCLIBC_HAS_STUBS is not set
+UCLIBC_HAS_SHADOW=y
+UCLIBC_HAS_PROGRAM_INVOCATION_NAME=y
+UCLIBC_HAS___PROGNAME=y
+UCLIBC_HAS_PTY=y
+ASSUME_DEVPTS=y
+UNIX98PTY_ONLY=y
+UCLIBC_HAS_GETPT=y
+UCLIBC_HAS_LIBUTIL=y
+UCLIBC_HAS_TM_EXTENSIONS=y
+UCLIBC_HAS_TZ_CACHING=y
+UCLIBC_HAS_TZ_FILE=y
+UCLIBC_HAS_TZ_FILE_READ_MANY=y
+UCLIBC_TZ_FILE_PATH="/etc/TZ"
+UCLIBC_FALLBACK_TO_ETC_LOCALTIME=y
+
+#
+# Advanced Library Settings
+#
+UCLIBC_PWD_BUFFER_SIZE=256
+UCLIBC_GRP_BUFFER_SIZE=256
+
+#
+# Support various families of functions
+#
+UCLIBC_LINUX_MODULE_26=y
+# UCLIBC_LINUX_MODULE_24 is not set
+UCLIBC_LINUX_SPECIFIC=y
+UCLIBC_HAS_GNU_ERROR=y
+UCLIBC_BSD_SPECIFIC=y
+UCLIBC_HAS_BSD_ERR=y
+UCLIBC_HAS_OBSOLETE_BSD_SIGNAL=y
+# UCLIBC_HAS_OBSOLETE_SYSV_SIGNAL is not set
+# UCLIBC_NTP_LEGACY is not set
+UCLIBC_SV4_DEPRECATED=y
+UCLIBC_HAS_REALTIME=y
+UCLIBC_HAS_ADVANCED_REALTIME=y
+UCLIBC_HAS_EPOLL=y
+UCLIBC_HAS_XATTR=y
+UCLIBC_HAS_PROFILING=y
+UCLIBC_HAS_CRYPT_IMPL=y
+UCLIBC_HAS_SHA256_CRYPT_IMPL=y
+# UCLIBC_HAS_SHA512_CRYPT_IMPL is not set
+UCLIBC_HAS_CRYPT=y
+UCLIBC_HAS_NETWORK_SUPPORT=y
+UCLIBC_HAS_SOCKET=y
+UCLIBC_HAS_IPV4=y
+UCLIBC_HAS_IPV6=y
+UCLIBC_HAS_RPC=y
+UCLIBC_HAS_FULL_RPC=y
+# UCLIBC_HAS_REENTRANT_RPC is not set
+UCLIBC_USE_NETLINK=y
+UCLIBC_SUPPORT_AI_ADDRCONFIG=y
+UCLIBC_HAS_BSD_RES_CLOSE=y
+UCLIBC_HAS_COMPAT_RES_STATE=y
+# UCLIBC_HAS_EXTRA_COMPAT_RES_STATE is not set
+UCLIBC_HAS_RESOLVER_SUPPORT=y
+UCLIBC_HAS_LIBRESOLV_STUB=y
+UCLIBC_HAS_LIBNSL_STUB=y
+
+UCLIBC_HAS_STRING_GENERIC_OPT=y
+UCLIBC_HAS_STRING_ARCH_OPT=y
+UCLIBC_HAS_STDIO_FUTEXES=y
+UCLIBC_HAS_CTYPE_TABLES=y
+UCLIBC_HAS_CTYPE_SIGNED=y
+# UCLIBC_HAS_CTYPE_UNSAFE is not set
+UCLIBC_HAS_CTYPE_CHECKED=y
+# UCLIBC_HAS_CTYPE_ENFORCED is not set
+UCLIBC_HAS_WCHAR=y
+# UCLIBC_HAS_LOCALE is not set
+UCLIBC_HAS_HEXADECIMAL_FLOATS=y
+UCLIBC_HAS_GLIBC_CUSTOM_PRINTF=y
+UCLIBC_PRINTF_SCANF_POSITIONAL_ARGS=9
+UCLIBC_HAS_STDIO_BUFSIZ_4096=y
+UCLIBC_HAS_STDIO_BUILTIN_BUFFER_NONE=y
+UCLIBC_HAS_STDIO_GETC_MACRO=y
+UCLIBC_HAS_STDIO_PUTC_MACRO=y
+UCLIBC_HAS_STDIO_AUTO_RW_TRANSITION=y
+UCLIBC_HAS_FOPEN_EXCLUSIVE_MODE=y
+UCLIBC_HAS_GLIBC_CUSTOM_STREAMS=y
+UCLIBC_HAS_PRINTF_M_SPEC=y
+UCLIBC_HAS_ERRNO_MESSAGES=y
+UCLIBC_HAS_SIGNUM_MESSAGES=y
+UCLIBC_HAS_GNU_GETOPT=y
+UCLIBC_HAS_GETOPT_LONG=y
+UCLIBC_HAS_GNU_GETSUBOPT=y
+UCLIBC_HAS_ARGP=y
+
+UCLIBC_HAS_REGEX=y
+# UCLIBC_HAS_REGEX_OLD is not set
+UCLIBC_HAS_FNMATCH=y
+# UCLIBC_HAS_FNMATCH_OLD is not set
+UCLIBC_HAS_WORDEXP=y
+UCLIBC_HAS_NFTW=y
+UCLIBC_HAS_FTW=y
+UCLIBC_HAS_FTS=y
+UCLIBC_HAS_GLOB=y
+UCLIBC_HAS_GNU_GLOB=y
+
+CROSS_COMPILER_PREFIX=""
+UCLIBC_EXTRA_CFLAGS=""
+# DOSTRIP is not set
diff --git a/include/elf.h b/include/elf.h
index e0937b7..0f188e7 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -2985,6 +2985,9 @@ typedef Elf32_Addr Elf32_Conflict;
 #define R_NDS32_PLTREL_LO12			65
 #define R_NDS32_PLT_GOTREL_HI20			66
 #define R_NDS32_PLT_GOTREL_LO12			67
+#define R_NDS32_TLS_TPOFF                       102
+#define R_NDS32_TLS_DESC                        119
+
 
 /* Processor specific section indices.  These sections do not actually
    exist.  Symbols with a st_shndx field corresponding to one of these
diff --git a/ldso/ldso/nds32/dl-startup.h b/ldso/ldso/nds32/dl-startup.h
index f700531..56892a2 100644
--- a/ldso/ldso/nds32/dl-startup.h
+++ b/ldso/ldso/nds32/dl-startup.h
@@ -6,68 +6,7 @@
 /* Need bootstrap relocations */
 #define ARCH_NEEDS_BOOTSTRAP_RELOCS
 
-#if defined(NDS32_ABI_2) || defined(NDS32_ABI_2FP)
-# define STACK_PUSH
-# define STACK_POP
-#else
-# define STACK_PUSH     "addi   $sp,    $sp,    -24"
-# define STACK_POP      "addi   $sp,    $sp,    24"
-#endif
 
-
-#ifdef __NDS32_N1213_43U1H__
-__asm__("\
-	.text\n\
-	.globl 	_start\n\
-	.globl  _dl_start\n\
-	.globl 	_dl_start_user\n\
-    .type	_start,#function\n\
-    .type	_dl_start,#function\n\
-	.type 	_dl_start_user,#function\n\
-	.align	4\n\
-	.pic\n\
-1:\n\
-	ret\n\
-_start:\n\
-	! we are PIC code, so get global offset table\n\
-	jal	1b\n\
-	sethi	$gp, HI20(_GLOBAL_OFFSET_TABLE_)\n\
-	ori		$gp, $gp, LO12(_GLOBAL_OFFSET_TABLE_+4)\n\
-	add		$gp, $lp, $gp\n\
-\n\
-	! at start time, all the args are on the stack\n\
-	addi	$r0,	$sp,	0\n\
-    ! adjust stack\n\
-    !addi    $sp,    $sp,    -24\n\
-	"STACK_PUSH"\n\
-	bal	_dl_start at PLT\n\
-	! save user entry point in r6\n\
-	addi	$r6,	$r0,	0\n\
-    ! adjust sp and reload registers\n\
-    !addi    $sp,    $sp,    24\n\
-	"STACK_POP"\n\
-\n\
-_dl_start_user:\n\
-\n\
-	! See if we were run as a command with the executable file\n\
-	! name as an extra leading argument.\n\
-	! skip these arguments\n\
-	l.w		$r2,	_dl_skip_args at GOTOFF	! args to skip\n\
-	lwi		$r0,	[$sp+0]					! original argc\n\
-	slli	$r1,	$r2,	2				! offset for new sp\n\
-	add		$sp,	$sp,	$r1				! adjust sp to skip args\n\
-	sub		$r0,	$r0,	$r2				! set new argc\n\
-	swi		$r0,	[$sp+0]					! save new argc\n\
-\n\
-	! load address of _dl_fini finalizer function\n\
-	la		$r5, _dl_fini at GOTOFF\n\
-	! jump to the user_s entry point\n\
-	addi	$r15,	$r6,	0\n\
-	jr		$r15\n\
-	.size   _dl_start_user, . - _dl_start_user\n\
-	.previous\n\
-");
-#else
 __asm__("\
 	.text\n\
 	.globl 	_start\n\
@@ -89,13 +28,11 @@ _start:\n\
 	addi	$r0,	$sp,	0\n\
     ! adjust stack\n\
     !addi    $sp,    $sp,    -24\n\
-	"STACK_PUSH"\n\
 	bal	_dl_start at PLT\n\
 	! save user entry point in r6\n\
 	addi	$r6,	$r0,	0\n\
     ! adjust sp and reload registers\n\
     !addi    $sp,    $sp,    24\n\
-	"STACK_POP"\n\
 \n\
 _dl_start_user:\n\
 	! See if we were run as a command with the executable file\n\
@@ -115,31 +52,12 @@ _dl_start_user:\n\
 	.size   _dl_start_user, . - _dl_start_user\n\
 	.previous\n\
 ");
-#endif
 
-#define COPY_UNALIGNED_WORD(swp, twp, align) \
-  { \
-    void *__s = (swp), *__t = (twp); \
-    unsigned char *__s1 = __s, *__t1 = __t; \
-    unsigned short *__s2 = __s, *__t2 = __t; \
-    unsigned long *__s4 = __s, *__t4 = __t; \
-    switch ((align)) \
-    { \
-    case 0: \
-      *__t4 = *__s4; \
-      break; \
-    case 2: \
-      *__t2++ = *__s2++; \
-      *__t2 = *__s2; \
-      break; \
-    default: \
-      *__t1++ = *__s1++; \
-      *__t1++ = *__s1++; \
-      *__t1++ = *__s1++; \
-      *__t1 = *__s1; \
-      break; \
-    } \
-  }
+#define COPY_UNALIGNED_WORD(swp, twp) \
+{ \
+        __typeof (swp) __tmp = __builtin_nds32_unaligned_load_w ((unsigned int*)&swp); \
+        __builtin_nds32_unaligned_store_w ((unsigned int *)twp, __tmp); \
+}
 
 /* Get a pointer to the argv array.  On many platforms this can be just
  * the address if the first argument, on other platforms we need to
@@ -162,7 +80,7 @@ void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr,
 			break;
 		case R_NDS32_32_RELA:
 			value = symbol_addr + rpnt->r_addend;
-			COPY_UNALIGNED_WORD (&value, reloc_addr, (int) reloc_addr & 3);
+			COPY_UNALIGNED_WORD (value, reloc_addr);
 			break;
 #undef COPY_UNALIGNED_WORD
 		case R_NDS32_RELATIVE:
diff --git a/ldso/ldso/nds32/dl-sysdep.h b/ldso/ldso/nds32/dl-sysdep.h
index c4a32ca..5ff2aa9 100644
--- a/ldso/ldso/nds32/dl-sysdep.h
+++ b/ldso/ldso/nds32/dl-sysdep.h
@@ -57,7 +57,8 @@ unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
    ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
    of the main executable's symbols, as for a COPY reloc.  */
 #define elf_machine_type_class(type) \
-  ((((type) == R_NDS32_JMP_SLOT) * ELF_RTYPE_CLASS_PLT)	\
+  ((((type) == R_NDS32_JMP_SLOT || (type) == R_NDS32_TLS_TPOFF \
+      || (type) == R_NDS32_TLS_DESC) * ELF_RTYPE_CLASS_PLT)	\
    | (((type) == R_NDS32_COPY) * ELF_RTYPE_CLASS_COPY))
 
 /* Return the link-time address of _DYNAMIC.  Conveniently, this is the
@@ -81,7 +82,7 @@ elf_machine_load_address (void)
      via the GOT to make sure the compiler initialized %ebx in time.  */
 
 	Elf32_Addr addr;
-	__asm__ ("la	%0, _dl_start at GOTOFF\n" : "=r" (addr) );
+	__asm__ ("la	%0, _DYNAMIC at GOTOFF\n" : "=r" (addr) );
 	return addr - elf_machine_dynamic();
 }
 
diff --git a/ldso/ldso/nds32/dl-tlsdesc.S b/ldso/ldso/nds32/dl-tlsdesc.S
new file mode 100644
index 0000000..a7ea1f2
--- /dev/null
+++ b/ldso/ldso/nds32/dl-tlsdesc.S
@@ -0,0 +1,100 @@
+/* Thread-local storage handling in the ELF dynamic linker.  NDS32 version.
+   Copyright (C) 2006-2013 Free Software Foundation, Inc.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+#if defined __UCLIBC_HAS_TLS__
+#include <tls.h>
+#include "tlsdesc.h"
+
+	.text
+	.hidden _dl_tlsdesc_return
+	.global	_dl_tlsdesc_return
+	.type	_dl_tlsdesc_return,#function
+	cfi_startproc
+	.align 2
+_dl_tlsdesc_return:
+	lwi	$r0,	[$r0	+ 4]
+	add	$r0,	$r0,	$r25
+	ret
+	cfi_endproc
+	.size   _dl_tlsdesc_return, .-_dl_tlsdesc_return
+
+#ifdef SHARED
+	.hidden _dl_tlsdesc_dynamic
+	.global	_dl_tlsdesc_dynamic
+	.type	_dl_tlsdesc_dynamic,#function
+	cfi_startproc
+	.pic
+/*
+	The assembly code that follows is a rendition of the following
+	C code, hand-optimized a little bit.
+
+ptrdiff_t
+_dl_tlsdesc_dynamic(struct tlsdesc *tdp)
+{
+       struct tlsdesc_dynamic_arg *td = tdp->argument.pointer;
+       dtv_t *dtv = (dtv_t *)THREAD_DTV();
+       if (__builtin_expect (td->gen_count <= dtv[0].counter
+                             && dtv[td->tlsinfo.ti_module].pointer.val
+                                != TLS_DTV_UNALLOCATED,
+                             1))
+               return dtv[td->tlsinfo.ti_module].pointer.val +
+                       td->tlsinfo.ti_offset - __builtin_thread_pointer();
+
+       return __tls_get_addr (&td->tlsinfo) - __builtin_thread_pointer();
+}
+*/
+	.align 2
+
+_dl_tlsdesc_dynamic:
+	lwi	$r0,	[$r0	+ 4]
+	lwi	$r1,	[$r0 +	#TLSDESC_GEN_COUNT]  	/* $r0=td $r1=td->gen_count*/
+	lwi	$r2,	[$r25 +	#DTV_OFFSET]	    	/* $r2=&dtv[0]*/
+	lwi	$r3,	[$r2]
+	sub	$r1,	$r1,	$r3
+	bgtz	$r1,	2f
+	lwi	$r3,	[$r0 +	#TLSDESC_MODID]	    	/* r3=module id */
+	slli	$r3,	$r3,	#3			/* r3=module offset=module id*8(byte) */
+	lw	$r3,	[$r2 +	$r3]		   	/* r3=&dtc[module ID]=&dtv[0]+ module offset*/
+	movi	$r1,	#-1
+	beq	$r3,	$r1,	2f
+	lwi	$r1,	[$r0 +	#TLSDESC_MODOFF]
+	add	$r0,	$r3,	$r1
+1:
+	ret
+2:
+	smw.adm $sp,[$sp],$sp,#0x6
+	cfi_adjust_cfa_offset(8)
+	cfi_rel_offset(gp, 0)
+	cfi_rel_offset(lp, 4)
+	mfusr 	$r15, $PC;
+	sethi 	$gp,  hi20(_GLOBAL_OFFSET_TABLE_ + 4);
+	ori   	$gp,  $gp,  lo12(_GLOBAL_OFFSET_TABLE_ + 8);
+	add   	$gp,  $r15, $gp;
+	sethi 	$r15, hi20(__tls_get_addr at PLT);
+	ori	$r15, $r15, lo12(__tls_get_addr at PLT);
+	add	$r15, $r15, $gp
+	jral 	$r15
+	lmw.bim $sp,[$sp],$sp,#0x6
+	cfi_adjust_cfa_offset(-8)
+	cfi_restore(gp)
+	cfi_restore(lp)
+	j	1b
+	cfi_endproc
+	.size   _dl_tlsdesc_dynamic, .-_dl_tlsdesc_dynamic
+#endif
+#endif // __UCLIBC_HAS_TLS__
diff --git a/ldso/ldso/nds32/elfinterp.c b/ldso/ldso/nds32/elfinterp.c
index 6a091f8..9f67141 100644
--- a/ldso/ldso/nds32/elfinterp.c
+++ b/ldso/ldso/nds32/elfinterp.c
@@ -44,6 +44,11 @@
 
 #include "ldso.h"
 
+#if defined(USE_TLS) && USE_TLS
+#include "dl-tls.h"
+#include "tlsdeschtab.h"
+#endif
+
 extern int _dl_linux_resolve(void);
 
 unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
@@ -95,7 +100,7 @@ unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
 		{
 			_dl_dprintf(_dl_debug_file, "\nresolve function: %s", symname);
 			if (_dl_debug_detail) _dl_dprintf(_dl_debug_file,
-					"\tpatch %x ==> %x @ %x", *got_addr, new_addr, got_addr);
+					"\tpatch %x ==> %x @ %x", (unsigned int)*got_addr, (unsigned int)new_addr, (unsigned int)got_addr);
 		}
 	}
 	if (!_dl_debug_nofixups) {
@@ -168,6 +173,9 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope,
 	int reloc_type;
 	int symtab_index;
 	char *symname = NULL;
+#if defined USE_TLS && USE_TLS
+	struct elf_resolve *tls_tpnt = NULL;
+#endif
 	unsigned long *reloc_addr;
 	unsigned long symbol_addr;
 	int goof = 0;
@@ -190,40 +198,40 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope,
 		 * have been intentional.  We should not be linking local symbols
 		 * here, so all bases should be covered.
 		 */
-		if (!symbol_addr && ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK) {
+		if (!symbol_addr
+		    && (ELF32_ST_TYPE(symtab[symtab_index].st_info) != STT_TLS)
+		    && (ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK)) {
 			_dl_dprintf (2, "%s: can't resolve symbol '%s'\n",
-				     _dl_progname, strtab + symtab[symtab_index].st_name);
+				     _dl_progname, symname);
 			_dl_exit (1);
 		}
+		if (_dl_trace_prelink) {
+			_dl_debug_lookup(symname, tpnt, &symtab[symtab_index],
+				&sym_ref, elf_machine_type_class(reloc_type));
+		}
+#if defined USE_TLS && USE_TLS
+		tls_tpnt = sym_ref.tpnt;
+#endif
 	}
 
-#define COPY_UNALIGNED_WORD(swp, twp, align) \
-  { \
-    void *__s = (swp), *__t = (twp); \
-    unsigned char *__s1 = __s, *__t1 = __t; \
-    unsigned short *__s2 = __s, *__t2 = __t; \
-    unsigned long *__s4 = __s, *__t4 = __t; \
-    switch ((align)) \
-    { \
-    case 0: \
-      *__t4 = *__s4; \
-      break; \
-    case 2: \
-      *__t2++ = *__s2++; \
-      *__t2 = *__s2; \
-      break; \
-    default: \
-      *__t1++ = *__s1++; \
-      *__t1++ = *__s1++; \
-      *__t1++ = *__s1++; \
-      *__t1 = *__s1; \
-      break; \
-    } \
-  }
+#if defined USE_TLS && USE_TLS
+	/* In case of a TLS reloc, tls_tpnt NULL means we have an 'anonymous'
+	   symbol.  This is the case for a static tls variable, so the lookup
+	   module is just that one is referencing the tls variable. */
+	if (!tls_tpnt)
+		tls_tpnt = tpnt;
+#endif
 
+#define COPY_UNALIGNED_WORD(swp, twp) \
+{ \
+	__typeof (swp) __tmp = __builtin_nds32_unaligned_load_w ((unsigned int*)&swp); \
+	__builtin_nds32_unaligned_store_w ((unsigned int *)twp, __tmp); \
+}
 #if defined (__SUPPORT_LD_DEBUG__)
 	{
-		unsigned long old_val = *reloc_addr;
+		unsigned long old_val = 0;
+		if(reloc_type != R_NDS32_NONE)
+			old_val = *reloc_addr;
 #endif
 		symbol_addr += rpnt->r_addend ;
 		switch (reloc_type) {
@@ -235,7 +243,7 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope,
 				*reloc_addr = symbol_addr;
 				break;
 			case R_NDS32_32_RELA:
-				COPY_UNALIGNED_WORD (&symbol_addr, reloc_addr,(int) reloc_addr & 3);
+				COPY_UNALIGNED_WORD (symbol_addr, reloc_addr);
 				break;
 #undef COPY_UNALIGNED_WORD
 			case R_NDS32_RELATIVE:
@@ -245,12 +253,38 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope,
 				_dl_memcpy((void *) reloc_addr,
 					   (void *) symbol_addr, symtab[symtab_index].st_size);
 				break;
+#if defined USE_TLS && USE_TLS
+			case R_NDS32_TLS_TPOFF:
+				CHECK_STATIC_TLS ((struct link_map *) tls_tpnt);
+				*reloc_addr = (symbol_addr + tls_tpnt->l_tls_offset);
+				break;
+			case R_NDS32_TLS_DESC:
+				{
+					struct tlsdesc volatile *td = 
+							(struct tlsdesc volatile *)reloc_addr;
+#ifndef SHARED
+					CHECK_STATIC_TLS((struct link_map *) tls_tpnt);
+#else
+					if (!TRY_STATIC_TLS ((struct link_map *) tls_tpnt))
+					{
+					        td->argument.pointer = _dl_make_tlsdesc_dynamic((struct link_map *) tls_tpnt, symbol_addr);
+					        td->entry = _dl_tlsdesc_dynamic;
+					}
+					else
+#endif
+					{
+					        td->argument.value = symbol_addr + tls_tpnt->l_tls_offset;
+					        td->entry = _dl_tlsdesc_return;
+					}
+				}
+				break;
+#endif
 			default:
 				return -1; /*call _dl_exit(1) */
 		}
 #if defined (__SUPPORT_LD_DEBUG__)
 		if (_dl_debug_reloc && _dl_debug_detail)
-			_dl_dprintf(_dl_debug_file, "\tpatch: %x ==> %x @ %x", old_val, *reloc_addr, reloc_addr);
+			_dl_dprintf(_dl_debug_file, "\tpatch: %x ==> %x @ %x", (unsigned int)old_val, (unsigned int)*reloc_addr, (unsigned int)reloc_addr);
 	}
 
 #endif
@@ -283,7 +317,7 @@ _dl_do_lazy_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope,
 		}
 #if defined (__SUPPORT_LD_DEBUG__)
 		if (_dl_debug_reloc && _dl_debug_detail)
-			_dl_dprintf(_dl_debug_file, "\tpatch: %x ==> %x @ %x", old_val, *reloc_addr, reloc_addr);
+			_dl_dprintf(_dl_debug_file, "\tpatch: %x ==> %x @ %x", (unsigned int)old_val, (unsigned int)*reloc_addr, (unsigned int)reloc_addr);
 	}
 
 #endif
diff --git a/ldso/ldso/nds32/resolve.S b/ldso/ldso/nds32/resolve.S
index 8c53850..e88d9ad 100644
--- a/ldso/ldso/nds32/resolve.S
+++ b/ldso/ldso/nds32/resolve.S
@@ -3,14 +3,6 @@
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#if defined(NDS32_ABI_2) || defined(NDS32_ABI_2FP)
-# define STACK_PUSH
-# define STACK_POP
-#else
-# define STACK_PUSH     addi   $sp,    $sp,    -24
-# define STACK_POP      addi   $sp,    $sp,    24
-#endif
-
  .text
  .align 4      ! 16 byte boundary
  .globl _dl_linux_resolve
@@ -28,22 +20,11 @@ _dl_linux_resolve:
 	smw.adm	$r0,	[$sp],	$r5,	6
 
 	! init gp
-#ifdef __NDS32_N1213_43U1H__
-	sethi	$gp,	HI20(_GLOBAL_OFFSET_TABLE_+4)
-	ori	$gp,	$gp,	LO12(_GLOBAL_OFFSET_TABLE_+8)
-	add	$gp,	$ta,	$gp
-#else
 	mfusr	$ta,	$PC
 	sethi	$gp,	HI20(_GLOBAL_OFFSET_TABLE_+4)
 	ori	$gp,	$gp,	LO12(_GLOBAL_OFFSET_TABLE_+8)
 	add	$gp,	$ta,	$gp
-#endif
 
-	! #ifdef __NDS32_ABI_1__
-	! adjust stack
-	!addi	$sp,	$sp,	-24
-	STACK_PUSH
-	! #endif
 
 	! set arguments
 	addi	$r0,	$r17,	0
@@ -61,11 +42,6 @@ _dl_linux_resolve:
 	! save the return
 	addi	$ta,	$r0,	0
 
-	! #ifdef __NDS32_ABI_1__
-	! adjust sp
-	!addi	$sp,	$sp,	24
-	STACK_POP
-	! #endif
 
 	! reload registers
 	lmw.bim	$r0,	[$sp],	$r5,	6
diff --git a/ldso/libdl/Makefile.in b/ldso/libdl/Makefile.in
index 24e00fa..3fd8a6c 100644
--- a/ldso/libdl/Makefile.in
+++ b/ldso/libdl/Makefile.in
@@ -33,7 +33,6 @@ libdl_SRC := $(libdl_DIR)/libdl.c
 libdl_OBJ := $(patsubst $(libdl_DIR)/%.c,$(libdl_OUT)/%.o,$(libdl_SRC))
 
 resolve := $(top_builddir)ldso/ldso/$(TARGET_ARCH)/resolve.o
-
 libdl-a-y := $(libdl_OBJ) $(resolve)
 ifeq ($(DOPIC),y)
 libdl-a-y := $(libdl-a-y:.o=.os)
diff --git a/libc/string/nds32/memcpy.S b/libc/string/nds32/memcpy.S
index 4f285b5..4da2c83 100644
--- a/libc/string/nds32/memcpy.S
+++ b/libc/string/nds32/memcpy.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Andes Technology, Inc.
+ * Copyright (C) 2016-2017 Andes Technology, Inc.
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
@@ -54,12 +54,32 @@ ENTRY(memcpy)
 	srli	$r3, $r2, #5
 	beqz	$r3, .Lword_copy_entry
 	pushm	$r6, $r13
+        cfi_adjust_cfa_offset(32)
+        cfi_rel_offset(r6, 0)
+        cfi_rel_offset(r7, 4)
+        cfi_rel_offset(r8, 8)
+        cfi_rel_offset(r9, 12)
+        cfi_rel_offset(r10, 16)
+        cfi_rel_offset(r11, 20)
+        cfi_rel_offset(r12, 24)
+        cfi_rel_offset(r13, 28)
+
 .L3:
 	lmw.bim	$r6, [$r1], $r13
 	addi	$r3, $r3, #-1
 	smw.bim	$r6, [$r0], $r13
 	bnez	$r3, .L3
 	popm	$r6, $r13
+        cfi_adjust_cfa_offset(-32)
+        cfi_restore(r6)
+        cfi_restore(r7)
+        cfi_restore(r8)
+        cfi_restore(r9)
+        cfi_restore(r10)
+        cfi_restore(r11)
+        cfi_restore(r12)
+        cfi_restore(r13)
+
 
 .Lword_copy_entry:
 	andi	$r2, $r2, #31
diff --git a/libc/string/nds32/memset.S b/libc/string/nds32/memset.S
index edd15a4..ba208f6 100644
--- a/libc/string/nds32/memset.S
+++ b/libc/string/nds32/memset.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Andes Technology, Inc.
+ * Copyright (C) 2016-2017 Andes Technology, Inc.
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
diff --git a/libc/sysdeps/linux/common/posix_fadvise.c b/libc/sysdeps/linux/common/posix_fadvise.c
index c4ebeaa..82a25d0 100644
--- a/libc/sysdeps/linux/common/posix_fadvise.c
+++ b/libc/sysdeps/linux/common/posix_fadvise.c
@@ -41,7 +41,7 @@ int posix_fadvise(int fd, off_t offset, off_t len, int advice)
 #  if __WORDSIZE == 64
 	ret = INTERNAL_SYSCALL(fadvise64_64, err, 4, fd, offset, len, advice);
 #  else
-#   if defined (__arm__) || \
+#   if defined (__arm__) || defined (__nds32__) || \
       (defined(__UCLIBC_SYSCALL_ALIGN_64BIT__) && (defined(__powerpc__) || defined(__xtensa__)))
 	/* arch with 64-bit data in even reg alignment #1: [powerpc/xtensa]
 	 * custom syscall handler (rearranges @advice to avoid register hole punch) */
diff --git a/libc/sysdeps/linux/common/posix_fadvise64.c b/libc/sysdeps/linux/common/posix_fadvise64.c
index eb722ec..b9a9d93 100644
--- a/libc/sysdeps/linux/common/posix_fadvise64.c
+++ b/libc/sysdeps/linux/common/posix_fadvise64.c
@@ -25,7 +25,7 @@ int posix_fadvise64(int fd, off64_t offset, off64_t len, int advice)
 	int ret;
 	INTERNAL_SYSCALL_DECL (err);
 	/* ARM has always been funky. */
-#if defined (__arm__) || \
+#if defined (__arm__) || defined (__nds32__) || \
     (defined(__UCLIBC_SYSCALL_ALIGN_64BIT__) && (defined(__powerpc__) || defined(__xtensa__)))
 	/* arch with 64-bit data in even reg alignment #1: [powerpc/xtensa]
 	 * custom syscall handler (rearranges @advice to avoid register hole punch) */
diff --git a/libc/sysdeps/linux/common/sync_file_range.c b/libc/sysdeps/linux/common/sync_file_range.c
index ed03d2f..faeae3c 100644
--- a/libc/sysdeps/linux/common/sync_file_range.c
+++ b/libc/sysdeps/linux/common/sync_file_range.c
@@ -28,7 +28,7 @@ static int __NC(sync_file_range)(int fd, off64_t offset, off64_t nbytes, unsigne
 	return INLINE_SYSCALL(sync_file_range, 6, fd,
 			OFF64_HI_LO(offset), OFF64_HI_LO(nbytes), flags);
 #  elif (defined __mips__ && _MIPS_SIM == _ABIO32) || \
-	(defined(__UCLIBC_SYSCALL_ALIGN_64BIT__) && !(defined(__powerpc__) || defined(__xtensa__)))
+	(defined(__UCLIBC_SYSCALL_ALIGN_64BIT__) && !(defined(__powerpc__) || defined(__xtensa__) || defined(__nds32__)))
 	/* arch with 64-bit data in even reg alignment #2: [arcv2/others-in-future]
 	 * stock syscall handler in kernel (reg hole punched)
 	 * see libc/sysdeps/linux/common/posix_fadvise.c for more details */
diff --git a/libc/sysdeps/linux/nds32/Makefile b/libc/sysdeps/linux/nds32/Makefile
index 633c91f..86a32a6 100644
--- a/libc/sysdeps/linux/nds32/Makefile
+++ b/libc/sysdeps/linux/nds32/Makefile
@@ -1,9 +1,5 @@
-# Makefile for uClibc
-#
-# Copyright (C) 2000-2005 Erik Andersen <andersen at uclibc.org>
-#
+# Makefile for uClibc-ng
 # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
-#
 
 top_srcdir=../../../../
 top_builddir=../../../../
diff --git a/libc/sysdeps/linux/nds32/Makefile.arch b/libc/sysdeps/linux/nds32/Makefile.arch
index 8691875..d5cdddb 100644
--- a/libc/sysdeps/linux/nds32/Makefile.arch
+++ b/libc/sysdeps/linux/nds32/Makefile.arch
@@ -1,5 +1,7 @@
 # Copyright (C) 2016 Andes Technology, Inc.
 # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
 
-CSRC-y := brk.c sigaction.c
-SSRC-y := setjmp.S __longjmp.S bsd-setjmp.S bsd-_setjmp.S clone.S mmap.S sigrestorer.S vfork.S sysdep.S syscall.S
+CSRC-y := brk.c prctl.c mremap.c syscall.c
+SSRC-y := setjmp.S __longjmp.S bsd-setjmp.S bsd-_setjmp.S clone.S vfork.S sysdep.S syscall.S
+CSRC-$(UCLIBC_HAS_CONTEXT_FUNCS) += makecontext.c swapcontext.c
+SSRC-$(UCLIBC_HAS_CONTEXT_FUNCS) += getcontext.S setcontext.S
diff --git a/libc/sysdeps/linux/nds32/__longjmp.S b/libc/sysdeps/linux/nds32/__longjmp.S
index fbea6f6..16c4dad 100644
--- a/libc/sysdeps/linux/nds32/__longjmp.S
+++ b/libc/sysdeps/linux/nds32/__longjmp.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Andes Technology, Inc.
+ * Copyright (C) 2016-2017 Andes Technology, Inc.
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
diff --git a/libc/sysdeps/linux/nds32/bits/atomic.h b/libc/sysdeps/linux/nds32/bits/atomic.h
new file mode 100644
index 0000000..f93fa7a
--- /dev/null
+++ b/libc/sysdeps/linux/nds32/bits/atomic.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2016-2017 Andes Technology, Inc.
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#ifndef _NDS32_BITS_ATOMIC_H
+#define _NDS32_BITS_ATOMIC_H
+
+#include <stdint.h>
+
+typedef int8_t atomic8_t;
+typedef uint8_t uatomic8_t;
+typedef int_fast8_t atomic_fast8_t;
+typedef uint_fast8_t uatomic_fast8_t;
+
+typedef int16_t atomic16_t;
+typedef uint16_t uatomic16_t;
+typedef int_fast16_t atomic_fast16_t;
+typedef uint_fast16_t uatomic_fast16_t;
+
+typedef int32_t atomic32_t;
+typedef uint32_t uatomic32_t;
+typedef int_fast32_t atomic_fast32_t;
+typedef uint_fast32_t uatomic_fast32_t;
+
+typedef int64_t atomic64_t;
+typedef uint64_t uatomic64_t;
+typedef int_fast64_t atomic_fast64_t;
+typedef uint_fast64_t uatomic_fast64_t;
+
+typedef intptr_t atomicptr_t;
+typedef uintptr_t uatomicptr_t;
+typedef intmax_t atomic_max_t;
+typedef uintmax_t uatomic_max_t;
+
+
+#ifndef atomic_full_barrier
+# define atomic_full_barrier() __asm__ ("dsb" ::: "memory")
+#endif
+
+#ifndef atomic_read_barrier
+# define atomic_read_barrier() atomic_full_barrier ()
+#endif
+
+#ifndef atomic_write_barrier
+# define atomic_write_barrier() atomic_full_barrier ()
+#endif
+
+#define atomic_exchange_acq(mem, newval)                    \
+  ({   unsigned long val, offset, temp;                     \
+                                                            \
+       __asm__ volatile (                                       \
+               "move   %2, %4\n\t"                          \
+               "move   %1, #0x0\n\t"                        \
+               "1:\n\t"                                     \
+               "llw    %0, [%3 + %1 << 0]\n\t"              \
+               "move   %2, %4\n\t"                          \
+               "scw    %2, [%3 + %1 << 0]\n\t"              \
+               "beqz   %2, 1b\n\t"                          \
+               : "=&r" (val), "=&r" (offset), "=&r" (temp)  \
+               : "r" (mem), "r" (newval)                    \
+               : "memory" );                                \
+       val; })
+
+#define atomic_compare_and_exchange_val_acq(mem, newval, oldval)  \
+  ({   unsigned long val, offset, temp;                     \
+                                                            \
+       __asm__ volatile (                                       \
+               "move   %1, #0x0\n\t"                        \
+               "move   %2, %4\n\t"                          \
+               "1:\n\t"                                     \
+               "llw    %0, [%3 + %1 << 0]\n\t"              \
+               "bne    %0, %5, 2f\n\t"                      \
+               "move   %2, %4\n\t"                          \
+               "scw    %2, [%3 + %1 << 0]\n\t"              \
+               "beqz   %2, 1b\n\t"                          \
+               "j      3f\n\t"                              \
+               "2:\n\t"                                     \
+               "move   %2, %0\n\t"                          \
+               "scw    %2, [%3 + %1 << 0]\n\t"              \
+               "3:\n\t"                                     \
+               : "=&r" (val), "=&r" (offset), "=&r" (temp)  \
+               : "r" (mem), "r" (newval), "r" (oldval)      \
+               : "memory" ); \
+       val; })
+
+#define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
+  ({   unsigned long val, offset, temp;                     \
+                                                            \
+       __asm__ volatile (                                       \
+               "move   %1, #0x0\n\t"                        \
+               "move   %2, %4\n\t"                          \
+               "1:\n\t"                                     \
+               "llw    %0, [%3 + %1 << 0]\n\t"              \
+               "bne    %5, %0, 2f\n\t"                      \
+               "move   %2, %4\n\t"                          \
+               "scw    %2, [%3 + %1 << 0]\n\t"              \
+               "beqz   %2, 1b\n\t"                          \
+               "addi   %0, %1, #0\n\t"                      \
+               "j      3f\n\t"                              \
+               "2:\n\t"                                     \
+               "scw    %0, [%3 + %1 << 0]\n\t"              \
+               "addi   %0, %1, #0x1\n\t"                    \
+               "3:\n\t"                                     \
+               : "=&r" (val), "=&r" (offset), "=&r" (temp)  \
+               : "r" (mem), "r" (newval), "r" (oldval)      \
+               : "memory" ); \
+       val; })
+
+#endif
diff --git a/libc/sysdeps/linux/nds32/bits/fcntl.h b/libc/sysdeps/linux/nds32/bits/fcntl.h
index d21c4e0..a936023 100644
--- a/libc/sysdeps/linux/nds32/bits/fcntl.h
+++ b/libc/sysdeps/linux/nds32/bits/fcntl.h
@@ -1,7 +1,11 @@
+/*
+ * Copyright (C) 2016-2017 Andes Technology, Inc.
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
 /* O_*, F_*, FD_* bit values for Linux.
    Copyright (C) 1995, 1996, 1997, 1998, 2000, 2004, 2007
    Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
diff --git a/libc/sysdeps/linux/nds32/bits/fenv.h b/libc/sysdeps/linux/nds32/bits/fenv.h
new file mode 100644
index 0000000..010d870
--- /dev/null
+++ b/libc/sysdeps/linux/nds32/bits/fenv.h
@@ -0,0 +1,79 @@
+/* Copyright (C) 2004-2012 Free Software Foundation, Inc.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _FENV_H
+# error "Never use <bits/fenv.h> directly; include <fenv.h> instead."
+#endif
+
+/* Define bits representing exceptions in the FPCSR status word.  */
+enum
+  {
+    FE_INVALID =
+#define FE_INVALID	0x4
+      FE_INVALID,
+    FE_DIVBYZERO =
+#define FE_DIVBYZERO	0x8
+      FE_DIVBYZERO,
+    FE_OVERFLOW =
+#define FE_OVERFLOW	0x10
+      FE_OVERFLOW,
+    FE_UNDERFLOW =
+#define FE_UNDERFLOW	0x20
+      FE_UNDERFLOW,
+    FE_INEXACT =
+#define FE_INEXACT	0x40
+      FE_INEXACT,
+  };
+
+
+/* All supported exceptions.  */
+#define FE_ALL_EXCEPT	\
+	(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT)
+
+/* Define bits representing rounding modes in the FPCSR RM field.  */
+enum
+  {
+    FE_TONEAREST =
+#define FE_TONEAREST    0x0
+      FE_TONEAREST,
+    FE_UPWARD =
+#define FE_UPWARD       0x1
+      FE_UPWARD,
+    FE_DOWNWARD =
+#define FE_DOWNWARD     0x2
+      FE_DOWNWARD,
+    FE_TOWARDZERO =
+#define FE_TOWARDZERO   0x3
+      FE_TOWARDZERO
+  };
+
+/* Type representing exception flags. */
+typedef unsigned int fexcept_t;
+
+/* Type representing floating-point environment.  */
+typedef struct
+  {
+    unsigned int __fpcsr;
+  }
+fenv_t;
+
+/* If the default argument is used we use this value.  */
+#define FE_DFL_ENV	((const fenv_t *) -1l)
+
+#ifdef __USE_GNU
+/* Floating-point environment where none of the exceptions are masked.  */
+# define FE_NOMASK_ENV  ((const fenv_t *) -2)
+#endif
diff --git a/libc/sysdeps/linux/nds32/bits/mman.h b/libc/sysdeps/linux/nds32/bits/mman.h
index 13f3e60..ac242e0 100644
--- a/libc/sysdeps/linux/nds32/bits/mman.h
+++ b/libc/sysdeps/linux/nds32/bits/mman.h
@@ -103,4 +103,5 @@
 /* Flags for `mremap'.  */
 #ifdef __USE_GNU
 # define MREMAP_MAYMOVE	1
+# define MREMAP_FIXED	2
 #endif
diff --git a/libc/sysdeps/linux/nds32/bits/setjmp.h b/libc/sysdeps/linux/nds32/bits/setjmp.h
index 92d8900..e287c24 100644
--- a/libc/sysdeps/linux/nds32/bits/setjmp.h
+++ b/libc/sysdeps/linux/nds32/bits/setjmp.h
@@ -24,19 +24,25 @@
 #ifndef _BITS_SETJMP_H
 #define _BITS_SETJMP_H  1
 
-#ifndef _SETJMP_H
+#if !defined _SETJMP_H && !defined _PTHREAD_H
 # error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
 #endif
 
 #ifndef _ASM
 typedef struct
   {
-    /* Callee-saved registers r6 - r14, r16 - r19 and r28 - r31.  */
-    int __regs[31];
+    /* Callee-saved registers: r6 - r14,
+ *      * fp, gp, lp, sp: r28 - r31.  */
+    int __regs[13];
+
+    /* Floating-Point Configuration Register.  */
+    int __fpcfg;
+
+    /* Callee-saved fp registers pointer.  */
+    int __fpregs[32];
+
+  } __jmp_buf[1] __attribute__((__aligned__ (8)));
 
-    /* Program counter.  */
-    void * __pc;
-  } __jmp_buf[1];
 #endif
 
 #endif  /* bits/setjmp.h */
diff --git a/libc/sysdeps/linux/nds32/bits/sigcontext.h b/libc/sysdeps/linux/nds32/bits/sigcontext.h
deleted file mode 100644
index e91f6a9..0000000
--- a/libc/sysdeps/linux/nds32/bits/sigcontext.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2016 Andes Technology, Inc.
- * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
- */
-
-#ifndef _BITS_SIGCONTEXT_H
-#define _BITS_SIGCONTEXT_H 1
-
-#ifndef sigcontext_struct
-#define sigcontext_struct sigcontext
-
-struct sigcontext{
-        unsigned long trap_no;
-        unsigned long error_code;
-        unsigned long oldmask;
-        unsigned long nds32_r0;
-        unsigned long nds32_r1;
-        unsigned long nds32_r2;
-        unsigned long nds32_r3;
-        unsigned long nds32_r4;
-        unsigned long nds32_r5;
-        unsigned long nds32_r6;
-        unsigned long nds32_r7;
-        unsigned long nds32_r8;
-        unsigned long nds32_r9;
-        unsigned long nds32_r10;
-        unsigned long nds32_r11;
-        unsigned long nds32_r12;
-        unsigned long nds32_r13;
-        unsigned long nds32_r14;
-        unsigned long nds32_r15;
-        unsigned long nds32_r16;
-        unsigned long nds32_r17;
-        unsigned long nds32_r18;
-        unsigned long nds32_r19;
-	unsigned long nds32_r20;
-	unsigned long nds32_r21;
-	unsigned long nds32_r22;
-	unsigned long nds32_r23;
-	unsigned long nds32_r24;
-	unsigned long nds32_r25;
-        unsigned long nds32_fp;   //r28
-        unsigned long nds32_gp;   //r29
-        unsigned long nds32_lp;   //r30
-        unsigned long nds32_sp;   //r31
-        unsigned long nds32_d1lo;
-        unsigned long nds32_d1hi;
-        unsigned long nds32_d0lo;
-        unsigned long nds32_d0hi;
-        unsigned long nds32_ipsw;
-        unsigned long nds32_ipc;
-        unsigned long fault_address;
-};
-
-#define sc_pc  nds32_ipc /* For sysdeps/generic/profil-counter.h.  */
-
-#endif /* sigcontext_struct  */
-
-#endif /* _BITS_SIGCONTEXT_H  */
diff --git a/libc/sysdeps/linux/nds32/bits/sigcontextinfo.h b/libc/sysdeps/linux/nds32/bits/sigcontextinfo.h
new file mode 100644
index 0000000..f3237bd
--- /dev/null
+++ b/libc/sysdeps/linux/nds32/bits/sigcontextinfo.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016-2017 Andes Technology, Inc.
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/* Copyright (C) 1999-2013 Free Software Foundation, Inc.
+   Contributed by Philip Blundell <philb at gnu.org>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sys/ucontext.h>
+
+#define SIGCONTEXT siginfo_t *_si, struct ucontext *
+#define SIGCONTEXT_EXTRA_ARGS _si,
+
+#define GET_PC(ctx)	((void *) (ctx)->uc_mcontext.nds32_ipc)
+#define GET_FRAME(ctx)	ADVANCE_STACK_FRAME ((void *) ctx->uc_mcontext.nds32_fp)
+#define GET_STACK(ctx)	((void *) (ctx)->uc_mcontext.nds32_sp)
+
+
+#define CALL_SIGHANDLER(handler, signo, ctx) \
+  (handler)((signo), SIGCONTEXT_EXTRA_ARGS (ctx))
+
diff --git a/libc/sysdeps/linux/nds32/bits/syscalls.h b/libc/sysdeps/linux/nds32/bits/syscalls.h
index f69ad4c..215ce34 100644
--- a/libc/sysdeps/linux/nds32/bits/syscalls.h
+++ b/libc/sysdeps/linux/nds32/bits/syscalls.h
@@ -3,6 +3,26 @@
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
+/*
+ * For nds32 ISA, the syscall number(SWID) shall be determined at compile time.
+ * (ex: asm("syscall SWID"); )
+ * If the value of syscall number is determined at run time, we shall issue
+ * this syscall through sys_syscall.
+ * (ex:
+ *     asm("move $r0, SYSCALL_number"
+ *         "syscall 0x5071");
+ *     where 0x5071 is syscall number for sys_syscall
+ * )
+ *
+ * The following two macros are implemented according that syscall number
+ * is determined in compiler time or run time,
+ *
+ * 1. INTERNAL_SYSCALL_NCS: the syscall number is determined at run time
+ * 2. INTERNAL_SYSCALL: the syscall number is determined at compile time
+ *
+ */
+
+
 #ifndef _BITS_SYSCALLS_H
 #define _BITS_SYSCALLS_H
 #ifndef _SYSCALL_H
@@ -11,6 +31,14 @@
 
 #ifndef __ASSEMBLER__
 #include <errno.h>
+#include <common/sysdep.h>
+
+#define X(x) #x
+#define Y(x) X(x)
+#define        LIB_SYSCALL    __NR_syscall
+
+#define __issue_syscall(syscall_name)                   		\
+"       syscall  "  Y(syscall_name) ";	\n"
 
 #undef INTERNAL_SYSCALL_ERROR_P
 #define INTERNAL_SYSCALL_ERROR_P(val, err) ((unsigned int) (val) >= 0xfffff001u)
@@ -18,86 +46,258 @@
 #undef INTERNAL_SYSCALL_ERRNO
 #define INTERNAL_SYSCALL_ERRNO(val, err)	(-(val))
 
-#define X(x) #x
-#define Y(x) X(x)
+#undef INLINE_SYSCALL
+#define INLINE_SYSCALL(name, nr, args...)                        	\
+  ({                                                             	\
+     INTERNAL_SYSCALL_DECL (err);                                	\
+     long result_var = INTERNAL_SYSCALL (name, err, nr, args);   	\
+     if (INTERNAL_SYSCALL_ERROR_P (result_var, err))             	\
+       {                                                         	\
+         __set_errno (INTERNAL_SYSCALL_ERRNO (result_var, err)); 	\
+			result_var = -1 ;			 	\
+       }                                                         	\
+     result_var;                                                 	\
+  })
+
+
+#undef INTERNAL_SYSCALL_DECL
+#define INTERNAL_SYSCALL_DECL(err) do { } while (0)
+
 
-#define __issue_syscall(syscall_name)                   \
-"       syscall  "  Y(syscall_name) ";                    \n"
-
-#define INTERNAL_SYSCALL_NCS(name, err, nr, args...)	\
-(__extension__ 						\
-({							\
-	register long __result __asm__("$r0");		\
-	register long _sys_num __asm__("$r8");		\
-							\
-	LOAD_ARGS_##nr (name, args)			\
-        _sys_num = (name);				\
-							\
-        __asm__ volatile (				\
-		__issue_syscall (name)                  \
-		: "=r" (__result)			\
-		: "r"(_sys_num) ASM_ARGS_##nr		\
-		: "$lp", "memory");			\
-	__result;					\
-}) \
-)
-
-/* Macros for setting up inline __asm__ input regs */
-#define ASM_ARGS_0
-#define ASM_ARGS_1	ASM_ARGS_0, "r" (__result)
-#define ASM_ARGS_2	ASM_ARGS_1, "r" (_arg2)
-#define ASM_ARGS_3	ASM_ARGS_2, "r" (_arg3)
-#define ASM_ARGS_4	ASM_ARGS_3, "r" (_arg4)
-#define ASM_ARGS_5	ASM_ARGS_4, "r" (_arg5)
-#define ASM_ARGS_6	ASM_ARGS_5, "r" (_arg6)
-#define ASM_ARGS_7	ASM_ARGS_6, "r" (_arg7)
-
-/* Macros for converting sys-call wrapper args into sys call args */
-#define LOAD_ARGS_0(name, arg)					\
-	_sys_num = (long) (name);				\
-
-#define LOAD_ARGS_1(name, arg1)					\
-	__result = (long) (arg1);					\
-	LOAD_ARGS_0 (name, arg1)
+#undef INTERNAL_SYSCALL
+#define INTERNAL_SYSCALL(name, err, nr, args...) internal_syscall##nr(__NR_##name, err, args)
 
 /*
- * Note that the use of _tmpX might look superflous, however it is needed
- * to ensure that register variables are not clobbered if arg happens to be
- * a function call itself. e.g. sched_setaffinity() calling getpid() for arg2
- *
- * Also this specific order of recursive calling is important to segregate
- * the tmp args evaluation (function call case described above) and assigment
- * of register variables
- */
-#define LOAD_ARGS_2(name, arg1, arg2)				\
-	long _tmp2 = (long) (arg2);				\
-	LOAD_ARGS_1 (name, arg1)				\
-	register long _arg2 __asm__ ("$r1") = _tmp2;
-
-#define LOAD_ARGS_3(name, arg1, arg2, arg3)			\
-	long _tmp3 = (long) (arg3);				\
-	LOAD_ARGS_2 (name, arg1, arg2)				\
-	register long _arg3 __asm__ ("$r2") = _tmp3;
-
-#define LOAD_ARGS_4(name, arg1, arg2, arg3, arg4)		\
-	long _tmp4 = (long) (arg4);				\
-	LOAD_ARGS_3 (name, arg1, arg2, arg3)			\
-	register long _arg4 __asm__ ("$r3") = _tmp4;
-
-#define LOAD_ARGS_5(name, arg1, arg2, arg3, arg4, arg5)		\
-	long _tmp5 = (long) (arg5);				\
-	LOAD_ARGS_4 (name, arg1, arg2, arg3, arg4)		\
-	register long _arg5 __asm__ ("$r4") = _tmp5;
-
-#define LOAD_ARGS_6(name,  arg1, arg2, arg3, arg4, arg5, arg6)	\
-	long _tmp6 = (long) (arg6);				\
-	LOAD_ARGS_5 (name, arg1, arg2, arg3, arg4, arg5)	\
-	register long _arg6 __asm__ ("$r5") = _tmp6;
-
-#define LOAD_ARGS_7(name, arg1, arg2, arg3, arg4, arg5, arg6, arg7)\
-	long _tmp7 = (long) (arg7);				\
-	LOAD_ARGS_6 (name, arg1, arg2, arg3, arg4, arg5, arg6)	\
-	register long _arg7 __asm__ ("$r6") = _tmp7;
+   The _NCS variant allows non-constant syscall numbers but it is not
+   possible to use more than four parameters.
+*/
+#undef INTERNAL_SYSCALL_NCS
+#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) internal_syscall_ncs##nr(name, err, args)
+
+
+#define internal_syscall0(name, err, dummy...)                   	\
+  ({                                                             	\
+       register long ___res  __asm__("$r0");               		\
+       __asm__ volatile (                                        	\
+       __issue_syscall (name)                                    	\
+       : "=r" (___res)         /* output operands  */             	\
+       :							 	\
+       : __SYSCALL_CLOBBERS); /* list of clobbered registers  */ 	\
+       ___res;							 	\
+  })
+
+#define internal_syscall1(name, err, arg1)                       	\
+  ({                                                             	\
+       register long ___res  __asm__("$r0");                         	\
+       register long __arg1 __asm__("$r0") = (long) (arg1);         	\
+       __asm__ volatile (                                        	\
+       __issue_syscall (name)                                    	\
+       : "=r" (___res)         /* output operands  */             	\
+       : "r" (__arg1)         /* input operands  */              	\
+       : __SYSCALL_CLOBBERS); /* list of clobbered registers  */ 	\
+        ___res;                                                   	\
+  })
+
+#define internal_syscall2(name, err, arg1, arg2)                 	\
+  ({                                                             	\
+       register long ___res  __asm__("$r0");                         	\
+       register long __arg1 __asm__("$r0") = (long) (arg1);         	\
+       register long __arg2 __asm__("$r1") = (long) (arg2);         	\
+       __asm__ volatile (                                        	\
+       __issue_syscall (name)                                    	\
+       : "=r" (___res)         /* output operands  */             	\
+       : "r" (__arg1)         /* input operands  */              	\
+       , "r" (__arg2)         /* input operands  */              	\
+       : __SYSCALL_CLOBBERS); /* list of clobbered registers  */ 	\
+        ___res;                                                   	\
+  })
+
+#define internal_syscall3(name, err, arg1, arg2, arg3)           	\
+  ({                                                             	\
+       register long ___res  __asm__("$r0");                         	\
+       register long __arg1 __asm__("$r0") = (long) (arg1);         	\
+       register long __arg2 __asm__("$r1") = (long) (arg2);         	\
+       register long __arg3 __asm__("$r2") = (long) (arg3);         	\
+       __asm__ volatile (                                        	\
+       __issue_syscall (name)                                    	\
+       : "=r" (___res)         /* output operands  */             	\
+       : "r" (__arg1)         /* input operands  */              	\
+       , "r" (__arg2)         /* input operands  */              	\
+       , "r" (__arg3)         /* input operands  */              	\
+       : __SYSCALL_CLOBBERS); /* list of clobbered registers  */ 	\
+        ___res;                                                   	\
+  })
+
+#define internal_syscall4(name, err, arg1, arg2, arg3, arg4)     	\
+  ({                                                             	\
+       register long ___res  __asm__("$r0");                         	\
+       register long __arg1 __asm__("$r0") = (long) (arg1);         	\
+       register long __arg2 __asm__("$r1") = (long) (arg2);         	\
+       register long __arg3 __asm__("$r2") = (long) (arg3);         	\
+       register long __arg4 __asm__("$r3") = (long) (arg4);         	\
+       __asm__ volatile (                                        	\
+       __issue_syscall (name)                                    	\
+       : "=r" (___res)         /* output operands  */             	\
+       : "r" (__arg1)         /* input operands  */              	\
+       , "r" (__arg2)         /* input operands  */              	\
+       , "r" (__arg3)         /* input operands  */              	\
+       , "r" (__arg4)         /* input operands  */              	\
+       : __SYSCALL_CLOBBERS); /* list of clobbered registers  */ 	\
+        ___res;                                                   	\
+  })
+
+#define internal_syscall5(name, err, arg1, arg2, arg3, arg4, arg5) 	\
+  ({                                                             	\
+       register long ___res  __asm__("$r0");                         	\
+       register long __arg1 __asm__("$r0") = (long) (arg1);         	\
+       register long __arg2 __asm__("$r1") = (long) (arg2);         	\
+       register long __arg3 __asm__("$r2") = (long) (arg3);         	\
+       register long __arg4 __asm__("$r3") = (long) (arg4);         	\
+       register long __arg5 __asm__("$r4") = (long) (arg5);         	\
+       __asm__ volatile (                                        	\
+       __issue_syscall (name)                                    	\
+       : "=r" (___res)         /* output operands  */             	\
+       : "r" (__arg1)         /* input operands  */              	\
+       , "r" (__arg2)         /* input operands  */              	\
+       , "r" (__arg3)         /* input operands  */              	\
+       , "r" (__arg4)         /* input operands  */              	\
+       , "r" (__arg5)         /* input operands  */              	\
+       : __SYSCALL_CLOBBERS); /* list of clobbered registers  */ 	\
+        ___res;                                                   	\
+  })
+
+#define internal_syscall6(name, err, arg1, arg2, arg3, arg4, arg5, arg6) 	\
+  ({                                                             		\
+       register long ___res  __asm__("$r0");                         		\
+       register long __arg1 __asm__("$r0") = (long) (arg1);         		\
+       register long __arg2 __asm__("$r1") = (long) (arg2);         		\
+       register long __arg3 __asm__("$r2") = (long) (arg3);         		\
+       register long __arg4 __asm__("$r3") = (long) (arg4);         		\
+       register long __arg5 __asm__("$r4") = (long) (arg5);         		\
+       register long __arg6 __asm__("$r5") = (long) (arg6);         		\
+       __asm__ volatile (                                        		\
+       __issue_syscall (name)                                    		\
+       : "=r" (___res)         /* output operands  */             		\
+       : "r" (__arg1)         /* input operands  */              		\
+       , "r" (__arg2)         /* input operands  */              		\
+       , "r" (__arg3)         /* input operands  */              		\
+       , "r" (__arg4)         /* input operands  */              		\
+       , "r" (__arg5)         /* input operands  */              		\
+       , "r" (__arg6)         /* input operands  */              		\
+       : __SYSCALL_CLOBBERS); /* list of clobbered registers  */ 		\
+        ___res;                                                   		\
+  })
+#define internal_syscall7(name, err, arg1, arg2, arg3, arg4, arg5, arg6, arg7) 	\
+  ({                                                             		\
+       register long ___res  __asm__("$r0");                         		\
+       register long __arg1 __asm__("$r0") = (long) (arg1);         		\
+       register long __arg2 __asm__("$r1") = (long) (arg2);         		\
+       register long __arg3 __asm__("$r2") = (long) (arg3);         		\
+       register long __arg4 __asm__("$r3") = (long) (arg4);         		\
+       register long __arg5 __asm__("$r4") = (long) (arg5);         		\
+       register long __arg6 __asm__("$r5") = (long) (arg6);         		\
+       __asm__ volatile (                                        		\
+	"addi10.sp\t  #-4\n\t"							\
+	CFI_ADJUST_CFA_OFFSET(4)"\n\t"						\
+        "push\t %7\n\t"								\
+	CFI_ADJUST_CFA_OFFSET(4)"\n\t"						\
+       __issue_syscall (name)                                    		\
+	"addi10.sp\t  #4\n\t"							\
+	CFI_ADJUST_CFA_OFFSET(-4)"\n\t"						\
+        "pop\t %7\n\t"								\
+	CFI_ADJUST_CFA_OFFSET(-4)"\n\t"						\
+       : "=r" (___res)         /* output operands  */             		\
+       : "r" (__arg1)         /* input operands  */              		\
+       , "r" (__arg2)         /* input operands  */              		\
+       , "r" (__arg3)         /* input operands  */              		\
+       , "r" (__arg4)         /* input operands  */              		\
+       , "r" (__arg5)         /* input operands  */              		\
+       , "r" (__arg6)         /* input operands  */              		\
+       , "r" (arg7)         /* input operands  */              		\
+       : __SYSCALL_CLOBBERS); /* list of clobbered registers  */ 		\
+        ___res;                                                   		\
+  })
+
+#define internal_syscall_ncs0(name, err, dummy...)               	\
+  ({                                                             	\
+       register long __res  __asm__("$r0");                         	\
+       register long __no   __asm__("$r0") = (long) (name);         	\
+       __asm__ volatile (                                        	\
+       __issue_syscall (LIB_SYSCALL)                             	\
+       : "=r" (__res)         /* output operands  */             	\
+       : "r" (__no)           /* input operands  */              	\
+       : __SYSCALL_CLOBBERS); /* list of clobbered registers  */ 	\
+       __res;							 	\
+  })
+
+#define internal_syscall_ncs1(name, err, arg1)                   	\
+  ({                                                             	\
+       register long __res  __asm__("$r0");                         	\
+       register long __no   __asm__("$r0") = (long) (name);         	\
+       register long __arg1 __asm__("$r1") = (long) (arg1);         	\
+       __asm__ volatile (                                        	\
+       __issue_syscall (LIB_SYSCALL)                             	\
+       : "=r" (__res)         /* output operands  */             	\
+       : "r" (__arg1)         /* input operands  */              	\
+       , "r" (__no)           /* input operands  */              	\
+       : __SYSCALL_CLOBBERS); /* list of clobbered registers  */ 	\
+        __res;                                                   	\
+  })
+
+#define internal_syscall_ncs2(name, err, arg1, arg2)             	\
+  ({                                                             	\
+       register long __res  __asm__("$r0");                         	\
+       register long __no   __asm__("$r0") = (long) (name);         	\
+       register long __arg1 __asm__("$r1") = (long) (arg1);         	\
+       register long __arg2 __asm__("$r2") = (long) (arg2);         	\
+       __asm__ volatile (                                        	\
+       __issue_syscall (LIB_SYSCALL)                             	\
+       : "=r" (__res)         /* output operands  */             	\
+       : "r" (__arg1)         /* input operands  */              	\
+       , "r" (__arg2)         /* input operands  */              	\
+       , "r" (__no)           /* input operands  */              	\
+       : __SYSCALL_CLOBBERS); /* list of clobbered registers  */ 	\
+        __res;                                                   	\
+  })
+
+#define internal_syscall_ncs3(name, err, arg1, arg2, arg3)      	\
+  ({                                                            	\
+       register long __res  __asm__("$r0");                     	\
+       register long __no   __asm__("$r0") = (long) (name);     	\
+       register long __arg1 __asm__("$r1") = (long) (arg1);     	\
+       register long __arg2 __asm__("$r2") = (long) (arg2);     	\
+       register long __arg3 __asm__("$r3") = (long) (arg3);     	\
+       __asm__ volatile (                                       	\
+       __issue_syscall (LIB_SYSCALL)                            	\
+       : "=r" (__res)         /* output operands  */            	\
+       : "r" (__arg1)         /* input operands  */             	\
+       , "r" (__arg2)         /* input operands  */             	\
+       , "r" (__arg3)         /* input operands  */             	\
+       , "r" (__no)           /* input operands  */             	\
+       : __SYSCALL_CLOBBERS); /* list of clobbered registers  */	\
+        __res;                                                  	\
+  })
+
+#define internal_syscall_ncs4(name, err, arg1, arg2, arg3, arg4) 	\
+  ({                                                             	\
+       register long __res  __asm__("$r0");                      	\
+       register long __no   __asm__("$r0") = (long) (name);      	\
+       register long __arg1 __asm__("$r1") = (long) (arg1);      	\
+       register long __arg2 __asm__("$r2") = (long) (arg2);      	\
+       register long __arg3 __asm__("$r3") = (long) (arg3);      	\
+       register long __arg4 __asm__("$r4") = (long) (arg4);      	\
+       __asm__ volatile (                                        	\
+       __issue_syscall (LIB_SYSCALL)                             	\
+       : "=r" (__res)         /* output operands  */             	\
+       : "r" (__arg1)         /* input operands  */              	\
+       , "r" (__arg2)         /* input operands  */              	\
+       , "r" (__arg3)         /* input operands  */              	\
+       , "r" (__arg4)         /* input operands  */              	\
+       , "r" (__no)           /* input operands  */              	\
+       : __SYSCALL_CLOBBERS); /* list of clobbered registers  */ 	\
+        __res;                                                   	\
+  })
 
+#define __SYSCALL_CLOBBERS "$lp", "memory"
 #endif /* ! __ASSEMBLER__  */
 #endif /* _BITS_SYSCALLS_H */
diff --git a/libc/sysdeps/linux/nds32/bits/uClibc_arch_features.h b/libc/sysdeps/linux/nds32/bits/uClibc_arch_features.h
index 12e4af9..5c4f634 100644
--- a/libc/sysdeps/linux/nds32/bits/uClibc_arch_features.h
+++ b/libc/sysdeps/linux/nds32/bits/uClibc_arch_features.h
@@ -11,7 +11,7 @@
 #define _BITS_UCLIBC_ARCH_FEATURES_H
 
 /* instruction used when calling abort() to kill yourself */
-#undef __UCLIBC_ABORT_INSTRUCTION__
+#define __UCLIBC_ABORT_INSTRUCTION__ "bal abort"
 
 /* does your target align 64bit values in register pairs ? (32bit arches only) */
 #define __UCLIBC_SYSCALL_ALIGN_64BIT__
diff --git a/libc/sysdeps/linux/nds32/bsd-_setjmp.S b/libc/sysdeps/linux/nds32/bsd-_setjmp.S
index a7ab1c7..745f109 100644
--- a/libc/sysdeps/linux/nds32/bsd-_setjmp.S
+++ b/libc/sysdeps/linux/nds32/bsd-_setjmp.S
@@ -21,8 +21,8 @@ ENTRY(_setjmp)
 	add     $r2, $r15, $r2
 
 	! la    $r3, __sigsetjmp at PLT
-	sethi   $r3, hi20(__sigsetjmp at PLT)
-	ori     $r3, $r3, lo12(__sigsetjmp at PLT)
+	sethi   $r3, hi20(HIDDEN_JUMPTARGET(__sigsetjmp)@PLT)
+	ori     $r3, $r3, lo12(HIDDEN_JUMPTARGET(__sigsetjmp)@PLT)
 	add     $r3, $r3, $r2
 
 	jr      $r3
@@ -32,4 +32,3 @@ ENTRY(_setjmp)
 #endif
 
 END(_setjmp)
-libc_hidden_def(_setjmp)
diff --git a/libc/sysdeps/linux/nds32/bsd-setjmp.S b/libc/sysdeps/linux/nds32/bsd-setjmp.S
index b00e62d..e1f7c83 100644
--- a/libc/sysdeps/linux/nds32/bsd-setjmp.S
+++ b/libc/sysdeps/linux/nds32/bsd-setjmp.S
@@ -21,8 +21,8 @@ ENTRY(setjmp)
 	add     $r2, $r15, $r2
 
 	! la    $r3, __sigsetjmp at PLT
-	sethi   $r3, hi20(__sigsetjmp at PLT)
-	ori     $r3, $r3, lo12(__sigsetjmp at PLT)
+	sethi   $r3, hi20(HIDDEN_JUMPTARGET(__sigsetjmp)@PLT)
+	ori     $r3, $r3, lo12(HIDDEN_JUMPTARGET(__sigsetjmp)@PLT)
 	add     $r3, $r3, $r2
 
 	jr      $r3
diff --git a/libc/sysdeps/linux/nds32/clone.S b/libc/sysdeps/linux/nds32/clone.S
index 5dba178..1ed77fb 100644
--- a/libc/sysdeps/linux/nds32/clone.S
+++ b/libc/sysdeps/linux/nds32/clone.S
@@ -1,92 +1,180 @@
 /*
- * Copyright (C) 2016 Andes Technology, Inc.
+ * Copyright (C) 2016-2017 Andes Technology, Inc.
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
+/* Copyright (C) 2010-2014 Free Software Foundation, Inc.
+   Contributed by Pat Beirne <patb at corelcomputer.com>
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
 /* clone() is even more special than fork() as it mucks with stacks
    and invokes a function in the right context after its all over.  */
 
 #include <sysdep.h>
-#include <sys/syscall.h>
 #define _ERRNO_H	1
 #include <bits/errno.h>
 
-/*
-       int clone(int (*fn)(void *), void *child_stack, int flags, void *arg);
-       _syscall2(int, clone, int, flags, void *, child_stack)
-*/
+#ifdef RESET_PID
+#include <tcb-offsets.h>
+#endif
+
+#define CLONE_VM      0x00000100
+#define CLONE_THREAD  0x00010000
+
+/* int clone(int (*fn)(void *), void *child_stack, int flags, void *arg);
+   _syscall2(int, clone, int, flags, void *, child_stack)  */
 
 ENTRY(__clone)
+#ifdef __NDS32_ABI_2FP_PLUS__
+	lwi	$r4, [$sp]
+	lwi	$r5, [$sp+4]
+#endif
 #ifdef PIC
 	/* set GP register to parent only, cause child's $SP will be $r1. */
 	pushm	$fp, $gp
-#ifndef __NDS32_N1213_43U1H__
-	mfusr $r15, $PC
-#endif
-	sethi	$gp,	hi20(_GLOBAL_OFFSET_TABLE_+4)
-	ori	$gp,	$gp,	lo12(_GLOBAL_OFFSET_TABLE_+8)
-	add	$gp,	$gp,	$r15
-#endif
-        /* sanity check arguments.  */
-        beqz    $r0, 1f
-        bnez    $r1, 2f
+	cfi_adjust_cfa_offset(8)
+	cfi_rel_offset(fp, 0)
+	cfi_rel_offset(gp, 4)
+	mfusr	$r15, $pc
+	sethi	$gp, hi20(_GLOBAL_OFFSET_TABLE_+4)
+	ori	$gp, $gp, lo12(_GLOBAL_OFFSET_TABLE_+8)
+	add	$gp, $gp, $r15
+#endif /* PIC  */
+
+	/* sanity check arguments.  */
+	beqz	$r0, 1f
+	bnez	$r1, 2f
 
 1:
-        movi    $r0, -EINVAL
+	movi	$r0, -EINVAL
+
 5:
 #ifdef PIC
-		  /* restore GP register, only in parent's stack */
-		  popm	$fp, $gp
-        la      $r15, C_SYMBOL_NAME(__syscall_error at PLT)
-        jr      $r15
-#else
-        b       C_SYMBOL_NAME(__syscall_error)
-#endif
+	/* restore GP register, only in parent's stack  */
+	la	$r15, C_SYMBOL_NAME(__syscall_error at PLT)
+	push	$lp
+	cfi_adjust_cfa_offset(4)
+	cfi_rel_offset(lp, 0)
+	addi	$sp, $sp, -4
+	cfi_adjust_cfa_offset(4)
+	jral	$r15
+	addi	$sp, $sp, 4
+	cfi_adjust_cfa_offset(-4)
+	pop	$lp
+	cfi_adjust_cfa_offset(-4)
+	cfi_restore(lp)
+	popm	$fp, $gp
+	cfi_adjust_cfa_offset(-8)
+	cfi_restore(fp)
+	cfi_restore(gp)
+	ret
+#else /* ! PIC  */
+	la	$r15, C_SYMBOL_NAME(__syscall_error)
+	jr	$r15
+#endif /* ! PIC  */
 
 2:
-	/* Child's $SP will be $r1, push to child's stack only. */
+	/* Child's $sp will be $r1, make $sp 8-byte alignment */
+	bitci	$r1, $r1, 7
+	/* push to child's stack only.  */
 	addi	$r1, $r1, -4
-        swi.p   $r3, [$r1], -4  ! arg
-        swi     $r0, [$r1]  ! fn
+	swi.p	$r3, [$r1], -4			! arg
+	swi	$r0, [$r1]			! fn
+
+	/* do the system call  */
+	or	$r0, $r2, $r2			! move $r0, $r2
+
+	move    $r3, $r5
+	move    $r5, $r2                        ! Use $r5 to backup $r2
+						! The pt_regs is placed in $r5 in kerenl (sys_clone_wrapper)
+	move    $r2, $r4
 
-        /* do the system call */
-        or      $r0, $r2, $r2   ! move r0, r2
-        __do_syscall(clone)
-	!syscall (__NR_clone)
-        beqz    $r0, 4f
-        bltz    $r0, 5b
+#ifdef __NDS32_ABI_2FP_PLUS__
+# ifdef PIC
+       lwi     $r4, [$sp+#0x10]
+# else
+       lwi     $r4, [$sp+#0x8]
+# endif
+#else
+# ifdef PIC
+       lwi     $r4, [$sp+#0x8]
+# else
+       lwi     $r4, [$sp]
+# endif
+#endif
+
+	__do_syscall(clone)
+	beqz    $r0, 4f
+	bltz    $r0, 5b
 
-        ! parent
+
+10:
 #ifdef PIC
-	/* restore GP register, only in parent's stack */
+	/* restore GP register, only in parent's stack  */
 	popm	$fp, $gp
-#endif
-        ret
+	cfi_adjust_cfa_offset(-8)
+	cfi_restore(gp)
+	cfi_restore(fp)
+#endif /* PIC  */
+	ret
 
+#ifdef RESET_PID
 4:
-	/* Only in child's stack. */
-        pop     $r1  ! fn
-        pop     $r0  ! arg
-#if defined(NDS32_ABI_2) || defined(NDS32_ABI_2FP)
+	cfi_undefined(lp)
+	movi	$r0, CLONE_THREAD		! Skip when CLONE_THREAD is set.
+	and	$r0, $r5, $r0
+	bnez	$r0, 8f
+	movi    $r0, CLONE_VM			! Value = -1 when CLONE_VM is set.
+	and	$r0, $r5, $r0
+	beqz	$r0, 6f
+	movi	$r0, -1
+	j	7f
+6:
+        __do_syscall(getpid) ! __do_syscall(gettid) ! __do_syscall(getpid)
+7:
+	swi     $r0, [$r25 + PID_OFFSET]
+        swi     $r0, [$r25 + TID_OFFSET]
+8:
 #else
-	addi	$sp, $sp, -24
-#endif
-	! use r15 in case _exit is PIC
-#ifdef __NDS32_N1213_43U1H__
-        or      $r15, $r1, $r1   ! move r15, r2
+4:
 #endif
-        bral    $r1
-#if defined(NDS32_ABI_2) || defined(NDS32_ABI_2FP)
-#else
+	/* Only in child's stack.  */
+	pop	$r1				! fn
+	pop	$r0				! arg
+
+
+#if !defined(__NDS32_ABI_2__) && !defined(__NDS32_ABI_2FP_PLUS__)
+	addi	$sp, $sp, -24
+#endif /* !defined(__NDS32_ABI_2__) && !defined(__NDS32_ABI_2FP_PLUS__)  */
+
+	! use $r15 in case _exit is PIC
+	bral	$r1
+
+#if !defined(__NDS32_ABI_2__) && !defined(__NDS32_ABI_2FP_PLUS__)
 	addi	$sp, $sp, 24
-#endif
-	! use r15 in case _exit is PIC
+#endif /* !defined(__NDS32_ABI_2__) && !defined(__NDS32_ABI_2FP_PLUS__)  */
+
+	! use $r15 in case _exit is PIC
 #ifdef PIC
-        la      $r15, C_SYMBOL_NAME(_exit at PLT)
-        jr      $r15
-#else
-        b       C_SYMBOL_NAME(_exit)
-#endif
+	la	$r15, C_SYMBOL_NAME(_exit at PLT)
+#else /* ! PIC  */
+	la	$r15, C_SYMBOL_NAME(_exit)
+#endif /* ! PIC  */
+	jr	$r15
 
 
 PSEUDO_END (__clone)
diff --git a/libc/sysdeps/linux/nds32/crt1.S b/libc/sysdeps/linux/nds32/crt1.S
index 5454401..c30f433 100644
--- a/libc/sysdeps/linux/nds32/crt1.S
+++ b/libc/sysdeps/linux/nds32/crt1.S
@@ -45,17 +45,10 @@ _start:
 
 #ifdef SHARED
 	/* set gp register */
-#ifdef __NDS32_N1213_43U1H__
-	jal	1b
-	sethi	$gp,	HI20(_GLOBAL_OFFSET_TABLE_)
-	ori	$gp,	$gp, LO12(_GLOBAL_OFFSET_TABLE_ + 4)
-	add	$gp,	$lp,	$gp
-#else
 	mfusr 	$r15, 	$PC
 	sethi	$gp,	HI20(_GLOBAL_OFFSET_TABLE_+4)
 	ori	$gp,	$gp, LO12(_GLOBAL_OFFSET_TABLE_ + 8)
 	add	$gp,	$r15,	$gp
-#endif
 
 	la		$r3,	_init at GOTOFF
 	la		$r4,	_fini at GOTOFF
diff --git a/libc/sysdeps/linux/nds32/crti.S b/libc/sysdeps/linux/nds32/crti.S
index 92e5e71..61d01b6 100644
--- a/libc/sysdeps/linux/nds32/crti.S
+++ b/libc/sysdeps/linux/nds32/crti.S
@@ -11,8 +11,6 @@
 	.type	_init, @function
 _init:
 .LFB28:
-        ! Generate instructions for ABI: 1
-	! pretend args size: 0, auto vars size: 0, pushed regs size: 12, outgoing args size: 24
         ! Generate instructions for ABI: 2
 	! pretend args size: 0, auto vars size: 0, pushed regs size: 12, outgoing args size: 0
 	! frame pointer: $fp, needed: yes
@@ -22,22 +20,12 @@ _init:
 	smw.adm $sp,[$sp],$sp,#0x8
 	smw.adm $sp,[$sp],$sp,#0x6
 	.restore_16bit
-#ifdef __NDS32_N1213_43U1H__
-	sethi	$gp, hi20(_GLOBAL_OFFSET_TABLE_+8)
-	ori	$gp, $gp, lo12(_GLOBAL_OFFSET_TABLE_+12)
-#else
 	sethi	$gp, hi20(_GLOBAL_OFFSET_TABLE_-8)
 	ori	$gp, $gp, lo12(_GLOBAL_OFFSET_TABLE_-4)
 	mfusr	$ta, $pc
-#endif
 	add	$gp, $ta, $gp
-#if defined(NDS32_ABI_2) || defined(NDS32_ABI_2FP)
         addi    $sp, $sp, -4
         addi    $fp, $sp, 8
-#else
-        addi    $sp, $sp, -28
-        addi    $fp, $sp, 32
-#endif
 	! end of prologue
 #APP
 	.align	2
@@ -48,8 +36,6 @@ _init:
 	.type	_fini, @function
 _fini:
 .LFB29:
-        ! Generate instructions for ABI: 1
-	! pretend args size: 0, auto vars size: 0, pushed regs size: 12, outgoing args size: 24
         ! Generate instructions for ABI: 2
 	! pretend args size: 0, auto vars size: 0, pushed regs size: 12, outgoing args size: 0
 	! frame pointer: $fp, needed: yes
@@ -59,22 +45,12 @@ _fini:
 	smw.adm $sp,[$sp],$sp,#0x8
 	smw.adm $sp,[$sp],$sp,#0x6
 	.restore_16bit
-#ifdef __NDS32_N1213_43U1H__
-	sethi	$gp, hi20(_GLOBAL_OFFSET_TABLE_+8)
-	ori	$gp, $gp, lo12(_GLOBAL_OFFSET_TABLE_+12)
-#else
 	sethi	$gp, hi20(_GLOBAL_OFFSET_TABLE_-8)
 	ori	$gp, $gp, lo12(_GLOBAL_OFFSET_TABLE_-4)
 	mfusr	$ta, $pc
-#endif
 	add	$gp, $ta, $gp
-#if defined(NDS32_ABI_2) || defined(NDS32_ABI_2FP)
         addi    $sp, $sp, -4
         addi    $fp, $sp, 8
-#else
-        addi    $sp, $sp, -28
-        addi    $fp, $sp, 32
-#endif
 	! end of prologue
 #APP
 	.align  2
diff --git a/libc/sysdeps/linux/nds32/fpu_control.h b/libc/sysdeps/linux/nds32/fpu_control.h
new file mode 100644
index 0000000..8ad43f6
--- /dev/null
+++ b/libc/sysdeps/linux/nds32/fpu_control.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2016-2017 Andes Technology, Inc.
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#ifndef _FPU_CONTROL_H
+
+#ifdef  __NDS32_ABI_2FP_PLUS__
+/*
+ * Andes Floating-Point Control Status Register
+ * 31-20 -> Reserved
+ * 19	 -> RIT (RO)
+ * 18	 -> DNIT(RO)
+ * 17	 -> IEXT(RO)
+ * 16	 -> UDFT(RO)
+ * 15	 -> OVFT(RO)
+ * 14	 -> DBZT(RO)
+ * 13	 -> IVOT(RO)
+ * 12	 -> DNZ(RW),Denormalized flush-to-Zero mode.
+ * 11	 -> IEXE(RW),IEEE Ineaxct (IEX) exception trapping enable.
+ * 10	 -> UDFE(RW),IEEE Underflow (UDF) exception trapping enable.
+ * 9	 -> OVFE(RW),IEEE Overflow (OVF) exception trapping enable.
+ * 8	 -> DBZE(RW),IEEE Divide by Zero (DBZ) exception trapping enable.
+ * 7	 -> IVOE(RW),IEEE Invalid Operation (IVO) exception trapping enable.
+ * 6	 -> IEX(RW),IEEE Inexact (IEX) cumulative exception flag.
+ * 5	 -> UDF(RW),IEEE Underflow (UDF) cumulative exception flag.
+ * 4	 -> OVF(RW),IEEE Overflow (OVF) cumulative exception flag.
+ * 3	 -> DBZ(RW),IEEE Divide by Zero (DBZ) cumulative exception flag.
+ * 2	 -> IVO(RW),IEEE Invalid Operation (IVO) cumulative exception flag.
+ * 1-0	 -> Rounding modes.
+ *
+ * Rounding modes.
+ * 00 - rounding to nearest (RN)
+ * 01 - rounding (up) toward plus infinity (RP)
+ * 10 - rounding (down)toward minus infinity (RM)
+ * 11 - rounding toward zero (RZ)
+ *
+ */
+
+
+/* masking of interrupts */
+#define _FPU_MASK_IEX  	0x0800  /* Invalid operation */
+#define _FPU_MASK_UDF  	0x0400  /* Underflow         */
+#define _FPU_MASK_OVF  	0x0200  /* Overflow          */
+#define _FPU_MASK_DBZ  	0x0100  /* Division by zero  */
+#define _FPU_MASK_IVO 	0x0080  /* Invalid operation */
+
+/*Reserved and read-only bits*/
+#define _FPU_RESERVED	0xffffe000
+#define _FPU_DEFAULT    0x00000000
+
+/* Default + exceptions enabled. */
+#define _FPU_IEEE	(_FPU_DEFAULT | 0x00000f80)
+
+/* Type of the control word.  */
+typedef unsigned int fpu_control_t;
+
+/* Macros for accessing the hardware control word.  */
+/* This is fmrx %0, fpscr.  */
+#define _FPU_GETCW(cw) \
+  __asm__ __volatile__ ("fmfcsr\t %0\n\t" : "=r" (cw))
+/* This is fmxr fpscr, %0.  */
+#define _FPU_SETCW(cw) \
+  __asm__ __volatile__ ("fmtcsr\t %0\n\t": : "r" (cw))
+
+/* Default control word set at startup.  */
+extern fpu_control_t __fpu_control;
+#else
+#define _FPU_GETCW(cw) (cw) = 0
+#define _FPU_SETCW(cw) (void) (cw)
+#define _FPU_RESERVED 0xffffffff
+#define _FPU_DEFAULT  0x00000000
+typedef unsigned int fpu_control_t;
+extern fpu_control_t __fpu_control;
+
+#endif //__NDS32_ABI_2FP_PLUS__
+#endif //_FPU_CONTROL_H
diff --git a/libc/sysdeps/linux/nds32/getcontext.S b/libc/sysdeps/linux/nds32/getcontext.S
new file mode 100644
index 0000000..7bc1ca2
--- /dev/null
+++ b/libc/sysdeps/linux/nds32/getcontext.S
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2016-2017 Andes Technology, Inc.
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/* Copyright (C) 20[B01-2013 Free Software Foundation, Inc.
+   Contributed by Martin Schwidefsky (schwidefsky at de.ibm.com).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+#include "ucontext_i.h"
+
+/*  __getcontext (const ucontext_t *ucp)
+
+  Saves the machine context in UCP such that when it is activated,
+  it appears as if __getcontext() returned again.
+
+  This implementation is intended to be used for *synchronous* context
+  switches only.  Therefore, it does not have to save anything
+  other than the PRESERVED state.  */
+
+ENTRY(__getcontext)
+        swi     $lp, [$r0 + UCONTEXT_PC]
+        addi    $r15, $r0, UCONTEXT_GREGS
+        xor     $r1, $r1, $r1
+	smw.bim	$r1, [$r15], $r1
+	smw.bim	$r1, [$r15], $r14
+        addi    $r15, $r15, 4
+	smw.bim	$r16, [$r15], $r25, #0xf
+	move    $r4, $r0
+
+	/* sigprocmask (SIG_BLOCK, NULL, &sc->sc_mask).  */
+	move    $r0, SIG_BLOCK
+	move	$r1, 0
+	addi	$r2, $r4, UCONTEXT_SIGMASK
+	move	$r3, _NSIG8
+	syscall SYS_ify(rt_sigprocmask)
+        bnez    $r0, 1f
+
+
+#ifdef __NDS32_ABI_2FP_PLUS__
+	addi	$r2, $r4, UCONTEXT_FDREGS
+/* Process for FPU registers.  */
+	fmfcfg	$r20	/* Keep $fpcfg in $r20.  */
+	slli	$r20, $r20, #28
+	srli	$r20, $r20, #30	/* Set $r20 as $fpcfg.freg.  */
+
+	/* Case switch for $r20 as $fpcfg.freg.  */
+	beqz	$r20, .LCFG0		/* Branch if $fpcfg.freg = 0b00.  */
+	xori	$r15, $r20, #0b10
+	beqz	$r15, .LCFG2		/* Branch if $fpcfg.freg = 0b10.  */
+	srli	$r20, $r20, #0b01
+	beqz	$r20, .LCFG1		/* Branch if $fpcfg.freg = 0b01.  */
+	/* Fall-through if $fpcfg.freg = 0b11.  */
+.LCFG3:
+	fsdi $fd31, [$r2 + 248]
+	fsdi $fd30, [$r2 + 240]
+	fsdi $fd29, [$r2 + 232]
+	fsdi $fd28, [$r2 + 224]
+	fsdi $fd27, [$r2 + 216]
+	fsdi $fd26, [$r2 + 208]
+	fsdi $fd25, [$r2 + 200]
+	fsdi $fd24, [$r2 + 192]
+.LCFG2:
+	fsdi $fd10, [$r2 + 80]
+	fsdi $fd9, [$r2 + 72]
+	fsdi $fd8, [$r2 + 64]
+.LCFG1:
+	fsdi $fd7, [$r2 + 56]
+	fsdi $fd6, [$r2 + 48]
+	fsdi $fd5, [$r2 + 40]
+	fsdi $fd4, [$r2 + 32]
+.LCFG0:
+	fsdi $fd3, [$r2 + 24]
+	/*save fpcsr*/
+	fmfcsr $r1
+	swi $r1, [$r2 + 0x100]
+#endif /* __NDS32_ABI_2FP_PLUS__ */
+
+	/* Set __getcontext return value to 0.  */
+        xor      $r0, $r0, $r0
+        /* Return first_return: 1 */
+        addi     $r1, $r0, 1
+        ret
+
+1:
+	move $r0, -1
+	ret
+END(__getcontext)
+
+weak_alias (__getcontext, getcontext)
+
diff --git a/libc/sysdeps/linux/nds32/jmpbuf-unwind.h b/libc/sysdeps/linux/nds32/jmpbuf-unwind.h
index 14a3029..8499e99 100644
--- a/libc/sysdeps/linux/nds32/jmpbuf-unwind.h
+++ b/libc/sysdeps/linux/nds32/jmpbuf-unwind.h
@@ -5,8 +5,24 @@
 
 #include <setjmp.h>
 #include <jmpbuf-offsets.h>
+#include <stdint.h>
+#include <unwind.h>
+#include <sysdep.h>
 
 /* Test if longjmp to JMPBUF would unwind the frame
    containing a local variable at ADDRESS.  */
 #define _JMPBUF_UNWINDS(jmpbuf, address) \
-  ((void *) (address) < (void *) &(jmpbuf)[0].__regs[__JMP_BUF_SP])
+  ((void *) (address) < &(jmpbuf)[0].__regs[__JMP_BUF_SP])
+
+#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \
+  _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj)
+
+static inline uintptr_t __attribute__ ((unused))
+_jmpbuf_sp (__jmp_buf regs)
+{
+  uintptr_t sp = &(regs)[0].__regs[__JMP_BUF_SP];
+  return sp;
+}
+
+#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \
+  ((uintptr_t) (_address) - (_adj) < _jmpbuf_sp (_jmpbuf) - (_adj))
diff --git a/libc/sysdeps/linux/nds32/makecontext.c b/libc/sysdeps/linux/nds32/makecontext.c
new file mode 100644
index 0000000..d8f38aa
--- /dev/null
+++ b/libc/sysdeps/linux/nds32/makecontext.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2016-2017 Andes Technology, Inc.
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/* Copyright (C) 2011-2013 Free Software Foundation, Inc.
+   Contributed by Chris Metcalf <cmetcalf at tilera.com>, 2011.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <ucontext.h>
+
+/* makecontext sets up a stack and the registers for the
+   user context.  The stack looks like this:
+
+               +-----------------------+
+	       | padding as required   |
+               +-----------------------+
+    sp ->      | parameter 7-n         |
+               +-----------------------+
+
+   The registers are set up like this:
+     $r0 .. $r5: parameter 1 to 6
+     $r6   : uc_link
+     $sp   : stack pointer.
+*/
+void
+__makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
+{
+  extern void __startcontext (void);
+  unsigned long int *sp;
+  unsigned long *regptr;
+  va_list ap;
+  int i;
+
+  sp = (unsigned long int *)
+    ((uintptr_t) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size);
+
+  /* Allocate stack arguments.  */
+  sp -= argc < 6 ? 0 : argc - 6;
+
+  /* Keep the stack aligned.  */
+  sp = (unsigned long int *) (((uintptr_t) sp) & -8L);
+
+  ucp->uc_mcontext.nds32_r6 = (uintptr_t) ucp->uc_link;
+  ucp->uc_mcontext.nds32_sp = (uintptr_t) sp;
+  ucp->uc_mcontext.nds32_ipc = (uintptr_t) func;
+  ucp->uc_mcontext.nds32_lp = (uintptr_t) &__startcontext;
+
+  va_start (ap, argc);
+  regptr = &ucp->uc_mcontext.nds32_r0;
+  for (i = 0; i < argc; ++i)
+    if (i < 6)
+      *regptr++ = va_arg (ap, unsigned long int);
+    else
+      sp[i - 6] = va_arg (ap, unsigned long int);
+
+  va_end (ap);
+
+}
+weak_alias (__makecontext, makecontext)
diff --git a/libc/sysdeps/linux/nds32/mmap.S b/libc/sysdeps/linux/nds32/mmap.S
deleted file mode 100644
index 351d1c5..0000000
--- a/libc/sysdeps/linux/nds32/mmap.S
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2016 Andes Technology, Inc.
- * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
- */
-
-/* Copyright (C) 1998, 2000, 2003 Free Software Foundation, Inc.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-
-#include <sys/syscall.h>
-#include <sysdep.h>
-	.text
-
-.globl __mmap
-ENTRY (__mmap)
-
-#ifdef PIC
-.pic
-#endif
-
-   // reserve space for r0, r1
-#if defined(NDS32_ABI_2) || defined(NDS32_ABI_2FP)
-#else
-   addi  $sp, $sp, -8
-#endif
-   // change to units  of the  system  page  size
-   srli $r5, $r5, 0xc
-
-   syscall SYS_ify(mmap2)
-#if defined(NDS32_ABI_2) || defined(NDS32_ABI_2FP)
-#else
-   addi  $sp, $sp, 8
-#endif
-
-   /* r0 is < -4096 if there was an error.  */
-   bgez $r0, 1f
-   sltsi $r1,$r0,-4096
-   beqz $r1,2f
-
-1:
-   ret
-2:
-#ifdef PIC
-#ifdef __NDS32_N1213_43U1H__
-	! save lp
-	addi	$r2,	$lp,	0
-
-	! set r1 as gp
-	jal	1b
-	sethi	$r1,	hi20(_GLOBAL_OFFSET_TABLE_)
-	ori	$r1,	$r1,	lo12(_GLOBAL_OFFSET_TABLE_+4)
-	add	$r1,	$lp,	$r1
-
-	! restore lp
-	addi	$lp,	$r2,	0
-
-	! r15=SYSCALL_ERROR at PLT
-	sethi $r15, hi20(SYSCALL_ERROR at PLT)
-	ori	$r15,	$r15, lo12(SYSCALL_ERROR at PLT)
-	add	$r15, $r15, $r1
-
-	! jump to SYSCALL_ERROR
-	jr		$r15
-#else
-	! set r1 as gp
-	mfusr $r15, $PC
-	sethi	$r1,	hi20(_GLOBAL_OFFSET_TABLE_+4)
-	ori	$r1,	$r1,	lo12(_GLOBAL_OFFSET_TABLE_+8)
-	add	$r1,	$r1,	$r15
-
-	! r15=SYSCALL_ERROR at PLT
-	sethi $r15, hi20(SYSCALL_ERROR at PLT)
-	ori	$r15,	$r15, lo12(SYSCALL_ERROR at PLT)
-	add	$r15, $r15, $r1
-
-	! jump to SYSCALL_ERROR
-	jr		$r15
-#endif
-#else
-	j SYSCALL_ERROR
-#endif
-
-ret
-
-PSEUDO_END (__mmap)
-
-weak_alias (__mmap, mmap)
-libc_hidden_def(mmap)
diff --git a/libc/sysdeps/linux/nds32/mremap.c b/libc/sysdeps/linux/nds32/mremap.c
new file mode 100644
index 0000000..9b2d835
--- /dev/null
+++ b/libc/sysdeps/linux/nds32/mremap.c
@@ -0,0 +1,28 @@
+/*
+ *  Copyright (C) 2017 Andes Technology, Inc.
+ *  Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <errno.h>
+#include <stdarg.h>
+#include <sysdep.h>
+
+#include <sys/mman.h>
+#include <sys/syscall.h>
+
+#ifdef __NR_mremap
+void *mremap (void *__addr, size_t __old_len, size_t __new_len,
+                     int __flags, ...);
+libc_hidden_proto(mremap)
+
+void *mremap (void *__addr, size_t __old_len, size_t __new_len, int __flags, ...)
+{
+        unsigned long arg1;
+        va_list arg;
+        va_start (arg, __flags);
+        arg1 = va_arg (arg, int);
+        va_end (arg);
+        return (void *)INLINE_SYSCALL(mremap,5,__addr,__old_len,__new_len,__flags,arg1);
+}
+libc_hidden_def (mremap)
+#endif
diff --git a/libc/sysdeps/linux/nds32/prctl.c b/libc/sysdeps/linux/nds32/prctl.c
new file mode 100644
index 0000000..b20f4ca
--- /dev/null
+++ b/libc/sysdeps/linux/nds32/prctl.c
@@ -0,0 +1,23 @@
+/*
+ *  Copyright (C) 2017 Andes Technology, Inc.
+ *  Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <errno.h>
+#include <stdarg.h>
+#include <sysdep.h>
+#include <sys/prctl.h>
+#include <sys/syscall.h>
+
+int prctl (int __option, ...)
+{
+	unsigned long arg1,arg2,arg3,arg4;
+	va_list arg;
+	va_start (arg, __option);
+	arg1 = va_arg (arg, unsigned long);
+	arg2 = va_arg (arg, unsigned long);
+	arg3 = va_arg (arg, unsigned long);
+	arg4 = va_arg (arg, unsigned long);
+	va_end (arg);
+	return INLINE_SYSCALL(prctl,5,__option,arg1,arg2,arg3,arg4);
+}
diff --git a/libc/sysdeps/linux/nds32/setcontext.S b/libc/sysdeps/linux/nds32/setcontext.S
new file mode 100644
index 0000000..f926532
--- /dev/null
+++ b/libc/sysdeps/linux/nds32/setcontext.S
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2016-2017 Andes Technology, Inc.
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <sysdep.h>
+
+#include "ucontext_i.h"
+
+ENTRY(__setcontext)
+        move    $r4, $r0
+
+#ifdef __NDS32_ABI_2FP_PLUS__
+	addi	$r0,  $r4, UCONTEXT_FDREGS
+
+	/* Case switch for $r20 as $fpcfg.freg.  */
+	beqz    $r20, .LCFG0         /* Branch if $fpcfg.freg = 0b00.  */
+	xori    $r15, $r20, #0b10
+	beqz    $r15, .LCFG2         /* Branch if $fpcfg.freg = 0b10.  */
+	srli    $r20, $r20, #0b01
+	beqz    $r20, .LCFG1         /* Branch if $fpcfg.freg = 0b01.  */
+	/* Fall-through if $fpcfg.freg = 0b11.  */
+.LCFG3:
+	fldi $fd31, [$r0 + 248]
+	fldi $fd30, [$r0 + 240]
+	fldi $fd29, [$r0 + 232]
+	fldi $fd28, [$r0 + 224]
+	fldi $fd27, [$r0 + 216]
+	fldi $fd26, [$r0 + 208]
+	fldi $fd25, [$r0 + 200]
+	fldi $fd24, [$r0 + 192]
+.LCFG2:
+	fldi $fd10, [$r0 + 80]
+	fldi $fd9, [$r0 + 72]
+	fldi $fd8, [$r0 + 64]
+.LCFG1:
+	fldi $fd7, [$r0 + 56]
+	fldi $fd6, [$r0 + 48]
+	fldi $fd5, [$r0 + 40]
+	fldi $fd4, [$r0 + 32]
+.LCFG0:
+	fldi $fd3, [$r0 + 24]
+	/*save fpcsr*/
+	lwi $r1, [$r0 + 0x100]
+	fmtcsr $r1
+#endif /* __NDS32_ABI_2FP_PLUS__ */
+
+	/* sigprocmask (SIG_BLOCK, &sc->sc_mask, NULL).  */
+	move    $r0, SIG_SETMASK
+	addi	$r1, $r4, UCONTEXT_SIGMASK
+	move	$r2, 0
+	move	$r3, _NSIG8
+	syscall SYS_ify(rt_sigprocmask)
+        bnez    $r0, 1f
+
+        move    $r0, $r4
+        addi    $r15, $r4, UCONTEXT_GREGS + 4
+	lmw.bim	$r1, [$r15], $r14
+        addi    $r15, $r15, 4
+	lmw.bim	$r16, [$r15], $r25, #0xf
+        lwi     $r15, [$r0 + UCONTEXT_PC]
+        push    $r1
+	cfi_adjust_cfa_offset (4)
+        move    $r1, $r0
+        lwi     $r0, [$r1 + UCONTEXT_GREGS]
+        pop     $r1
+	cfi_adjust_cfa_offset (-4)
+        jr      $r15
+1:
+	move $r0, -1
+	ret
+END(__setcontext)
+
+weak_alias (__setcontext, setcontext)
+libc_hidden_def(__setcontext)
+
+ENTRY (__startcontext)
+        move $r0, $r6
+	beqz $r0, 1f
+	jal HIDDEN_JUMPTARGET(__setcontext)
+1:	
+	move $r0, 0
+	j HIDDEN_JUMPTARGET(exit)
+END (__startcontext)
+
diff --git a/libc/sysdeps/linux/nds32/setjmp.S b/libc/sysdeps/linux/nds32/setjmp.S
index 8cb9adb..262d749 100644
--- a/libc/sysdeps/linux/nds32/setjmp.S
+++ b/libc/sysdeps/linux/nds32/setjmp.S
@@ -106,4 +106,4 @@ ENTRY(__sigsetjmp)
 #endif
 
 END(__sigsetjmp)
-hidden_def(__sigsetjmp)
+libc_hidden_def(__sigsetjmp)
diff --git a/libc/sysdeps/linux/nds32/sigaction.c b/libc/sysdeps/linux/nds32/sigaction.c
deleted file mode 100644
index 1a24c49..0000000
--- a/libc/sysdeps/linux/nds32/sigaction.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2016 Andes Technology, Inc.
- * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
- */
-
-#include <errno.h>
-#include <signal.h>
-#include <sys/syscall.h>
-#include <string.h>
-#include <bits/kernel_sigaction.h>
-
-#define SA_RESTORER	0x04000000
-
-extern void __default_sa_restorer(void);
-
-int __libc_sigaction(int sig, const struct sigaction *act,
-					  struct sigaction *oact)
-{
-	struct sigaction kact;
-
-	if (act && !(act->sa_flags & SA_RESTORER)) {
-		memcpy(&kact, act, sizeof(kact));
-		kact.sa_restorer = __default_sa_restorer;
-		kact.sa_flags |= SA_RESTORER;
-		act = &kact;
-	}
-	/* NB: kernel (as of 2.6.25) will return EINVAL
-	 * if sizeof(act->sa_mask) does not match kernel's sizeof(sigset_t) */
-	return __syscall_rt_sigaction(sig, act, oact, sizeof(act->sa_mask));
-}
-
-#ifndef LIBC_SIGACTION
-# ifndef __UCLIBC_HAS_THREADS__
-strong_alias(__libc_sigaction,sigaction)
-libc_hidden_def(sigaction)
-# else
-weak_alias(__libc_sigaction,sigaction)
-libc_hidden_weak(sigaction)
-# endif
-#endif
diff --git a/libc/sysdeps/linux/nds32/sigrestorer.S b/libc/sysdeps/linux/nds32/sigrestorer.S
deleted file mode 100644
index bf61886..0000000
--- a/libc/sysdeps/linux/nds32/sigrestorer.S
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2016 Andes Technology, Inc.
- * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
- */
-
-/* Copyright (C) 1999 Free Software Foundation, Inc.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-
-#include <sysdep.h>
-#include <sys/syscall.h>
-
-/* If no SA_RESTORER function was specified by the application we use
-   one of these.  This avoids the need for the kernel to synthesise a return
-   instruction on the stack, which would involve expensive cache flushes. */
-
-ENTRY(__default_sa_restorer)
-	/* DO NOT SAVE r7 INTO STACK, THIS SYSCALL NEVER RETURN */
-	syscall	SYS_ify(sigreturn)
-END(__default_sa_restorer)
-
-#ifdef __NR_rt_sigreturn
-
-ENTRY(__default_rt_sa_restorer)
-	/* DO NOT SAVE r7 INTO STACK, THIS SYSCALL NEVER RETURN */
-	syscall	SYS_ify(rt_sigreturn)
-END(__default_rt_sa_restorer)
-
-#endif
diff --git a/libc/sysdeps/linux/nds32/swapcontext.c b/libc/sysdeps/linux/nds32/swapcontext.c
new file mode 100644
index 0000000..310923f
--- /dev/null
+++ b/libc/sysdeps/linux/nds32/swapcontext.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 2001-2013 Free Software Foundation, Inc.
+     Contributed by David Mosberger-Tang <davidm at hpl.hp.com>.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <ucontext.h>
+
+struct rv
+  {
+    long retval;
+    long first_return;
+  };
+
+extern struct rv __getcontext (ucontext_t *__ucp);
+extern int __setcontext (const ucontext_t *__ucp);
+
+int
+__swapcontext (ucontext_t *oucp, const ucontext_t *ucp)
+{
+  struct rv rv = __getcontext (oucp);
+  if (rv.first_return)
+    __setcontext (ucp);
+  return 0;
+}
+
+weak_alias (__swapcontext, swapcontext)
diff --git a/libc/sysdeps/linux/nds32/sys/ucontext.h b/libc/sysdeps/linux/nds32/sys/ucontext.h
index 4dca27f..0d7422a 100644
--- a/libc/sysdeps/linux/nds32/sys/ucontext.h
+++ b/libc/sysdeps/linux/nds32/sys/ucontext.h
@@ -1,7 +1,20 @@
-/*
- * Copyright (C) 2016 Andes Technology, Inc.
- * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
- */
+/* Copyright (C) 1998, 1999, 2001, 2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
 
 #ifndef _SYS_UCONTEXT_H
 #define _SYS_UCONTEXT_H	1
@@ -10,103 +23,25 @@
 #include <signal.h>
 #include <sys/procfs.h>
 
-typedef int greg_t;
-
-/* Number of general registers.  */
-#define NGREG	32
-
-/* Container for all general registers.  */
-typedef elf_gregset_t gregset_t;
+/* We need the signal context definitions even if they are not used
+ *    included in <signal.h>.  */
+#include <bits/sigcontext.h>
 
-/* Number of each register is the `gregset_t' array.  */
-enum
-{
-  R0 = 0,
-#define R0	R0
-  R1 = 1,
-#define R1	R1
-  R2 = 2,
-#define R2	R2
-  R3 = 3,
-#define R3	R3
-  R4 = 4,
-#define R4	R4
-  R5 = 5,
-#define R5	R5
-  R6 = 6,
-#define R6	R6
-  R7 = 7,
-#define R7	R7
-  R8 = 8,
-#define R8	R8
-  R9 = 9,
-#define R9	R9
-  R10 = 10,
-#define R10	R10
-  R11 = 11,
-#define R11	R11
-  R12 = 12,
-#define R12	R12
-  R13 = 13,
-#define R13	R13
-  R14 = 14,
-#define R14	R14
-  R15 = 15,
-#define R15	R15
-  R16 = 16,
-#define R16     R16
-  R17 = 17,
-#define R17     R17
-  R18 = 18,
-#define R18     R18
-  R19 = 19,
-#define R19     R19
-  R20 = 20,
-#define R20     R20
-  R21 = 21,
-#define R21     R21
-  R22 = 22,
-#define R22     R22
-  R23 = 23,
-#define R23     R23
-  R24 = 24,
-#define R24     R24
-  R25 = 25,
-#define R25     R25
-  R26 = 26,
-#define R26     R26
-  R27 = 27,
-#define R27     R27
-  R28 = 28,
-#define R28     R28
-  R29 = 29,
-#define R29     R29
-  R30 = 30,
-#define R30     R30
-  R31 = 31
-#define R31     R31
 
-};
+/* Context to describe whole processor state.  This only describes
+   the core registers; coprocessor registers get saved elsewhere
+   (e.g. in uc_regspace, or somewhere unspecified on the stack
+   during non-RT signal handlers).  */
+typedef struct sigcontext mcontext_t;
 
-/* Structure to describe FPU registers.  */
-typedef elf_fpregset_t	fpregset_t;
-
-/* Context to describe whole processor state.  */
-typedef struct
-  {
-    gregset_t gregs;
-    fpregset_t fpregs;
-  } mcontext_t;
 
 /* Userlevel context.  */
 typedef struct ucontext
   {
     unsigned long int uc_flags;
     struct ucontext *uc_link;
-    __sigset_t uc_sigmask;
     stack_t uc_stack;
     mcontext_t uc_mcontext;
-    long int uc_filler[5];
+    __sigset_t uc_sigmask;
   } ucontext_t;
-
 #endif /* sys/ucontext.h */
diff --git a/libc/sysdeps/linux/nds32/syscall.S b/libc/sysdeps/linux/nds32/syscall.S
deleted file mode 100644
index 032c643..0000000
--- a/libc/sysdeps/linux/nds32/syscall.S
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2016 Andes Technology, Inc.
- * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
- */
-
-#include <sys/syscall.h>
-#include <sysdep.h>
-
-	.text
-#ifdef PIC
-	.pic
-#endif
-	.align 2
-
-
-#ifdef PIC
-#ifdef __NDS32_N1213_43U1H__
-1:
-	ret
-99:
-	addi 	$r2, $lp, 0
-	jal 	1b
-	sethi 	$r1, hi20(_GLOBAL_OFFSET_TABLE_)
-	ori 	$r1, $r1, lo12(_GLOBAL_OFFSET_TABLE_+4)
-	add 	$r1, $lp, $r1
-	addi 	$lp, $r2, 0
-#else		/* !__NDS32_N1213_43U1H__ */
-99:
-	mfusr 	$r15, $PC
-	sethi 	$r1, hi20(_GLOBAL_OFFSET_TABLE_ + 4)
-	ori 	$r1, $r1, lo12(_GLOBAL_OFFSET_TABLE_ + 8)
-	add 	$r1, $r15, $r1
-#endif		/* end of __NDS32_N1213_43U1H__ */
-	sethi 	$r15, hi20(__syscall_error at PLT)
-	ori 	$r15, $r15, lo12(__syscall_error at PLT)
-	add 	$r15, $r15, $r1
-	jr 		$r15
-#else		/* !PIC	*/
-99:
-	j __syscall_error
-#endif		/* end of PIC */
-
-#ifdef PIC	
-	.pic 
-#endif
-
-	.align 2
-	.globl syscall
-	.func syscall
-	.type syscall, @function
-
-syscall:
-	syscall __NR_syscall
-	bgez $r0, 2f
-	sltsi $r1, $r0, -4096; 
-	beqz $r1, 99b; 
-2:
-	ret
-	.endfunc 
-	.size syscall, .-syscall
diff --git a/libc/sysdeps/linux/nds32/syscall.c b/libc/sysdeps/linux/nds32/syscall.c
new file mode 100644
index 0000000..2c949ef
--- /dev/null
+++ b/libc/sysdeps/linux/nds32/syscall.c
@@ -0,0 +1,28 @@
+/*
+ *  Copyright (C) 2017 Andes Technology, Inc.
+ *  Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <errno.h>
+#include <stdarg.h>
+#include <sys/syscall.h>
+#include <sysdep.h>
+#include <unistd.h>
+long int syscall (long int __sysno, ...)
+{
+
+	int result;
+	unsigned long arg1,arg2,arg3,arg4,arg5,arg6;
+	va_list arg;
+	va_start (arg, __sysno);
+	arg1 = va_arg (arg, unsigned long);
+	arg2 = va_arg (arg, unsigned long);
+	arg3 = va_arg (arg, unsigned long);
+	arg4 = va_arg (arg, unsigned long);
+	arg5 = va_arg (arg, unsigned long);
+	arg6 = va_arg (arg, unsigned long);
+	va_end (arg);
+        __asm__ volatile ( "" ::: "memory" );
+	result = INLINE_SYSCALL(syscall,7,__sysno,arg1,arg2,arg3,arg4,arg5,arg6);
+	return result;
+}
diff --git a/libc/sysdeps/linux/nds32/sysdep.S b/libc/sysdeps/linux/nds32/sysdep.S
index 4e86a26..0ab325f 100644
--- a/libc/sysdeps/linux/nds32/sysdep.S
+++ b/libc/sysdeps/linux/nds32/sysdep.S
@@ -26,15 +26,10 @@
 
 .text
 
-.globl C_SYMBOL_NAME(errno)
 .globl __syscall_error
 
 ENTRY (__syscall_error)
-#ifdef OLD_ABI
-	subri $r5, $r5, #0
-#else
 	subri $r0, $r0, #0
-#endif
 
 #define __syscall_error __syscall_error_1
 
@@ -48,56 +43,57 @@ syscall_error:
 #ifdef PIC
 	/* set GP register */
 	pushm	$gp, $lp
-#ifdef __NDS32_N1213_43U1H__
-	jal	2f
-	sethi	$gp,	hi20(_GLOBAL_OFFSET_TABLE_)
-	ori	$gp,	$gp,	lo12(_GLOBAL_OFFSET_TABLE_+4)
-	add	$gp,	$gp,	$lp
-#else
+        cfi_adjust_cfa_offset(8)
+        cfi_rel_offset(gp, 0)
+        cfi_rel_offset(lp, 4)
 	mfusr	$r15, $PC
 	sethi	$gp,	hi20(_GLOBAL_OFFSET_TABLE_+4)
 	ori	$gp,	$gp,	lo12(_GLOBAL_OFFSET_TABLE_+8)
 	add	$gp,	$gp,	$r15
 #endif
-#endif
 
 #if defined (EWOULDBLOCK_sys) && EWOULDBLOCK_sys != EAGAIN
 	/* We translate the system's EWOULDBLOCK error into EAGAIN.
 	   The GNU C library always defines EWOULDBLOCK==EAGAIN.
 	   EWOULDBLOCK_sys is the original number.  */
 	   push	$t0
+           cfi_adjust_cfa_offset(4)
 	   li	$t0, EWOULDBLOCK_sys
 	   bne	$r0, $t0, 1f
 	   pop	$t0
+	   cfi_adjust_cfa_offset(-4)
 	   li	$r0, EAGAIN
 1:
 #endif
 
 #ifdef _LIBC_REENTRANT
 	push	$lp
+        cfi_adjust_cfa_offset(4)
+        cfi_rel_offset(lp, 0)
 	push	$r0
-#if defined(NDS32_ABI_2) || defined(NDS32_ABI_2FP)
-#else
-	addi	$sp,	$sp, -24
-#endif
+        cfi_adjust_cfa_offset(4)
+        cfi_rel_offset(r0, 0)
 
 #ifdef PIC
 	bal	C_SYMBOL_NAME(__errno_location at PLT)
 #else
 	bal	C_SYMBOL_NAME(__errno_location)
 #endif
-#if defined(NDS32_ABI_2) || defined(NDS32_ABI_2FP)
-#else
-	addi	$sp,	$sp, 24
-#endif
 	pop	$r1
+        cfi_adjust_cfa_offset(-4)
+        cfi_restore(r1)
 
 	swi	$r1, [$r0]
 	li	$r0, -1
 	pop	$lp
+        cfi_adjust_cfa_offset(-4)
+        cfi_restore(lp)
 #ifdef PIC
 	/* restore GP register */
 	popm	$gp, $lp
+        cfi_adjust_cfa_offset(-8)
+        cfi_restore(lp)
+        cfi_restore(gp)
 #endif
 2:
 	ret
@@ -115,6 +111,9 @@ syscall_error:
 	
 	/* restore GP register */
 	popm	$gp, $lp
+        cfi_adjust_cfa_offset(-8)
+        cfi_restore(lp)
+        cfi_restore(gp)
 2:
 	ret
 
diff --git a/libc/sysdeps/linux/nds32/sysdep.h b/libc/sysdeps/linux/nds32/sysdep.h
index 7472a99..3407978 100644
--- a/libc/sysdeps/linux/nds32/sysdep.h
+++ b/libc/sysdeps/linux/nds32/sysdep.h
@@ -1,148 +1,96 @@
-//#include <sysdeps/generic/sysdep.h>
+/*
+ * Copyright (C) 2016-2017 Andes Technology, Inc.
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#ifndef _LINUX_NDS32_SYSDEP_H
+#define _LINUX_NDS32_SYSDEP_H 1
+
+#include <common/sysdep.h>
+
 #ifdef	__ASSEMBLER__
 /* Define an entry point visible from C.  */
-#ifdef PIC
-#define ENTRY(name)                      \
+# ifdef PIC
+# define ENTRY(name)                      \
   .pic										\
   .align 2;                              \
   .globl C_SYMBOL_NAME(name);            \
   .func  C_SYMBOL_NAME(name);            \
   .type  C_SYMBOL_NAME(name), @function; \
-C_SYMBOL_NAME(name):
-#else
-#define ENTRY(name)                      \
+C_SYMBOL_NAME(name):			\
+	        cfi_startproc;
+
+# else
+# define ENTRY(name)                      \
   .align 2;                              \
   .globl C_SYMBOL_NAME(name);            \
   .func  C_SYMBOL_NAME(name);            \
   .type  C_SYMBOL_NAME(name), @function; \
-C_SYMBOL_NAME(name):
-#endif
+C_SYMBOL_NAME(name):			\
+	        cfi_startproc;
+# endif
 
 #undef END
 #define END(name) \
+  cfi_endproc;        \
   .endfunc;           \
   .size C_SYMBOL_NAME(name), .-C_SYMBOL_NAME(name)
 
 /* If compiled for profiling, call `mcount' at the start of each function.  */
-#ifdef HAVE_ELF
+# ifdef HAVE_ELF
 	#undef NO_UNDERSCORES
 	#define NO_UNDERSCORES
-#endif
+# endif
 
-#ifdef NO_UNDERSCORES
+# ifdef NO_UNDERSCORES
 	#define syscall_error __syscall_error
-#endif
+# endif
 
 #define SYS_ify(syscall_name)  (__NR_##syscall_name)
 
 #define __do_syscall(syscall_name)		\
   syscall	SYS_ify(syscall_name);
 
-#define SYSCALL_ERROR_HANDLER
-#define SYSCALL_ERROR __syscall_error
-
-
-#ifdef PIC
-#ifdef __NDS32_N1213_43U1H__
-#ifdef NDS_ABI_V0
-#define PSEUDO(name, syscall_name, args)	\
-  .pic;										\
-  .align 2;					\
-  1:	ret;	\
-  99:	addi	$r0,	$lp,	0;	\
-	jal	1b;	\
-	sethi	$r1,	hi20(_GLOBAL_OFFSET_TABLE_);	\
-	ori	$r1,	$r1,	lo12(_GLOBAL_OFFSET_TABLE_+4);	\
-	add	$r1,	$lp,	$r1;	\
-	addi	$lp,	$r0,	0;	\
-	sethi $r15, hi20(SYSCALL_ERROR at PLT);	\
-	ori	$r15,	$r15, lo12(SYSCALL_ERROR at PLT);	\
-	add	$r15, $r15, $r1;	\
-	jr		$r15;	\
-	nop;                                   	\
-	ENTRY(name);                          	\
-	__do_syscall(syscall_name);            	\
-	bgez $r5, 2f;				\
-	sltsi	$r0, $r5, -4096;		\
-	beqz	$r0, 99b;			\
-  2:
-#else
-#define PSEUDO(name, syscall_name, args)	\
-  .pic;										\
-  .align 2;					\
-  1:	ret;	\
-  99:	addi	$r2,	$lp,	0;	\
-	jal	1b;	\
-	sethi	$r1,	hi20(_GLOBAL_OFFSET_TABLE_);	\
-	ori	$r1,	$r1,	lo12(_GLOBAL_OFFSET_TABLE_+4);	\
-	add	$r1,	$lp,	$r1;	\
-	addi	$lp,	$r2,	0;	\
-	sethi $r15, hi20(SYSCALL_ERROR at PLT);	\
-	ori	$r15,	$r15, lo12(SYSCALL_ERROR at PLT);	\
-	add	$r15, $r15, $r1;	\
-	jr		$r15;	\
-	nop;                                   	\
-	ENTRY(name);                          	\
-	__do_syscall(syscall_name);            	\
-	bgez $r0, 2f;				\
-	sltsi	$r1, $r0, -4096;		\
-	beqz	$r1, 99b;			\
-  2:
-#endif
-#else
-#define PSEUDO(name, syscall_name, args)	\
-  .pic;										\
-  .align 2;					\
-  99:	mfusr $r15, $PC;	\
-	sethi	$r1,	hi20(_GLOBAL_OFFSET_TABLE_ + 4);	\
+# ifdef PIC
+# define PSEUDO(name, syscall_name, args)				\
+  .pic;									\
+  .align 2;								\
+  99:	mfusr $r15, $PC;						\
+	sethi	$r1,	hi20(_GLOBAL_OFFSET_TABLE_ + 4);		\
 	ori	$r1,	$r1,	lo12(_GLOBAL_OFFSET_TABLE_ + 8);	\
-	add	$r1,	$r15,	$r1;	\
-	sethi $r15, hi20(SYSCALL_ERROR at PLT);	\
-	ori	$r15,	$r15, lo12(SYSCALL_ERROR at PLT);	\
-	add	$r15, $r15, $r1;	\
-	jr		$r15;	\
-	nop;                                   	\
-	ENTRY(name);                          	\
-	__do_syscall(syscall_name);            	\
-	bgez $r0, 2f;				\
-	sltsi	$r1, $r0, -4096;		\
-	beqz	$r1, 99b;			\
+	add	$r1,	$r15,	$r1;					\
+	sethi $r15, hi20(SYSCALL_ERROR at PLT);				\
+	ori	$r15,	$r15, 	lo12(SYSCALL_ERROR at PLT);		\
+	add	$r15,	$r15, 	$r1;					\
+	jr	$r15;							\
+	nop;                                   				\
+	ENTRY(name);                          				\
+	__do_syscall(syscall_name);            				\
+	bgez $r0, 2f;							\
+	sltsi	$r1, 	$r0, 	-4096;					\
+	beqz	$r1, 	99b;						\
   2:
-#endif
-#else
-#ifdef OLD2_ABI
-#define PSEUDO(name, syscall_name, args)	\
-  .align 2;					\
-  99:	j SYSCALL_ERROR;                  	\
-	nop;                                   	\
-	ENTRY(name);                          	\
-	__do_syscall(syscall_name);            	\
-        bgez $r5, 2f;                           \
-        sltsi   $r0, $r5, -4096;                \
-        beqz    $r0, 99b;                       \
+# else
+# define PSEUDO(name, syscall_name, args)				\
+  .align 2;								\
+  99:	j SYSCALL_ERROR;                  				\
+	nop;                                   				\
+	ENTRY(name);                          				\
+	__do_syscall(syscall_name);            				\
+        bgez $r0, 2f;                           			\
+        sltsi   $r1, $r0, -4096;                			\
+        beqz    $r1, 99b;                       			\
   2:
-#else
-#define PSEUDO(name, syscall_name, args)	\
-  .align 2;					\
-  99:	j SYSCALL_ERROR;                  	\
-	nop;                                   	\
-	ENTRY(name);                          	\
-	__do_syscall(syscall_name);            	\
-        bgez $r0, 2f;                           \
-        sltsi   $r1, $r0, -4096;                \
-        beqz    $r1, 99b;                       \
-  2:
-#endif
-#endif
+# endif
 
 
-#define PSEUDO_NOERRNO(name, syscall_name, args) \
-  ENTRY(name);                                   \
+#define PSEUDO_NOERRNO(name, syscall_name, args) 			\
+  ENTRY(name);                                   			\
   __do_syscall(syscall_name);
 
 #undef PSEUDO_END
-#define PSEUDO_END(sym)				\
-	SYSCALL_ERROR_HANDLER			\
+#define PSEUDO_END(sym)							\
+	SYSCALL_ERROR_HANDLER						\
 	END(sym)
 
 #undef PSEUDO_END_ERRVAL
@@ -152,120 +100,65 @@ C_SYMBOL_NAME(name):
 
 #define ret_ERRVAL ret
 
-#define ret_NOERRNO ret	
+#define ret_NOERRNO ret
 #if defined NOT_IN_libc
 	#define SYSCALL_ERROR __local_syscall_error
 	#ifdef PIC
-		#ifdef __NDS32_N1213_43U1H__
-			#ifdef NDS_ABI_V0
-				#define SYSCALL_ERROR_HANDLER				\
-				__local_syscall_error:	pushm	$gp, $lp, $sp;				\
-					jal	1f;	\
-					sethi	$gp,	hi20(_GLOBAL_OFFSET_TABLE_);	\
-					ori	$gp,	$gp,	lo12(_GLOBAL_OFFSET_TABLE_+4);	\
-					add	$gp,	$gp,	$lp;	\
-					neg	$r5, $r5;	\
-					push	$r5;				\
-					addi	$sp,	$sp, -28; \
-					bal	C_SYMBOL_NAME(__errno_location at PLT);	\
-					addi	$sp,	$sp, 28; \
-					pop	$r1;			\
-					swi	$r1, [$r5];				\
-					li		$r5, -1;				\
-					popm	$gp, $lp, $sp;				\
-				1:	ret;
-			#else
-				#define SYSCALL_ERROR_HANDLER				\
-					__local_syscall_error:	pushm	$gp, $lp, $sp;				\
-						jal	1f;	\
-						sethi	$gp,	hi20(_GLOBAL_OFFSET_TABLE_);	\
-						ori	$gp,	$gp,	lo12(_GLOBAL_OFFSET_TABLE_+4);	\
-						add	$gp,	$gp,	$lp;	\
-						neg	$r0, $r0;	\
-						push	$r0;				\
-					#if defined(NDS32_ABI_2) || defined(NDS32_ABI_2FP) \
-					        addi    $sp,    $sp, -4; \
-					#else \
-						addi	$sp,	$sp, -28; \
-					#endif \
-						bal	C_SYMBOL_NAME(__errno_location at PLT);	\
-					#if defined(NDS32_ABI_2) || defined(NDS32_ABI_2FP) \
-					        addi    $sp,    $sp, 4; \
-					#else \
-						addi	$sp,	$sp, 28; \
-					#endif \
-						pop	$r1;			\
-						swi	$r1, [$r0];				\
-						li		$r0, -1;				\
-						popm	$gp, $lp, $sp;				\
-					1:	ret;
-			#endif
-		#else
-			#define SYSCALL_ERROR_HANDLER				\
-				__local_syscall_error:	pushm	$gp, $lp, $sp;				\
-					mfusr $r15, $PC;	\
-					sethi	$gp,	hi20(_GLOBAL_OFFSET_TABLE_+4);	\
-					ori	$gp,	$gp,	lo12(_GLOBAL_OFFSET_TABLE_+8);	\
-					add	$gp,	$gp,	$r15;	\
-					neg	$r0, $r0;	\
-					push	$r0;				\
-					#if defined(NDS32_ABI_2) || defined(NDS32_ABI_2FP) \
-					        addi    $sp,    $sp, -4; \
-					#else \
-						addi	$sp,	$sp, -28; \
-					#endif \
-					bal	C_SYMBOL_NAME(__errno_location at PLT);	\
-					#if defined(NDS32_ABI_2) || defined(NDS32_ABI_2FP) \
-					        addi    $sp,    $sp, 4; \
-					#else \
-						addi	$sp,	$sp, 28; \
-					#endif \
-					pop	$r1;			\
-					swi	$r1, [$r0];				\
-					li		$r0, -1;				\
-					popm	$gp, $lp, $sp;				\
-				1:	ret;
-		#endif
+		#define SYSCALL_ERROR_HANDLER						\
+			__local_syscall_error:						\
+				pushm	$gp, 	$lp;					\
+			        cfi_adjust_cfa_offset(8)				\
+			        cfi_rel_offset(gp, 0)					\
+			        cfi_rel_offset(lp, 4)					\
+				mfusr 	$r15, 	$PC;					\
+				sethi	$gp,	hi20(_GLOBAL_OFFSET_TABLE_+4);		\
+				ori	$gp,	$gp,	lo12(_GLOBAL_OFFSET_TABLE_+8);	\
+				add	$gp,	$gp,	$r15;				\
+				neg	$r0, 	$r0;					\
+				push	$r0;						\
+			        cfi_adjust_cfa_offset(4)				\
+			        cfi_rel_offset(r0, 0)					\
+				addi    $sp,    $sp, 	-4; 			\
+				bal	C_SYMBOL_NAME(__errno_location at PLT);		\
+				addi    $sp,    $sp, 	4; 			\
+				pop	$r1;						\
+			        cfi_adjust_cfa_offset(-4);                      	\
+			        cfi_restore(r1);                                	\
+				swi	$r1,	[$r0];					\
+				li	$r0,	-1;					\
+				popm	$gp,	$lp;					\
+			        cfi_adjust_cfa_offset(-8);                      	\
+			        cfi_restore(lp);                                	\
+			        cfi_restore(gp);  					\
+			1:	ret;
 	#else
-		#ifdef NDS_ABI_V0
-			#define SYSCALL_ERROR_HANDLER	\
-			__local_syscall_error:	push	$lp;				\
-				neg	$r5, $r5;	\
-				push	$r5;				\
-				addi	$sp,	$sp, -28; \
-				bal	C_SYMBOL_NAME(__errno_location);	\
-				addi	$sp,	$sp, 28; \
-				pop	$r1;			\
-				swi	$r1, [$r5];				\
-				li		$r5, -1;				\
-				pop	$lp;				\
+		#define SYSCALL_ERROR_HANDLER						\
+			__local_syscall_error:						\
+				push	$lp;						\
+			        cfi_adjust_cfa_offset(4)				\
+			        cfi_rel_offset(lp, 0)					\
+				neg	$r0,	$r0;					\
+				push	$r0;						\
+			        cfi_adjust_cfa_offset(4)				\
+			        cfi_rel_offset(r0, 0)					\
+				addi    $sp,    $sp, 	-4; 			\
+				bal	C_SYMBOL_NAME(__errno_location);		\
+				addi    $sp,    $sp, 	4; 			\
+				pop	$r1;						\
+			        cfi_adjust_cfa_offset(-4);                      	\
+			        cfi_restore(r1);                                	\
+				swi	$r1,	[$r0];					\
+				li	$r0,	-1;					\
+				pop	$lp;						\
+			        cfi_adjust_cfa_offset(-4);                      	\
+			        cfi_restore(lp);                                	\
 				ret;
-		#else
-			#define SYSCALL_ERROR_HANDLER	\
-			__local_syscall_error:	push	$lp;				\
-				neg	$r0, $r0;	\
-				push	$r0;				\
-				#if defined(NDS32_ABI_2) || defined(NDS32_ABI_2FP) \
-				        addi    $sp,    $sp, -4; \
-				#else \
-					addi	$sp,	$sp, -28; \
-				#endif \
-				bal	C_SYMBOL_NAME(__errno_location);	\
-				#if defined(NDS32_ABI_2) || defined(NDS32_ABI_2FP) \
-				        addi    $sp,    $sp, 4; \
-				#else \
-					addi	$sp,	$sp, 28; \
-				#endif \
-				pop	$r1;			\
-				swi	$r1, [$r0];				\
-				li		$r0, -1;				\
-				pop	$lp;				\
-				ret;
-		#endif
 	#endif
 
 #else
 	#define SYSCALL_ERROR_HANDLER
 	#define SYSCALL_ERROR __syscall_error
 #endif
+
 #endif	/* __ASSEMBLER__ */
+#endif //_LINUX_NDS32_SYSDEP_H
diff --git a/libc/sysdeps/linux/nds32/ucontext_i.sym b/libc/sysdeps/linux/nds32/ucontext_i.sym
new file mode 100644
index 0000000..1a5f2e5
--- /dev/null
+++ b/libc/sysdeps/linux/nds32/ucontext_i.sym
@@ -0,0 +1,27 @@
+#include <stddef.h>
+#include <signal.h>
+#include <sys/ucontext.h>
+
+--
+
+SIG_BLOCK
+SIG_SETMASK
+_NSIG8          (_NSIG / 8)
+
+#define ucontext(member)	offsetof (ucontext_t, member)
+#define mcontext(member)	ucontext (uc_mcontext.member)
+#define mreg(reg)		mcontext (nds32_##reg)
+
+
+UCONTEXT_GREGS                  mcontext (nds32_r0)
+#ifdef __NDS32_ABI_2FP_PLUS__
+UCONTEXT_FDREGS                 mcontext (fpu.fd_regs)
+#endif
+UCONTEXT_PC                     mcontext (nds32_ipc)
+
+
+UCONTEXT_FLAGS                  ucontext (uc_flags)
+UCONTEXT_LINK                   ucontext (uc_link)
+UCONTEXT_STACK                  ucontext (uc_stack)
+UCONTEXT_MCONTEXT               ucontext (uc_mcontext)
+UCONTEXT_SIGMASK                ucontext (uc_sigmask)
diff --git a/libc/sysdeps/linux/nds32/vfork.S b/libc/sysdeps/linux/nds32/vfork.S
index c955359..ac3fa30 100644
--- a/libc/sysdeps/linux/nds32/vfork.S
+++ b/libc/sysdeps/linux/nds32/vfork.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Andes Technology, Inc.
+ * Copyright (C) 2016-2017 Andes Technology, Inc.
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
@@ -21,24 +21,36 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-#include <sys/syscall.h>
 #include <sysdep.h>
-
 #define _ERRNO_H    1
+#include <bits/errno.h>
+
+#ifndef SAVE_PID
+#define SAVE_PID
+#endif
 
+#ifndef RESTORE_PID
+#define RESTORE_PID
+#endif
 /* Clone the calling process, but without copying the whole address space.
    The calling process is suspended until the new process exits or is
    replaced by a call to `execve'.  Return -1 for errors, 0 to the new process,
    and the process ID of the new process to the old process.  */
 
+
 ENTRY (__vfork)
 #ifdef PIC
 .pic
 #endif
 
 #ifdef __NR_vfork
-
+# ifdef SAVE_PID
+    SAVE_PID
+# endif
     syscall __NR_vfork
+# ifdef RESTORE_PID
+    RESTORE_PID
+# endif
     bltz $r0, 2f
 1:
     ret
@@ -46,42 +58,86 @@ ENTRY (__vfork)
     sltsi $r1, $r0, -4096
     bnez $r1, 1b;
 
+# ifdef __ASSUME_VFORK_SYSCALL
 #  ifdef PIC
-	#ifdef __NDS32_N1213_43U1H__
-		! save lp
-		addi	$r2,	$lp,	0
-
-		! set r1 as gp
-		jal	1b
-		sethi	$r1,	hi20(_GLOBAL_OFFSET_TABLE_)
-		ori	$r1,	$r1,	lo12(_GLOBAL_OFFSET_TABLE_+4)
-		add	$r1,	$lp,	$r1
-
-		! restore lp
-		addi	$lp,	$r2,	0
-	#else
-		! set r1 as gp
-		mfusr $r15, $PC
-		sethi	$r1,	hi20(_GLOBAL_OFFSET_TABLE_+4)
-		ori	$r1,	$r1,	lo12(_GLOBAL_OFFSET_TABLE_+8)
-		add	$r1,	$r1,	$r15
-	#endif
+	pushm	$gp,	$lp
+	cfi_adjust_cfa_offset(8)
+	cfi_rel_offset(gp, 0)
+	cfi_rel_offset(lp, 4)
+	mfusr 	$r15, 	$PC
+	sethi	$gp,	hi20(_GLOBAL_OFFSET_TABLE_+4)
+	ori	$gp,	$gp,	lo12(_GLOBAL_OFFSET_TABLE_+8)
+	add	$gp,	$gp,	$r15
 
 	! r15=C_SYMBOL_NAME(__syscall_error)@PLT
-	sethi $r15, hi20(C_SYMBOL_NAME(__syscall_error)@PLT)
+	sethi	$r15, 	hi20(C_SYMBOL_NAME(__syscall_error)@PLT)
 	ori	$r15,	$r15, lo12(C_SYMBOL_NAME(__syscall_error)@PLT)
-	add	$r15, $r15, $r1
+	add	$r15, 	$r15, 	$gp
 
 	! jump to SYSCALL_ERROR
-	jr		$r15
+	jral		$r15
+	popm	$gp,	$lp
+	cfi_adjust_cfa_offset(-8)
+	cfi_restore(lp)
+	cfi_restore(gp)
+	ret
 #  else
 	j C_SYMBOL_NAME(__syscall_error)
 #  endif
+# else
+    /* Check if vfork syscall is known at all. */
+	li $r1, -ENOSYS
+	beq	$r0, $r1, 1f
+
+# ifdef PIC
+3:
+	pushm	$gp,	$lp
+	cfi_adjust_cfa_offset(8)
+	cfi_rel_offset(gp, 0)
+	cfi_rel_offset(lp, 4)
+	mfusr	$r15,   $PC
+	sethi   $gp,    hi20(_GLOBAL_OFFSET_TABLE_+4)
+	ori     $gp,    $gp,    lo12(_GLOBAL_OFFSET_TABLE_+8)
+	add     $gp,    $gp,    $r15
+
+	! r15=C_SYMBOL_NAME(__syscall_error)@PLT
+	sethi	$r15,	hi20(C_SYMBOL_NAME(__syscall_error)@PLT)
+	ori     $r15,	$r15, lo12(C_SYMBOL_NAME(__syscall_error)@PLT)
+	add     $r15,	$r15, 	$gp
+
+	! jump to SYSCALL_ERROR
+	jral		$r15
+	popm	$gp,	$lp
+	cfi_adjust_cfa_offset(-8)
+	cfi_restore(lp)
+	cfi_restore(gp)
+	ret
+# else
+        j C_SYMBOL_NAME(__syscall_error)
+# endif
+1:
+# endif
+#endif
+
+#ifndef __ASSUME_VFORK_SYSCALL
+    /* If we don't have vfork, fork is close enough. */
+	syscall __NR_fork
+	bgez $r0, 1f
+	sltsi $r1, $r0, -4096
+	bnez	$r1, 1f
+
+# ifdef PIC
+        b       3b
+# else
+        j C_SYMBOL_NAME(__syscall_error)
+# endif
+1:
+    ret
 
-#else
-# error "__NR_vfork not available"
+#elif !defined __NR_vfork
+# error "__NR_vfork not available and __ASSUME_VFORK_SYSCALL defined"
 #endif
 
 PSEUDO_END (__vfork)
 weak_alias (__vfork, vfork)
-libc_hidden_def(vfork)
+libc_hidden_def (vfork)
diff --git a/libm/nds32/Makefile.arch b/libm/nds32/Makefile.arch
new file mode 100644
index 0000000..bd38690
--- /dev/null
+++ b/libm/nds32/Makefile.arch
@@ -0,0 +1,16 @@
+# Makefile for uClibc-ng
+# Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
+
+ifeq ($(UCLIBC_HAS_FENV),y)
+libm_ARCH_SRC:=$(wildcard $(libm_ARCH_DIR)/*.c)
+libm_ARCH_OBJ:=$(patsubst $(libm_ARCH_DIR)/%.c,$(libm_ARCH_OUT)/%.o,$(libm_ARCH_SRC))
+endif
+
+libm_ARCH_OBJS:=$(libm_ARCH_OBJ)
+
+ifeq ($(DOPIC),y)
+libm-a-y+=$(libm_ARCH_OBJS:.o=.os)
+else
+libm-a-y+=$(libm_ARCH_OBJS)
+endif
+libm-so-y+=$(libm_ARCH_OBJS:.o=.os)
diff --git a/libm/nds32/e_sqrt.c b/libm/nds32/e_sqrt.c
new file mode 100644
index 0000000..c737e10
--- /dev/null
+++ b/libm/nds32/e_sqrt.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016-2017 Andes Technology, Inc.
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/* Copyright (C) 2002-2013 Free Software Foundation, Inc.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#if defined(__NDS32_ABI_2FP_PLUS__) && defined(__NDS32_EXT_FPU_DP__)
+
+double __ieee754_sqrt (double x)
+{
+  double z;
+  __asm__ ("fsqrtd %0,%1" : "=f" (z) : "f" (x));
+  return z;
+}
+strong_alias(__ieee754_sqrt, sqrt)
+libm_hidden_def(sqrt)
+#else
+#include <libm/e_sqrt.c>
+#endif
diff --git a/libm/nds32/fclrexcpt.c b/libm/nds32/fclrexcpt.c
new file mode 100644
index 0000000..938f15a
--- /dev/null
+++ b/libm/nds32/fclrexcpt.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2016-2017 Andes Technology, Inc.
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/* Clear given exceptions in current floating-point environment.
+   Copyright (C) 1997-2013 Free Software Foundation, Inc.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include "fenv_libc.h"
+#include <fpu_control.h>
+
+
+int
+feclearexcept (int excepts)
+{
+#ifdef  __NDS32_ABI_2FP_PLUS__
+      unsigned long int temp;
+
+      /* Mask out unsupported bits/exceptions.  */
+      excepts &= FE_ALL_EXCEPT;
+
+      /* Get the current floating point status. */
+      _FPU_GETCW (temp);
+
+      /* Clear the relevant bits.  */
+      temp &= ~excepts;
+
+      /* Put the new data in effect.  */
+      _FPU_SETCW (temp);
+
+      /* Success.  */
+      return 0;
+#else
+      /* Unsupported, so fail unless nothing needs to be done.  */
+      return (excepts != 0);
+#endif
+}
diff --git a/libm/nds32/fedisblxcpt.c b/libm/nds32/fedisblxcpt.c
new file mode 100644
index 0000000..bbb6d54
--- /dev/null
+++ b/libm/nds32/fedisblxcpt.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2016-2017 Andes Technology, Inc.
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/* Disable floating-point exceptions.
+   Copyright (C) 2001-2013 Free Software Foundation, Inc.
+   Contributed by Philip Blundell <philb at gnu.org>, 2001.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include "fenv_libc.h"
+#include <fpu_control.h>
+
+int
+fedisableexcept (int excepts)
+{
+#ifdef __NDS32_ABI_2FP_PLUS__
+	unsigned long int new_exc, old_exc;
+
+	_FPU_GETCW(new_exc);
+
+	old_exc = (new_exc & ENABLE_MASK) >> ENABLE_SHIFT;
+
+	excepts &= FE_ALL_EXCEPT;
+
+	new_exc &= ~(excepts << ENABLE_SHIFT);
+	new_exc &= ~_FPU_RESERVED;
+	_FPU_SETCW (new_exc);
+
+	return old_exc;
+#else
+	/* Unsupported, so return -1 for failure.  */
+	return -1;
+#endif
+}
diff --git a/libm/nds32/feenablxcpt.c b/libm/nds32/feenablxcpt.c
new file mode 100644
index 0000000..14aef98
--- /dev/null
+++ b/libm/nds32/feenablxcpt.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2016-2017 Andes Technology, Inc.
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/* Enable floating-point exceptions.
+   Copyright (C) 2001-2013 Free Software Foundation, Inc.
+   Contributed by Philip Blundell <philb at gnu.org>, 2001.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include "fenv_libc.h"
+#include <fpu_control.h>
+
+int
+feenableexcept (int excepts)
+{
+#ifdef __NDS32_ABI_2FP_PLUS__
+	unsigned long int new_exc, old_exc;
+
+	_FPU_GETCW(new_exc);
+
+	old_exc = (new_exc & ENABLE_MASK) >> ENABLE_SHIFT;
+
+	excepts &= FE_ALL_EXCEPT;
+
+	new_exc |= (excepts << ENABLE_SHIFT);
+	new_exc &= ~_FPU_RESERVED;
+
+	_FPU_SETCW(new_exc);
+
+	return old_exc;
+#else
+  /* Unsupported, so return -1 for failure.  */
+  return -1;
+#endif
+}
diff --git a/libm/nds32/fegetenv.c b/libm/nds32/fegetenv.c
new file mode 100644
index 0000000..782cf79
--- /dev/null
+++ b/libm/nds32/fegetenv.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016-2017 Andes Technology, Inc.
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/* Store current floating-point environment.
+   Copyright (C) 1997-2013 Free Software Foundation, Inc.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+int
+fegetenv (fenv_t *envp)
+{
+#ifdef __NDS32_ABI_2FP_PLUS__
+      unsigned long int temp;
+      _FPU_GETCW (temp);
+      envp->__fpcsr = temp;
+
+      /* Success.  */
+      return 0;
+#else
+  /* Unsupported, so fail.  */
+  return 1;
+#endif
+}
diff --git a/libm/nds32/fegetexcept.c b/libm/nds32/fegetexcept.c
new file mode 100644
index 0000000..1ffe361
--- /dev/null
+++ b/libm/nds32/fegetexcept.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2016-2017 Andes Technology, Inc.
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/* Get floating-point exceptions.
+   Copyright (C) 2001-2013 Free Software Foundation, Inc.
+   Contributed by Philip Blundell <philb at gnu.org>, 2001
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include "fenv_libc.h"
+#include <fpu_control.h>
+
+int
+fegetexcept (void)
+{
+#ifdef __NDS32_ABI_2FP_PLUS__
+	unsigned long temp;
+
+	_FPU_GETCW (temp);
+
+	return (temp & ENABLE_MASK) >> ENABLE_SHIFT;
+#else
+	/* Unsupported. Return all exceptions disabled.  */
+	return 0;
+#endif
+}
diff --git a/libm/nds32/fegetround.c b/libm/nds32/fegetround.c
new file mode 100644
index 0000000..e4e70ea
--- /dev/null
+++ b/libm/nds32/fegetround.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016-2017 Andes Technology, Inc.
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/* Return current rounding direction.
+   Copyright (C) 2004-2013 Free Software Foundation, Inc.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+int
+fegetround (void)
+{
+#ifdef __NDS32_ABI_2FP_PLUS__
+	unsigned int temp;
+
+	/* Get the current environment.  */
+	_FPU_GETCW (temp);
+
+	return temp & 0x3;
+#else
+	/* The current soft-float implementation only handles TONEAREST.  */
+	return FE_TONEAREST;
+#endif
+}
diff --git a/libm/nds32/feholdexcpt.c b/libm/nds32/feholdexcpt.c
new file mode 100644
index 0000000..4ea3679
--- /dev/null
+++ b/libm/nds32/feholdexcpt.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2016-2017 Andes Technology, Inc.
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/* Store current floating-point environment and clear exceptions.
+   Copyright (C) 1997-2013 Free Software Foundation, Inc.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include <fpu_control.h>
+#include "fenv_libc.h"
+
+int
+feholdexcept (fenv_t *envp)
+{
+#ifdef __NDS32_ABI_2FP_PLUS__
+	unsigned long int temp;
+
+	/* Store the environment.  */
+	_FPU_GETCW(temp);
+	envp->__fpcsr = temp;
+
+	/* Now set all exceptions to non-stop.  */
+	temp &= ~(FE_ALL_EXCEPT << ENABLE_SHIFT);
+
+	/* And clear all exception flags.  */
+	temp &= ~FE_ALL_EXCEPT;
+
+	_FPU_SETCW(temp);
+
+	return 0;
+#else
+	/* Unsupported, so fail.  */
+	return 1;
+#endif
+}
+
diff --git a/libm/nds32/fenv_libc.h b/libm/nds32/fenv_libc.h
new file mode 100644
index 0000000..a76f131
--- /dev/null
+++ b/libm/nds32/fenv_libc.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2016-2017 Andes Technology, Inc.
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/* Copyright (C) 2000-2013 Free Software Foundation, Inc.
+   Contributed by Alexandre Oliva <aoliva at redhat.com>
+   based on the corresponding file in the mips port.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _FENV_LIBC_H
+#define _FENV_LIBC_H
+
+/* Mask for enabling exceptions and for the CAUSE bits.  */
+#define ENABLE_MASK	0x00F80U
+
+/* Shift for FE_* flags to get up to the ENABLE bits.  */
+#define	ENABLE_SHIFT	5
+
+#endif /* _FENV_LIBC_H */
diff --git a/libm/nds32/fesetenv.c b/libm/nds32/fesetenv.c
new file mode 100644
index 0000000..4682d3c
--- /dev/null
+++ b/libm/nds32/fesetenv.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2016-2017 Andes Technology, Inc.
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/* Install given floating-point environment.
+   Copyright (C) 2004-2013 Free Software Foundation, Inc.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+int
+fesetenv (const fenv_t *envp)
+{
+#ifdef __NDS32_ABI_2FP_PLUS__
+	unsigned int temp;
+
+	_FPU_GETCW (temp);
+	temp &= _FPU_RESERVED;
+
+	if (envp == FE_DFL_ENV)
+	  temp |= _FPU_DEFAULT;
+	else if (envp == FE_NOMASK_ENV)
+	  temp |= _FPU_IEEE;
+	else
+	  temp |= envp->__fpcsr & ~_FPU_RESERVED;
+
+	_FPU_SETCW (temp);
+
+	/* Success.  */
+	return 0;
+#else
+
+	/* Unsupported, so fail.  */
+	return 1;
+#endif
+}
diff --git a/libm/nds32/fesetround.c b/libm/nds32/fesetround.c
new file mode 100644
index 0000000..012a5bf
--- /dev/null
+++ b/libm/nds32/fesetround.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2016-2017 Andes Technology, Inc.
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/* Set current rounding direction.
+   Copyright (C) 2004-2013 Free Software Foundation, Inc.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+int
+fesetround (int round)
+{
+#ifdef __NDS32_ABI_2FP_PLUS__
+	fpu_control_t temp;
+	if ((round & ~0x3) != 0)
+	  /* ROUND is no valid rounding mode.  */
+		return 1;
+
+	_FPU_GETCW (temp);
+	temp = (temp & ~0x3) | round;
+	_FPU_SETCW (temp);
+	return 0;
+#else
+	return (round != FE_TONEAREST);
+#endif
+}
diff --git a/libm/nds32/feupdateenv.c b/libm/nds32/feupdateenv.c
new file mode 100644
index 0000000..d58c900
--- /dev/null
+++ b/libm/nds32/feupdateenv.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016-2017 Andes Technology, Inc.
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/* Install given floating-point environment and raise exceptions.
+   Copyright (C) 1997-2013 Free Software Foundation, Inc.
+   Contributed by Ulrich Drepper <drepper at cygnus.com>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+int
+feupdateenv (const fenv_t *envp)
+{
+#ifdef __NDS32_ABI_2FP_PLUS__
+	unsigned int temp;
+
+	/* Get the current exception state.  */
+	_FPU_GETCW (temp);
+
+	/* Install new environment.  */
+	fesetenv (envp);
+
+	/* Raise the saved exceptions.  */
+	feraiseexcept (temp & FE_ALL_EXCEPT);
+
+	/* Success.  */
+	return 0;
+#else
+	/* Unsupported, so fail.  */
+	return 1;
+#endif
+}
diff --git a/libm/nds32/fgetexcptflg.c b/libm/nds32/fgetexcptflg.c
new file mode 100644
index 0000000..e446c42
--- /dev/null
+++ b/libm/nds32/fgetexcptflg.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016-2017 Andes Technology, Inc.
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/* Store current representation for exceptions.
+   Copyright (C) 1997-2013 Free Software Foundation, Inc.
+   Contributed by Ulrich Drepper <drepper at cygnus.com>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+int
+fegetexceptflag (fexcept_t *flagp, int excepts)
+{
+#ifdef __NDS32_ABI_2FP_PLUS__
+	fpu_control_t temp;
+
+	/* Get the current exceptions.  */
+	_FPU_GETCW (temp);
+
+	*flagp = temp & excepts & FE_ALL_EXCEPT;
+
+	/* Success.  */
+	return 0;
+#else
+	/* Unsupported, so fail.  */
+	return 1;
+#endif
+}
diff --git a/libm/nds32/fraiseexcpt.c b/libm/nds32/fraiseexcpt.c
new file mode 100644
index 0000000..d194211
--- /dev/null
+++ b/libm/nds32/fraiseexcpt.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2016-2017 Andes Technology, Inc.
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/* Raise given exceptions.
+   Copyright (C) 2004-2013 Free Software Foundation, Inc.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fpu_control.h>
+#include <fenv.h>
+#include <float.h>
+#include "fenv_libc.h"
+
+int
+feraiseexcept (int excepts)
+{
+#ifdef __NDS32_ABI_2FP_PLUS__
+	float temp1 = 0.0, temp2 = 1.0;
+	if (FE_INVALID & excepts)
+	{
+		__asm__ volatile(
+			"fmtsr\t %0, $fs0\n\t"
+			"fdivs\t $fs0, $fs0, $fs0\n\t"
+			:
+			:"r"(temp1)
+			:"$fs0"
+			);
+	}
+	if (FE_DIVBYZERO & excepts)
+	{
+		__asm__ volatile(
+			"fmtsr\t %0, $fs0\n\t"
+			"fmtsr\t %1, $fs1\n\t"
+			"fdivs\t $fs0, $fs1, $fs0\n\t"
+			:
+			:"r"(temp1),"r"(temp2)
+			:"$fs0"
+			);
+	}
+	if (FE_OVERFLOW & excepts)
+	{
+	/* There's no way to raise overflow without also raising inexact.
+	*/
+		unsigned int fpcsr;
+		temp1 = FLT_MAX;
+		__asm__ volatile(
+			"fmfcsr\t %0\n\t"
+			"fmtsr\t %1, $fs0\n\t"
+			"fadds\t $fs0, $fs0, $fs0\n\t"
+			"ori\t %0,%0,0x10\n\t"
+			"fmtcsr\t %0\n\t"
+			:"=&r"(fpcsr)
+			:"r"(temp1)
+			:"$fs0"
+			);
+	}
+	if (FE_UNDERFLOW & excepts)
+	{
+	/* There's no way to raise overflow without also raising inexact.
+	*/
+		temp1 = FLT_MIN;
+		temp2 = 2.0;
+		__asm__ volatile(
+			"fmtsr\t %0, $fs0\n\t"
+			"fmtsr\t %1, $fs1\n\t"
+			"fdivs\t $fs1, $fs0, $fs1\n\t"
+			:
+			:"r"(temp1),"r"(temp2)
+			:"$fs0","$fs1"
+			);
+	}
+	if (FE_INEXACT & excepts)
+	{
+		temp1 = 3.0;
+		__asm__ volatile(
+			"fmtsr\t %0, $fs1\n\t"
+			"fmtsr\t %1, $fs0\n\t"
+			"fdivs\t $fs1, $fs0, $fs1\n\t"
+			:
+			:"r"(temp1),"r"(temp2)
+			:"$fs0","$fs1"
+			);
+	}
+
+	return 0;
+
+#endif
+	/* Unsupported, so fail unless nothing needs to be done.  */
+	return (excepts != 0);
+}
diff --git a/libm/nds32/fsetexcptflg.c b/libm/nds32/fsetexcptflg.c
new file mode 100644
index 0000000..7da943b
--- /dev/null
+++ b/libm/nds32/fsetexcptflg.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016-2017 Andes Technology, Inc.
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/* Set floating-point environment exception handling.
+   Copyright (C) 1997-2013 Free Software Foundation, Inc.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+int
+fesetexceptflag (const fexcept_t *flagp, int excepts)
+{
+#ifdef __NDS32_ABI_2FP_PLUS__
+	fexcept_t temp;
+
+	/* Get the current environment.  */
+	_FPU_GETCW (temp);
+
+	/* Set the desired exception mask.  */
+	temp &= ~(excepts & FE_ALL_EXCEPT);
+	temp |= (*flagp & excepts & FE_ALL_EXCEPT);
+
+	/* Save state back to the FPU.  */
+	_FPU_SETCW (temp);
+
+	/* Success.  */
+	return 0;
+#else
+	/* Unsupported, so fail unless nothing needs to be done.  */
+	return (excepts != 0);
+#endif
+}
diff --git a/libm/nds32/ftestexcept.c b/libm/nds32/ftestexcept.c
new file mode 100644
index 0000000..8257b6f
--- /dev/null
+++ b/libm/nds32/ftestexcept.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016-2017 Andes Technology, Inc.
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/* Test exception in current environment.
+   Copyright (C) 1997-2013 Free Software Foundation, Inc.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+int
+fetestexcept (int excepts)
+{
+#ifdef __NDS32_ABI_2FP_PLUS__
+	fexcept_t temp;
+
+	/* Get current exceptions.  */
+	_FPU_GETCW(temp);
+
+	return temp & excepts & FE_ALL_EXCEPT;
+#else
+	/* Unsupported, return 0.  */
+	return 0;
+#endif
+}
diff --git a/libpthread/linuxthreads/sysdeps/nds32/pspinlock.c b/libpthread/linuxthreads/sysdeps/nds32/pspinlock.c
index f8adf07..770a55a 100644
--- a/libpthread/linuxthreads/sysdeps/nds32/pspinlock.c
+++ b/libpthread/linuxthreads/sysdeps/nds32/pspinlock.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Andes Technology, Inc.
+ * Copyright (C) 2016-2017 Andes Technology, Inc.
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
diff --git a/libpthread/linuxthreads/sysdeps/nds32/pt-machine.h b/libpthread/linuxthreads/sysdeps/nds32/pt-machine.h
index 5bbb9e8..631c284 100644
--- a/libpthread/linuxthreads/sysdeps/nds32/pt-machine.h
+++ b/libpthread/linuxthreads/sysdeps/nds32/pt-machine.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Andes Technology, Inc.
+ * Copyright (C) 2016-2017 Andes Technology, Inc.
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
diff --git a/libpthread/nptl/sysdeps/nds32/Makefile.arch b/libpthread/nptl/sysdeps/nds32/Makefile.arch
new file mode 100644
index 0000000..7eb852a
--- /dev/null
+++ b/libpthread/nptl/sysdeps/nds32/Makefile.arch
@@ -0,0 +1,16 @@
+# Makefile for uClibc-ng NPTL
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+
+ASFLAGS-dl-tlsdesc.S = -DNOT_IN_libc=1
+libc_arch_a_SSRC = libc-dl-tlsdesc.S
+
+CFLAGS-gen_tlsdesc.c = -S
+$(libpthread_arch_OUT)/gen_tlsdesc.c: $(libpthread_arch_DIR)/tlsdesc.sym | $(libpthread_arch_OUT)
+	$(do_awk) $(top_srcdir)extra/scripts/gen-as-const.awk $< > $@
+$(libpthread_arch_OUT)/gen_tlsdesc.s: $(libpthread_arch_OUT)/gen_tlsdesc.c | headers
+	$(compile.c)
+libpthread-generated-y += $(libpthread_arch_OUT)/gen_tlsdesc.s
+$(libpthread_arch_OUT)/tlsdesc.h: $(libpthread_arch_OUT)/gen_tlsdesc.s
+	$(do_sed) $(PTHREAD_GENERATE_MANGLE) $< > $@
+	@if test ! -s $@ ; then rm -f $@ ; false ; fi
+pregen-headers-$(UCLIBC_HAS_THREADS_NATIVE) += $(libpthread_arch_OUT)/tlsdesc.h
diff --git a/libpthread/nptl/sysdeps/nds32/dl-tls.h b/libpthread/nptl/sysdeps/nds32/dl-tls.h
new file mode 100644
index 0000000..3b11e7f
--- /dev/null
+++ b/libpthread/nptl/sysdeps/nds32/dl-tls.h
@@ -0,0 +1,59 @@
+/* Thread-local storage handling in the ELF dynamic linker.  NDS32 version.
+   Copyright (C) 2013 Free Software Foundation, Inc.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _NDS32_DL_TLS_H
+#define _NDS32_DL_TLS_H 1
+
+
+/* Type used to represent a TLS descriptor.  */
+struct tlsdesc
+{
+  ptrdiff_t (*entry)(struct tlsdesc *);
+  union
+    {
+      void *pointer;
+      long value;
+    } argument;
+};
+
+/* Type used for the representation of TLS information in the GOT.  */
+typedef struct
+{
+  unsigned long int ti_module;
+  unsigned long int ti_offset;
+} tls_index;
+
+
+/* Type used as the argument in a TLS descriptor for a symbol that
+ *    needs dynamic TLS offsets.  */
+struct tlsdesc_dynamic_arg
+{
+  tls_index tlsinfo;
+  size_t gen_count;
+};
+
+
+extern void *__tls_get_addr (tls_index *ti);
+
+extern ptrdiff_t attribute_hidden
+  _dl_tlsdesc_return(struct tlsdesc_dynamic_arg *);
+
+extern void *_dl_make_tlsdesc_dynamic (struct link_map *map, size_t ti_offset);
+extern ptrdiff_t attribute_hidden
+  _dl_tlsdesc_dynamic(struct tlsdesc *);
+
+#endif //_NDS32_DL_TLS_H
diff --git a/libpthread/nptl/sysdeps/nds32/libc-dl-tlsdesc.S b/libpthread/nptl/sysdeps/nds32/libc-dl-tlsdesc.S
new file mode 100644
index 0000000..5892a8b
--- /dev/null
+++ b/libpthread/nptl/sysdeps/nds32/libc-dl-tlsdesc.S
@@ -0,0 +1 @@
+#include <ldso/ldso/nds32/dl-tlsdesc.S>
diff --git a/libpthread/nptl/sysdeps/nds32/pthread_spin_lock.c b/libpthread/nptl/sysdeps/nds32/pthread_spin_lock.c
new file mode 100644
index 0000000..cec3acb
--- /dev/null
+++ b/libpthread/nptl/sysdeps/nds32/pthread_spin_lock.c
@@ -0,0 +1,65 @@
+/* pthread_spin_lock -- lock a spin lock.  Generic version.
+   Copyright (C) 2012-2016 Free Software Foundation, Inc.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <atomic.h>
+#include "pthreadP.h"
+
+/* A machine-specific version can define SPIN_LOCK_READS_BETWEEN_CMPXCHG
+  to the number of plain reads that it's optimal to spin on between uses
+  of atomic_compare_and_exchange_val_acq.  If spinning forever is optimal
+  then use -1.  If no plain reads here would ever be optimal, use 0.  */
+#define SPIN_LOCK_READS_BETWEEN_CMPXCHG 1000
+
+int
+pthread_spin_lock (pthread_spinlock_t *lock)
+{
+  /* atomic_exchange usually takes less instructions than
+     atomic_compare_and_exchange.  On the other hand,
+     atomic_compare_and_exchange potentially generates less bus traffic
+     when the lock is locked.
+     We assume that the first try mostly will be successful, and we use
+     atomic_exchange.  For the subsequent tries we use
+     atomic_compare_and_exchange.  */
+  if (atomic_exchange_acq (lock, 1) == 0)
+    return 0;
+
+  do
+    {
+      /* The lock is contended and we need to wait.  Going straight back
+	 to cmpxchg is not a good idea on many targets as that will force
+	 expensive memory synchronizations among processors and penalize other
+	 running threads.
+	 On the other hand, we do want to update memory state on the local core
+	 once in a while to avoid spinning indefinitely until some event that
+	 will happen to update local memory as a side-effect.  */
+      if (SPIN_LOCK_READS_BETWEEN_CMPXCHG >= 0)
+	{
+	  int wait = SPIN_LOCK_READS_BETWEEN_CMPXCHG;
+
+	  while (*lock != 0 && wait > 0)
+	    --wait;
+	}
+      else
+	{
+	  while (*lock != 0)
+	    ;
+	}
+    }
+  while (atomic_compare_and_exchange_val_acq (lock, 1, 0) != 0);
+
+  return 0;
+}
diff --git a/libpthread/nptl/sysdeps/nds32/pthread_spin_trylock.c b/libpthread/nptl/sysdeps/nds32/pthread_spin_trylock.c
new file mode 100644
index 0000000..4e9aa64
--- /dev/null
+++ b/libpthread/nptl/sysdeps/nds32/pthread_spin_trylock.c
@@ -0,0 +1,26 @@
+/* pthread_spin_trylock -- trylock a spin lock.  Generic version.
+   Copyright (C) 2012-2016 Free Software Foundation, Inc.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <atomic.h>
+#include "pthreadP.h"
+
+int
+pthread_spin_trylock (pthread_spinlock_t *lock)
+{
+  return atomic_exchange_acq (lock, 1) ? EBUSY : 0;
+}
diff --git a/libpthread/nptl/sysdeps/nds32/pthreaddef.h b/libpthread/nptl/sysdeps/nds32/pthreaddef.h
new file mode 100644
index 0000000..c9d3f77
--- /dev/null
+++ b/libpthread/nptl/sysdeps/nds32/pthreaddef.h
@@ -0,0 +1,39 @@
+/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Default stack size.  */
+#define ARCH_STACK_DEFAULT_SIZE	(2 * 1024 * 1024)
+
+/* Required stack pointer alignment at beginning.  SSE requires 16
+   bytes.  */
+#define STACK_ALIGN		16
+
+/* Minimal stack size after allocating thread descriptor and guard size.  */
+#define MINIMAL_REST_STACK	2048
+
+/* Alignment requirement for TCB.  */
+#define TCB_ALIGNMENT		16
+
+
+/* Location of current stack frame.  */
+#define CURRENT_STACK_FRAME	__builtin_frame_address (0)
+
+
+/* XXX Until we have a better place keep the definitions here.  */
+#define __exit_thread_inline(val) \
+  INLINE_SYSCALL (exit, 1, (val))
+
+
diff --git a/libpthread/nptl/sysdeps/nds32/tcb-offsets.sym b/libpthread/nptl/sysdeps/nds32/tcb-offsets.sym
new file mode 100644
index 0000000..3b9e101
--- /dev/null
+++ b/libpthread/nptl/sysdeps/nds32/tcb-offsets.sym
@@ -0,0 +1,12 @@
+#include <sysdep.h>
+#include <tls.h>
+
+--
+
+-- Derive offsets relative to the thread register.
+#define thread_offsetof(mem)    (long)(offsetof(struct pthread, mem) - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE)
+
+MULTIPLE_THREADS_OFFSET         thread_offsetof (header.multiple_threads)
+PID_OFFSET                      thread_offsetof (pid)
+TID_OFFSET                      thread_offsetof (tid)
+
diff --git a/libpthread/nptl/sysdeps/nds32/tls.h b/libpthread/nptl/sysdeps/nds32/tls.h
new file mode 100644
index 0000000..e2a3862
--- /dev/null
+++ b/libpthread/nptl/sysdeps/nds32/tls.h
@@ -0,0 +1,178 @@
+/* Definition for thread-local data handling.  NPTL/NDS32 version.
+   Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _TLS_H
+#define _TLS_H	1
+
+
+#ifndef __ASSEMBLER__
+# include <stdbool.h>
+# include <stddef.h>
+# include <stdint.h>
+
+/* Type for the dtv.  */
+typedef union dtv
+{
+  size_t counter;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } pointer;
+} dtv_t;
+
+#else /* __ASSEMBLER__ */
+# include <tcb-offsets.h>
+#endif /* __ASSEMBLER__ */
+
+
+/* We require TLS support in the tools.  */
+#define HAVE_TLS_SUPPORT                1
+#define HAVE_TLS_MODEL_ATTRIBUTE        1
+#define HAVE___THREAD                   1
+
+/* Signal that TLS support is available.  */
+#define USE_TLS	1
+
+#ifndef __ASSEMBLER__
+
+/* Get system call information.  */
+# include <sysdep.h>
+
+/* The TP points to the start of the thread blocks.  */
+# define TLS_DTV_AT_TP	1
+
+/* We use the multiple_threads field in the pthread struct */
+#define TLS_MULTIPLE_THREADS_IN_TCB	1
+
+/* Get the thread descriptor definition.  */
+# include <../../descr.h>
+
+/* The stack_guard is accessed directly by GCC -fstack-protector code,
+   so it is a part of public ABI.  The dtv and pointer_guard fields
+   are private.  */
+typedef struct
+{
+  dtv_t *dtv;
+  void *private;
+} tcbhead_t;
+
+/* This is the size of the initial TCB.  */
+# define TLS_INIT_TCB_SIZE      0
+
+/* Alignment requirements for the initial TCB.  */
+# define TLS_INIT_TCB_ALIGN     __alignof__ (struct pthread)
+
+/* This is the size of the TCB.  */
+# define TLS_TCB_SIZE           0
+
+/* Alignment requirements for the TCB.  */
+# define TLS_TCB_ALIGN          __alignof__ (struct pthread)
+
+
+
+/* This is the size we need before TCB - actually, it includes the TCB.  */
+# define TLS_PRE_TCB_SIZE \
+  (sizeof (struct pthread)						      \
+   + ((sizeof (tcbhead_t) + TLS_TCB_ALIGN - 1) & ~(TLS_TCB_ALIGN - 1)))
+
+/* Return the thread descriptor (tp) for the current thread.  */
+register void *__thread_pointer __asm__ ("$r25");
+
+
+/* The thread pointer (in hardware register tp) points to the end of
+   the TCB.  The pthread_descr structure is immediately in front of the TCB.  */
+#ifndef TLS_TCB_OFFSET
+# define TLS_TCB_OFFSET	0
+#endif
+
+/* Install the dtv pointer.  The pointer passed is to the element with
+   index -1 which contain the length.  */
+# define INSTALL_DTV(tcbp, dtvp) \
+  (((tcbhead_t *) (tcbp))[-1].dtv = (dtvp) + 1)
+
+/* Install new dtv for current thread.  */
+# define INSTALL_NEW_DTV(dtv) (THREAD_DTV() = (dtv))
+
+/* Return dtv of given thread descriptor.  */
+# define GET_DTV(tcbp)	(((tcbhead_t *) (tcbp))[-1].dtv)
+
+/* Code to initially initialize the thread pointer (tp).  */
+# define TLS_INIT_TP(tcbp, secondcall) \
+    (__thread_pointer = (char *)(tcbp) + TLS_TCB_OFFSET, NULL)
+
+/* Return the address of the dtv for the current thread.  */
+# define THREAD_DTV() \
+    (((tcbhead_t *) (__thread_pointer - TLS_TCB_OFFSET))[-1].dtv)
+
+/* Return the thread descriptor for the current thread.  */
+# define THREAD_SELF \
+    ((struct pthread *) (__thread_pointer \
+			 - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE))
+
+/* Magic for libthread_db to know how to do THREAD_SELF.  */
+# define DB_THREAD_SELF \
+  REGISTER (32, 32, 152, - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE)
+
+/* Read member of the thread descriptor directly.  */
+# define THREAD_GETMEM(descr, member) (descr->member)
+
+/* Same as THREAD_GETMEM, but the member offset can be non-constant.  */
+# define THREAD_GETMEM_NC(descr, member, idx) \
+    (descr->member[idx])
+
+/* Set member of the thread descriptor directly.  */
+# define THREAD_SETMEM(descr, member, value) \
+    (descr->member = (value))
+
+/* Same as THREAD_SETMEM, but the member offset can be non-constant.  */
+# define THREAD_SETMEM_NC(descr, member, idx, value) \
+    (descr->member[idx] = (value))
+
+
+/* l_tls_offset == 0 is perfectly valid on Tile, so we have to use some
+   different value to mean unset l_tls_offset.  */
+# define NO_TLS_OFFSET		-1
+
+/* Get and set the global scope generation counter in struct pthread.  */
+#define THREAD_GSCOPE_FLAG_UNUSED 0
+#define THREAD_GSCOPE_FLAG_USED   1
+#define THREAD_GSCOPE_FLAG_WAIT   2
+#define THREAD_GSCOPE_RESET_FLAG() \
+  do									     \
+    { int __res								     \
+	= atomic_exchange_rel (&THREAD_SELF->header.gscope_flag,	     \
+			       THREAD_GSCOPE_FLAG_UNUSED);		     \
+      if (__res == THREAD_GSCOPE_FLAG_WAIT)				     \
+	lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1, LLL_PRIVATE);   \
+    }									     \
+  while (0)
+#define THREAD_GSCOPE_SET_FLAG() \
+  do									     \
+    {									     \
+      THREAD_SELF->header.gscope_flag = THREAD_GSCOPE_FLAG_USED;	     \
+      atomic_write_barrier ();						     \
+    }									     \
+  while (0)
+#define THREAD_GSCOPE_WAIT() \
+  GL(dl_wait_lookup_done) ()
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* tls.h */
+
+
diff --git a/libpthread/nptl/sysdeps/nds32/tlsdesc.sym b/libpthread/nptl/sysdeps/nds32/tlsdesc.sym
new file mode 100644
index 0000000..4fa3ada
--- /dev/null
+++ b/libpthread/nptl/sysdeps/nds32/tlsdesc.sym
@@ -0,0 +1,17 @@
+#include <stddef.h>
+#include <sysdep.h>
+#include <tls.h>
+#include <link.h>
+#include <dl-tls.h>
+
+--
+
+-- Abuse tls.h macros to derive offsets relative to the thread register.
+#define dtv_offsetof(dtv) (long)(offsetof(tcbhead_t, dtv) - sizeof (tcbhead_t))
+DTV_OFFSET                      dtv_offsetof(dtv)
+
+TLSDESC_ARG			offsetof(struct tlsdesc, argument.pointer)
+
+TLSDESC_GEN_COUNT		offsetof(struct tlsdesc_dynamic_arg, gen_count)
+TLSDESC_MODID			offsetof(struct tlsdesc_dynamic_arg, tlsinfo.ti_module)
+TLSDESC_MODOFF			offsetof(struct tlsdesc_dynamic_arg, tlsinfo.ti_offset)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/Makefile b/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/Makefile
new file mode 100644
index 0000000..2caba11
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/Makefile
@@ -0,0 +1,9 @@
+# Makefile for uClibc-ng NPTL
+# Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
+
+top_srcdir=../../../../../../../
+top_builddir=../../../../../../../
+all: objs
+include $(top_builddir)Rules.mak
+include Makefile.arch
+include $(top_srcdir)Makerules
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/Makefile.arch b/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/Makefile.arch
new file mode 100644
index 0000000..3b8935c
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/Makefile.arch
@@ -0,0 +1,12 @@
+# Makefile for uClibc-ng NPTL
+# Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
+
+libpthread_linux_arch_SSRC =
+libpthread_linux_arch_CSRC = pthread_once.c
+
+libc_linux_arch_CSRC = fork.c
+libc_linux_arch_SSRC = clone.S vfork.S
+libc_linux_arch_SSRC-OMIT = waitpid.S
+
+CFLAGS += $(SSP_ALL_CFLAGS)
+
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/bits/pthreadtypes.h b/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/bits/pthreadtypes.h
new file mode 100644
index 0000000..695a61f
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/bits/pthreadtypes.h
@@ -0,0 +1,177 @@
+/* Copyright (C) 2002,2003,2004,2005,2006,2007 Free Software Foundation, Inc.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _BITS_PTHREADTYPES_H
+#define _BITS_PTHREADTYPES_H	1
+
+#define __SIZEOF_PTHREAD_ATTR_T 36
+#define __SIZEOF_PTHREAD_MUTEX_T 24
+#define __SIZEOF_PTHREAD_MUTEXATTR_T 4
+#define __SIZEOF_PTHREAD_COND_T 48
+#define __SIZEOF_PTHREAD_COND_COMPAT_T 12
+#define __SIZEOF_PTHREAD_CONDATTR_T 4
+#define __SIZEOF_PTHREAD_RWLOCK_T 32
+#define __SIZEOF_PTHREAD_RWLOCKATTR_T 8
+#define __SIZEOF_PTHREAD_BARRIER_T 20
+#define __SIZEOF_PTHREAD_BARRIERATTR_T 4
+
+
+/* Thread identifiers.  The structure of the attribute type is not
+   exposed on purpose.  */
+typedef unsigned long int pthread_t;
+
+union pthread_attr_t
+{
+  char __size[__SIZEOF_PTHREAD_ATTR_T];
+  long int __align;
+};
+#ifndef __have_pthread_attr_t
+typedef union pthread_attr_t pthread_attr_t;
+# define __have_pthread_attr_t  1
+#endif
+
+
+typedef struct __pthread_internal_slist
+{
+  struct __pthread_internal_slist *__next;
+} __pthread_slist_t;
+
+
+/* Data structures for mutex handling.  The structure of the attribute
+   type is not exposed on purpose.  */
+typedef union
+{
+  struct __pthread_mutex_s
+  {
+    int __lock;
+    unsigned int __count;
+    int __owner;
+    /* KIND must stay at this position in the structure to maintain
+       binary compatibility.  */
+    int __kind;
+    unsigned int __nusers;
+    __extension__ union
+    {
+      int __spins;
+      __pthread_slist_t __list;
+    };
+  } __data;
+  char __size[__SIZEOF_PTHREAD_MUTEX_T];
+  long int __align;
+} pthread_mutex_t;
+
+typedef union
+{
+  char __size[__SIZEOF_PTHREAD_MUTEXATTR_T];
+  long int __align;
+} pthread_mutexattr_t;
+
+
+/* Data structure for conditional variable handling.  The structure of
+   the attribute type is not exposed on purpose.  */
+typedef union
+{
+  struct
+  {
+    int __lock;
+    unsigned int __futex;
+    __extension__ unsigned long long int __total_seq;
+    __extension__ unsigned long long int __wakeup_seq;
+    __extension__ unsigned long long int __woken_seq;
+    void *__mutex;
+    unsigned int __nwaiters;
+    unsigned int __broadcast_seq;
+  } __data;
+  char __size[__SIZEOF_PTHREAD_COND_T];
+  __extension__ long long int __align;
+} pthread_cond_t;
+
+typedef union
+{
+  char __size[__SIZEOF_PTHREAD_CONDATTR_T];
+  long int __align;
+} pthread_condattr_t;
+
+
+/* Keys for thread-specific data */
+typedef unsigned int pthread_key_t;
+
+
+/* Once-only execution */
+typedef int pthread_once_t;
+
+
+#if defined __USE_UNIX98 || defined __USE_XOPEN2K
+/* Data structure for read-write lock variable handling.  The
+   structure of the attribute type is not exposed on purpose.  */
+typedef union
+{
+  struct
+  {
+    int __lock;
+    unsigned int __nr_readers;
+    unsigned int __readers_wakeup;
+    unsigned int __writer_wakeup;
+    unsigned int __nr_readers_queued;
+    unsigned int __nr_writers_queued;
+    /* FLAGS must stay at this position in the structure to maintain
+       binary compatibility.  */
+    unsigned char __flags;
+    unsigned char __shared;
+    unsigned char __pad1;
+    unsigned char __pad2;
+    int __writer;
+  } __data;
+  char __size[__SIZEOF_PTHREAD_RWLOCK_T];
+  long int __align;
+} pthread_rwlock_t;
+
+typedef union
+{
+  char __size[__SIZEOF_PTHREAD_RWLOCKATTR_T];
+  long int __align;
+} pthread_rwlockattr_t;
+#endif
+
+
+#ifdef __USE_XOPEN2K
+/* POSIX spinlock data type.  */
+typedef volatile int pthread_spinlock_t;
+
+
+/* POSIX barriers data type.  The structure of the type is
+   deliberately not exposed.  */
+typedef union
+{
+  char __size[__SIZEOF_PTHREAD_BARRIER_T];
+  long int __align;
+} pthread_barrier_t;
+
+typedef union
+{
+  char __size[__SIZEOF_PTHREAD_BARRIERATTR_T];
+  int __align;
+} pthread_barrierattr_t;
+#endif
+/* Extra attributes for the cleanup functions.  */
+/*
+ FIXME, check this after gcc uprgrade.
+ #define __cleanup_fct_attribute __attribute__ ((__regparm__ (1)))
+ warning: '__regparm__' attribute directive ignored
+*/
+
+#endif	/* bits/pthreadtypes.h */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/bits/semaphore.h b/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/bits/semaphore.h
new file mode 100644
index 0000000..8ee7742
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/bits/semaphore.h
@@ -0,0 +1,38 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+   Contributed by Ulrich Drepper <drepper at redhat.com>, 2002.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _SEMAPHORE_H
+# error "Never use <bits/semaphore.h> directly; include <semaphore.h> instead."
+#endif
+
+
+#define __SIZEOF_SEM_T 16
+
+
+/* Value returned if `sem_open' failed.  */
+#define SEM_FAILED      ((sem_t *) 0)
+
+/* Maximum value the semaphore can have.  */
+#define SEM_VALUE_MAX   (2147483647)
+
+
+typedef union
+{
+  char __size[__SIZEOF_SEM_T];
+  long int __align;
+} sem_t;
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/clone.S b/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/clone.S
new file mode 100644
index 0000000..94b39fc
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/clone.S
@@ -0,0 +1,4 @@
+/* We want an #include_next, but we are the main source file.
+   So, #include ourselves and in that incarnation we can use #include_next.  */
+# define RESET_PID
+# include <libc/sysdeps/linux/nds32/clone.S>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/createthread.c b/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/createthread.c
new file mode 100644
index 0000000..486bc24
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/createthread.c
@@ -0,0 +1,22 @@
+/* Copyright (C) 2005-2013 Free Software Foundation, Inc.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Value passed to 'clone' for initialization of the thread register.  */
+#define TLS_VALUE ((void *) (pd) \
+		   + TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE)
+
+/* Get the real implementation.	 */
+#include <sysdeps/pthread/createthread.c>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/fork.c b/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/fork.c
new file mode 100644
index 0000000..beb6cb0
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/fork.c
@@ -0,0 +1,27 @@
+/* Copyright (C) 2005 Free Software Foundation, Inc.
+   Contributed by Phil Blundell <pb at nexus.co.uk>, 2005
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+#include <sched.h>
+#include <signal.h>
+#include <sysdep.h>
+#include <tls.h>
+
+#define ARCH_FORK() \
+  INLINE_SYSCALL (clone, 5,                                                  \
+                 CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, 0,     \
+                 NULL, NULL, &THREAD_SELF->tid)
+
+#include "../fork.c"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/lowlevellock.h
new file mode 100644
index 0000000..32b0044
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/lowlevellock.h
@@ -0,0 +1,323 @@
+/* Copyright (C) 2005-2013 Free Software Foundation, Inc.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _LOWLEVELLOCK_H
+#define _LOWLEVELLOCK_H	1
+
+#include <time.h>
+#include <sys/param.h>
+#include <bits/pthreadtypes.h>
+#include <atomic.h>
+#include <sysdep.h>
+#include <bits/kernel-features.h>
+
+
+#define FUTEX_WAIT		0
+#define FUTEX_WAKE		1
+#define FUTEX_REQUEUE		3
+#define FUTEX_CMP_REQUEUE	4
+#define FUTEX_WAKE_OP		5
+#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE	((4 << 24) | 1)
+#define FUTEX_LOCK_PI		6
+#define FUTEX_UNLOCK_PI		7
+#define FUTEX_TRYLOCK_PI	8
+#define FUTEX_WAIT_BITSET	9
+#define FUTEX_WAKE_BITSET	10
+#define FUTEX_WAIT_REQUEUE_PI   11
+#define FUTEX_CMP_REQUEUE_PI    12
+#define FUTEX_PRIVATE_FLAG	128
+#define FUTEX_CLOCK_REALTIME	256
+
+#define FUTEX_BITSET_MATCH_ANY	0xffffffff
+
+/* Values for 'private' parameter of locking macros.  Yes, the
+   definition seems to be backwards.  But it is not.  The bit will be
+   reversed before passing to the system call.  */
+#define LLL_PRIVATE	0
+#define LLL_SHARED	FUTEX_PRIVATE_FLAG
+
+
+#if !defined NOT_IN_libc || defined IS_IN_rtld
+/* In libc.so or ld.so all futexes are private.  */
+# ifdef __ASSUME_PRIVATE_FUTEX
+#  define __lll_private_flag(fl, private) \
+  ((fl) | FUTEX_PRIVATE_FLAG)
+# else
+#  define __lll_private_flag(fl, private) \
+  ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex))
+# endif
+#else
+# ifdef __ASSUME_PRIVATE_FUTEX
+#  define __lll_private_flag(fl, private) \
+  (((fl) | FUTEX_PRIVATE_FLAG) ^ (private))
+# else
+#  define __lll_private_flag(fl, private) \
+  (__builtin_constant_p (private)					      \
+   ? ((private) == 0							      \
+      ? ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex))	      \
+      : (fl))								      \
+   : ((fl) | (((private) ^ FUTEX_PRIVATE_FLAG)				      \
+	      & THREAD_GETMEM (THREAD_SELF, header.private_futex))))
+# endif
+#endif
+
+
+#define lll_futex_wait(futexp, val, private) \
+  lll_futex_timed_wait(futexp, val, NULL, private)
+
+#define lll_futex_timed_wait(futexp, val, timespec, private) \
+  ({									      \
+    INTERNAL_SYSCALL_DECL (__err);					      \
+    long int __ret;							      \
+    __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp),		      \
+			      __lll_private_flag (FUTEX_WAIT, private),	      \
+			      (val), (timespec));			      \
+    __ret;								      \
+  })
+
+#define lll_futex_timed_wait_bitset(futexp, val, timespec, clockbit, private) \
+  ({									\
+    INTERNAL_SYSCALL_DECL (__err);					\
+    long int __ret;							\
+    int __op = FUTEX_WAIT_BITSET | clockbit;				\
+    __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp),		\
+			      __lll_private_flag (__op, private),	\
+			      (val), (timespec), NULL /* Unused.  */,	\
+			      FUTEX_BITSET_MATCH_ANY);			\
+    __ret;								\
+  })
+
+#define lll_futex_wake(futexp, nr, private) \
+  ({									      \
+    INTERNAL_SYSCALL_DECL (__err);					      \
+    long int __ret;							      \
+    __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp),		      \
+			      __lll_private_flag (FUTEX_WAKE, private),	      \
+			      (nr), 0);					      \
+    __ret;								      \
+  })
+
+#define lll_robust_dead(futexv, private) \
+  do									      \
+    {									      \
+      int *__futexp = &(futexv);					      \
+      atomic_or (__futexp, FUTEX_OWNER_DIED);				      \
+      lll_futex_wake (__futexp, 1, private);				      \
+    }									      \
+  while (0)
+
+/* Returns non-zero if error happened, zero if success.  */
+#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val, private) \
+  ({									      \
+    INTERNAL_SYSCALL_DECL (__err);					      \
+    long int __ret;							      \
+    __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp),		      \
+			      __lll_private_flag (FUTEX_CMP_REQUEUE, private),\
+			      (nr_wake), (nr_move), (mutex), (val));	      \
+    INTERNAL_SYSCALL_ERROR_P (__ret, __err);				      \
+  })
+
+
+/* Returns non-zero if error happened, zero if success.  */
+#define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2, private) \
+  ({									      \
+    INTERNAL_SYSCALL_DECL (__err);					      \
+    long int __ret;							      \
+    __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp),		      \
+			      __lll_private_flag (FUTEX_WAKE_OP, private),    \
+			      (nr_wake), (nr_wake2), (futexp2),		      \
+			      FUTEX_OP_CLEAR_WAKE_IF_GT_ONE);		      \
+    INTERNAL_SYSCALL_ERROR_P (__ret, __err);				      \
+  })
+
+/* Priority Inheritance support.  */
+#define lll_futex_wait_requeue_pi(futexp, val, mutex, private) \
+  lll_futex_timed_wait_requeue_pi (futexp, val, NULL, 0, mutex, private)
+
+#define lll_futex_timed_wait_requeue_pi(futexp, val, timespec, clockbit,      \
+					mutex, private)			      \
+  ({									      \
+    INTERNAL_SYSCALL_DECL (__err);					      \
+    int __op = FUTEX_WAIT_REQUEUE_PI | clockbit;			      \
+									      \
+    INTERNAL_SYSCALL (futex, __err, 5, (futexp),			      \
+		      __lll_private_flag (__op, private),		      \
+		      (val), (timespec), mutex); 			      \
+  })
+
+#define lll_futex_cmp_requeue_pi(futexp, nr_wake, nr_move, mutex, val, priv)  \
+  ({									      \
+    INTERNAL_SYSCALL_DECL (__err);					      \
+    long int __ret;							      \
+									      \
+    __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp),		      \
+			      __lll_private_flag (FUTEX_CMP_REQUEUE_PI, priv),\
+			      (nr_wake), (nr_move), (mutex), (val));	      \
+    INTERNAL_SYSCALL_ERROR_P (__ret, __err);				      \
+  })
+
+
+#define lll_trylock(lock)	\
+  atomic_compare_and_exchange_val_acq(&(lock), 1, 0)
+
+#define lll_cond_trylock(lock)	\
+  atomic_compare_and_exchange_val_acq(&(lock), 2, 0)
+
+#define __lll_robust_trylock(futex, id) \
+  (atomic_compare_and_exchange_val_acq (futex, id, 0) != 0)
+#define lll_robust_trylock(lock, id) \
+  __lll_robust_trylock (&(lock), id)
+
+extern void __lll_lock_wait_private (int *futex) attribute_hidden;
+extern void __lll_lock_wait (int *futex, int private) attribute_hidden;
+extern int __lll_robust_lock_wait (int *futex, int private) attribute_hidden;
+
+#define __lll_lock(futex, private)					      \
+  ((void) ({								      \
+    int *__futex = (futex);						      \
+    if (__builtin_expect (atomic_compare_and_exchange_val_acq (__futex,       \
+								1, 0), 0))    \
+      {									      \
+	if (__builtin_constant_p (private) && (private) == LLL_PRIVATE)	      \
+	  __lll_lock_wait_private (__futex);				      \
+	else								      \
+	  __lll_lock_wait (__futex, private);				      \
+      }									      \
+  }))
+#define lll_lock(futex, private) __lll_lock (&(futex), private)
+
+
+#define __lll_robust_lock(futex, id, private)				      \
+  ({									      \
+    int *__futex = (futex);						      \
+    int __val = 0;							      \
+									      \
+    if (__builtin_expect (atomic_compare_and_exchange_bool_acq (__futex, id,  \
+								0), 0))	      \
+      __val = __lll_robust_lock_wait (__futex, private);		      \
+    __val;								      \
+  })
+#define lll_robust_lock(futex, id, private) \
+  __lll_robust_lock (&(futex), id, private)
+
+
+#define __lll_cond_lock(futex, private)					      \
+  ((void) ({								      \
+    int *__futex = (futex);						      \
+    if (__builtin_expect (atomic_exchange_acq (__futex, 2), 0))		      \
+      __lll_lock_wait (__futex, private);				      \
+  }))
+#define lll_cond_lock(futex, private) __lll_cond_lock (&(futex), private)
+
+
+#define lll_robust_cond_lock(futex, id, private) \
+  __lll_robust_lock (&(futex), (id) | FUTEX_WAITERS, private)
+
+
+extern int __lll_timedlock_wait (int *futex, const struct timespec *,
+				 int private) attribute_hidden;
+extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *,
+					int private) attribute_hidden;
+
+#define __lll_timedlock(futex, abstime, private)			      \
+  ({									      \
+     int *__futex = (futex);						      \
+     int __val = 0;							      \
+									      \
+     if (__builtin_expect (atomic_exchange_acq (__futex, 1), 0))	      \
+       __val = __lll_timedlock_wait (__futex, abstime, private);	      \
+     __val;								      \
+  })
+#define lll_timedlock(futex, abstime, private) \
+  __lll_timedlock (&(futex), abstime, private)
+
+
+#define __lll_robust_timedlock(futex, abstime, id, private)		      \
+  ({									      \
+    int *__futex = (futex);						      \
+    int __val = 0;							      \
+									      \
+    if (__builtin_expect (atomic_compare_and_exchange_bool_acq (__futex, id,  \
+								0), 0))	      \
+      __val = __lll_robust_timedlock_wait (__futex, abstime, private);	      \
+    __val;								      \
+  })
+#define lll_robust_timedlock(futex, abstime, id, private) \
+  __lll_robust_timedlock (&(futex), abstime, id, private)
+
+
+#define __lll_unlock(futex, private) \
+  (void)							\
+    ({ int *__futex = (futex);					\
+       int __oldval = atomic_exchange_rel (__futex, 0);		\
+       if (__builtin_expect (__oldval > 1, 0))			\
+	 lll_futex_wake (__futex, 1, private);			\
+       lll_futex_wake (__futex, 1, private);			\
+    })
+#define lll_unlock(futex, private) __lll_unlock(&(futex), private)
+
+
+#define __lll_robust_unlock(futex, private) \
+  (void)							\
+    ({ int *__futex = (futex);					\
+       int __oldval = atomic_exchange_rel (__futex, 0);		\
+       if (__builtin_expect (__oldval & FUTEX_WAITERS, 0))	\
+	 lll_futex_wake (__futex, 1, private);			\
+       lll_futex_wake (__futex, 1, private);			\
+    })
+#define lll_robust_unlock(futex, private) \
+  __lll_robust_unlock(&(futex), private)
+
+
+#define lll_islocked(futex) \
+  (futex != 0)
+
+
+/* Our internal lock implementation is identical to the binary-compatible
+   mutex implementation. */
+
+/* Initializers for lock.  */
+#define LLL_LOCK_INITIALIZER		(0)
+#define LLL_LOCK_INITIALIZER_LOCKED	(1)
+
+/* The states of a lock are:
+    0  -  untaken
+    1  -  taken by one user
+   >1  -  taken by more users */
+
+/* The kernel notifies a process which uses CLONE_CHILD_CLEARTID via futex
+   wakeup when the clone terminates.  The memory location contains the
+   thread ID while the clone is running and is reset to zero
+   afterwards.	*/
+#define lll_wait_tid(tid) \
+  do {					\
+    __typeof (tid) __tid;		\
+    while ((__tid = (tid)) != 0)	\
+      lll_futex_wait (&(tid), __tid, LLL_SHARED);\
+  } while (0)
+
+extern int __lll_timedwait_tid (int *, const struct timespec *)
+     attribute_hidden;
+
+#define lll_timedwait_tid(tid, abstime) \
+  ({							\
+    int __res = 0;					\
+    if ((tid) != 0)					\
+      __res = __lll_timedwait_tid (&(tid), (abstime));	\
+    __res;						\
+  })
+
+#endif	/* lowlevellock.h */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/pt-raise.c b/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/pt-raise.c
new file mode 100644
index 0000000..6c0d4b5
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/pt-raise.c
@@ -0,0 +1,18 @@
+/* Copyright (C) 2002-2013 Free Software Foundation, Inc.
+   Contributed by Ulrich Drepper <drepper at redhat.com>, 2002.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <nptl/sysdeps/unix/sysv/linux/raise.c>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/pthread_once.c b/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/pthread_once.c
new file mode 100644
index 0000000..ce68ce6
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/pthread_once.c
@@ -0,0 +1,92 @@
+/* Copyright (C) 2003-2013 Free Software Foundation, Inc.
+   Contributed by Jakub Jelinek <jakub at redhat.com>, 2003.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "pthreadP.h"
+#include <lowlevellock.h>
+
+
+unsigned long int __fork_generation attribute_hidden;
+
+
+static void
+clear_once_control (void *arg)
+{
+  pthread_once_t *once_control = (pthread_once_t *) arg;
+
+  *once_control = 0;
+  lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+}
+
+
+int
+__pthread_once (once_control, init_routine)
+     pthread_once_t *once_control;
+     void (*init_routine) (void);
+{
+  while (1)
+    {
+      int oldval, val, newval;
+
+      val = *once_control;
+      do
+	{
+	  /* Check if the initialized has already been done.  */
+	  if ((val & 2) != 0)
+	    return 0;
+
+	  oldval = val;
+	  newval = (oldval & 3) | __fork_generation | 1;
+	  val = atomic_compare_and_exchange_val_acq (once_control, newval,
+						     oldval);
+	}
+      while (__builtin_expect (val != oldval, 0));
+
+      /* Check if another thread already runs the initializer.	*/
+      if ((oldval & 1) != 0)
+	{
+	  /* Check whether the initializer execution was interrupted
+	     by a fork.	 */
+	  if (((oldval ^ newval) & -4) == 0)
+	    {
+	      /* Same generation, some other thread was faster. Wait.  */
+	      lll_futex_wait (once_control, newval, LLL_PRIVATE);
+	      continue;
+	    }
+	}
+
+      /* This thread is the first here.  Do the initialization.
+	 Register a cleanup handler so that in case the thread gets
+	 interrupted the initialization can be restarted.  */
+      pthread_cleanup_push (clear_once_control, once_control);
+
+      init_routine ();
+
+      pthread_cleanup_pop (0);
+
+
+      /* Add one to *once_control.  */
+      atomic_increment (once_control);
+
+      /* Wake up all other threads.  */
+      lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+      break;
+    }
+
+  return 0;
+}
+weak_alias (__pthread_once, pthread_once)
+strong_alias (__pthread_once, __pthread_once_internal)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/sysdep-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/sysdep-cancel.h
new file mode 100644
index 0000000..a0f4de5
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/sysdep-cancel.h
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2016-2017 Andes Technology, Inc.
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/* Copyright (C) 2003-2013 Free Software Foundation, Inc.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+#include <tls.h>
+#ifndef __ASSEMBLER__
+# include <pthreadP.h>
+#endif
+
+
+
+#define PUSHARGS_0
+#define PUSHARGS_1	smw.adm $r0, [$sp], $r0, #0;	\
+			cfi_adjust_cfa_offset(4);	\
+			cfi_rel_offset(r0,0);		\
+			addi	$sp, $sp, -4;		\
+			cfi_adjust_cfa_offset(4);
+#define PUSHARGS_2	smw.adm $r0, [$sp], $r1, #0;	\
+			cfi_adjust_cfa_offset(8);	\
+			cfi_rel_offset(r1, 4);		\
+			cfi_rel_offset(r0, 0);
+#define PUSHARGS_3	smw.adm $r0, [$sp], $r2, #0;	\
+			cfi_adjust_cfa_offset(12);	\
+			cfi_rel_offset(r2, 8);		\
+			cfi_rel_offset(r1, 4);		\
+			cfi_rel_offset(r0, 0);		\
+			addi	$sp, $sp, -4;		\
+			cfi_adjust_cfa_offset(4);
+#define PUSHARGS_4	smw.adm $r0, [$sp], $r3, #0;	\
+			cfi_adjust_cfa_offset(16);	\
+			cfi_rel_offset(r3, 12);		\
+			cfi_rel_offset(r2, 8);		\
+			cfi_rel_offset(r1, 4);		\
+			cfi_rel_offset(r0, 0);
+#define PUSHARGS_5	smw.adm $r0, [$sp], $r4, #0;	\
+			cfi_adjust_cfa_offset(20);	\
+			cfi_rel_offset(r4, 16);		\
+			cfi_rel_offset(r3, 12);		\
+			cfi_rel_offset(r2, 8);		\
+			cfi_rel_offset(r1, 4);		\
+			cfi_rel_offset(r0, 0);		\
+			addi	$sp, $sp, -4;		\
+			cfi_adjust_cfa_offset(4);
+#define PUSHARGS_6	smw.adm $r0, [$sp], $r5, #0;	\
+			cfi_adjust_cfa_offset(24);	\
+			cfi_rel_offset(r5, 20);		\
+			cfi_rel_offset(r4, 16);		\
+			cfi_rel_offset(r3, 12);		\
+			cfi_rel_offset(r2, 8);		\
+			cfi_rel_offset(r1, 4);		\
+			cfi_rel_offset(r0, 0);
+
+#define POPARGS2_0
+#define POPARGS2_1	addi	$sp, $sp, 4;		\
+			cfi_adjust_cfa_offset(-4);	\
+			lmw.bim $r0, [$sp], $r0, #0;	\
+			cfi_adjust_cfa_offset(-4);	\
+			cfi_restore(r0);
+#define POPARGS2_2	lmw.bim $r0, [$sp], $r1, #0;	\
+			cfi_adjust_cfa_offset(-8);	\
+			cfi_restore(r0);		\
+			cfi_restore(r1);
+#define POPARGS2_3	addi	$sp, $sp, 4;		\
+			cfi_adjust_cfa_offset(-4);	\
+			lmw.bim $r0, [$sp], $r2, #0;	\
+			cfi_adjust_cfa_offset(-12);	\
+			cfi_restore(r0);		\
+			cfi_restore(r1);		\
+			cfi_restore(r2);
+#define POPARGS2_4	lmw.bim $r0, [$sp], $r3, #0;	\
+			cfi_adjust_cfa_offset(-16);	\
+			cfi_restore(r0);		\
+			cfi_restore(r1);		\
+			cfi_restore(r2);		\
+			cfi_restore(r3);
+#define POPARGS2_5	addi	$sp, $sp, 4;		\
+			cfi_adjust_cfa_offset(-4);	\
+			lmw.bim $r0, [$sp], $r4, #0;	\
+			cfi_adjust_cfa_offset(-20);	\
+			cfi_restore(r0);		\
+			cfi_restore(r1);		\
+			cfi_restore(r2);		\
+			cfi_restore(r3);		\
+			cfi_restore(r4);
+#define POPARGS2_6	lmw.bim $r0, [$sp], $r5, #0;	\
+			cfi_adjust_cfa_offset(-24);	\
+			cfi_restore(r0);		\
+			cfi_restore(r1);		\
+			cfi_restore(r2);		\
+			cfi_restore(r3);		\
+			cfi_restore(r4);		\
+			cfi_restore(r5);
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+/* NOTE: We do mark syscalls with unwind annotations, for the benefit of
+   cancellation; but they're really only accurate at the point of the
+   syscall.  The ARM unwind directives are not rich enough without adding
+   a custom personality function.  */
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)				\
+  .align 2;                                                             \
+  ENTRY (__##syscall_name##_nocancel);					\
+  __do_syscall(syscall_name);                                           \
+  PSEUDO_RET;                                                           \
+  ret;							                \
+  END (__##syscall_name##_nocancel);					\
+  ENTRY (name);								\
+  smw.adm $r6,[$sp],$r6,0x2;                                            \
+  cfi_adjust_cfa_offset(8); 						\
+  cfi_offset(r6,-8);						\
+  cfi_offset(lp,-4);						\
+  SINGLE_THREAD_P ($r15);                                               \
+  bgtz $r15, .Lpseudo_cancel;                                           \
+  __do_syscall(syscall_name);                                           \
+  j 50f;                                                                \
+  .Lpseudo_cancel:							\
+	PUSHARGS_##args;	/* save syscall args etc. around CENABLE.  */	\
+	CENABLE ($r5);							\
+	mov55 $r6, $r0;		/* put mask in safe place.  */    	\
+	POPARGS2_##args;                                                \
+	__do_syscall(syscall_name);		/* do the call.  */	\
+	push $r0;                                                       \
+	cfi_adjust_cfa_offset(4);					\
+	cfi_rel_offset(r0, 0);						\
+	addi $sp, $sp, -4;						\
+	cfi_adjust_cfa_offset(4);					\
+        mov55	$r0, $r6;		/* save syscall return value. */\
+	CDISABLE($r5);							\
+	addi $sp, $sp, 4;						\
+	cfi_adjust_cfa_offset(-4);					\
+        pop $r0;                          /* retrieve return value.  */	\
+	cfi_adjust_cfa_offset(-4);					\
+	cfi_restore(r0);						\
+50:									\
+  lmw.bim $r6,[$sp],$r6, 0x2;                                           \
+  cfi_adjust_cfa_offset(-8); 						\
+  cfi_restore(lp);							\
+  cfi_restore(r6);							\
+  PSEUDO_RET;
+# ifndef __ASSEMBLER__
+//#  if defined IS_IN_libpthread || !defined NOT_IN_libc
+//extern int __local_multiple_threads attribute_hidden;
+//#  define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
+//#  else
+/*  There is no __local_multiple_threads for librt */
+#  define SINGLE_THREAD_P __builtin_expect (THREAD_GETMEM (THREAD_SELF,       \
+				           header.multiple_threads) == 0, 1)
+//#  endif
+# else
+#   define SINGLE_THREAD_P(reg)            \
+    addi reg, $r25, MULTIPLE_THREADS_OFFSET; \
+    lw   reg, [reg];
+#   define SINGLE_THREAD_P_PIC(x) SINGLE_THREAD_P(x)
+# endif
+
+
+# ifdef IS_IN_libpthread
+#  define CENABLE(reg)	jmp(reg, __pthread_enable_asynccancel)
+#  define CDISABLE(reg) jmp(reg, __pthread_disable_asynccancel)
+#  define __local_multiple_threads __pthread_multiple_threads
+# elif !defined NOT_IN_libc
+#  define CENABLE(reg)	jmp(reg, __libc_enable_asynccancel)
+#  define CDISABLE(reg)	jmp(reg, __libc_disable_asynccancel)
+#  define __local_multiple_threads __libc_multiple_threads
+# elif defined IS_IN_librt
+#  define CENABLE(reg)	jmp(reg, __librt_enable_asynccancel)
+#  define CDISABLE(reg)	jmp(reg, __librt_disable_asynccancel)
+# else
+#  error Unsupported library
+# endif
+
+#elif !defined __ASSEMBLER__
+
+/* For rtld, et cetera.  */
+# define SINGLE_THREAD_P 1
+# define NO_CANCELLATION 1
+
+#endif
+
+
+
+
+
+
+
+#ifndef __ASSEMBLER__
+# define RTLD_SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+				   header.multiple_threads) == 0, 1)
+#endif
+
+
+
+#ifdef PIC
+#define PSEUDO_RET \
+	 .pic \
+   .align 2; \
+   bgez $r0, 1f; \
+   sltsi $r1, $r0, -4096;    \
+   bgtz  $r1, 1f;     \
+   PIC_jmp_err	\
+	 nop; \
+   1:
+#else  /* PIC*/
+#define PSEUDO_RET \
+   .align 2;         \
+   bgez  $r0, 1f; \
+   sltsi $r1, $r0, -4096; \
+   bgtz  $r1, 1f;     \
+   j SYSCALL_ERROR; \
+   1:
+#endif
+
+#ifdef PIC
+#define jmp(reg, symble) PIC_jmpr(reg, symble)
+/* reg: available register */
+#define PIC_jmp_err \
+   smw.adm $sp,[$sp],$sp,#0x6;  \
+   mfusr $r15, $PC;  \
+   sethi $gp,  hi20(_GLOBAL_OFFSET_TABLE_ + 4);  \
+   ori   $gp,  $gp,  lo12(_GLOBAL_OFFSET_TABLE_ + 8);  \
+   add   $gp,  $r15, $gp;  \
+   sethi $r15, hi20(SYSCALL_ERROR at PLT);  \
+   ori   $r15, $r15, lo12(SYSCALL_ERROR at PLT);  \
+   add   $r15, $r15, $gp;  \
+   jral  $r15; \
+   lmw.bim $sp,[$sp],$sp,#0x6; \
+   ret;
+
+#define PIC_jmp(reg, symble) \
+   mfusr $r15, $PC;  \
+   sethi reg,  hi20(_GLOBAL_OFFSET_TABLE_ + 4);  \
+   ori   reg,  reg,  lo12(_GLOBAL_OFFSET_TABLE_ + 8);  \
+   add   reg,  $r15, reg;  \
+   sethi $r15, hi20(symble at PLT);  \
+   ori   $r15, $r15, lo12(symble at PLT);  \
+   add   $r15, $r15, reg;  \
+   jr    $r15;
+
+
+#define PIC_jmpr(reg, symble) \
+   mfusr $r15, $PC;  \
+   sethi reg,  hi20(_GLOBAL_OFFSET_TABLE_ + 4);  \
+   ori   reg,  reg,  lo12(_GLOBAL_OFFSET_TABLE_ + 8);  \
+   add   reg,  $r15, reg;  \
+   sethi $r15, hi20(symble at PLT);  \
+   ori   $r15, $r15, lo12(symble at PLT);  \
+   add   $r15, $r15, reg;  \
+   jral  $r15;
+
+#else
+#define jmp(reg, symble) jal symble
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/vfork.S
new file mode 100644
index 0000000..f11f76a
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/nds32/vfork.S
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2016-2017 Andes Technology, Inc.
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/* Copyright (C) 2013 Free Software Foundation, Inc.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <tls.h>
+
+/* Save the PID value.  */
+#define SAVE_PID \
+	lwi  	$r1, [$r25 + PID_OFFSET];/* Get the thread pointer.  */	\
+	subri	$r1, $r1, 0x0;		 /* Negate it.  */		\
+	bnez	$r1, 1f;		 /* If it was zero... */		\
+	sethi	$r1, 0x80000;		 /* use 0x80000000 instead.  */	\
+1:	swi	$r1, [$r25 + PID_OFFSET];/* Store the temporary PID.  */
+
+/* Restore the old PID value in the parent.  */
+#define RESTORE_PID \
+	beqz	$r0, 1f;		/* If we are the parent... */	\
+	lwi  	$r1, [$r25 + PID_OFFSET];/* Get the thread pointer.  */	\
+	subri	$r1, $r1, 0x0;		/* Re-negate it.  */		\
+	sethi	$r2, 0x80000;		/* Load 0x80000000... */	\
+	bne	$r1, $r2, 2f;		/* ... compare against it... */	\
+	movi	$r1, 0;			/* ... use 0 instead.  */	\
+2:	swi	$r1, [$r25 + PID_OFFSET];/* Restore the PID.  */		\
+1:
+
+#include <../../../../../../../libc/sysdeps/linux/nds32/vfork.S>


hooks/post-receive
-- 
uClibc-ng - small C library for embedded systems


More information about the devel mailing list