OSDN Git Service

Merge commit 'origin/master' into nptl
[uclinux-h8/uClibc.git] / libpthread / nptl / sysdeps / unix / sysv / linux / powerpc / powerpc32 / sysdep-cancel.h
1 /* Cancellable system call stubs.  Linux/PowerPC version.
2    Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Franz Sirl <Franz.Sirl-kernel@lauterbach.com>, 2003.
5
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; if not, write to the Free
18    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19    02111-1307 USA.  */
20
21 #include <sysdep.h>
22 #include <tls.h>
23 #ifndef __ASSEMBLER__
24 # include <nptl/pthreadP.h>
25 #endif
26
27 #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
28
29 # undef PSEUDO
30 # define PSEUDO(name, syscall_name, args)                               \
31   .section ".text";                                                     \
32   ENTRY (name)                                                          \
33     cfi_startproc;                                                      \
34     SINGLE_THREAD_P;                                                    \
35     bne- .Lpseudo_cancel;                                               \
36   .type __##syscall_name##_nocancel,@function;                          \
37   .globl __##syscall_name##_nocancel;                                   \
38   __##syscall_name##_nocancel:                                          \
39     DO_CALL (SYS_ify (syscall_name));                                   \
40     PSEUDO_RET;                                                         \
41   .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel;      \
42   .Lpseudo_cancel:                                                      \
43     stwu 1,-48(1);                                                      \
44     cfi_adjust_cfa_offset (48);                                         \
45     mflr 9;                                                             \
46     stw 9,52(1);                                                        \
47     cfi_offset (lr, 4);                                                 \
48     CGOTSETUP;                                                          \
49     DOCARGS_##args;     /* save syscall args around CENABLE.  */        \
50     CENABLE;                                                            \
51     stw 3,16(1);        /* store CENABLE return value (MASK).  */       \
52     UNDOCARGS_##args;   /* restore syscall args.  */                    \
53     DO_CALL (SYS_ify (syscall_name));                                   \
54     mfcr 0;             /* save CR/R3 around CDISABLE.  */              \
55     stw 3,8(1);                                                         \
56     stw 0,12(1);                                                        \
57     lwz 3,16(1);        /* pass MASK to CDISABLE.  */                   \
58     CDISABLE;                                                           \
59     lwz 4,52(1);                                                        \
60     lwz 0,12(1);        /* restore CR/R3. */                            \
61     lwz 3,8(1);                                                         \
62     CGOTRESTORE;                                                        \
63     mtlr 4;                                                             \
64     mtcr 0;                                                             \
65     addi 1,1,48;                                                        \
66     cfi_endproc;
67
68 # define DOCARGS_0
69 # define UNDOCARGS_0
70
71 # define DOCARGS_1      stw 3,20(1); DOCARGS_0
72 # define UNDOCARGS_1    lwz 3,20(1); UNDOCARGS_0
73
74 # define DOCARGS_2      stw 4,24(1); DOCARGS_1
75 # define UNDOCARGS_2    lwz 4,24(1); UNDOCARGS_1
76
77 # define DOCARGS_3      stw 5,28(1); DOCARGS_2
78 # define UNDOCARGS_3    lwz 5,28(1); UNDOCARGS_2
79
80 # define DOCARGS_4      stw 6,32(1); DOCARGS_3
81 # define UNDOCARGS_4    lwz 6,32(1); UNDOCARGS_3
82
83 # define DOCARGS_5      stw 7,36(1); DOCARGS_4
84 # define UNDOCARGS_5    lwz 7,36(1); UNDOCARGS_4
85
86 # define DOCARGS_6      stw 8,40(1); DOCARGS_5
87 # define UNDOCARGS_6    lwz 8,40(1); UNDOCARGS_5
88
89 # define CGOTSETUP
90 # define CGOTRESTORE
91
92 # ifdef IS_IN_libpthread
93 #  define CENABLE       bl __pthread_enable_asynccancel@local
94 #  define CDISABLE      bl __pthread_disable_asynccancel@local
95 # elif !defined NOT_IN_libc
96 #  define CENABLE       bl __libc_enable_asynccancel@local
97 #  define CDISABLE      bl __libc_disable_asynccancel@local
98 # elif defined IS_IN_librt
99 #  define CENABLE       bl JUMPTARGET(__librt_enable_asynccancel)
100 #  define CDISABLE      bl JUMPTARGET(__librt_disable_asynccancel)
101 #  if defined HAVE_AS_REL16 && defined __PIC__
102 #   undef CGOTSETUP
103 #   define CGOTSETUP                                                    \
104     bcl 20,31,1f;                                                       \
105  1: stw 30,44(1);                                                       \
106     mflr 30;                                                            \
107     addis 30,30,_GLOBAL_OFFSET_TABLE-1b@ha;                             \
108     addi 30,30,_GLOBAL_OFFSET_TABLE-1b@l
109 #   undef CGOTRESTORE
110 #   define CGOTRESTORE                                                  \
111     lwz 30,44(1)
112 #  endif
113 # else
114 #  error Unsupported library
115 # endif
116
117 # ifndef __ASSEMBLER__
118 #  define SINGLE_THREAD_P                                               \
119   __builtin_expect (THREAD_GETMEM (THREAD_SELF,                         \
120                                    header.multiple_threads) == 0, 1)
121 # else
122 #  define SINGLE_THREAD_P                                               \
123   lwz 10,MULTIPLE_THREADS_OFFSET(2);                                    \
124   cmpwi 10,0
125 # endif
126
127 #elif !defined __ASSEMBLER__
128
129 # define SINGLE_THREAD_P (1)
130 # define NO_CANCELLATION 1
131
132 #endif