summaryrefslogtreecommitdiff
path: root/libc/sysdeps/linux/nds32/bits
diff options
context:
space:
mode:
authorVincent Ren-Wei Chen <vincentc@andestech.com>2017-01-17 07:31:24 +0100
committerWaldemar Brodkorb <wbx@openadk.org>2017-01-22 10:06:29 +0100
commit6af3332a4cbd1ffbc81f74759ef7c5e1a87d2e10 (patch)
tree4deae5f23fd1e2664f21c09dfb57fda799dffd10 /libc/sysdeps/linux/nds32/bits
parent82af21a60bc6e53dd92c1c140f20179d2ae4ad40 (diff)
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@andestech.com>
Diffstat (limited to 'libc/sysdeps/linux/nds32/bits')
-rw-r--r--libc/sysdeps/linux/nds32/bits/atomic.h110
-rw-r--r--libc/sysdeps/linux/nds32/bits/fcntl.h6
-rw-r--r--libc/sysdeps/linux/nds32/bits/fenv.h79
-rw-r--r--libc/sysdeps/linux/nds32/bits/mman.h1
-rw-r--r--libc/sysdeps/linux/nds32/bits/setjmp.h18
-rw-r--r--libc/sysdeps/linux/nds32/bits/sigcontext.h59
-rw-r--r--libc/sysdeps/linux/nds32/bits/sigcontextinfo.h35
-rw-r--r--libc/sysdeps/linux/nds32/bits/syscalls.h354
-rw-r--r--libc/sysdeps/linux/nds32/bits/uClibc_arch_features.h2
9 files changed, 520 insertions, 144 deletions
diff --git a/libc/sysdeps/linux/nds32/bits/atomic.h b/libc/sysdeps/linux/nds32/bits/atomic.h
new file mode 100644
index 000000000..f93fa7a43
--- /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 d21c4e03c..a936023aa 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 000000000..010d870f5
--- /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 13f3e60b3..ac242e065 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 92d89003a..e287c2481 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 e91f6a9b0..000000000
--- 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 000000000..f3237bd57
--- /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@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 f69ad4c41..215ce3467 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 12e4af9cd..5c4f634a0 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__