OSDN Git Service

901982ec85389114a213ce71a78cbfb8fdda07b2
[uclinux-h8/uClibc.git] / libpthread / linuxthreads / sysdeps / unix / sysv / linux / powerpc / powerpc64 / sysdep-cancel.h
1 /* Copyright (C) 2003 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Franz Sirl <Franz.Sirl-kernel@lauterbach.com>, 2003.
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 <linuxthreads/internals.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   .section ".text";                                                     \
30   ENTRY (name)                                                          \
31     SINGLE_THREAD_P;                                                    \
32     bne- .Lpseudo_cancel;                                               \
33     DO_CALL (SYS_ify (syscall_name));                                   \
34     PSEUDO_RET;                                                         \
35   .Lpseudo_cancel:                                                      \
36     stdu 1,-128(1);                                                     \
37     mflr 9;                                                             \
38     std  9,128+16(1);                                                   \
39     DOCARGS_##args;     /* save syscall args around CENABLE.  */        \
40     CENABLE;                                                            \
41     std  3,72(1);       /* store CENABLE return value (MASK).  */       \
42     UNDOCARGS_##args;   /* restore syscall args.  */                    \
43     DO_CALL (SYS_ify (syscall_name));                                   \
44     mfcr 0;             /* save CR/R3 around CDISABLE.  */              \
45     std  3,64(1);                                                               \
46     std  0,8(1);                                                        \
47     ld   3,72(1);       /* pass MASK to CDISABLE.  */                   \
48     CDISABLE;                                                           \
49     ld   9,128+16(1);                                                   \
50     ld   0,8(1);        /* restore CR/R3. */                            \
51     ld   3,64(1);                                                               \
52     mtlr 9;                                                             \
53     mtcr 0;                                                             \
54     addi 1,1,128;
55
56 # define DOCARGS_0
57 # define UNDOCARGS_0
58
59 # define DOCARGS_1      std 3,80(1); DOCARGS_0
60 # define UNDOCARGS_1    ld 3,80(1); UNDOCARGS_0
61
62 # define DOCARGS_2      std 4,88(1); DOCARGS_1
63 # define UNDOCARGS_2    ld 4,88(1); UNDOCARGS_1
64
65 # define DOCARGS_3      std 5,96(1); DOCARGS_2
66 # define UNDOCARGS_3    ld 5,96(1); UNDOCARGS_2
67
68 # define DOCARGS_4      std 6,104(1); DOCARGS_3
69 # define UNDOCARGS_4    ld 6,104(1); UNDOCARGS_3
70
71 # define DOCARGS_5      std 7,112(1); DOCARGS_4
72 # define UNDOCARGS_5    ld 7,112(1); UNDOCARGS_4
73
74 # define DOCARGS_6      std 8,120(1); DOCARGS_5
75 # define UNDOCARGS_6    ld 8,120(1); UNDOCARGS_5
76
77 # ifdef IS_IN_libpthread
78 #  define CENABLE       bl JUMPTARGET(__pthread_enable_asynccancel)
79 #  define CDISABLE      bl JUMPTARGET(__pthread_disable_asynccancel)
80 #  define __local_multiple_threads __pthread_multiple_threads
81 # elif !defined NOT_IN_libc
82 #  define CENABLE       bl JUMPTARGET(__libc_enable_asynccancel)
83 #  define CDISABLE      bl JUMPTARGET(__libc_disable_asynccancel)
84 #  define __local_multiple_threads __libc_multiple_threads
85 # else
86 #  define CENABLE       bl JUMPTARGET(__librt_enable_asynccancel); nop
87 #  define CDISABLE      bl JUMPTARGET(__librt_disable_asynccancel); nop
88 #  define __local_multiple_threads __librt_multiple_threads
89 # endif
90
91 # ifdef HAVE_TLS_SUPPORT
92 #  ifndef __ASSEMBLER__
93 #   define SINGLE_THREAD_P                                              \
94   __builtin_expect (THREAD_GETMEM (THREAD_SELF, p_multiple_threads) == 0, 1)
95 #  else
96 #   define SINGLE_THREAD_P                                              \
97   lwz 10,MULTIPLE_THREADS_OFFSET(13);                                   \
98   cmpwi 10,0
99 #  endif
100 # else /* !HAVE_TLS_SUPPORT */
101 #  ifndef __ASSEMBLER__
102 extern int __local_multiple_threads
103 #   if !defined NOT_IN_libc || defined IS_IN_libpthread
104   attribute_hidden;
105 #   else
106   ;
107 #   endif
108 #   define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
109 #  else
110 #   define SINGLE_THREAD_P                                              \
111         .section        ".toc","aw";                                    \
112 .LC__local_multiple_threads:;                                           \
113         .tc __local_multiple_threads[TC],__local_multiple_threads;      \
114   .previous;                                                            \
115   ld    10,.LC__local_multiple_threads@toc(2);                          \
116   lwz   10,0(10);                                                       \
117   cmpwi 10,0
118 #  endif
119 # endif
120
121 #elif !defined __ASSEMBLER__
122
123 /* This code should never be used but we define it anyhow.  */
124 # define SINGLE_THREAD_P (1)
125
126 #endif