about summary refs log tree commit diff
path: root/ports/sysdeps/unix/sysv/linux/am33/linuxthreads/sysdep-cancel.h
diff options
context:
space:
mode:
Diffstat (limited to 'ports/sysdeps/unix/sysv/linux/am33/linuxthreads/sysdep-cancel.h')
-rw-r--r--ports/sysdeps/unix/sysv/linux/am33/linuxthreads/sysdep-cancel.h158
1 files changed, 158 insertions, 0 deletions
diff --git a/ports/sysdeps/unix/sysv/linux/am33/linuxthreads/sysdep-cancel.h b/ports/sysdeps/unix/sysv/linux/am33/linuxthreads/sysdep-cancel.h
new file mode 100644
index 0000000000..5f3dab5c40
--- /dev/null
+++ b/ports/sysdeps/unix/sysv/linux/am33/linuxthreads/sysdep-cancel.h
@@ -0,0 +1,158 @@
+/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Alexandre Oliva <aoliva@redhat.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 <tls.h>
+#include <pt-machine.h>
+#ifndef __ASSEMBLER__
+# include <linuxthreads/internals.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)				\
+  .text	;								\
+ ENTRY (name)								\
+  PUSHARGS_##args							\
+  DOARGS_##args								\
+  SINGLE_THREAD_P;							\
+  bne L(pseudo_cancel);							\
+  mov SYS_ify (syscall_name),d0;					\
+  syscall 0								\
+  POPARGS_##args ;							\
+  cmp -126,d0;								\
+  bls L(pseudo_end);							\
+  jmp SYSCALL_ERROR_LABEL;						\
+ L(pseudo_cancel):							\
+  add -(16+STACK_SPACE (args)),sp;					\
+  SAVE_ARGS_##args							\
+  CENABLE								\
+  mov d0,r0;								\
+  LOAD_ARGS_##args							\
+  mov SYS_ify (syscall_name),d0;					\
+  syscall 0;								\
+  mov d0,(12,sp);							\
+  mov r0,d0;								\
+  CDISABLE								\
+  mov (12,sp),d0;							\
+  add +16+STACK_SPACE (args),sp						\
+  POPARGS_##args ;							\
+  cmp -126,d0;								\
+  bls L(pseudo_end);							\
+  jmp SYSCALL_ERROR_LABEL;						\
+ L(pseudo_end):								\
+  mov d0,a0
+
+/* Reserve up to 2 stack slots for a0 and d1, but fewer than that if
+   we don't have that many arguments.  */
+# define STACK_SPACE(n) (((((n) < 3) * (2 - (n))) + 2) * 4)
+
+# define SAVE_ARGS_0
+# define SAVE_ARGS_1	mov a0,(20,sp) ;
+# define SAVE_ARGS_2	SAVE_ARGS_1 mov d1,(24,sp) ;
+# define SAVE_ARGS_3	SAVE_ARGS_2
+# define SAVE_ARGS_4	SAVE_ARGS_3
+# define SAVE_ARGS_5	SAVE_ARGS_4
+# define SAVE_ARGS_6	SAVE_ARGS_5
+
+# define LOAD_ARGS_0
+# define LOAD_ARGS_1	mov (20,sp),a0 ;
+# define LOAD_ARGS_2	LOAD_ARGS_1 mov (24,sp),d1 ;
+# define LOAD_ARGS_3	LOAD_ARGS_2
+# define LOAD_ARGS_4	LOAD_ARGS_3
+# define LOAD_ARGS_5	LOAD_ARGS_4
+# define LOAD_ARGS_6	LOAD_ARGS_5
+
+# ifdef IS_IN_libpthread
+#  define CENABLE	call __pthread_enable_asynccancel,[],0;
+#  define CDISABLE	call __pthread_disable_asynccancel,[],0;
+# elif defined IS_IN_librt
+#  ifdef PIC
+#   define CENABLE	movm [a2],(sp); \
+			1: mov pc,a2; \
+			add _GLOBAL_OFFSET_TABLE_-(1b-.),a2; \
+			call +__librt_enable_asynccancel@PLT,[],0; \
+			movm (sp),[a2];
+#   define CENABLE	movm [a2],(sp); \
+			1: mov pc,a2; \
+			add _GLOBAL_OFFSET_TABLE_-(1b-.),a2; \
+			call +__librt_disable_asynccancel@PLT,[],0; \
+			movm (sp),[a2];
+#  else
+#   define CENABLE	call +__librt_enable_asynccancel,[],0;
+#   define CDISABLE	call +__librt_disable_asynccancel,[],0;
+#  endif
+# else
+#  define CENABLE	call +__libc_enable_asynccancel,[],0;
+#  define CDISABLE	call +__libc_disable_asynccancel,[],0;
+# endif
+
+#if !defined NOT_IN_libc
+# define __local_multiple_threads __libc_multiple_threads
+#elif defined IS_IN_libpthread
+# define __local_multiple_threads __pthread_multiple_threads
+#else
+# define __local_multiple_threads __librt_multiple_threads
+#endif
+
+# ifndef __ASSEMBLER__
+#  if defined FLOATING_STACKS && USE___THREAD && defined PIC
+#   define SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF,				      \
+				   p_header.data.multiple_threads) == 0, 1)
+#  else
+extern int __local_multiple_threads
+#   if !defined NOT_IN_libc || defined IS_IN_libpthread
+  attribute_hidden;
+#   else
+  ;
+#   endif
+#   define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
+#  endif
+# else
+#  if !defined PIC
+#   define SINGLE_THREAD_P \
+	mov (+__local_multiple_threads),d0; \
+	cmp 0,d0
+#  elif !defined NOT_IN_libc || defined IS_IN_libpthread
+#   define SINGLE_THREAD_P \
+	movm [a2],(sp); \
+     1: mov pc,a2; \
+	add _GLOBAL_OFFSET_TABLE_-(1b-.),a2; \
+	mov (+__local_multiple_threads@GOTOFF,a2),d0; \
+	movm (sp),[a2]; \
+	cmp 0,d0
+#  else
+#   define SINGLE_THREAD_P \
+	movm [a2],(sp); \
+     1: mov pc,a2; \
+	add _GLOBAL_OFFSET_TABLE_-(1b-.),a2; \
+	mov (+__local_multiple_threads@GOT,a2),a2; \
+	mov (a2),d0; \
+	movm (sp),[a2]; \
+	cmp 0,d0
+#  endif
+# endif
+
+#elif !defined __ASSEMBLER__
+
+/* This code should never be used but we define it anyhow.  */
+# define SINGLE_THREAD_P (1)
+
+#endif