OSDN Git Service

Patch by Joseph S. Myers to add support for ARM EABI
[uclinux-h8/uClibc.git] / libc / sysdeps / linux / arm / bits / syscalls.h
1 #ifndef _BITS_SYSCALLS_H
2 #define _BITS_SYSCALLS_H
3 #ifndef _SYSCALL_H
4 # error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
5 #endif
6
7 /* This includes the `__NR_<name>' syscall numbers taken from the Linux kernel
8  * header files.  It also defines the traditional `SYS_<name>' macros for older
9  * programs.  */
10 #include <bits/sysnum.h>
11
12 #ifndef __set_errno
13 # define __set_errno(val) (*__errno_location ()) = (val)
14 #endif
15 #ifndef SYS_ify
16 # define SYS_ify(syscall_name)  (__NR_##syscall_name)
17 #endif
18
19 /*
20    Some of the sneaky macros in the code were taken from 
21    glibc-2.3.2/sysdeps/unix/sysv/linux/arm/sysdep.h
22 */
23
24 #ifdef __ASSEMBLER__
25 /* Call a given syscall, with arguments loaded.  For EABI, we must
26    save and restore r7 for the syscall number.  Unlike the DO_CALL
27    macro in glibc, this macro does not load syscall arguments.  */
28 #undef DO_CALL
29 #if defined(__ARM_EABI__)
30 #define DO_CALL(syscall_name)                   \
31     mov ip, r7;                                 \
32     ldr r7, =SYS_ify (syscall_name);            \
33     swi 0x0;                                    \
34     mov r7, ip;
35 #else
36 #define DO_CALL(syscall_name)                   \
37     swi SYS_ify (syscall_name);
38 #endif
39 #else
40
41 #undef _syscall0
42 #define _syscall0(type,name) \
43 type name(void) \
44 { \
45 return (type) (INLINE_SYSCALL(name, 0)); \
46 }
47
48 #undef _syscall1
49 #define _syscall1(type,name,type1,arg1) \
50 type name(type1 arg1) \
51 { \
52 return (type) (INLINE_SYSCALL(name, 1, arg1)); \
53 }
54
55 #undef _syscall2
56 #define _syscall2(type,name,type1,arg1,type2,arg2) \
57 type name(type1 arg1,type2 arg2) \
58 { \
59 return (type) (INLINE_SYSCALL(name, 2, arg1, arg2)); \
60 }
61
62 #undef _syscall3
63 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
64 type name(type1 arg1,type2 arg2,type3 arg3) \
65 { \
66 return (type) (INLINE_SYSCALL(name, 3, arg1, arg2, arg3)); \
67 }
68
69 #undef _syscall4
70 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
71 type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
72 { \
73 return (type) (INLINE_SYSCALL(name, 4, arg1, arg2, arg3, arg4)); \
74
75
76 #undef _syscall5
77 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
78           type5,arg5) \
79 type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
80 { \
81 return (type) (INLINE_SYSCALL(name, 5, arg1, arg2, arg3, arg4, arg5)); \
82 }
83
84 #undef _syscall6
85 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
86           type5,arg5,type6,arg6) \
87 type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, type6 arg6) \
88 { \
89 return (type) (INLINE_SYSCALL(name, 6, arg1, arg2, arg3, arg4, arg5, arg6)); \
90 }
91
92 #undef _syscall7
93 #define _syscall7(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
94           type5,arg5,type6,arg6,type7,arg7) \
95 type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, type6 arg6,type7 arg7) \
96 { \
97 return (type) (INLINE_SYSCALL(name, 7, arg1, arg2, arg3, arg4, arg5, arg6, arg7)); \
98 }
99
100
101 #undef INLINE_SYSCALL
102 #define INLINE_SYSCALL(name, nr, args...)                               \
103   ({ unsigned int __sys_result = INTERNAL_SYSCALL (name, , nr, args);   \
104      if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (__sys_result, ), 0))       \
105        {                                                                \
106          __set_errno (INTERNAL_SYSCALL_ERRNO (__sys_result, ));         \
107          __sys_result = (unsigned int) -1;                              \
108        }                                                                \
109      (int) __sys_result; })
110
111 #undef INTERNAL_SYSCALL_DECL
112 #define INTERNAL_SYSCALL_DECL(err) do { } while (0)
113
114 #undef INTERNAL_SYSCALL
115 #if defined(__ARM_EABI__)
116 #define INTERNAL_SYSCALL(name, err, nr, args...)                        \
117   ({unsigned int _sys_result;                                           \
118      {                                                                  \
119        register int _a1 asm ("r0"), _nr asm ("r7");                     \
120        LOAD_ARGS_##nr (args)                                            \
121        _nr = SYS_ify(name);                                             \
122        asm volatile ("swi       0x0     @ syscall " #name               \
123                      : "=r" (_a1)                                       \
124                      : "r" (_nr) ASM_ARGS_##nr                          \
125                      : "memory");                                       \
126        _sys_result = _a1;                                               \
127      }                                                                  \
128      (int) _sys_result; })
129 #else /* !defined(__ARM_EABI__) */ 
130 #if !defined(__thumb__)
131 #define INTERNAL_SYSCALL(name, err, nr, args...)                \
132   ({ unsigned int _sys_result;                                  \
133      {                                                          \
134        register int _a1 asm ("a1");                             \
135        LOAD_ARGS_##nr (args)                                    \
136        asm volatile ("swi       %1      @ syscall " #name       \
137                      : "=r" (_a1)                               \
138                      : "i" (SYS_ify(name)) ASM_ARGS_##nr        \
139                      : "memory");                               \
140        _sys_result = _a1;                                       \
141      }                                                          \
142      (int) _sys_result; })
143 #else
144 #define INTERNAL_SYSCALL(name, err, nr, args...)                \
145   ({ unsigned int _sys_result;                                  \
146      {                                                          \
147        register int _a1 asm ("a1");                             \
148        LOAD_ARGS_##nr (args)                                    \
149        register int _r7 asm ("r7") = (int) (SYS_ify(name));     \
150        asm volatile ("swi       0       @ syscall " #name       \
151                      : "=r" (_a1)                               \
152                      : "r" (_r7) ASM_ARGS_##nr                  \
153                      : "memory");                               \
154        _sys_result = _a1;                                       \
155      }                                                          \
156      (int) _sys_result; })
157 #endif
158 #endif /* !defined(__ARM_EABI__) */
159
160 #undef INTERNAL_SYSCALL_ERROR_P
161 #define INTERNAL_SYSCALL_ERROR_P(val, err) \
162   ((unsigned int) (val) >= 0xfffff001u)
163
164 #undef INTERNAL_SYSCALL_ERRNO
165 #define INTERNAL_SYSCALL_ERRNO(val, err)        (-(val))
166
167 #define LOAD_ARGS_0()
168 #define ASM_ARGS_0
169 #define LOAD_ARGS_1(a1)                         \
170   _a1 = (int) (a1);                             \
171   LOAD_ARGS_0 ()
172 #define ASM_ARGS_1      ASM_ARGS_0, "r" (_a1)
173 #define LOAD_ARGS_2(a1, a2)                     \
174   register int _a2 asm ("a2") = (int) (a2);     \
175   LOAD_ARGS_1 (a1)
176 #define ASM_ARGS_2      ASM_ARGS_1, "r" (_a2)
177 #define LOAD_ARGS_3(a1, a2, a3)                 \
178   register int _a3 asm ("a3") = (int) (a3);     \
179   LOAD_ARGS_2 (a1, a2)
180 #define ASM_ARGS_3      ASM_ARGS_2, "r" (_a3)
181 #define LOAD_ARGS_4(a1, a2, a3, a4)             \
182   register int _a4 asm ("a4") = (int) (a4);     \
183   LOAD_ARGS_3 (a1, a2, a3)
184 #define ASM_ARGS_4      ASM_ARGS_3, "r" (_a4)
185 #define LOAD_ARGS_5(a1, a2, a3, a4, a5)         \
186   register int _v1 asm ("v1") = (int) (a5);     \
187   LOAD_ARGS_4 (a1, a2, a3, a4)
188 #define ASM_ARGS_5      ASM_ARGS_4, "r" (_v1)
189 #define LOAD_ARGS_6(a1, a2, a3, a4, a5, a6)     \
190   register int _v2 asm ("v2") = (int) (a6);     \
191   LOAD_ARGS_5 (a1, a2, a3, a4, a5)
192 #define ASM_ARGS_6      ASM_ARGS_5, "r" (_v2)
193 #define LOAD_ARGS_7(a1, a2, a3, a4, a5, a6, a7) \
194   register int _v3 asm ("v3") = (int) (a7);     \
195   LOAD_ARGS_6 (a1, a2, a3, a4, a5, a6)
196 #define ASM_ARGS_7      ASM_ARGS_6, "r" (_v3)
197
198
199 #endif /* __ASSEMBLER__ */
200 #endif /* _BITS_SYSCALLS_H */