SH: Consolidate nptl/ subdirectories under linux/.....
[platform/upstream/glibc.git] / sysdeps / unix / sysv / linux / m68k / nptl / sysdep-cancel.h
1 /* Copyright (C) 2010-2014 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Maxim Kuvyrkov <maxim@codesourcery.com>, 2010.
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 #ifndef __ASSEMBLER__
22 # include <nptl/pthreadP.h>
23 #endif
24
25 #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
26
27 # undef PSEUDO
28 # define PSEUDO(name, syscall_name, args)                                     \
29   .text;                                                                      \
30   ENTRY (name)                                                                \
31     SINGLE_THREAD_P;                                                          \
32     jne .Lpseudo_cancel;                                                      \
33   .type __##syscall_name##_nocancel,@function;                                \
34   .globl __##syscall_name##_nocancel;                                         \
35   __##syscall_name##_nocancel:                                                \
36     DO_CALL (syscall_name, args);                                             \
37     cmp.l &-4095, %d0;                                                        \
38     jcc SYSCALL_ERROR_LABEL;                                                  \
39     rts;                                                                      \
40   .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel;            \
41   .Lpseudo_cancel:                                                            \
42     CENABLE;                                                                  \
43     DOCARGS_##args                                                            \
44     move.l %d0, -(%sp); /* Save result of CENABLE.  */                        \
45     cfi_adjust_cfa_offset (4); \
46     move.l &SYS_ify (syscall_name), %d0;                                      \
47     trap &0;                                                                  \
48     move.l %d0, %d2;                                                          \
49     CDISABLE;                                                                 \
50     addq.l &4, %sp; /* Remove result of CENABLE from the stack.  */           \
51     cfi_adjust_cfa_offset (-4); \
52     move.l %d2, %d0;                                                          \
53     UNDOCARGS_##args                                                          \
54     cmp.l &-4095, %d0;                                                        \
55     jcc SYSCALL_ERROR_LABEL
56
57 /* Note: we use D2 to save syscall's return value as D0 will be clobbered in
58    CDISABLE.  */
59 # define DOCARGS_0      move.l %d2, -(%sp);             \
60   cfi_adjust_cfa_offset (4); cfi_rel_offset (%d2, 0);
61 # define UNDOCARGS_0    move.l (%sp)+, %d2;     \
62   cfi_adjust_cfa_offset (-4); cfi_restore (%d2);
63
64 # define DOCARGS_1      _DOCARGS_1 (4); DOCARGS_0
65 # define _DOCARGS_1(n)  move.l n(%sp), %d1;
66 # define UNDOCARGS_1    UNDOCARGS_0
67
68 # define DOCARGS_2      _DOCARGS_2 (8)
69 # define _DOCARGS_2(n)  DOCARGS_0 move.l n+4(%sp), %d2; _DOCARGS_1 (n)
70 # define UNDOCARGS_2    UNDOCARGS_0
71
72 # define DOCARGS_3      _DOCARGS_3 (12)
73 # define _DOCARGS_3(n)  move.l %d3, -(%sp);                             \
74   cfi_adjust_cfa_offset (4); cfi_rel_offset (%d3, 0);                   \
75   move.l n+4(%sp), %d3; _DOCARGS_2 (n)
76 # define UNDOCARGS_3    UNDOCARGS_2 move.l (%sp)+, %d3;         \
77   cfi_adjust_cfa_offset (-4); cfi_restore (%d3);
78
79 # define DOCARGS_4      _DOCARGS_4 (16)
80 # define _DOCARGS_4(n)  move.l %d4, -(%sp);                     \
81   cfi_adjust_cfa_offset (4); cfi_rel_offset (%d4, 0);           \
82   move.l n+4(%sp), %d4; _DOCARGS_3 (n)
83 # define UNDOCARGS_4    UNDOCARGS_3 move.l (%sp)+, %d4; \
84   cfi_adjust_cfa_offset (-4); cfi_restore (%d4);
85
86 # define DOCARGS_5      _DOCARGS_5 (20)
87 # define _DOCARGS_5(n)  move.l %d5, -(%sp);                     \
88   cfi_adjust_cfa_offset (4); cfi_rel_offset (%d5, 0);           \
89   move.l n+4(%sp), %d5; _DOCARGS_4 (n)
90 # define UNDOCARGS_5    UNDOCARGS_4 move.l (%sp)+, %d5; \
91   cfi_adjust_cfa_offset (-4); cfi_restore (%d5);
92
93 # define DOCARGS_6      _DOCARGS_6 (24)
94 # define _DOCARGS_6(n)  move.l n(%sp), %a0; _DOCARGS_5 (n-4)
95 # define UNDOCARGS_6    UNDOCARGS_5
96
97 # ifdef PIC
98 #  define PSEUDO_JMP(sym) jbsr sym ## @PLTPC
99 # else
100 #  define PSEUDO_JMP(sym) jbsr sym
101 # endif
102
103 # ifdef IS_IN_libpthread
104 #  define CENABLE       PSEUDO_JMP (__pthread_enable_asynccancel)
105 #  define CDISABLE      PSEUDO_JMP (__pthread_disable_asynccancel)
106 # elif !defined NOT_IN_libc
107 #  define CENABLE       PSEUDO_JMP (__libc_enable_asynccancel)
108 #  define CDISABLE      PSEUDO_JMP (__libc_disable_asynccancel)
109 # elif defined IS_IN_librt
110 #  define CENABLE       PSEUDO_JMP (__librt_enable_asynccancel)
111 #  define CDISABLE      PSEUDO_JMP (__librt_disable_asynccancel)
112 # else
113 #  error Unsupported library
114 # endif
115
116 # ifndef __ASSEMBLER__
117 #  define SINGLE_THREAD_P                                               \
118   __builtin_expect (THREAD_GETMEM (THREAD_SELF,                         \
119                                    header.multiple_threads) == 0, 1)
120 # else
121 #  define SINGLE_THREAD_P                       \
122   PSEUDO_JMP (__m68k_read_tp);                  \
123   tst.l MULTIPLE_THREADS_OFFSET(%a0)
124 # endif
125
126 #elif !defined __ASSEMBLER__
127
128 # define SINGLE_THREAD_P (1)
129 # define NO_CANCELLATION (1)
130
131 #endif
132
133 #ifndef __ASSEMBLER__
134 # define RTLD_SINGLE_THREAD_P                                     \
135   __builtin_expect (THREAD_GETMEM (THREAD_SELF,                   \
136                                    header.multiple_threads) == 0, \
137                     1)
138 #endif