This is the mail archive of the
libc-help@sourceware.org
mailing list for the glibc project.
Re: [RFC PATCH 10/10] C-SKY: Linux ABI
On 16/03/2018 17:58, Mao Han wrote:
> diff --git a/sysdeps/unix/sysv/linux/csky/sysdep-cancel.h b/sysdeps/unix/sysv/linux/csky/sysdep-cancel.h
> new file mode 100644
> index 0000000..dd39ecf
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/csky/sysdep-cancel.h
New ports should not provide sysdep-cancel.h any more, cancellable syscall
not generated by syscalls.list and if it an advantage for the ABI, it
can define SINGLE_THREAD_BY_GLOBAL on sysdep.h (so the single-thread
check will be done by a global variable instead of using a TCB field).
> @@ -0,0 +1,407 @@
> +/* Copyright (C) 2018 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/>. */
> +
> +#include <sysdep.h>
> +#include <tls.h>
> +#include <csky_readtp.h>
> +#ifndef __ASSEMBLER__
> +# include <nptl/pthreadP.h>
> +#endif
> +
> +#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt)
> +
> +# ifdef __PIC__
> +# define __GET_GB \
> + bsr 1f; 1: lrw gb, 1b@GOTPC; addu gb, lr;
> +# define __JSR(symbol) \
> + lrw a2, symbol@PLT; add a2, gb; ld.w a2, (a2); jsr a2;
> +
> +# if !IS_IN (libc)
> +# define PSEUDO_ERRJMP \
> + subi sp, 8; st.w lr, (sp); st.w gb, (sp, 4); \
> + __GET_GB \
> + bsr SYSCALL_ERROR; \
> + ld.w lr, (sp); ld.w gb, (sp, 4); addi sp, 8; \
> + rts;
> +# else /* !IS_IN (libc) */
> +# define PSEUDO_ERRJMP \
> + subi sp, 8; st.w lr, (sp); st.w gb, (sp, 4); \
> + __GET_GB \
> + lrw a2, SYSCALL_ERROR@PLT; add a2, gb; ld.w a2, (a2); \
> + jsr a2; \
> + ld.w lr, (sp); ld.w gb, (sp, 4); addi sp, 8; \
> + rts;
> +# endif
> +
> +# else
> +
> +# define __GET_GB
> +# define __JSR(symbol) jsri symbol;
> +# define PSEUDO_ERRJMP jmpi SYSCALL_ERROR;
> +# endif
> +
> +
> +#ifdef __CSKYABIV2__
> +#undef PSEUDO
> +#define PSEUDO(name, syscall_name, args) \
> + .section ".text"; \
> + 99: PSEUDO_ERRJMP \
> + .type __##syscall_name##_nocancel,@function; \
> + .globl __##syscall_name##_nocancel; \
> + __##syscall_name##_nocancel: \
> + cfi_startproc; \
> + DO_CALL (syscall_name, args); \
> + btsti a0, 31; \
> + bt 99b; \
> + rts; \
> + cfi_endproc; \
> + .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
> + ENTRY (name); \
> + SINGLE_THREAD_P; \
> + bt .Lpseudo_cancel; \
> + DO_CALL (syscall_name, args); \
> + btsti a0, 31; \
> + bt 99b; \
> + rts; \
> +.Lpseudo_cancel: \
> + DOCARGS_##args; /* save syscall reg(r7), syscall args and lr */ \
> + __GET_GB; \
> + CENABLE; \
> + mov t0, a0; /* Save result of CENABLE */ \
> + UNDOSYSARGS_##args; /* restore syscall args */ \
> + DO_CALL_2 (syscall_name, args); \
> + mov r7, a0; /* save result of syscall */ \
> + mov a0, t0; /* restore result of CENABLE */ \
> + CDISABLE; \
> + mov a0, r7; /* restore result of syscall */ \
> + RESTORE_LR_R7_##args; \
> + btsti a0, 31; \
> + bt 99b; \
> + rts; \
> +
> +
> +#else /* __CSKYABIV1__ */
> +
> +#undef PSEUDO
> +#define PSEUDO(name, syscall_name, args) \
> + .section ".text"; \
> + 99: PSEUDO_ERRJMP \
> + .type __##syscall_name##_nocancel,@function; \
> + .globl __##syscall_name##_nocancel; \
> + __##syscall_name##_nocancel: \
> + DO_CALL (syscall_name, args); \
> + btsti a0, 31; \
> + bt 99b; \
> + rts; \
> + .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
> + ENTRY (name); \
> + SINGLE_THREAD_P; \
> + bt .Lpseudo_cancel; \
> + DO_CALL (syscall_name, args); \
> + btsti a0, 31; \
> + bt 99b; \
> + rts; \
> +.Lpseudo_cancel: \
> + DOCARGS_##args; /* save syscall args and lr */ \
> + __GET_GB; \
> + CENABLE; \
> + mov r9, a0; \
> + UNDOSYSARGS_##args; /* restore syscall args */ \
> + lrw r1, SYS_ify (syscall_name); \
> + trap 0; \
> + mov r1, a0; /* save result of syscall */ \
> + mov a0, r9; /* restore result of CENABLE */ \
> + mov r9, r1; \
> + CDISABLE; \
> + mov a0, r9; /* restore result of syscall */ \
> + RESTORE_LR_##args; \
> + btsti a0, 31; \
> + bt 99b; \
> + rts; \
> +
> +#endif /* __CSKYABIV2__ */
> +
> +#ifdef __CSKYABIV2__
> +#define DOCARGS_0 \
> + subi sp, 12; .cfi_def_cfa_offset 12; \
> + stw r15, (sp, 0); .cfi_offset 15, -12; \
> + stw gb, (sp, 4); .cfi_offset 28, -8; \
> + stw r7, (sp, 8); .cfi_offset 7, -4;
> +#define UNDOSYSARGS_0
> +#define RESTORE_LR_R7_0 \
> + ldw r15, (sp, 0); \
> + ldw gb, (sp, 4); \
> + ldw r7, (sp, 8); \
> + addi sp, 12
> +
> +#define DOCARGS_1 \
> + subi sp, 16; .cfi_def_cfa_offset 16; \
> + stw a0, (sp, 0); \
> + stw r15, (sp, 4); .cfi_offset 15, -12; \
> + stw gb, (sp, 8); .cfi_offset 28, -8; \
> + stw r7, (sp, 12); .cfi_offset 7, -4;
> +#define UNDOSYSARGS_1 \
> + ldw a0, (sp, 0); \
> + addi sp, 4; .cfi_adjust_cfa_offset -4;
> +#define RESTORE_LR_R7_1 RESTORE_LR_R7_0
> +
> +#define DOCARGS_2 \
> + subi sp, 20; .cfi_def_cfa_offset 20; \
> + stw a0, (sp, 0); \
> + stw a1, (sp, 4); \
> + stw r15, (sp, 8); .cfi_offset 15, -12; \
> + stw gb, (sp, 12); .cfi_offset 28, -8; \
> + stw r7, (sp, 16); .cfi_offset 7, -4;
> +#define UNDOSYSARGS_2 \
> + ldw a0, (sp, 0); \
> + ldw a1, (sp, 4); \
> + addi sp, 8; .cfi_adjust_cfa_offset -8;
> +#define RESTORE_LR_R7_2 RESTORE_LR_R7_0
> +
> +#define DOCARGS_3 \
> + subi sp, 24; .cfi_def_cfa_offset 24; \
> + stw a0, (sp, 0); \
> + stw a1, (sp, 4); \
> + stw a2, (sp, 8); \
> + stw r15, (sp, 12); .cfi_offset 15, -12; \
> + stw gb, (sp, 16); .cfi_offset 28, -8; \
> + stw r7, (sp, 20); .cfi_offset 7, -4;
> +#define UNDOSYSARGS_3 \
> + ldw a0, (sp, 0); \
> + ldw a1, (sp, 4); \
> + ldw a2, (sp, 8); \
> + addi sp, 12; .cfi_adjust_cfa_offset -12;
> +#define RESTORE_LR_R7_3 RESTORE_LR_R7_0
> +
> +#define DOCARGS_4 \
> + subi sp, 28;; .cfi_def_cfa_offset 28; \
> + stw a0, (sp, 0); \
> + stw a1, (sp, 4); \
> + stw a2, (sp, 8); \
> + stw a3, (sp, 12); \
> + stw r15, (sp, 16); .cfi_offset 15, -12; \
> + stw gb, (sp, 20); .cfi_offset 28, -8; \
> + stw r7, (sp, 24); .cfi_offset 7, -4;
> +#define UNDOSYSARGS_4 \
> + ldw a0, (sp, 0); \
> + ldw a1, (sp, 4); \
> + ldw a2, (sp, 8); \
> + ldw a3, (sp, 12); \
> + addi sp, 16; .cfi_adjust_cfa_offset -16;
> +#define RESTORE_LR_R7_4 RESTORE_LR_R7_0
> +
> +#define DOCARGS_5 DOCARGS_4
> +#define UNDOSYSARGS_5 UNDOSYSARGS_4
> +#define RESTORE_LR_R7_5 RESTORE_LR_R7_0
> +#define DOCARGS_6 DOCARGS_4
> +#define UNDOSYSARGS_6 UNDOSYSARGS_4
> +#define RESTORE_LR_R7_6 RESTORE_LR_R7_0
> +#else /* __CSKYABIV1__ */
> +#define DOCARGS_0 \
> + subi sp, 16; .cfi_def_cfa_offset 16; \
> + stw r15, (sp, 0); .cfi_offset 15, -16; \
> + stw r9, (sp, 4); .cfi_offset 9, -12; \
> + stw r14, (sp, 8); .cfi_offset 14, -8;
> +#define UNDOSYSARGS_0
> +#define RESTORE_LR_0 \
> + ldw r15, (sp, 0); \
> + ldw r9, (sp, 4); \
> + ldw r14, (sp, 8); \
> + addi sp, 16
> +
> +#define DOCARGS_1 \
> + subi sp, 16; .cfi_def_cfa_offset 16; \
> + stw r15, (sp, 0); .cfi_offset 15, -16; \
> + stw r9, (sp, 4); .cfi_offset 9, -12; \
> + stw r14, (sp, 8); .cfi_offset 14, -8; \
> + stw r2, (sp, 12);
> +#define UNDOSYSARGS_1 \
> + ldw r2, (sp, 12);
> +#define RESTORE_LR_1 RESTORE_LR_0
> +
> +#define DOCARGS_2 \
> + subi sp, 24; .cfi_def_cfa_offset 24; \
> + stw r2, (sp, 0); \
> + stw r3, (sp, 4); \
> + stw r15, (sp, 8); .cfi_offset 15, -16; \
> + stw r9, (sp, 12); .cfi_offset 9, -12; \
> + stw r14, (sp, 16); .cfi_offset 14, -8;
> +#define UNDOSYSARGS_2 \
> + ldw r2, (sp, 0); \
> + ldw r3, (sp, 4); \
> + addi sp, 8; .cfi_adjust_cfa_offset -8;
> +#define RESTORE_LR_2 RESTORE_LR_0
> +
> +#define DOCARGS_3 \
> + subi sp, 24; .cfi_def_cfa_offset 24; \
> + stw r2, (sp, 0); \
> + stw r3, (sp, 4); \
> + stw r15, (sp, 8); .cfi_offset 15, -16; \
> + stw r9, (sp, 12); .cfi_offset 9, -12; \
> + stw r14, (sp, 16); .cfi_offset 14, -8; \
> + stw r4, (sp, 20);
> +#define UNDOSYSARGS_3 \
> + ldw r2, (sp, 0); \
> + ldw r3, (sp, 4); \
> + ldw r4, (sp, 20); \
> + addi sp, 8; .cfi_adjust_cfa_offset -8;
> +#define RESTORE_LR_3 RESTORE_LR_0
> +
> +#define DOCARGS_4 \
> + subi sp, 32; .cfi_def_cfa_offset 32; \
> + stw r2, (sp, 0); \
> + stw r3, (sp, 4); \
> + stw r4, (sp, 8); \
> + stw r5, (sp, 12); \
> + stw r15, (sp, 16); .cfi_offset 15, -16; \
> + stw r9, (sp, 20); .cfi_offset 9, -12; \
> + stw r14, (sp, 24); .cfi_offset 14, -8;
> +#define UNDOSYSARGS_4 \
> + ldw r2, (sp, 0); \
> + ldw r3, (sp, 4); \
> + ldw r4, (sp, 8); \
> + ldw r5, (sp, 12); \
> + addi sp, 16; .cfi_adjust_cfa_offset -16;
> +#define RESTORE_LR_4 RESTORE_LR_0
> +
> +#define DOCARGS_5 \
> + subi sp, 32; .cfi_def_cfa_offset 32; \
> + stw r2, (sp, 0); \
> + stw r3, (sp, 4); \
> + stw r4, (sp, 8); \
> + stw r5, (sp, 12); \
> + stw r15, (sp, 16); .cfi_offset 15, -16; \
> + stw r9, (sp, 20); .cfi_offset 9, -12; \
> + stw r14, (sp, 24); .cfi_offset 14, -8; \
> + stw r6, (sp, 28);
> +#define UNDOSYSARGS_5 \
> + ldw r2, (sp, 0); \
> + ldw r3, (sp, 4); \
> + ldw r4, (sp, 8); \
> + ldw r5, (sp, 12); \
> + ldw r6, (sp, 28); \
> + addi sp, 16; .cfi_adjust_cfa_offset -16;
> +#define RESTORE_LR_5 RESTORE_LR_0
> +
> +#define DOCARGS_6 \
> + subi sp, 32; .cfi_def_cfa_offset 32; \
> + subi sp, 8; .cfi_def_cfa_offset 8; \
> + stw r2, (sp, 0); \
> + stw r3, (sp, 4); \
> + stw r4, (sp, 8); \
> + stw r5, (sp, 12); \
> + stw r6, (sp, 16); \
> + stw r7, (sp, 20); \
> + stw r15, (sp, 24); .cfi_offset 15, -16; \
> + stw r9, (sp, 28); .cfi_offset 9, -12; \
> + stw r14, (sp, 32); .cfi_offset 14, -8;
> +#define UNDOSYSARGS_6 \
> + ldw r2, (sp, 0); \
> + ldw r3, (sp, 4); \
> + ldw r4, (sp, 8); \
> + ldw r5, (sp, 12); \
> + ldw r6, (sp, 16); \
> + ldw r7, (sp, 20); \
> + addi sp, 24; .cfi_adjust_cfa_offset -24;
> +#define RESTORE_LR_6 RESTORE_LR_0
> +
> +#define UNDOARGS_0
> +#define UNDOARGS_1
> +#define UNDOARGS_2
> +#define UNDOARGS_3
> +#define UNDOARGS_4
> +#define UNDOARGS_5
> +#define UNDOARGS_6
> +
> +#endif /* __CSKYABIV2__ */
> +
> +
> +
> +# if IS_IN (libpthread)
> +# ifdef __PIC__
> +# define CENABLE __JSR (__pthread_enable_asynccancel)
> +# define CDISABLE __JSR (__pthread_disable_asynccancel)
> +# else
> +# define CENABLE __JSR (__pthread_enable_asynccancel)
> +# define CDISABLE __JSR (__pthread_disable_asynccancel)
> +# endif
> +# elif IS_IN (libc)
> +# ifdef __PIC__
> +# define CENABLE __JSR (__libc_enable_asynccancel)
> +# define CDISABLE __JSR (__libc_disable_asynccancel)
> +# else
> +# define CENABLE __JSR (__libc_enable_asynccancel)
> +# define CDISABLE __JSR (__libc_disable_asynccancel)
> +# endif
> +# else
> +# ifdef __PIC__
> +# define CENABLE __JSR (__librt_enable_asynccancel)
> +# define CDISABLE __JSR (__librt_disable_asynccancel)
> +# else
> +# define CENABLE __JSR (__librt_enable_asynccancel)
> +# define CDISABLE __JSR (__librt_disable_asynccancel)
> +# endif
> +# endif
> +
> +# if IS_IN (libc)
> +# define __local_multiple_threads __libc_multiple_threads
> +# elif IS_IN (libpthread)
> +# define __local_multiple_threads __pthread_multiple_threads
> +# else
> +# define __local_multiple_threads __librt_multiple_threads
> +# endif
> +
> +#ifndef __ASSEMBLER__
> +# if IS_IN (libpthread) || IS_IN (libc)
> +extern int __local_multiple_threads attribute_hidden;
> +# define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
> +# else /* IS_IN_libpthread || !defined NOT_IN_libc */
> +# define SINGLE_THREAD_P \
> + __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
> + header.multiple_threads) == 0, 1)
> +# endif
> +#else
> +# define SINGLE_THREAD_P \
> + subi sp, 8; \
> + stw a0, (sp, 0); \
> + stw a1, (sp, 4); \
> + csky_read_tp; \
> + lrw a1, MULTIPLE_THREADS_OFFSET; \
> + add a0, a1; \
> + ldw a0, (a0); \
> + cmpnei a0, 0; \
> + ldw a0, (sp, 0); \
> + ldw a1, (sp, 4); \
> + addi sp, 8
> +# endif
> +
> +
> +
> +#elif !defined __ASSEMBLER__
> +
> +/* This code should never be used but we define it anyhow. */
> +# 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
> diff --git a/sysdeps/unix/sysv/linux/csky/sysdep.S b/sysdeps/unix/sysv/linux/csky/sysdep.S
> new file mode 100644
> index 0000000..7b919ec
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/csky/sysdep.S
> @@ -0,0 +1,119 @@
> +/* Copyright (C) 2018 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/>. */
> +
> +#include <sysdep.h>
> +#include <csky_readtp.h>
> +
> +/* The syscall stubs jump here when they detect an error.
> + The code for Linux is almost identical to the canonical Unix
> + code, except that the error number in R0 is negated. */
> +
> +#undef CALL_MCOUNT
> +#define CALL_MCOUNT /* Don't insert the profiling call, it clobbers R0. */
> +
> + .text
> +ENTRY(__syscall_error)
> + movi a1, 0
> + rsub a0, a0, a1
> +
> +#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. */
> + cmpnei a0, EWOULDBLOCK /* Is it the old EWOULDBLOCK? */
> + bt 1f
> + mov a0, EAGAIN /* Yes; translate it to EAGAIN. */
> +#endif
I am not sure if this is true or required for new ports, does C-SKY
really require this code snippet?
> +
> +#ifdef __CSKYABIV2__
> +1:
> +# if !IS_IN (rtld)
> + mov a1, a0
> + csky_read_tp
> +
> + grs t1, .Lgetpc1
> +.Lgetpc1:
> + lrw t0, errno@gottpoff
> + add t1, t1, t0
> + ldw t1, (t1)
> + add t1, a0
> + stw a1, (t1)
> + bmaski a0, 0
> + rts
> +# elif RTLD_PRIVATE_ERRNO /* !IS_IN (rtld) */
> +# ifdef __PIC__
> + grs t1, .Lgetpc2
> +.Lgetpc2:
> + lrw t0, .Lgetpc2@GOTPC
> + addu t1, t1, t0
> + lrw t0, rtld_errno@PLT
> + ldr.w t0, (t1, t0 << 0)
> +# else
> + lrw t0, rtld_errno
> +# endif /* __PIC__ */
> + stw a0, (t0)
> + bmaski a0, 0
> + rts
> +# else
> +# error "Unsupported non-TLS case"
> +# endif /* RTLD_PRIVATE_ERRNO */
> +
> +# undef __syscall_error
> +END (__syscall_error)
> +
> +#else /* __CSKYABIV2__ */
> +
> +1:
> +# if !IS_IN (rtld)
> + mov r7, r15
> + mov r1, r2
> + csky_read_tp
> +
> + bsr .Lgetpc1
> +.Lgetpc1:
> + lrw r5, errno@gottpoff
> + add r5, r15
> + ldw r5, (r5)
> + add r5, r2
> + stw r1, (r5)
> + bmaski r2, 0
> + mov r15, r7
> + rts
> +# elif RTLD_PRIVATE_ERRNO /* !IS_IN (rtld) */
> +# ifdef __PIC__
> + mov r7, r15
> + bsr .Lgetpc2
> +.Lgetpc2:
> + lrw r6, .Lgetpc2@GOTPC
> + addu r6, r15
> + lrw r5, rtld_errno@PLT
> + addu r5, r6
> + ldw r5, (r5)
> + mov r15, r7
> +# else /* __PIC__ */
> + lrw r5, rtld_errno
> +# endif /* __PIC__ */
> + stw r2, (r5)
> + bmaski r2, 0
> + rts
> +# else
> +# error "Unsupported non-TLS case"
> +# endif /* RTLD_PRIVATE_ERRNO */
> +
> +END (__syscall_error)
> +
> +#endif /* __CSKYABIV2__ */
> diff --git a/sysdeps/unix/sysv/linux/csky/sysdep.h b/sysdeps/unix/sysv/linux/csky/sysdep.h
> new file mode 100644
> index 0000000..7edc559
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/csky/sysdep.h
> @@ -0,0 +1,730 @@
> +/* Copyright (C) 2018 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 _LINUX_CSKY_SYSDEP_H
> +#define _LINUX_CSKY_SYSDEP_H 1
> +
> +/* There is some commonality. */
> +#include <sysdeps/unix/sysv/linux/sysdep.h>
> +#include <sysdeps/unix/csky/sysdep.h>
> +
> +/* Defines RTLD_PRIVATE_ERRNO and USE_DL_SYSINFO. */
> +#include <dl-sysdep.h>
> +
> +#include <tls.h>
> +
> +/* In order to get __set_errno() definition in INLINE_SYSCALL. */
> +#ifndef __ASSEMBLER__
> +# include <errno.h>
> +#endif
> +
> +#undef SYS_ify
> +#define SYS_ify(syscall_name) (__NR_##syscall_name)
> +
> +#ifdef __ASSEMBLER__
> +/* Linux uses a negative return value to indicate syscall errors,
> + unlike most Unices, which use the condition codes' carry flag.
> +
> + Since version 2.1 the return value of a system call might be
> + negative even if the call succeeded. E.g., the `lseek' system call
> + might return a large offset. Therefore we must not anymore test
> + for < 0, but test for a real error by making sure the value in R0
> + is a real error number. Linus said he will make sure the no syscall
> + returns a value in -1 .. -4095 as a valid result so we can safely
> + test with -4095. */
> +
> +# undef PSEUDO
> +# define PSEUDO(name, syscall_name, args) \
> + .text; \
> + ENTRY (name); \
> + DO_CALL (syscall_name, args);
> +
> +
> +# if defined (__PIC__)
> +# define __GET_GB1 \
> + bsr getgb; getgb: lrw gb, getgb@GOTPC; addu gb, lr;
> +# else
> +# define __GET_GB1
> +# endif /* !__PIC__ */
> +
> +# undef PSEUDO_RET
> +# ifdef __PIC__
> +# if !IS_IN (libc)
> +# define PSEUDO_RET \
> + btsti a0, 31; \
> + bf 1f; \
> + subi sp, 8; st.w lr, (sp); st.w gb, (sp, 4); \
> + __GET_GB1 \
> + bsr SYSCALL_ERROR; \
> + ld.w lr, (sp); ld.w gb, (sp, 4); addi sp, 8; \
> +1: \
> + rts
> +# else
> +# define PSEUDO_RET \
> + btsti a0, 31; \
> + bf 2f; \
> + subi sp, 8; st.w lr, (sp); st.w gb, (sp, 4); \
> + __GET_GB1; \
> + lrw a2, SYSCALL_ERROR@PLT; \
> + add a2, gb; \
> + ld.w a2, (a2); \
> + jsr a2; \
> + ld.w lr, (sp); ld.w gb, (sp, 4); addi sp, 8; \
> +2: \
> + rts
> +# endif /* IS_IN (libc) */
> +# else
> +# if !IS_IN (libc)
> +# define PSEUDO_RET \
> + btsti a0, 31; \
> + bt SYSCALL_ERROR; \
> + rts
> +# else
> +# define PSEUDO_RET \
> + btsti a0, 31; \
> + bf 3f; \
> + jmpi SYSCALL_ERROR; \
> +3: \
> + rts
> +# endif /* !IS_IN (libc) */
> +# endif /* __PIC__ */
> +
> +
> +# undef ret
> +# define ret PSEUDO_RET
> +
> +# undef PSEUDO_END
> +# define PSEUDO_END(name) \
> + .align 4; \
> + SYSCALL_ERROR_HANDLER; \
> + END (name)
> +
> +# undef PSEUDO_NOERRNO
> +# define PSEUDO_NOERRNO(name, syscall_name, args) \
> + .text; \
> + ENTRY (name); \
> + DO_CALL (syscall_name, args)
> +
> +# define PSEUDO_RET_NOERRNO \
> + jmp r15;
> +
> +# undef ret_NOERRNO
> +# define ret_NOERRNO PSEUDO_RET_NOERRNO
> +
> +# undef PSEUDO_END_NOERRNO
> +# define PSEUDO_END_NOERRNO(name) \
> + END (name)
> +
> +/* The function has to return the error code. */
> +# undef PSEUDO_ERRVAL
> +# define PSEUDO_ERRVAL(name, syscall_name, args) \
> + .text; \
> + ENTRY (name) \
> + DO_CALL (syscall_name, args); \
> + not a0; \
> + addi a0, 1
> +
> +# undef PSEUDO_END_ERRVAL
> +# define PSEUDO_END_ERRVAL(name) \
> + END (name)
> +
> +# define ret_ERRVAL rts
> +
> +# if !IS_IN (libc)
> +# define SYSCALL_ERROR __local_syscall_error
> +# if RTLD_PRIVATE_ERRNO
> +# ifdef __PIC__
> +# define SYSCALL_ERROR_HANDLER \
> +__local_syscall_error: \
> + lrw a1, rtld_errno@PLT; \
> + addu a1, gb; \
> + ldw a1, (a1); \
> + rsubi a0, 0; \
> + stw a0, (a1); \
> + bmaski a0, 0; \
> + rts
> +# else /* __PIC__ */
> +# define SYSCALL_ERROR_HANDLER \
> +__local_syscall_error: \
> + lrw a1, rtld_errno; \
> + rsubi a0, 0; \
> + stw a0, (a1); \
> + bmaski a0, 0; \
> + rts
> +# endif /* __PIC__ */
> +# else /* !RTLD_PRIVATE_ERRNO */
> +# ifdef __PIC__
> +# define SYSCALL_ERROR_HANDLER \
> +__local_syscall_error: \
> + subi sp, 8; \
> + stw a0, (sp, 0); \
> + stw r15, (sp, 4); \
> + lrw a1, __errno_location@PLT; \
> + add a1, gb; \
> + ldw a1, (a1); \
> + jsr a1; \
> + ldw a1, (sp, 0); /* load errno*/ \
> + ldw r15, (sp, 4); \
> + addi sp, 8; \
> + movi a2, 0; \
> + rsub a1, a1, a2; \
> + stw a1, (a0); \
> + bmaski a0, 0; \
> + rts
> +# else
> +# define SYSCALL_ERROR_HANDLER \
> +__local_syscall_error: \
> + subi sp, 8; \
> + stw a0, (sp, 0); \
> + stw r15, (sp, 4); \
> + lrw a1, __errno_location; \
> + jsr a1; \
> + ldw a1, (sp, 0); /* load errno */ \
> + ldw r15, (sp, 4); \
> + addi sp, 8; \
> + movi a2, 0; \
> + rsub a1, a1, a2; \
> + stw a1, (a0); \
> + bmaski a0, 0; \
> + rts
> +# endif /* __PIC__ */
> +# endif/* RTLD_PRIVATE_ERROR */
> +# else
> +# define SYSCALL_ERROR_HANDLER /* Nothing here; code in sysdep.S is used. */
> +# define SYSCALL_ERROR __syscall_error
> +# endif/* IS_IN (libc) */
> +
> +/* define DO_CALL */
> +#ifdef __CSKYABIV2__
> +#undef DO_CALL
> +#define DO_CALL(syscall_name, args) \
> + DOARGS_##args; \
> + lrw r7, SYS_ify(syscall_name); \
> + trap 0; \
> + UNDOARGS_##args
> +
> +#undef DOARGS_0
> +#define DOARGS_0 \
> + subi sp, 8; \
> + cfi_adjust_cfa_offset (8); \
> + stw r7, (sp, 0); \
> + cfi_rel_offset (r7, 0);
> +
> +#undef DOARGS_1
> +#define DOARGS_1 DOARGS_0
> +#undef DOARGS_2
> +#define DOARGS_2 DOARGS_0
> +#undef DOARGS_3
> +#define DOARGS_3 DOARGS_0
> +#undef DOARGS_4
> +#define DOARGS_4 DOARGS_0
> +#undef DOARGS_5
> +#define DOARGS_5 \
> + subi sp, 8; \
> + cfi_adjust_cfa_offset (8); \
> + stw r7, (sp, 0); \
> + cfi_rel_offset (7, 0); \
> + stw r4, (sp, 4); \
> + cfi_rel_offset (4, 4); \
> + ldw r4, (sp, 8)
> +#undef DOARGS_6
> +#define DOARGS_6 \
> + subi sp, 16; \
> + cfi_adjust_cfa_offset (16); \
> + stw r7, (sp, 0); \
> + cfi_rel_offset (7, 0); \
> + stw r4, (sp, 4); \
> + cfi_rel_offset (4, 4); \
> + stw r5, (sp, 8); \
> + cfi_rel_offset (5, 8); \
> + ldw r4, (sp, 16); \
> + ldw r5, (sp, 20)
> +
> +#undef UNDOARGS_0
> +#define UNDOARGS_0 \
> + ldw r7, (sp, 0); \
> + cfi_restore (r7); \
> + addi sp, 8; \
> + cfi_adjust_cfa_offset (-8);
> +
> +#undef UNDOARGS_1
> +#define UNDOARGS_1 UNDOARGS_0
> +#undef UNDOARGS_2
> +#define UNDOARGS_2 UNDOARGS_0
> +#undef UNDOARGS_3
> +#define UNDOARGS_3 UNDOARGS_0
> +#undef UNDOARGS_4
> +#define UNDOARGS_4 UNDOARGS_0
> +#undef UNDOARGS_5
> +#define UNDOARGS_5 \
> + ldw r7, (sp, 0); \
> + cfi_restore (r4); \
> + ldw r4, (sp, 4); \
> + cfi_restore (r4); \
> + addi sp, 8; \
> + cfi_adjust_cfa_offset (-8);
> +
> +#undef UNDOARGS_6
> +#define UNDOARGS_6 \
> + ldw r7, (sp, 0); \
> + cfi_restore (r7); \
> + ldw r4, (sp, 4); \
> + cfi_restore (r4); \
> + ldw r5, (sp, 8); \
> + cfi_restore (r5); \
> + addi sp, 16; \
> + cfi_adjust_cfa_offset (-16);
> +
> +#else /* __CSKYABIV1__ */
> +
> +#undef DO_CALL
> +#define DO_CALL(syscall_name, args) \
> + lrw r1, SYS_ify(syscall_name); \
> + trap 0
> +//#endif /* DO_CALL */
> +#endif /* __CSKYABIV2__ */
> +
> +/* define DO_CALL_2, only ABIV2 need DO_CALL_2 */
> +#ifdef __CSKYABIV2__
> +
> +#undef DO_CALL_2
> +#define DO_CALL_2(syscall_name, args) \
> + DOARGS2_##args; \
> + lrw r7, SYS_ify(syscall_name); \
> + trap 0; \
> + UNDOARGS2_##args
> +
> +/*
> + * to be quite different with DO_CALL, DO_CALL_2 need not save r7.
> + */
> +#undef DOARGS2_0
> +#define DOARGS2_0
> +
> +#undef DOARGS2_1
> +#define DOARGS2_1 DOARGS2_0
> +#undef DOARGS2_2
> +#define DOARGS2_2 DOARGS2_0
> +#undef DOARGS2_3
> +#define DOARGS2_3 DOARGS2_0
> +#undef DOARGS2_4
> +#define DOARGS2_4 DOARGS2_0
> +#undef DOARGS2_5
> +#define DOARGS2_5 \
> + subi sp, 8; \
> + cfi_adjust_cfa_offset (8); \
> + stw r4, (sp, 0); \
> + cfi_rel_offset (4, 0); \
> + ldw r4, (sp, 20)
> +#undef DOARGS2_6
> +#define DOARGS2_6 \
> + subi sp, 8; \
> + cfi_adjust_cfa_offset (8); \
> + stw r4, (sp, 0); \
> + cfi_rel_offset (4, 0); \
> + stw r5, (sp, 4); \
> + cfi_rel_offset (5, 0); \
> + ldw r4, (sp, 20); \
> + ldw r5, (sp, 24)
> +
> +#undef UNDOARGS2_0
> +#define UNDOARGS2_0
> +
> +#undef UNDOARGS2_1
> +#define UNDOARGS2_1 UNDOARGS2_0
> +#undef UNDOARGS2_2
> +#define UNDOARGS2_2 UNDOARGS2_0
> +#undef UNDOARGS2_3
> +#define UNDOARGS2_3 UNDOARGS2_0
> +#undef UNDOARGS2_4
> +#define UNDOARGS2_4 UNDOARGS2_0
> +#undef UNDOARGS2_5
> +#define UNDOARGS2_5 \
> + ldw r4, (sp, 0); \
> + addi sp, 8
> +
> +#undef UNDOARGS2_6
> +#define UNDOARGS2_6 \
> + ldw r4, (sp, 0); \
> + ldw r5, (sp, 4); \
> + addi sp, 8
> +
> +#endif /* DO_CALL_2 */
> +
> +#else /* not __ASSEMBLER__ */
> +
> +
> +/* Define a macro which expands into the inline wrapper code for a system
> + call. */
> +#undef INLINE_SYSCALL
> +#define INLINE_SYSCALL(name, nr, args...) \
> + ({ unsigned int _inline_sys_result = INTERNAL_SYSCALL (name, , nr, args); \
> + if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (_inline_sys_result, ), 0)) \
> + { \
> + __set_errno (INTERNAL_SYSCALL_ERRNO (_inline_sys_result, )); \
> + _inline_sys_result = (unsigned int) -1; \
> + } \
> + (int) _inline_sys_result; })
> +
> +#undef INTERNAL_SYSCALL_DECL
> +#define INTERNAL_SYSCALL_DECL(err) do { } while (0)
> +
> +#undef INTERNAL_SYSCALL_ERROR_P
> +#define INTERNAL_SYSCALL_ERROR_P(val, err) \
> + ((unsigned int) (val) >= 0xffffff01u)
> +
> +#undef INTERNAL_SYSCALL_ERRNO
> +#define INTERNAL_SYSCALL_ERRNO(val, err) (-(val))
> +
> +
> +#undef INTERNAL_SYSCALL_RAW
> +#ifndef __CSKYABIV2__
> +#define INTERNAL_SYSCALL_RAW0(name, err, dummy...) \
> + ({unsigned int __sys_result; \
> + { \
> + register int _a1 __asm__ ("a0"), _nr __asm__ ("r1"); \
> + _nr = name; \
> + __asm__ __volatile__ ("trap 0 \n\t" \
> + : "=r" (_a1) \
> + : "r" (_nr) \
> + : "memory"); \
> + __sys_result = _a1; \
> + } \
> + (int) __sys_result; })
> +
> +#define INTERNAL_SYSCALL_RAW1(name, err, arg1) \
> + ({unsigned int __sys_result; \
> + register int _tmp_arg1 = (int)(arg1); \
> + { \
> + register int _a1 __asm__ ("a0"), _nr __asm__ ("r1"); \
> + _a1 = _tmp_arg1; \
> + _nr = name; \
> + __asm__ __volatile__ ("trap 0 \n\t" \
> + : "=r" (_a1) \
> + : "r" (_nr), "r" (_a1) \
> + : "memory"); \
> + __sys_result = _a1; \
> + } \
> + (int) __sys_result; })
> +
> +#define INTERNAL_SYSCALL_RAW2(name, err, arg1, arg2) \
> + ({unsigned int __sys_result; \
> + register int _tmp_arg1 = (int)(arg1), _tmp_arg2 = (int)(arg2); \
> + { \
> + register int _nr __asm__ ("r1"); \
> + register int _a1 __asm__ ("a0"), _a2 __asm__ ("a1"); \
> + _a1 = _tmp_arg1, _a2 = _tmp_arg2; \
> + _nr = name; \
> + __asm__ __volatile__ ("trap 0 \n\t" \
> + : "=r" (_a1) \
> + : "r" (_nr), "r" (_a1), "r" (_a2) \
> + : "memory"); \
> + __sys_result = _a1; \
> + } \
> + (int) __sys_result; })
> +
> +#define INTERNAL_SYSCALL_RAW3(name, err, arg1, arg2, arg3) \
> + ({unsigned int __sys_result; \
> + register int _tmp_arg1 = (int)(arg1), _tmp_arg2 = (int)(arg2); \
> + register int _tmp_arg3 = (int)(arg3); \
> + { \
> + register int _nr __asm__ ("r1"); \
> + register int _a1 __asm__ ("a0"), _a2 __asm__ ("a1"); \
> + register int _a3 __asm__ ("a2"); \
> + _a1 = _tmp_arg1; \
> + _a2 = _tmp_arg2; \
> + _a3 = _tmp_arg3; \
> + _nr = name; \
> + __asm__ __volatile__ ("trap 0 \n\t" \
> + : "=r" (_a1) \
> + : "r" (_nr), "r" (_a1), "r" (_a2), \
> + "r" (_a3) \
> + : "memory"); \
> + __sys_result = _a1; \
> + } \
> + (int) __sys_result; })
> +
> +#define INTERNAL_SYSCALL_RAW4(name, err, arg1, arg2, arg3, arg4) \
> + ({unsigned int __sys_result; \
> + register int _tmp_arg1 = (int)(arg1), _tmp_arg2 = (int)(arg2); \
> + register int _tmp_arg3 = (int)(arg3), _tmp_arg4 = (int)(arg4); \
> + { \
> + register int _nr __asm__ ("r1"); \
> + register int _a1 __asm__ ("a0"), _a2 __asm__ ("a1"); \
> + register int _a3 __asm__ ("a2"), _a4 __asm__ ("a3"); \
> + _a1 = _tmp_arg1, _a2 = _tmp_arg2, _a3 = _tmp_arg3; \
> + _a4 = _tmp_arg4; \
> + _nr = name; \
> + __asm__ __volatile__ ("trap 0 \n\t" \
> + : "=r" (_a1) \
> + : "r" (_nr), "r" (_a1), "r" (_a2), \
> + "r" (_a3), "r" (_a4) \
> + : "memory"); \
> + __sys_result = _a1; \
> + } \
> + (int) __sys_result; })
> +
> +#define INTERNAL_SYSCALL_RAW5(name, err, arg1, arg2, arg3, arg4, \
> + arg5) \
> + ({unsigned int __sys_result; \
> + register int _tmp_arg1 = (int)(arg1), _tmp_arg2 = (int)(arg2); \
> + register int _tmp_arg3 = (int)(arg3), _tmp_arg4 = (int)(arg4); \
> + register int _tmp_arg5 = (int)(arg5); \
> + { \
> + register int _nr __asm__ ("r1"); \
> + register int _a1 __asm__ ("a0"), _a2 __asm__ ("a1"); \
> + register int _a3 __asm__ ("a2"), _a4 __asm__ ("a3"); \
> + register int _a5 __asm__ ("a4"); \
> + _a1 = _tmp_arg1, _a2 = _tmp_arg2, _a3 = _tmp_arg3; \
> + _a4 = _tmp_arg4, _a5 = _tmp_arg5; \
> + _nr = name; \
> + __asm__ __volatile__ ("trap 0 \n\t" \
> + : "=r" (_a1) \
> + : "r" (_nr), "r" (_a1), "r" (_a2), \
> + "r" (_a3), "r" (_a4), "r" (_a5) \
> + : "memory"); \
> + __sys_result = _a1; \
> + } \
> + (int) __sys_result; })
> +
> +#define INTERNAL_SYSCALL_RAW6(name, err, arg1, arg2, arg3, arg4, \
> + arg5, arg6) \
> + ({unsigned int __sys_result; \
> + register int _tmp_arg1 = (int)(arg1), _tmp_arg2 = (int)(arg2); \
> + register int _tmp_arg3 = (int)(arg3), _tmp_arg4 = (int)(arg4); \
> + register int _tmp_arg5 = (int)(arg5), _tmp_arg6 = (int)(arg6); \
> + { \
> + register int _nr __asm__ ("r1"); \
> + register int _a1 __asm__ ("a0"), _a2 __asm__ ("a1"); \
> + register int _a3 __asm__ ("a2"), _a4 __asm__ ("a3"); \
> + register int _a5 __asm__ ("a4"), _a6 __asm__ ("a5"); \
> + _a1 = _tmp_arg1, _a2 = _tmp_arg2, _a3 = _tmp_arg3; \
> + _a4 = _tmp_arg4, _a5 = _tmp_arg5, _a6 = _tmp_arg6; \
> + _nr = name; \
> + __asm__ __volatile__ ("trap 0 \n\t" \
> + : "=r" (_a1) \
> + : "r" (_nr), "r" (_a1), "r" (_a2), \
> + "r" (_a3), "r" (_a4), "r" (_a5), \
> + "r" (_a6) \
> + : "memory"); \
> + __sys_result = _a1; \
> + } \
> + (int) __sys_result; })
> +
> +#define INTERNAL_SYSCALL_RAW7(name, err, arg1, arg2, arg3, arg4, \
> + arg5, arg6, arg7) \
> + ({unsigned int __sys_result; \
> + register int _tmp_arg1 = (int)(arg1), _tmp_arg2 = (int)(arg2); \
> + register int _tmp_arg3 = (int)(arg3), _tmp_arg4 = (int)(arg4); \
> + register int _tmp_arg5 = (int)(arg5), _tmp_arg6 = (int)(arg6); \
> + register int _tmp_arg7 = (int)(arg7); \
> + { \
> + register int _nr __asm__ ("r1"); \
> + register int _a1 __asm__ ("a0"), _a2 __asm__ ("a1"); \
> + register int _a3 __asm__ ("a2"), _a4 __asm__ ("a3"); \
> + register int _a5 __asm__ ("a4"), _a6 __asm__ ("a5"); \
> + register int _a7 __asm__ ("r8"); \
> + _a1 = _tmp_arg1, _a2 = _tmp_arg2, _a3 = _tmp_arg3; \
> + _a4 = _tmp_arg4, _a5 = _tmp_arg5, _a6 = _tmp_arg6; \
> + _a7 = _tmp_arg7; \
> + _nr = name; \
> + __asm__ __volatile__ ("trap 0 \n\t" \
> + : "=r" (_a1) \
> + : "r" (_nr), "r" (_a1), "r" (_a2), \
> + "r" (_a3), "r" (_a4), "r" (_a5), \
> + "r" (_a6), "r" (_a7) \
> + : "memory"); \
> + __sys_result = _a1; \
> + } \
> + (int) __sys_result; })
> +
> +#else
> +#define INTERNAL_SYSCALL_RAW0(name, err, dummy...) \
> + ({unsigned int __sys_result; \
> + { \
> + register int _a1 __asm__ ("a0"), _nr __asm__ ("r7"); \
> + _nr = name; \
> + __asm__ __volatile__ ("trap 0 \n\t" \
> + : "=r" (_a1) \
> + : "r" (_nr) \
> + : "memory"); \
> + __sys_result = _a1; \
> + } \
> + (int) __sys_result; })
> +
> +#define INTERNAL_SYSCALL_RAW1(name, err, arg1) \
> + ({unsigned int __sys_result; \
> + register int _tmp_arg1 = (int)(arg1); \
> + { \
> + register int _a1 __asm__ ("a0"), _nr __asm__ ("r7"); \
> + _a1 = _tmp_arg1; \
> + _nr = name; \
> + __asm__ __volatile__ ("trap 0 \n\t" \
> + : "=r" (_a1) \
> + : "r" (_nr), "r" (_a1) \
> + : "memory"); \
> + __sys_result = _a1; \
> + } \
> + (int) __sys_result; })
> +
> +#define INTERNAL_SYSCALL_RAW2(name, err, arg1, arg2) \
> + ({unsigned int __sys_result; \
> + register int _tmp_arg1 = (int)(arg1), _tmp_arg2 = (int)(arg2); \
> + { \
> + register int _nr __asm__ ("r7"); \
> + register int _a1 __asm__ ("a0"), _a2 __asm__ ("a1"); \
> + _a1 = _tmp_arg1, _a2 = _tmp_arg2; \
> + _nr = name; \
> + __asm__ __volatile__ ("trap 0 \n\t" \
> + : "=r" (_a1) \
> + : "r" (_nr), "r" (_a1), "r" (_a2) \
> + : "memory"); \
> + __sys_result = _a1; \
> + } \
> + (int) __sys_result; })
> +
> +#define INTERNAL_SYSCALL_RAW3(name, err, arg1, arg2, arg3) \
> + ({unsigned int __sys_result; \
> + register int _tmp_arg1 = (int)(arg1), _tmp_arg2 = (int)(arg2); \
> + register int _tmp_arg3 = (int)(arg3); \
> + { \
> + register int _nr __asm__ ("r7"); \
> + register int _a1 __asm__ ("a0"), _a2 __asm__ ("a1"); \
> + register int _a3 __asm__ ("a2"); \
> + _a1 = _tmp_arg1; \
> + _a2 = _tmp_arg2; \
> + _a3 = _tmp_arg3; \
> + _nr = name; \
> + __asm__ __volatile__ ("trap 0 \n\t" \
> + : "=r" (_a1) \
> + : "r" (_nr), "r" (_a1), "r" (_a2), \
> + "r" (_a3) \
> + : "memory"); \
> + __sys_result = _a1; \
> + } \
> + (int) __sys_result; })
> +
> +#define INTERNAL_SYSCALL_RAW4(name, err, arg1, arg2, arg3, arg4) \
> + ({unsigned int __sys_result; \
> + register int _tmp_arg1 = (int)(arg1), _tmp_arg2 = (int)(arg2); \
> + register int _tmp_arg3 = (int)(arg3), _tmp_arg4 = (int)(arg4); \
> + { \
> + register int _nr __asm__ ("r7"); \
> + register int _a1 __asm__ ("a0"), _a2 __asm__ ("a1"); \
> + register int _a3 __asm__ ("a2"), _a4 __asm__ ("a3"); \
> + _a1 = _tmp_arg1, _a2 = _tmp_arg2, _a3 = _tmp_arg3; \
> + _a4 = _tmp_arg4; \
> + _nr = name; \
> + __asm__ __volatile__ ("trap 0 \n\t" \
> + : "=r" (_a1) \
> + : "r" (_nr), "r" (_a1), "r" (_a2), \
> + "r" (_a3), "r" (_a4) \
> + : "memory"); \
> + __sys_result = _a1; \
> + } \
> + (int) __sys_result; })
> +
> +#define INTERNAL_SYSCALL_RAW5(name, err, arg1, arg2, arg3, arg4, \
> + arg5) \
> + ({unsigned int __sys_result; \
> + register int _tmp_arg1 = (int)(arg1), _tmp_arg2 = (int)(arg2); \
> + register int _tmp_arg3 = (int)(arg3), _tmp_arg4 = (int)(arg4); \
> + register int _tmp_arg5 = (int)(arg5); \
> + { \
> + register int _nr __asm__ ("r7"); \
> + register int _a1 __asm__ ("a0"), _a2 __asm__ ("a1"); \
> + register int _a3 __asm__ ("a2"), _a4 __asm__ ("a3"); \
> + register int _a5 __asm__ ("r4"); \
> + _a1 = _tmp_arg1, _a2 = _tmp_arg2, _a3 = _tmp_arg3; \
> + _a4 = _tmp_arg4, _a5 = _tmp_arg5; \
> + _nr = name; \
> + __asm__ __volatile__ ("trap 0 \n\t" \
> + : "=r" (_a1) \
> + : "r" (_nr), "r" (_a1), "r" (_a2), \
> + "r" (_a3), "r" (_a4), "r" (_a5) \
> + : "memory"); \
> + __sys_result = _a1; \
> + } \
> + (int) __sys_result; })
> +
> +#define INTERNAL_SYSCALL_RAW6(name, err, arg1, arg2, arg3, arg4, \
> + arg5, arg6) \
> + ({unsigned int __sys_result; \
> + register int _tmp_arg1 = (int)(arg1), _tmp_arg2 = (int)(arg2); \
> + register int _tmp_arg3 = (int)(arg3), _tmp_arg4 = (int)(arg4); \
> + register int _tmp_arg5 = (int)(arg5), _tmp_arg6 = (int)(arg6); \
> + { \
> + register int _nr __asm__ ("r7"); \
> + register int _a1 __asm__ ("a0"), _a2 __asm__ ("a1"); \
> + register int _a3 __asm__ ("a2"), _a4 __asm__ ("a3"); \
> + register int _a5 __asm__ ("r4"), _a6 __asm__ ("r5"); \
> + _a1 = _tmp_arg1, _a2 = _tmp_arg2, _a3 = _tmp_arg3; \
> + _a4 = _tmp_arg4, _a5 = _tmp_arg5, _a6 = _tmp_arg6; \
> + _nr = name; \
> + __asm__ __volatile__ ("trap 0 \n\t" \
> + : "=r" (_a1) \
> + : "r" (_nr), "r" (_a1), "r" (_a2), \
> + "r" (_a3), "r" (_a4), "r" (_a5), \
> + "r" (_a6) \
> + : "memory"); \
> + __sys_result = _a1; \
> + } \
> + (int) __sys_result; })
> +
> +#define INTERNAL_SYSCALL_RAW7(name, err, arg1, arg2, arg3, arg4, \
> + arg5, arg6, arg7) \
> + ({unsigned int __sys_result; \
> + register int _tmp_arg1 = (int)(arg1), _tmp_arg2 = (int)(arg2); \
> + register int _tmp_arg3 = (int)(arg3), _tmp_arg4 = (int)(arg4); \
> + register int _tmp_arg5 = (int)(arg5), _tmp_arg6 = (int)(arg6); \
> + register int _tmp_arg7 = (int)(arg7); \
> + { \
> + register int _nr __asm__ ("r7"); \
> + register int _a1 __asm__ ("a0"), _a2 __asm__ ("a1"); \
> + register int _a3 __asm__ ("a2"), _a4 __asm__ ("a3"); \
> + register int _a5 __asm__ ("r4"), _a6 __asm__ ("r5"); \
> + register int _a7 __asm__ ("r6"); \
> + _a1 = _tmp_arg1, _a2 = _tmp_arg2, _a3 = _tmp_arg3; \
> + _a4 = _tmp_arg4, _a5 = _tmp_arg5, _a6 = _tmp_arg6; \
> + _a7 = _tmp_arg7; \
> + _nr = name; \
> + __asm__ __volatile__ ("trap 0 \n\t" \
> + : "=r" (_a1) \
> + : "r" (_nr), "r" (_a1), "r" (_a2), \
> + "r" (_a3), "r" (_a4), "r" (_a5), \
> + "r" (_a6), "r" (_a7) \
> + : "memory"); \
> + __sys_result = _a1; \
> + } \
> + (int) __sys_result; })
> +
> +#endif /* __ABI_CSKY_V2__ */
> +
> +#undef INTERNAL_SYSCALL
> +#define INTERNAL_SYSCALL(name, err, nr, args...) \
> + INTERNAL_SYSCALL_RAW##nr(SYS_ify(name), err, args)
> +
> +#undef INTERNAL_SYSCALL_NCS
> +#define INTERNAL_SYSCALL_NCS(number, err, nr, args...) \
> + INTERNAL_SYSCALL_RAW##nr (number, err, args)
> +
> +#endif /* __ASSEMBLER__ */
> +
> +/* Pointer mangling is not yet supported for CSKY. */
> +#define PTR_MANGLE(var) (void) (var)
> +#define PTR_DEMANGLE(var) (void) (var)
Is there any special reason to not support it? Other architecture accomplish
by either using a global variable or a TCB field.