2d191d115c0a11cff2ae74624d20cf02e1a8afba
[kopensolaris-gnu/glibc.git] / linuxthreads / sysdeps / unix / sysv / linux / powerpc / powerpc32 / 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, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
19
20 #include <sysdep.h>
21 #include <tls.h>
22 #ifndef __ASSEMBLER__
23 # include <linuxthreads/internals.h>
24 #endif
25
26 #if !defined NOT_IN_libc || defined IS_IN_libpthread
27
28 # undef PSEUDO
29 # define PSEUDO(name, syscall_name, args)                               \
30   .section ".text";                                                     \
31   ENTRY (name)                                                          \
32     SINGLE_THREAD_P;                                                    \
33     bne- .Lpseudo_cancel;                                               \
34     DO_CALL (SYS_ify (syscall_name));                                   \
35     PSEUDO_RET;                                                         \
36   .Lpseudo_cancel:                                                      \
37     stwu 1,-48(1);                                                      \
38     mflr 9;                                                             \
39     stw 9,52(1);                                                        \
40     DOCARGS_##args;     /* save syscall args around CENABLE.  */        \
41     CENABLE;                                                            \
42     stw 3,16(1);        /* store CENABLE return value (MASK).  */       \
43     UNDOCARGS_##args;   /* restore syscall args.  */                    \
44     DO_CALL (SYS_ify (syscall_name));                                   \
45     mfcr 0;             /* save CR/R3 around CDISABLE.  */              \
46     stw 3,8(1);                                                         \
47     stw 0,12(1);                                                        \
48     lwz 3,16(1);        /* pass MASK to CDISABLE.  */                   \
49     CDISABLE;                                                           \
50     lwz 4,52(1);                                                        \
51     lwz 0,12(1);        /* restore CR/R3. */                            \
52     lwz 3,8(1);                                                         \
53     mtlr 4;                                                             \
54     mtcr 0;                                                             \
55     addi 1,1,48;
56
57 # define DOCARGS_0
58 # define UNDOCARGS_0
59
60 # define DOCARGS_1      stw 3,20(1); DOCARGS_0
61 # define UNDOCARGS_1    lwz 3,20(1); UNDOCARGS_0
62
63 # define DOCARGS_2      stw 4,24(1); DOCARGS_1
64 # define UNDOCARGS_2    lwz 4,24(1); UNDOCARGS_1
65
66 # define DOCARGS_3      stw 5,28(1); DOCARGS_2
67 # define UNDOCARGS_3    lwz 5,28(1); UNDOCARGS_2
68
69 # define DOCARGS_4      stw 6,32(1); DOCARGS_3
70 # define UNDOCARGS_4    lwz 6,32(1); UNDOCARGS_3
71
72 # define DOCARGS_5      stw 7,36(1); DOCARGS_4
73 # define UNDOCARGS_5    lwz 7,36(1); UNDOCARGS_4
74
75 # define DOCARGS_6      stw 8,40(1); DOCARGS_5
76 # define UNDOCARGS_6    lwz 8,40(1); UNDOCARGS_5
77
78 # ifdef IS_IN_libpthread
79 #  define CENABLE       bl JUMPTARGET(__pthread_enable_asynccancel)
80 #  define CDISABLE      bl JUMPTARGET(__pthread_disable_asynccancel)
81 # else
82 #  define CENABLE       bl JUMPTARGET(__libc_enable_asynccancel)
83 #  define CDISABLE      bl JUMPTARGET(__libc_disable_asynccancel)
84 # endif
85
86 # ifndef __ASSEMBLER__
87 #  define SINGLE_THREAD_P                                               \
88   __builtin_expect (THREAD_GETMEM (THREAD_SELF, p_multiple_threads) == 0, 1)
89 # else
90 #  define SINGLE_THREAD_P                                               \
91   lwz 10,MULTIPLE_THREADS_OFFSET(2);                                    \
92   cmpwi 10,0
93 # endif
94
95 #elif !defined __ASSEMBLER__
96
97 /* This code should never be used but we define it anyhow.  */
98 # define SINGLE_THREAD_P (1)
99
100 #endif