Update copyright notices with scripts/update-copyrights
[jlayton/glibc.git] / ports / sysdeps / unix / sysv / linux / am33 / linuxthreads / sysdep-cancel.h
1 /* Copyright (C) 2002-2014 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Alexandre Oliva <aoliva@redhat.com>
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library.  If not, see
17    <http://www.gnu.org/licenses/>.  */
18
19 #include <sysdep.h>
20 #include <tls.h>
21 #include <pt-machine.h>
22 #ifndef __ASSEMBLER__
23 # include <linuxthreads/internals.h>
24 #endif
25
26 #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
27
28 # undef PSEUDO
29 # define PSEUDO(name, syscall_name, args)                               \
30   .text ;                                                               \
31  ENTRY (name)                                                           \
32   PUSHARGS_##args                                                       \
33   DOARGS_##args                                                         \
34   SINGLE_THREAD_P;                                                      \
35   bne L(pseudo_cancel);                                                 \
36   mov SYS_ify (syscall_name),d0;                                        \
37   syscall 0                                                             \
38   POPARGS_##args ;                                                      \
39   cmp -126,d0;                                                          \
40   bls L(pseudo_end);                                                    \
41   jmp SYSCALL_ERROR_LABEL;                                              \
42  L(pseudo_cancel):                                                      \
43   add -(16+STACK_SPACE (args)),sp;                                      \
44   SAVE_ARGS_##args                                                      \
45   CENABLE                                                               \
46   mov d0,r0;                                                            \
47   LOAD_ARGS_##args                                                      \
48   mov SYS_ify (syscall_name),d0;                                        \
49   syscall 0;                                                            \
50   mov d0,(12,sp);                                                       \
51   mov r0,d0;                                                            \
52   CDISABLE                                                              \
53   mov (12,sp),d0;                                                       \
54   add +16+STACK_SPACE (args),sp                                         \
55   POPARGS_##args ;                                                      \
56   cmp -126,d0;                                                          \
57   bls L(pseudo_end);                                                    \
58   jmp SYSCALL_ERROR_LABEL;                                              \
59  L(pseudo_end):                                                         \
60   mov d0,a0
61
62 /* Reserve up to 2 stack slots for a0 and d1, but fewer than that if
63    we don't have that many arguments.  */
64 # define STACK_SPACE(n) (((((n) < 3) * (2 - (n))) + 2) * 4)
65
66 # define SAVE_ARGS_0
67 # define SAVE_ARGS_1    mov a0,(20,sp) ;
68 # define SAVE_ARGS_2    SAVE_ARGS_1 mov d1,(24,sp) ;
69 # define SAVE_ARGS_3    SAVE_ARGS_2
70 # define SAVE_ARGS_4    SAVE_ARGS_3
71 # define SAVE_ARGS_5    SAVE_ARGS_4
72 # define SAVE_ARGS_6    SAVE_ARGS_5
73
74 # define LOAD_ARGS_0
75 # define LOAD_ARGS_1    mov (20,sp),a0 ;
76 # define LOAD_ARGS_2    LOAD_ARGS_1 mov (24,sp),d1 ;
77 # define LOAD_ARGS_3    LOAD_ARGS_2
78 # define LOAD_ARGS_4    LOAD_ARGS_3
79 # define LOAD_ARGS_5    LOAD_ARGS_4
80 # define LOAD_ARGS_6    LOAD_ARGS_5
81
82 # ifdef IS_IN_libpthread
83 #  define CENABLE       call __pthread_enable_asynccancel,[],0;
84 #  define CDISABLE      call __pthread_disable_asynccancel,[],0;
85 # elif defined IS_IN_librt
86 #  ifdef PIC
87 #   define CENABLE      movm [a2],(sp); \
88                         1: mov pc,a2; \
89                         add _GLOBAL_OFFSET_TABLE_-(1b-.),a2; \
90                         call +__librt_enable_asynccancel@PLT,[],0; \
91                         movm (sp),[a2];
92 #   define CENABLE      movm [a2],(sp); \
93                         1: mov pc,a2; \
94                         add _GLOBAL_OFFSET_TABLE_-(1b-.),a2; \
95                         call +__librt_disable_asynccancel@PLT,[],0; \
96                         movm (sp),[a2];
97 #  else
98 #   define CENABLE      call +__librt_enable_asynccancel,[],0;
99 #   define CDISABLE     call +__librt_disable_asynccancel,[],0;
100 #  endif
101 # else
102 #  define CENABLE       call +__libc_enable_asynccancel,[],0;
103 #  define CDISABLE      call +__libc_disable_asynccancel,[],0;
104 # endif
105
106 #if !defined NOT_IN_libc
107 # define __local_multiple_threads __libc_multiple_threads
108 #elif defined IS_IN_libpthread
109 # define __local_multiple_threads __pthread_multiple_threads
110 #else
111 # define __local_multiple_threads __librt_multiple_threads
112 #endif
113
114 # ifndef __ASSEMBLER__
115 #  if defined FLOATING_STACKS && USE___THREAD && defined PIC
116 #   define SINGLE_THREAD_P \
117   __builtin_expect (THREAD_GETMEM (THREAD_SELF,                               \
118                                    p_header.data.multiple_threads) == 0, 1)
119 #  else
120 extern int __local_multiple_threads
121 #   if !defined NOT_IN_libc || defined IS_IN_libpthread
122   attribute_hidden;
123 #   else
124   ;
125 #   endif
126 #   define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
127 #  endif
128 # else
129 #  if !defined PIC
130 #   define SINGLE_THREAD_P \
131         mov (+__local_multiple_threads),d0; \
132         cmp 0,d0
133 #  elif !defined NOT_IN_libc || defined IS_IN_libpthread
134 #   define SINGLE_THREAD_P \
135         movm [a2],(sp); \
136      1: mov pc,a2; \
137         add _GLOBAL_OFFSET_TABLE_-(1b-.),a2; \
138         mov (+__local_multiple_threads@GOTOFF,a2),d0; \
139         movm (sp),[a2]; \
140         cmp 0,d0
141 #  else
142 #   define SINGLE_THREAD_P \
143         movm [a2],(sp); \
144      1: mov pc,a2; \
145         add _GLOBAL_OFFSET_TABLE_-(1b-.),a2; \
146         mov (+__local_multiple_threads@GOT,a2),a2; \
147         mov (a2),d0; \
148         movm (sp),[a2]; \
149         cmp 0,d0
150 #  endif
151 # endif
152
153 #elif !defined __ASSEMBLER__
154
155 /* This code should never be used but we define it anyhow.  */
156 # define SINGLE_THREAD_P (1)
157
158 #endif