chiark / gitweb /
eglibc (2.11.3-4+deb6u3) squeeze-lts; urgency=medium
[eglibc.git] / linuxthreads / sysdeps / unix / sysv / linux / mips / mips64 / sysdep-cancel.h
1 /* system call stubs with cancellation handling.  Linux/MIPS version.
2    Copyright (C) 2003, 2004 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Chris Demetriou of Broadcom Corporation,
5    based on work by Guido Guenther <agx@sigxcpu.org>.
6
7    The GNU C Library is free software; you can redistribute it and/or
8    modify it under the terms of the GNU Lesser General Public
9    License as published by the Free Software Foundation; either
10    version 2.1 of the License, or (at your option) any later version.
11
12    The GNU C Library is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    Lesser General Public License for more details.
16
17    You should have received a copy of the GNU Lesser General Public
18    License along with the GNU C Library; if not, write to the Free
19    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20    02111-1307 USA.  */
21
22 #include <sysdep.h>
23 #ifndef __ASSEMBLER__
24 # include <linuxthreads/internals.h>
25 #endif
26 #include <sys/asm.h>
27
28 #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
29
30 #ifdef __PIC__
31 # undef PSEUDO
32 # define PSEUDO(name, syscall_name, args)                                     \
33   .align 2;                                                                   \
34   99:                                                                         \
35   PTR_LA t9,__syscall_error;                                                  \
36   /* manual cpreturn.  */                                                     \
37   REG_L gp, STKOFF_GP(sp);                                                    \
38   RESTORESTK ;                                                                \
39   jr t9;                                                                      \
40   ENTRY (name)                                                                \
41     SAVESTK ;                                                                 \
42     .cpsetup t9, STKOFF_GP, name ;                                            \
43     .set reorder;                                                             \
44     SINGLE_THREAD_P(t0);                                                      \
45     bne zero, t0, L(pseudo_cancel);                                           \
46     .set noreorder;                                                           \
47     li v0, SYS_ify(syscall_name);                                             \
48     syscall;                                                                  \
49     .set reorder;                                                             \
50     bne a3, zero, SYSCALL_ERROR_LABEL;                                        \
51     /* manual cpreturn.  */                                                   \
52     REG_L gp, STKOFF_GP(sp);                                                  \
53     RESTORESTK ;                                                              \
54     ret;                                                                      \
55   L(pseudo_cancel):                                                           \
56     REG_S ra, STKOFF_RA(sp);                                                  \
57     PUSHARGS_##args;                    /* save syscall args */               \
58     CENABLE;                                                                  \
59     REG_S v0, STKOFF_SVMSK(sp);         /* save mask */                       \
60     POPARGS_##args;                     /* restore syscall args */            \
61     .set noreorder;                                                           \
62     li v0, SYS_ify (syscall_name);                                            \
63     syscall;                                                                  \
64     .set reorder;                                                             \
65     REG_S v0, STKOFF_SC_V0(sp);         /* save syscall result */             \
66     REG_S a3, STKOFF_SC_ERR(sp);        /* save syscall error flag */         \
67     REG_L a0, STKOFF_SVMSK(sp);         /* pass mask as arg1 */               \
68     CDISABLE;                                                                 \
69     REG_L a3, STKOFF_SC_ERR(sp);        /* restore syscall error flag */      \
70     REG_L ra, STKOFF_RA(sp);            /* restore return address */          \
71     REG_L v0, STKOFF_SC_V0(sp);         /* restore syscall result */          \
72     bne a3, zero, SYSCALL_ERROR_LABEL;                                        \
73     /* manual cpreturn.  */                                                   \
74     REG_L gp, STKOFF_GP(sp);                                                  \
75     RESTORESTK ;                                                              \
76   L(pseudo_end):
77 #endif
78
79 # define PUSHARGS_0     /* nothing to do */
80 # define PUSHARGS_1     PUSHARGS_0 REG_S a0, STKOFF_A0(sp);
81 # define PUSHARGS_2     PUSHARGS_1 REG_S a1, STKOFF_A1(sp);
82 # define PUSHARGS_3     PUSHARGS_2 REG_S a2, STKOFF_A2(sp);
83 # define PUSHARGS_4     PUSHARGS_3 REG_S a3, STKOFF_A3(sp);
84 # define PUSHARGS_5     PUSHARGS_4 REG_S a4, STKOFF_A4(sp);
85 # define PUSHARGS_6     PUSHARGS_5 REG_S a5, STKOFF_A5(sp);
86
87 # define POPARGS_0      /* nothing to do */
88 # define POPARGS_1      POPARGS_0 REG_L a0, STKOFF_A0(sp);
89 # define POPARGS_2      POPARGS_1 REG_L a1, STKOFF_A1(sp);
90 # define POPARGS_3      POPARGS_2 REG_L a2, STKOFF_A2(sp);
91 # define POPARGS_4      POPARGS_3 REG_L a3, STKOFF_A3(sp);
92 # define POPARGS_5      POPARGS_4 REG_L a4, STKOFF_A4(sp);
93 # define POPARGS_6      POPARGS_5 REG_L a5, STKOFF_A5(sp);
94
95 /* Save an even number of slots.  Should be 0 if an even number of slots
96    are used below, or SZREG if an odd number are used.  */
97 # define STK_PAD        SZREG
98
99 /* Place values that we are more likely to use later in this sequence, i.e.
100    closer to the SP at function entry.  If you do that, the are more
101    likely to already be in your d-cache.  */
102 # define STKOFF_A5      (STK_PAD)
103 # define STKOFF_A4      (STKOFF_A5 + SZREG)
104 # define STKOFF_A3      (STKOFF_A4 + SZREG)
105 # define STKOFF_A2      (STKOFF_A3 + SZREG)     /* MT and more args.  */
106 # define STKOFF_A1      (STKOFF_A2 + SZREG)     /* MT and 2 args.  */
107 # define STKOFF_A0      (STKOFF_A1 + SZREG)     /* MT and 1 arg.  */
108 # define STKOFF_RA      (STKOFF_A0 + SZREG)     /* Used if MT.  */
109 # define STKOFF_SC_V0   (STKOFF_RA + SZREG)     /* Used if MT.  */
110 # define STKOFF_SC_ERR  (STKOFF_SC_V0 + SZREG)  /* Used if MT.  */
111 # define STKOFF_SVMSK   (STKOFF_SC_ERR + SZREG) /* Used if MT.  */
112 # define STKOFF_GP      (STKOFF_SVMSK + SZREG)  /* Always used.  */
113
114 # define STKSPACE       (STKOFF_GP + SZREG)
115 # define SAVESTK        PTR_SUBU sp, STKSPACE
116 # define RESTORESTK     PTR_ADDU sp, STKSPACE
117
118 # ifdef IS_IN_libpthread
119 #  define CENABLE       PTR_LA t9, __pthread_enable_asynccancel; jalr t9;
120 #  define CDISABLE      PTR_LA t9, __pthread_disable_asynccancel; jalr t9;
121 #  define __local_multiple_threads __pthread_multiple_threads
122 # elif defined IS_IN_librt
123 #  define CENABLE       PTR_LA t9, __librt_enable_asynccancel; jalr t9;
124 #  define CDISABLE      PTR_LA t9, __librt_disable_asynccancel; jalr t9;
125 #  define __local_multiple_threads __librt_multiple_threads
126 # else
127 #  define CENABLE       PTR_LA t9, __libc_enable_asynccancel; jalr t9;
128 #  define CDISABLE      PTR_LA t9, __libc_disable_asynccancel; jalr t9;
129 #  define __local_multiple_threads __libc_multiple_threads
130 # endif
131
132 # ifndef __ASSEMBLER__
133 extern int __local_multiple_threads attribute_hidden;
134 #  define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
135 # else
136 #  define SINGLE_THREAD_P(reg) lw reg, __local_multiple_threads
137 #endif
138
139 #elif !defined __ASSEMBLER__
140
141 /* This code should never be used but we define it anyhow.  */
142 # define SINGLE_THREAD_P (1)
143
144 #endif