OSDN Git Service

de97d41a66d4387e9d202e225d0c17c60b799b7d
[uclinux-h8/uClibc.git] / libc / sysdeps / linux / alpha / bits / syscalls.h
1 /* Copyright (C) 1992, 1995, 1996, 2000, 2003, 2004, 2006
2    Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Brendan Kehoe (brendan@zen.org).
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, see
18    <http://www.gnu.org/licenses/>.  */
19
20 #ifndef _BITS_SYSCALLS_H
21 #define _BITS_SYSCALLS_H
22 #ifndef _SYSCALL_H
23 # error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
24 #endif
25
26 #ifndef __ASSEMBLER__
27
28 #define INLINE_SYSCALL_NCS(name, nr, args...)   \
29 (__extension__                                  \
30  ({                                             \
31         long _sc_ret, _sc_err;                  \
32         inline_syscall##nr(name, args);         \
33         if (unlikely (_sc_err))                 \
34           {                                     \
35             __set_errno (_sc_ret);              \
36             _sc_ret = -1L;                      \
37           }                                     \
38         _sc_ret;                                \
39   })                                            \
40 )
41
42 #define INTERNAL_SYSCALL_NCS(name, err_out, nr, args...) \
43 (__extension__ \
44  ({                                                     \
45         long _sc_ret, _sc_err;                          \
46         inline_syscall##nr(name, args);                 \
47         err_out = _sc_err;                              \
48         _sc_ret;                                        \
49   }) \
50 )
51 #define INTERNAL_SYSCALL_DECL(err)              long int err
52 #define INTERNAL_SYSCALL_ERROR_P(val, err)      err
53 #define INTERNAL_SYSCALL_ERRNO(val, err)        val
54
55 #define inline_syscall_clobbers                         \
56         "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", \
57         "$22", "$23", "$24", "$25", "$27", "$28", "memory"
58
59 /* If TLS is in use, we have a conflict between the PAL_rduniq primitive,
60    as modeled within GCC, and explicit use of the R0 register.  If we use
61    the register via the asm, the scheduler may place the PAL_rduniq insn
62    before we've copied the data from R0 into _sc_ret.  If this happens
63    we'll get a reload abort, since R0 is live at the same time it is
64    needed for the PAL_rduniq.
65
66    Solve this by using the "v" constraint instead of an asm for the syscall
67    output.  We don't do this unconditionally to allow compilation with
68    older compilers.  */
69
70 #ifdef HAVE___THREAD
71 #define inline_syscall_r0_asm
72 #define inline_syscall_r0_out_constraint        "=v"
73 #else
74 #define inline_syscall_r0_asm                   __asm__("$0")
75 #define inline_syscall_r0_out_constraint        "=r"
76 #endif
77
78 /* It is moderately important optimization-wise to limit the lifetime
79    of the hard-register variables as much as possible.  Thus we copy
80    in/out as close to the asm as possible.  */
81
82 #define inline_syscall0(name, args...)                          \
83 {                                                               \
84         register long _sc_0 inline_syscall_r0_asm;              \
85         register long _sc_19 __asm__("$19");                    \
86                                                                 \
87         _sc_0 = name;                                           \
88         __asm__ __volatile__                                    \
89           ("callsys # %0 %1 <= %2"                              \
90            : inline_syscall_r0_out_constraint (_sc_0),          \
91              "=r"(_sc_19)                                       \
92            : "0"(_sc_0)                                         \
93            : inline_syscall_clobbers,                           \
94              "$16", "$17", "$18", "$20", "$21");                \
95         _sc_ret = _sc_0, _sc_err = _sc_19;                      \
96 }
97
98 #define inline_syscall1(name,arg1)                              \
99 {                                                               \
100         register long _sc_0 inline_syscall_r0_asm;              \
101         register long _sc_16 __asm__("$16");                    \
102         register long _sc_19 __asm__("$19");                    \
103         register long _tmp_16 = (long) (arg1);                  \
104                                                                 \
105         _sc_0 = name;                                           \
106         _sc_16 = _tmp_16;                                       \
107         __asm__ __volatile__                                    \
108           ("callsys # %0 %1 <= %2 %3"                           \
109            : inline_syscall_r0_out_constraint (_sc_0),          \
110              "=r"(_sc_19), "=r"(_sc_16)                         \
111            : "0"(_sc_0), "2"(_sc_16)                            \
112            : inline_syscall_clobbers,                           \
113              "$17", "$18", "$20", "$21");                       \
114         _sc_ret = _sc_0, _sc_err = _sc_19;                      \
115 }
116
117 #define inline_syscall2(name,arg1,arg2)                         \
118 {                                                               \
119         register long _sc_0 inline_syscall_r0_asm;              \
120         register long _sc_16 __asm__("$16");                    \
121         register long _sc_17 __asm__("$17");                    \
122         register long _sc_19 __asm__("$19");                    \
123         register long _tmp_16 = (long) (arg1);                  \
124         register long _tmp_17 = (long) (arg2);                  \
125                                                                 \
126         _sc_0 = name;                                           \
127         _sc_16 = _tmp_16;                                       \
128         _sc_17 = _tmp_17;                                       \
129         __asm__ __volatile__                                    \
130           ("callsys # %0 %1 <= %2 %3 %4"                        \
131            : inline_syscall_r0_out_constraint (_sc_0),          \
132              "=r"(_sc_19), "=r"(_sc_16), "=r"(_sc_17)           \
133            : "0"(_sc_0), "2"(_sc_16), "3"(_sc_17)               \
134            : inline_syscall_clobbers,                           \
135              "$18", "$20", "$21");                              \
136         _sc_ret = _sc_0, _sc_err = _sc_19;                      \
137 }
138
139 #define inline_syscall3(name,arg1,arg2,arg3)                    \
140 {                                                               \
141         register long _sc_0 inline_syscall_r0_asm;              \
142         register long _sc_16 __asm__("$16");                    \
143         register long _sc_17 __asm__("$17");                    \
144         register long _sc_18 __asm__("$18");                    \
145         register long _sc_19 __asm__("$19");                    \
146         register long _tmp_16 = (long) (arg1);                  \
147         register long _tmp_17 = (long) (arg2);                  \
148         register long _tmp_18 = (long) (arg3);                  \
149                                                                 \
150         _sc_0 = name;                                           \
151         _sc_16 = _tmp_16;                                       \
152         _sc_17 = _tmp_17;                                       \
153         _sc_18 = _tmp_18;                                       \
154         __asm__ __volatile__                                    \
155           ("callsys # %0 %1 <= %2 %3 %4 %5"                     \
156            : inline_syscall_r0_out_constraint (_sc_0),          \
157              "=r"(_sc_19), "=r"(_sc_16), "=r"(_sc_17),          \
158              "=r"(_sc_18)                                       \
159            : "0"(_sc_0), "2"(_sc_16), "3"(_sc_17),              \
160              "4"(_sc_18)                                        \
161            : inline_syscall_clobbers, "$20", "$21");            \
162         _sc_ret = _sc_0, _sc_err = _sc_19;                      \
163 }
164
165 #define inline_syscall4(name,arg1,arg2,arg3,arg4)               \
166 {                                                               \
167         register long _sc_0 inline_syscall_r0_asm;              \
168         register long _sc_16 __asm__("$16");                    \
169         register long _sc_17 __asm__("$17");                    \
170         register long _sc_18 __asm__("$18");                    \
171         register long _sc_19 __asm__("$19");                    \
172         register long _tmp_16 = (long) (arg1);                  \
173         register long _tmp_17 = (long) (arg2);                  \
174         register long _tmp_18 = (long) (arg3);                  \
175         register long _tmp_19 = (long) (arg4);                  \
176                                                                 \
177         _sc_0 = name;                                           \
178         _sc_16 = _tmp_16;                                       \
179         _sc_17 = _tmp_17;                                       \
180         _sc_18 = _tmp_18;                                       \
181         _sc_19 = _tmp_19;                                       \
182         __asm__ __volatile__                                    \
183           ("callsys # %0 %1 <= %2 %3 %4 %5 %6"                  \
184            : inline_syscall_r0_out_constraint (_sc_0),          \
185              "=r"(_sc_19), "=r"(_sc_16), "=r"(_sc_17),          \
186              "=r"(_sc_18)                                       \
187            : "0"(_sc_0), "2"(_sc_16), "3"(_sc_17),              \
188              "4"(_sc_18), "1"(_sc_19)                           \
189            : inline_syscall_clobbers, "$20", "$21");            \
190         _sc_ret = _sc_0, _sc_err = _sc_19;                      \
191 }
192
193 #define inline_syscall5(name,arg1,arg2,arg3,arg4,arg5)          \
194 {                                                               \
195         register long _sc_0 inline_syscall_r0_asm;              \
196         register long _sc_16 __asm__("$16");                    \
197         register long _sc_17 __asm__("$17");                    \
198         register long _sc_18 __asm__("$18");                    \
199         register long _sc_19 __asm__("$19");                    \
200         register long _sc_20 __asm__("$20");                    \
201         register long _tmp_16 = (long) (arg1);                  \
202         register long _tmp_17 = (long) (arg2);                  \
203         register long _tmp_18 = (long) (arg3);                  \
204         register long _tmp_19 = (long) (arg4);                  \
205         register long _tmp_20 = (long) (arg5);                  \
206                                                                 \
207         _sc_0 = name;                                           \
208         _sc_16 = _tmp_16;                                       \
209         _sc_17 = _tmp_17;                                       \
210         _sc_18 = _tmp_18;                                       \
211         _sc_19 = _tmp_19;                                       \
212         _sc_20 = _tmp_20;                                       \
213         __asm__ __volatile__                                    \
214           ("callsys # %0 %1 <= %2 %3 %4 %5 %6 %7"               \
215            : inline_syscall_r0_out_constraint (_sc_0),          \
216              "=r"(_sc_19), "=r"(_sc_16), "=r"(_sc_17),          \
217              "=r"(_sc_18), "=r"(_sc_20)                         \
218            : "0"(_sc_0), "2"(_sc_16), "3"(_sc_17),              \
219              "4"(_sc_18), "1"(_sc_19), "5"(_sc_20)              \
220            : inline_syscall_clobbers, "$21");                   \
221         _sc_ret = _sc_0, _sc_err = _sc_19;                      \
222 }
223
224 #define inline_syscall6(name,arg1,arg2,arg3,arg4,arg5,arg6)     \
225 {                                                               \
226         register long _sc_0 inline_syscall_r0_asm;              \
227         register long _sc_16 __asm__("$16");                    \
228         register long _sc_17 __asm__("$17");                    \
229         register long _sc_18 __asm__("$18");                    \
230         register long _sc_19 __asm__("$19");                    \
231         register long _sc_20 __asm__("$20");                    \
232         register long _sc_21 __asm__("$21");                    \
233         register long _tmp_16 = (long) (arg1);                  \
234         register long _tmp_17 = (long) (arg2);                  \
235         register long _tmp_18 = (long) (arg3);                  \
236         register long _tmp_19 = (long) (arg4);                  \
237         register long _tmp_20 = (long) (arg5);                  \
238         register long _tmp_21 = (long) (arg6);                  \
239                                                                 \
240         _sc_0 = name;                                           \
241         _sc_16 = _tmp_16;                                       \
242         _sc_17 = _tmp_17;                                       \
243         _sc_18 = _tmp_18;                                       \
244         _sc_19 = _tmp_19;                                       \
245         _sc_20 = _tmp_20;                                       \
246         _sc_21 = _tmp_21;                                       \
247         __asm__ __volatile__                                    \
248           ("callsys # %0 %1 <= %2 %3 %4 %5 %6 %7 %8"            \
249            : inline_syscall_r0_out_constraint (_sc_0),          \
250              "=r"(_sc_19), "=r"(_sc_16), "=r"(_sc_17),          \
251              "=r"(_sc_18), "=r"(_sc_20), "=r"(_sc_21)           \
252            : "0"(_sc_0), "2"(_sc_16), "3"(_sc_17), "4"(_sc_18), \
253              "1"(_sc_19), "5"(_sc_20), "6"(_sc_21)              \
254            : inline_syscall_clobbers);                          \
255         _sc_ret = _sc_0, _sc_err = _sc_19;                      \
256 }
257
258 #endif /* __ASSEMBLER__ */
259 #endif /* _BITS_SYSCALLS_H */