diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/microblaze/Makefile | 5 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/microblaze/socket.S | 2 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/microblaze/sysdep-cancel.h | 158 |
4 files changed, 171 insertions, 1 deletions
@@ -1,3 +1,10 @@ +2014-07-01 David Holsgrove <david.holsgrove@xilinx.com> + + * sysdeps/unix/sysv/linux/microblaze/sysdep-cancel.h: New file. + * sysdeps/unix/sysv/linux/microblaze/socket.S: Update SINGLE_THREAD_P use. + * sysdeps/unix/sysv/linux/microblaze/Makefile(libpthread-routines): + Add sysdep. + 2014-06-30 Adhemerval Zanella <azanella@linux.vnet.ibm.com> * sysdeps/powerpc/fpu/libm-test-ulps: Update. diff --git a/sysdeps/unix/sysv/linux/microblaze/Makefile b/sysdeps/unix/sysv/linux/microblaze/Makefile index 614553204f..44a838fa11 100644 --- a/sysdeps/unix/sysv/linux/microblaze/Makefile +++ b/sysdeps/unix/sysv/linux/microblaze/Makefile @@ -1,3 +1,8 @@ ifeq ($(subdir),resource) sysdep_routines += backtrace_linux endif + +ifeq ($(subdir),nptl) +# pull in __syscall_error routine +libpthread-routines += sysdep +endif
\ No newline at end of file diff --git a/sysdeps/unix/sysv/linux/microblaze/socket.S b/sysdeps/unix/sysv/linux/microblaze/socket.S index ab1cb54070..a5b6ec4ac2 100644 --- a/sysdeps/unix/sysv/linux/microblaze/socket.S +++ b/sysdeps/unix/sysv/linux/microblaze/socket.S @@ -80,7 +80,7 @@ ENTRY(__socket) /* The rest of the args (if any) are on the caller's stack already. */ #if defined NEED_CANCELLATION && defined CENABLE - SINGLE_THREAD_P + SINGLE_THREAD_P(r12) bnei r12,L(socket_cancel) #endif diff --git a/sysdeps/unix/sysv/linux/microblaze/sysdep-cancel.h b/sysdeps/unix/sysv/linux/microblaze/sysdep-cancel.h new file mode 100644 index 0000000000..0080d8d4f9 --- /dev/null +++ b/sysdeps/unix/sysv/linux/microblaze/sysdep-cancel.h @@ -0,0 +1,158 @@ +/* Copyright (C) 2014 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> +#ifndef __ASSEMBLER__ +# include <nptl/pthreadP.h> +#endif + +#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt + +# if !defined(IS_IN_librt) || !defined(PIC) +# define AC_STACK_SIZE 16 /* space for r15, async_cancel arg and 2 temp words */ +# define AC_SET_GOT /* empty */ +# define AC_RESTORE_GOT /* empty */ +# else +# define AC_STACK_SIZE 20 /* extra 4 bytes for r20 */ +# define AC_SET_GOT \ + swi r20, r1, AC_STACK_SIZE-4; \ + mfs r20, rpc; \ + addik r20, r20, _GLOBAL_OFFSET_TABLE_+8; +# define AC_RESTORE_GOT \ + lwi r20, r1, AC_STACK_SIZE-4; +# endif + +# undef PSEUDO +# define PSEUDO(name, syscall_name, args) \ + .text; \ + ENTRY (name) \ + SINGLE_THREAD_P(r12); \ + bnei r12, L(pseudo_cancel); \ + .globl __##syscall_name##_nocancel; \ + .type __##syscall_name##_nocancel,@function; \ +__##syscall_name##_nocancel: \ + DO_CALL (syscall_name, args); \ + addik r4, r0, -4095; \ + cmpu r4, r4, r3; \ + bgei r4, SYSCALL_ERROR_LABEL; \ + rtsd r15, 8; \ + nop; \ + .size __##syscall_name##_nocancel, .-__##syscall_name##_nocancel; \ +L(pseudo_cancel): \ + addik r1, r1, -AC_STACK_SIZE; \ + swi r15, r1, 0; \ + AC_SET_GOT \ + DOCARGS_##args \ + CENABLE; \ + swi r3, r1, 8; \ + UNDOCARGS_##args \ + DO_CALL (syscall_name, args); \ + swi r3, r1, 12; \ + lwi r5, r1, 8; \ + CDISABLE; \ + lwi r3, r1, 12; \ + lwi r15, r1, 0; \ + AC_RESTORE_GOT \ + addik r1, r1, AC_STACK_SIZE; \ + addik r4, r0, -4095; \ + cmpu r4, r4, r3; \ + bgei r4, SYSCALL_ERROR_LABEL; \ + rtsd r15, 8; \ + nop; + +/* + * Macros to save/restore syscall arguments across CENABLE + * The arguments are saved into the caller's stack (original r1 + 4) + */ + +# define DOCARGS_0 +# define DOCARGS_1 swi r5, r1, AC_STACK_SIZE + 4; +# define DOCARGS_2 swi r6, r1, AC_STACK_SIZE + 8; DOCARGS_1 +# define DOCARGS_3 swi r7, r1, AC_STACK_SIZE + 12; DOCARGS_2 +# define DOCARGS_4 swi r8, r1, AC_STACK_SIZE + 16; DOCARGS_3 +# define DOCARGS_5 swi r9, r1, AC_STACK_SIZE + 20; DOCARGS_4 +# define DOCARGS_6 swi r10, r1, AC_STACK_SIZE + 24; DOCARGS_5 + +# define UNDOCARGS_0 +# define UNDOCARGS_1 lwi r5, r1, AC_STACK_SIZE + 4; +# define UNDOCARGS_2 UNDOCARGS_1 lwi r6, r1, AC_STACK_SIZE + 8; +# define UNDOCARGS_3 UNDOCARGS_2 lwi r7, r1, AC_STACK_SIZE + 12; +# define UNDOCARGS_4 UNDOCARGS_3 lwi r8, r1, AC_STACK_SIZE + 16; +# define UNDOCARGS_5 UNDOCARGS_4 lwi r9, r1, AC_STACK_SIZE + 20; +# define UNDOCARGS_6 UNDOCARGS_5 lwi r10, r1, AC_STACK_SIZE + 24; + +# ifdef PIC +# define PSEUDO_JMP(sym) brlid r15, sym##@PLTPC; addk r0, r0, r0 +# else +# define PSEUDO_JMP(sym) brlid r15, sym; addk r0, r0, r0 +# endif + +# ifdef IS_IN_libpthread +# define CENABLE PSEUDO_JMP (__pthread_enable_asynccancel) +# define CDISABLE PSEUDO_JMP (__pthread_disable_asynccancel) +# define __local_multiple_threads __pthread_multiple_threads +# elif !defined NOT_IN_libc +# define CENABLE PSEUDO_JMP (__libc_enable_asynccancel) +# define CDISABLE PSEUDO_JMP (__libc_disable_asynccancel) +# define __local_multiple_threads __libc_multiple_threads +# elif defined IS_IN_librt +# define CENABLE PSEUDO_JMP (__librt_enable_asynccancel) +# define CDISABLE PSEUDO_JMP (__librt_disable_asynccancel) +# else +# error Unsupported library +# endif + + +# if defined IS_IN_libpthread || !defined NOT_IN_libc +# ifndef __ASSEMBLER__ +extern int __local_multiple_threads attribute_hidden; +# define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1) +# else +# if !defined PIC +# define SINGLE_THREAD_P(reg) lwi reg, r0, __local_multiple_threads; +# else +# define SINGLE_THREAD_P(reg) \ + mfs reg, rpc; \ + addik reg, reg, _GLOBAL_OFFSET_TABLE_+8; \ + lwi reg, reg, __local_multiple_threads@GOT; \ + lwi reg, reg, 0; +# endif +# endif +# else +# ifndef __ASSEMBLER__ +# define SINGLE_THREAD_P \ + __builtin_expect (THREAD_GETMEM (THREAD_SELF, \ + header.multiple_threads) == 0, 1) +# else +# define SINGLE_THREAD_P(reg) \ + lwi reg, r0, MULTIPLE_THREADS_OFFSET(reg) +# endif +# endif + +#elif !defined __ASSEMBLER__ + +# 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 |