]>
Commit | Line | Data |
---|---|---|
f3c13160 RM |
1 | /* Cancellable system call stubs. Linux/PowerPC64 version. |
2 | Copyright (C) 2003 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 | |
28 | ||
29 | # undef PSEUDO | |
30 | # define PSEUDO(name, syscall_name, args) \ | |
31 | .section ".text"; \ | |
32 | ENTRY (name) \ | |
33 | SINGLE_THREAD_P; \ | |
34 | bne- .Lpseudo_cancel; \ | |
35 | DO_CALL (SYS_ify (syscall_name)); \ | |
36 | PSEUDO_RET; \ | |
37 | .Lpseudo_cancel: \ | |
38 | stdu 1,-128(1); \ | |
39 | mflr 9; \ | |
40 | std 9,128+16(1); \ | |
41 | DOCARGS_##args; /* save syscall args around CENABLE. */ \ | |
42 | CENABLE; \ | |
43 | std 3,72(1); /* store CENABLE return value (MASK). */ \ | |
44 | UNDOCARGS_##args; /* restore syscall args. */ \ | |
45 | DO_CALL (SYS_ify (syscall_name)); \ | |
46 | mfcr 0; /* save CR/R3 around CDISABLE. */ \ | |
47 | std 3,64(1); \ | |
48 | std 0,8(1); \ | |
49 | ld 3,72(1); /* pass MASK to CDISABLE. */ \ | |
50 | CDISABLE; \ | |
51 | ld 9,128+16(1); \ | |
52 | ld 0,8(1); /* restore CR/R3. */ \ | |
53 | ld 3,64(1); \ | |
54 | mtlr 9; \ | |
55 | mtcr 0; \ | |
56 | addi 1,1,128; | |
57 | ||
58 | # define DOCARGS_0 | |
59 | # define UNDOCARGS_0 | |
60 | ||
61 | # define DOCARGS_1 std 3,80(1); DOCARGS_0 | |
62 | # define UNDOCARGS_1 ld 3,80(1); UNDOCARGS_0 | |
63 | ||
64 | # define DOCARGS_2 std 4,88(1); DOCARGS_1 | |
65 | # define UNDOCARGS_2 ld 4,88(1); UNDOCARGS_1 | |
66 | ||
67 | # define DOCARGS_3 std 5,96(1); DOCARGS_2 | |
68 | # define UNDOCARGS_3 ld 5,96(1); UNDOCARGS_2 | |
69 | ||
70 | # define DOCARGS_4 std 6,104(1); DOCARGS_3 | |
71 | # define UNDOCARGS_4 ld 6,104(1); UNDOCARGS_3 | |
72 | ||
73 | # define DOCARGS_5 std 7,112(1); DOCARGS_4 | |
74 | # define UNDOCARGS_5 ld 7,112(1); UNDOCARGS_4 | |
75 | ||
76 | # define DOCARGS_6 std 8,120(1); DOCARGS_5 | |
77 | # define UNDOCARGS_6 ld 8,120(1); UNDOCARGS_5 | |
78 | ||
79 | # ifdef IS_IN_libpthread | |
80 | # define CENABLE bl JUMPTARGET(__pthread_enable_asynccancel) | |
81 | # define CDISABLE bl JUMPTARGET(__pthread_disable_asynccancel) | |
82 | # else | |
83 | # define CENABLE bl JUMPTARGET(__libc_enable_asynccancel) | |
84 | # define CDISABLE bl JUMPTARGET(__libc_disable_asynccancel) | |
85 | # endif | |
86 | ||
87 | # ifndef __ASSEMBLER__ | |
88 | # define SINGLE_THREAD_P \ | |
94659495 RM |
89 | __builtin_expect (THREAD_GETMEM (THREAD_SELF, \ |
90 | header.multiple_threads) == 0, 1) | |
f3c13160 RM |
91 | # else |
92 | # define SINGLE_THREAD_P \ | |
93 | lwz 10,MULTIPLE_THREADS_OFFSET(13); \ | |
94 | cmpdi 10,0 | |
95 | # endif | |
96 | ||
97 | #elif !defined __ASSEMBLER__ | |
98 | ||
99 | /* This code should never be used but we define it anyhow. */ | |
100 | # define SINGLE_THREAD_P (1) | |
101 | ||
102 | #endif |