d590359a4880cc9b84b6ed9e5477ccbbea25f22d
[openwrt/openwrt.git] / toolchain / uClibc / patches-0.9.33.2 / 619-mips64_fix_sysdep_cancel.patch
1 --- a/extra/Configs/Config.in
2 +++ b/extra/Configs/Config.in
3 @@ -235,6 +235,7 @@ config TARGET_SUBARCH
4 default "i486" if CONFIG_486
5 default "i586" if CONFIG_586 || CONFIG_586MMX
6 default "i686" if TARGET_ARCH = "i386"
7 + default "mips64" if CONFIG_MIPS_N64_ABI
8 default ""
9
10 source "extra/Configs/Config.in.arch"
11 --- /dev/null
12 +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/mips/mips64/sysdep-cancel.h
13 @@ -0,0 +1,182 @@
14 +/* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
15 + This file is part of the GNU C Library.
16 +
17 + The GNU C Library is free software; you can redistribute it and/or
18 + modify it under the terms of the GNU Lesser General Public
19 + License as published by the Free Software Foundation; either
20 + version 2.1 of the License, or (at your option) any later version.
21 +
22 + The GNU C Library is distributed in the hope that it will be useful,
23 + but WITHOUT ANY WARRANTY; without even the implied warranty of
24 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 + Lesser General Public License for more details.
26 +
27 + You should have received a copy of the GNU Lesser General Public
28 + License along with the GNU C Library. If not, see
29 + <http://www.gnu.org/licenses/>. */
30 +
31 +#include <sysdep.h>
32 +#include <tls.h>
33 +#ifndef __ASSEMBLER__
34 +# include <pthreadP.h>
35 +#endif
36 +#include <sys/asm.h>
37 +
38 +/* Gas will put the initial save of $gp into the CIE, because it appears to
39 + happen before any instructions. So we use cfi_same_value instead of
40 + cfi_restore. */
41 +
42 +#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
43 +
44 +#ifdef __PIC__
45 +# undef PSEUDO
46 +# define PSEUDO(name, syscall_name, args) \
47 + .align 2; \
48 + L(pseudo_start): \
49 + cfi_startproc; \
50 + cfi_adjust_cfa_offset (STKSPACE); \
51 + cfi_rel_offset (gp, STKOFF_GP); \
52 + 99: move a0, v0; \
53 + PTR_LA t9,__syscall_error; \
54 + /* manual cpreturn */ \
55 + REG_L gp, STKOFF_GP(sp); \
56 + cfi_same_value (gp); \
57 + RESTORESTK; \
58 + jr t9; \
59 + .type __##syscall_name##_nocancel, @function; \
60 + .globl __##syscall_name##_nocancel; \
61 + __##syscall_name##_nocancel: \
62 + SAVESTK; \
63 + .cpsetup t9, STKOFF_GP, name; \
64 + cfi_rel_offset (gp, STKOFF_GP); \
65 + li v0, SYS_ify(syscall_name); \
66 + syscall; \
67 + bne a3, zero, SYSCALL_ERROR_LABEL; \
68 + /* manual cpreturn */ \
69 + REG_L gp, STKOFF_GP(sp); \
70 + cfi_same_value (gp); \
71 + RESTORESTK; \
72 + ret; \
73 + .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
74 + ENTRY (name) \
75 + SAVESTK; \
76 + .cpsetup t9, STKOFF_GP, name; \
77 + cfi_rel_offset (gp, STKOFF_GP); \
78 + SINGLE_THREAD_P(v1); \
79 + bne zero, v1, L(pseudo_cancel); \
80 + .set noreorder; \
81 + li v0, SYS_ify(syscall_name); \
82 + syscall; \
83 + .set reorder; \
84 + bne a3, zero, SYSCALL_ERROR_LABEL; \
85 + /* manual cpreturn */ \
86 + REG_L gp, STKOFF_GP(sp); \
87 + cfi_same_value (gp); \
88 + RESTORESTK; \
89 + ret; \
90 + L(pseudo_cancel): \
91 + cfi_adjust_cfa_offset (STKSPACE); \
92 + cfi_rel_offset (gp, STKOFF_GP); \
93 + REG_S ra, STKOFF_RA(sp); \
94 + cfi_rel_offset (ra, STKOFF_RA); \
95 + PUSHARGS_##args; /* save syscall args */ \
96 + CENABLE; \
97 + REG_S v0, STKOFF_SVMSK(sp); /* save mask */ \
98 + POPARGS_##args; /* restore syscall args */ \
99 + .set noreorder; \
100 + li v0, SYS_ify (syscall_name); \
101 + syscall; \
102 + .set reorder; \
103 + REG_S v0, STKOFF_SC_V0(sp); /* save syscall result */ \
104 + REG_S a3, STKOFF_SC_ERR(sp); /* save syscall error flag */ \
105 + REG_L a0, STKOFF_SVMSK(sp); /* pass mask as arg1 */ \
106 + CDISABLE; \
107 + REG_L a3, STKOFF_SC_ERR(sp); /* restore syscall error flag */ \
108 + REG_L ra, STKOFF_RA(sp); /* restore return address */ \
109 + REG_L v0, STKOFF_SC_V0(sp); /* restore syscall result */ \
110 + bne a3, zero, SYSCALL_ERROR_LABEL; \
111 + /* manual cpreturn */ \
112 + REG_L gp, STKOFF_GP(sp); \
113 + cfi_same_value (gp); \
114 + RESTORESTK; \
115 + L(pseudo_end):
116 +
117 +
118 +# undef PSEUDO_END
119 +# define PSEUDO_END(sym) cfi_endproc; .end sym; .size sym,.-sym
120 +
121 +#endif
122 +
123 +# define PUSHARGS_0 /* nothing to do */
124 +# define PUSHARGS_1 PUSHARGS_0 REG_S a0, STKOFF_A0(sp); cfi_rel_offset (a0, STKOFF_A0);
125 +# define PUSHARGS_2 PUSHARGS_1 REG_S a1, STKOFF_A1(sp); cfi_rel_offset (a1, STKOFF_A1);
126 +# define PUSHARGS_3 PUSHARGS_2 REG_S a2, STKOFF_A2(sp); cfi_rel_offset (a2, STKOFF_A2);
127 +# define PUSHARGS_4 PUSHARGS_3 REG_S a3, STKOFF_A3(sp); cfi_rel_offset (a3, STKOFF_A3);
128 +# define PUSHARGS_5 PUSHARGS_4 REG_S a4, STKOFF_A4(sp); cfi_rel_offset (a3, STKOFF_A4);
129 +# define PUSHARGS_6 PUSHARGS_5 REG_S a5, STKOFF_A5(sp); cfi_rel_offset (a3, STKOFF_A5);
130 +
131 +# define POPARGS_0 /* nothing to do */
132 +# define POPARGS_1 POPARGS_0 REG_L a0, STKOFF_A0(sp);
133 +# define POPARGS_2 POPARGS_1 REG_L a1, STKOFF_A1(sp);
134 +# define POPARGS_3 POPARGS_2 REG_L a2, STKOFF_A2(sp);
135 +# define POPARGS_4 POPARGS_3 REG_L a3, STKOFF_A3(sp);
136 +# define POPARGS_5 POPARGS_4 REG_L a4, STKOFF_A4(sp);
137 +# define POPARGS_6 POPARGS_5 REG_L a5, STKOFF_A5(sp);
138 +
139 +/* Save an even number of slots. Should be 0 if an even number of slots
140 + are used below, or SZREG if an odd number are used. */
141 +# define STK_PAD SZREG
142 +
143 +/* Place values that we are more likely to use later in this sequence, i.e.
144 + closer to the SP at function entry. If you do that, the are more
145 + likely to already be in your d-cache. */
146 +# define STKOFF_A5 (STK_PAD)
147 +# define STKOFF_A4 (STKOFF_A5 + SZREG)
148 +# define STKOFF_A3 (STKOFF_A4 + SZREG)
149 +# define STKOFF_A2 (STKOFF_A3 + SZREG) /* MT and more args. */
150 +# define STKOFF_A1 (STKOFF_A2 + SZREG) /* MT and 2 args. */
151 +# define STKOFF_A0 (STKOFF_A1 + SZREG) /* MT and 1 arg. */
152 +# define STKOFF_RA (STKOFF_A0 + SZREG) /* Used if MT. */
153 +# define STKOFF_SC_V0 (STKOFF_RA + SZREG) /* Used if MT. */
154 +# define STKOFF_SC_ERR (STKOFF_SC_V0 + SZREG) /* Used if MT. */
155 +# define STKOFF_SVMSK (STKOFF_SC_ERR + SZREG) /* Used if MT. */
156 +# define STKOFF_GP (STKOFF_SVMSK + SZREG) /* Always used. */
157 +
158 +# define STKSPACE (STKOFF_GP + SZREG)
159 +# define SAVESTK PTR_SUBU sp, STKSPACE; cfi_adjust_cfa_offset(STKSPACE)
160 +# define RESTORESTK PTR_ADDU sp, STKSPACE; cfi_adjust_cfa_offset(-STKSPACE)
161 +
162 +# ifdef IS_IN_libpthread
163 +# define CENABLE PTR_LA t9, __pthread_enable_asynccancel; jalr t9
164 +# define CDISABLE PTR_LA t9, __pthread_disable_asynccancel; jalr t9
165 +# elif defined IS_IN_librt
166 +# define CENABLE PTR_LA t9, __librt_enable_asynccancel; jalr t9
167 +# define CDISABLE PTR_LA t9, __librt_disable_asynccancel; jalr t9
168 +# else
169 +# define CENABLE PTR_LA t9, __libc_enable_asynccancel; jalr t9
170 +# define CDISABLE PTR_LA t9, __libc_disable_asynccancel; jalr t9
171 +# endif
172 +
173 +# ifndef __ASSEMBLER__
174 +# define SINGLE_THREAD_P \
175 + __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
176 + header.multiple_threads) \
177 + == 0, 1)
178 +# else
179 +# define SINGLE_THREAD_P(reg) \
180 + READ_THREAD_POINTER(reg); \
181 + lw reg, MULTIPLE_THREADS_OFFSET(reg)
182 +#endif
183 +
184 +#elif !defined __ASSEMBLER__
185 +
186 +# define SINGLE_THREAD_P 1
187 +# define NO_CANCELLATION 1
188 +
189 +#endif
190 +
191 +#ifndef __ASSEMBLER__
192 +# define RTLD_SINGLE_THREAD_P \
193 + __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
194 + header.multiple_threads) == 0, 1)
195 +#endif