Move all files into ports/ subdirectory in preparation for merge with glibc
[jlayton/glibc.git] / ports / sysdeps / unix / sysv / linux / tile / nptl / sysdep-cancel.h
1 /* Copyright (C) 2011 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
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, see
17    <http://www.gnu.org/licenses/>.  */
18
19 #include <sysdep.h>
20 #include <tls.h>
21 #ifndef __ASSEMBLER__
22 # include <nptl/pthreadP.h>
23 #endif
24
25 #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
26
27 /* Allow hacking in some extra code if desired. */
28 #ifndef PSEUDO_EXTRA
29 #define PSEUDO_EXTRA
30 #endif
31
32 #undef PSEUDO
33 #define PSEUDO(name, syscall_name, args)                                      \
34   ENTRY(__##syscall_name##_nocancel);                                         \
35     PSEUDO_EXTRA                                                              \
36     moveli TREG_SYSCALL_NR_NAME, SYS_ify(syscall_name);                       \
37     swint1;                                                                   \
38     BNEZ r1, 0f;                                                              \
39     jrp lr;                                                                   \
40   END(__##syscall_name##_nocancel);                                           \
41   ENTRY (name)                                                                \
42     SINGLE_THREAD_P(r11);                                                     \
43     BEQZ r11, L(pseudo_cancel);                                               \
44     PSEUDO_EXTRA                                                              \
45     moveli TREG_SYSCALL_NR_NAME, SYS_ify(syscall_name);                       \
46     swint1;                                                                   \
47     BNEZ r1, 0f;                                                              \
48     jrp lr;                                                                   \
49   L(pseudo_cancel):                                                           \
50     {                                                                         \
51      move r11, sp;                                                            \
52      ST sp, lr;                                                               \
53      ADDI_PTR sp, sp, -STKSPACE;                                              \
54     };                                                                        \
55     cfi_offset (lr, 0);                                                       \
56     cfi_def_cfa_offset (STKSPACE);                                            \
57     {                                                                         \
58      ADDI_PTR r12, sp, REGSIZE;                                               \
59      ADDI_PTR r13, sp, 2 * REGSIZE;     /* set up for PUSHARGS_0 */           \
60     };                                                                        \
61     ST r12, r11;                                                              \
62     PUSHARGS_##args                     /* save syscall args */               \
63     CENABLE;                                                                  \
64     ADDI_PTR r12, sp, 10 * REGSIZE;                                           \
65     {                                                                         \
66      ST r12, r0;                        /* save mask */                       \
67      ADDI_PTR r13, sp, 2 * REGSIZE;     /* set up for POPARGS_0 */            \
68     };                                                                        \
69     POPARGS_##args                      /* restore syscall args */            \
70     PSEUDO_EXTRA                                                              \
71     moveli TREG_SYSCALL_NR_NAME, SYS_ify(syscall_name);                       \
72     swint1;                                                                   \
73     ADDI_PTR r12, sp, 12 * REGSIZE;                                           \
74     {                                                                         \
75      ST r12, r1;                        /* save syscall result */             \
76      ADDI_PTR r12, sp, 11 * REGSIZE;                                          \
77     };                                                                        \
78     {                                                                         \
79      ST r12, r0;                                                              \
80      ADDI_PTR r13, sp, 10 * REGSIZE;                                          \
81     };                                                                        \
82     LD r0, r13;                         /* pass mask as arg1 */               \
83     CDISABLE;                                                                 \
84     {                                                                         \
85      ADDI_PTR lr, sp, STKSPACE;                                               \
86      ADDI_PTR r0, sp, 11 * REGSIZE;                                           \
87     };                                                                        \
88     {                                                                         \
89      LD r0, r0;                                                               \
90      ADDI_PTR r1, sp, 12 * REGSIZE;                                           \
91     };                                                                        \
92     LD r1, r1;                                                                \
93     {                                                                         \
94      LD lr, lr;                                                               \
95      ADDI_PTR sp, sp, STKSPACE;                                               \
96     };                                                                        \
97     cfi_def_cfa_offset (0);                                                   \
98     BNEZ r1, 0f
99
100 # define PUSHARGS_0 /* nothing to do */
101 # define PUSHARGS_1 PUSHARGS_0 { ADDI_PTR r14, sp, 3 * REGSIZE; ST r13, r0 };
102 # define PUSHARGS_2 PUSHARGS_1 { ADDI_PTR r13, sp, 4 * REGSIZE; ST r14, r1 };
103 # define PUSHARGS_3 PUSHARGS_2 { ADDI_PTR r14, sp, 5 * REGSIZE; ST r13, r2 };
104 # define PUSHARGS_4 PUSHARGS_3 { ADDI_PTR r13, sp, 6 * REGSIZE; ST r14, r3 };
105 # define PUSHARGS_5 PUSHARGS_4 { ADDI_PTR r14, sp, 7 * REGSIZE; ST r13, r4 };
106 # define PUSHARGS_6 PUSHARGS_5 { ADDI_PTR r13, sp, 8 * REGSIZE; ST r14, r5 };
107 # define PUSHARGS_7 PUSHARGS_6 { ADDI_PTR r14, sp, 9 * REGSIZE; ST r13, r6 };
108
109 # define POPARGS_0  /* nothing to do */
110 # define POPARGS_1  POPARGS_0 { ADDI_PTR r14, sp, 3 * REGSIZE; LD r0, r13 };
111 # define POPARGS_2  POPARGS_1 { ADDI_PTR r13, sp, 4 * REGSIZE; LD r1, r14 };
112 # define POPARGS_3  POPARGS_2 { ADDI_PTR r14, sp, 5 * REGSIZE; LD r2, r13 };
113 # define POPARGS_4  POPARGS_3 { ADDI_PTR r13, sp, 6 * REGSIZE; LD r3, r14 };
114 # define POPARGS_5  POPARGS_4 { ADDI_PTR r14, sp, 7 * REGSIZE; LD r4, r13 };
115 # define POPARGS_6  POPARGS_5 { ADDI_PTR r13, sp, 8 * REGSIZE; LD r5, r14 };
116 # define POPARGS_7  POPARGS_6 { ADDI_PTR r14, sp, 9 * REGSIZE; LD r6, r13 };
117
118 # define STKSPACE       (13 * REGSIZE)
119
120 # ifdef IS_IN_libpthread
121 #  define CENABLE       jal __pthread_enable_asynccancel
122 #  define CDISABLE      jal __pthread_disable_asynccancel
123 # elif defined IS_IN_librt
124 #  define CENABLE       jal __librt_enable_asynccancel
125 #  define CDISABLE      jal __librt_disable_asynccancel
126 # else
127 #  define CENABLE       jal __libc_enable_asynccancel
128 #  define CDISABLE      jal __libc_disable_asynccancel
129 # endif
130
131 # ifndef __ASSEMBLER__
132 #  define SINGLE_THREAD_P                                               \
133         __builtin_expect (THREAD_GETMEM (THREAD_SELF,                   \
134                                          header.multiple_threads)       \
135                           == 0, 1)
136 # else
137 #  define SINGLE_THREAD_P(reg)                                          \
138   ADDLI_PTR reg, tp, MULTIPLE_THREADS_OFFSET;                           \
139   LD reg, reg;                                                          \
140   CMPEQI reg, reg, 0
141 #endif
142
143 #elif !defined __ASSEMBLER__
144
145 # define SINGLE_THREAD_P 1
146 # define NO_CANCELLATION 1
147
148 #endif
149
150 #ifndef __ASSEMBLER__
151 # define RTLD_SINGLE_THREAD_P                                           \
152   __builtin_expect (THREAD_GETMEM (THREAD_SELF,                         \
153                                    header.multiple_threads) == 0, 1)
154 #endif