2 * Copyright (C) 2016 Andes Technology, Inc.
3 * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
7 * For nds32 ISA, the syscall number(SWID) shall be determined at compile time.
8 * (ex: asm("syscall SWID"); )
9 * If the value of syscall number is determined at run time, we shall issue
10 * this syscall through sys_syscall.
12 * asm("move $r0, SYSCALL_number"
14 * where 0x5071 is syscall number for sys_syscall
17 * The following two macros are implemented according that syscall number
18 * is determined in compiler time or run time,
20 * 1. INTERNAL_SYSCALL_NCS: the syscall number is determined at run time
21 * 2. INTERNAL_SYSCALL: the syscall number is determined at compile time
26 #ifndef _BITS_SYSCALLS_H
27 #define _BITS_SYSCALLS_H
29 # error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
34 #include <common/sysdep.h>
38 #define LIB_SYSCALL __NR_syscall
40 #define __issue_syscall(syscall_name) \
41 " syscall " Y(syscall_name) "; \n"
43 #undef INTERNAL_SYSCALL_ERROR_P
44 #define INTERNAL_SYSCALL_ERROR_P(val, err) ((unsigned int) (val) >= 0xfffff001u)
46 #undef INTERNAL_SYSCALL_ERRNO
47 #define INTERNAL_SYSCALL_ERRNO(val, err) (-(val))
50 #define INLINE_SYSCALL(name, nr, args...) \
52 INTERNAL_SYSCALL_DECL (err); \
53 long result_var = INTERNAL_SYSCALL (name, err, nr, args); \
54 if (INTERNAL_SYSCALL_ERROR_P (result_var, err)) \
56 __set_errno (INTERNAL_SYSCALL_ERRNO (result_var, err)); \
63 #undef INTERNAL_SYSCALL_DECL
64 #define INTERNAL_SYSCALL_DECL(err) do { } while (0)
67 #undef INTERNAL_SYSCALL
68 #define INTERNAL_SYSCALL(name, err, nr, args...) internal_syscall##nr(__NR_##name, err, args)
71 The _NCS variant allows non-constant syscall numbers
73 #undef INTERNAL_SYSCALL_NCS
74 #define INTERNAL_SYSCALL_NCS(name, err, nr, args...) internal_syscall_ncs##nr(name, err, args)
77 #define internal_syscall0(name, err, dummy...) \
79 register long ___res __asm__("$r0"); \
81 __issue_syscall (name) \
82 : "=r" (___res) /* output operands */ \
84 : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
88 #define internal_syscall1(name, err, arg1) \
90 register long ___res __asm__("$r0"); \
91 register long __arg1 __asm__("$r0") = (long) (arg1); \
93 __issue_syscall (name) \
94 : "=r" (___res) /* output operands */ \
95 : "r" (__arg1) /* input operands */ \
96 : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
100 #define internal_syscall2(name, err, arg1, arg2) \
102 register long ___res __asm__("$r0"); \
103 register long __arg1 __asm__("$r0") = (long) (arg1); \
104 register long __arg2 __asm__("$r1") = (long) (arg2); \
106 __issue_syscall (name) \
107 : "=r" (___res) /* output operands */ \
108 : "r" (__arg1) /* input operands */ \
109 , "r" (__arg2) /* input operands */ \
110 : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
114 #define internal_syscall3(name, err, arg1, arg2, arg3) \
116 register long ___res __asm__("$r0"); \
117 register long __arg1 __asm__("$r0") = (long) (arg1); \
118 register long __arg2 __asm__("$r1") = (long) (arg2); \
119 register long __arg3 __asm__("$r2") = (long) (arg3); \
121 __issue_syscall (name) \
122 : "=r" (___res) /* output operands */ \
123 : "r" (__arg1) /* input operands */ \
124 , "r" (__arg2) /* input operands */ \
125 , "r" (__arg3) /* input operands */ \
126 : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
130 #define internal_syscall4(name, err, arg1, arg2, arg3, arg4) \
132 register long ___res __asm__("$r0"); \
133 register long __arg1 __asm__("$r0") = (long) (arg1); \
134 register long __arg2 __asm__("$r1") = (long) (arg2); \
135 register long __arg3 __asm__("$r2") = (long) (arg3); \
136 register long __arg4 __asm__("$r3") = (long) (arg4); \
138 __issue_syscall (name) \
139 : "=r" (___res) /* output operands */ \
140 : "r" (__arg1) /* input operands */ \
141 , "r" (__arg2) /* input operands */ \
142 , "r" (__arg3) /* input operands */ \
143 , "r" (__arg4) /* input operands */ \
144 : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
148 #define internal_syscall5(name, err, arg1, arg2, arg3, arg4, arg5) \
150 register long ___res __asm__("$r0"); \
151 register long __arg1 __asm__("$r0") = (long) (arg1); \
152 register long __arg2 __asm__("$r1") = (long) (arg2); \
153 register long __arg3 __asm__("$r2") = (long) (arg3); \
154 register long __arg4 __asm__("$r3") = (long) (arg4); \
155 register long __arg5 __asm__("$r4") = (long) (arg5); \
157 __issue_syscall (name) \
158 : "=r" (___res) /* output operands */ \
159 : "r" (__arg1) /* input operands */ \
160 , "r" (__arg2) /* input operands */ \
161 , "r" (__arg3) /* input operands */ \
162 , "r" (__arg4) /* input operands */ \
163 , "r" (__arg5) /* input operands */ \
164 : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
168 #define internal_syscall6(name, err, arg1, arg2, arg3, arg4, arg5, arg6) \
170 register long ___res __asm__("$r0"); \
171 register long __arg1 __asm__("$r0") = (long) (arg1); \
172 register long __arg2 __asm__("$r1") = (long) (arg2); \
173 register long __arg3 __asm__("$r2") = (long) (arg3); \
174 register long __arg4 __asm__("$r3") = (long) (arg4); \
175 register long __arg5 __asm__("$r4") = (long) (arg5); \
176 register long __arg6 __asm__("$r5") = (long) (arg6); \
178 __issue_syscall (name) \
179 : "=r" (___res) /* output operands */ \
180 : "r" (__arg1) /* input operands */ \
181 , "r" (__arg2) /* input operands */ \
182 , "r" (__arg3) /* input operands */ \
183 , "r" (__arg4) /* input operands */ \
184 , "r" (__arg5) /* input operands */ \
185 , "r" (__arg6) /* input operands */ \
186 : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
189 #define internal_syscall7(name, err, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
191 register long ___res __asm__("$r0"); \
192 register long __arg1 __asm__("$r0") = (long) (arg1); \
193 register long __arg2 __asm__("$r1") = (long) (arg2); \
194 register long __arg3 __asm__("$r2") = (long) (arg3); \
195 register long __arg4 __asm__("$r3") = (long) (arg4); \
196 register long __arg5 __asm__("$r4") = (long) (arg5); \
197 register long __arg6 __asm__("$r5") = (long) (arg6); \
199 "addi10.sp\t #-4\n\t" \
200 CFI_ADJUST_CFA_OFFSET(4)"\n\t" \
202 CFI_ADJUST_CFA_OFFSET(4)"\n\t" \
203 __issue_syscall (name) \
204 "addi10.sp\t #4\n\t" \
205 CFI_ADJUST_CFA_OFFSET(-4)"\n\t" \
207 CFI_ADJUST_CFA_OFFSET(-4)"\n\t" \
208 : "=r" (___res) /* output operands */ \
209 : "r" (__arg1) /* input operands */ \
210 , "r" (__arg2) /* input operands */ \
211 , "r" (__arg3) /* input operands */ \
212 , "r" (__arg4) /* input operands */ \
213 , "r" (__arg5) /* input operands */ \
214 , "r" (__arg6) /* input operands */ \
215 , "r" (arg7) /* input operands */ \
216 : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
220 #define internal_syscall_ncs0(name, err, dummy...) \
222 register long __res __asm__("$r0"); \
223 register long __no __asm__("$r0") = (long) (name); \
225 __issue_syscall (LIB_SYSCALL) \
226 : "=r" (__res) /* output operands */ \
227 : "r" (__no) /* input operands */ \
228 : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
232 #define internal_syscall_ncs1(name, err, arg1) \
234 register long __res __asm__("$r0"); \
235 register long __no __asm__("$r0") = (long) (name); \
236 register long __arg1 __asm__("$r1") = (long) (arg1); \
238 __issue_syscall (LIB_SYSCALL) \
239 : "=r" (__res) /* output operands */ \
240 : "r" (__arg1) /* input operands */ \
241 , "r" (__no) /* input operands */ \
242 : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
246 #define internal_syscall_ncs2(name, err, arg1, arg2) \
248 register long __res __asm__("$r0"); \
249 register long __no __asm__("$r0") = (long) (name); \
250 register long __arg1 __asm__("$r1") = (long) (arg1); \
251 register long __arg2 __asm__("$r2") = (long) (arg2); \
253 __issue_syscall (LIB_SYSCALL) \
254 : "=r" (__res) /* output operands */ \
255 : "r" (__arg1) /* input operands */ \
256 , "r" (__arg2) /* input operands */ \
257 , "r" (__no) /* input operands */ \
258 : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
262 #define internal_syscall_ncs3(name, err, arg1, arg2, arg3) \
264 register long __res __asm__("$r0"); \
265 register long __no __asm__("$r0") = (long) (name); \
266 register long __arg1 __asm__("$r1") = (long) (arg1); \
267 register long __arg2 __asm__("$r2") = (long) (arg2); \
268 register long __arg3 __asm__("$r3") = (long) (arg3); \
270 __issue_syscall (LIB_SYSCALL) \
271 : "=r" (__res) /* output operands */ \
272 : "r" (__arg1) /* input operands */ \
273 , "r" (__arg2) /* input operands */ \
274 , "r" (__arg3) /* input operands */ \
275 , "r" (__no) /* input operands */ \
276 : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
280 #define internal_syscall_ncs4(name, err, arg1, arg2, arg3, arg4) \
282 register long __res __asm__("$r0"); \
283 register long __no __asm__("$r0") = (long) (name); \
284 register long __arg1 __asm__("$r1") = (long) (arg1); \
285 register long __arg2 __asm__("$r2") = (long) (arg2); \
286 register long __arg3 __asm__("$r3") = (long) (arg3); \
287 register long __arg4 __asm__("$r4") = (long) (arg4); \
289 __issue_syscall (LIB_SYSCALL) \
290 : "=r" (__res) /* output operands */ \
291 : "r" (__arg1) /* input operands */ \
292 , "r" (__arg2) /* input operands */ \
293 , "r" (__arg3) /* input operands */ \
294 , "r" (__arg4) /* input operands */ \
295 , "r" (__no) /* input operands */ \
296 : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
300 #define internal_syscall_ncs5(name, err, arg1, arg2, arg3, arg4, arg5) \
302 register long ___res __asm__("$r0"); \
303 register long __no __asm__("$r0") = (long) (name); \
304 register long __arg1 __asm__("$r1") = (long) (arg1); \
305 register long __arg2 __asm__("$r2") = (long) (arg2); \
306 register long __arg3 __asm__("$r3") = (long) (arg3); \
307 register long __arg4 __asm__("$r4") = (long) (arg4); \
308 register long __arg5 __asm__("$r5") = (long) (arg5); \
310 __issue_syscall (LIB_SYSCALL) \
311 : "=r" (___res) /* output operands */ \
312 : "r" (__arg1) /* input operands */ \
313 , "r" (__arg2) /* input operands */ \
314 , "r" (__arg3) /* input operands */ \
315 , "r" (__arg4) /* input operands */ \
316 , "r" (__arg5) /* input operands */ \
317 : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
321 #define internal_syscall_ncs6(name, err, arg1, arg2, arg3, arg4, arg5, arg6) \
323 register long __res __asm__("$r0"); \
324 register long __no __asm__("$r0") = (long) (name); \
325 register long __arg1 __asm__("$r1") = (long) (arg1); \
326 register long __arg2 __asm__("$r2") = (long) (arg2); \
327 register long __arg3 __asm__("$r3") = (long) (arg3); \
328 register long __arg4 __asm__("$r4") = (long) (arg4); \
329 register long __arg5 __asm__("$r5") = (long) (arg5); \
331 "addi10.sp\t #-4\n\t" \
332 CFI_ADJUST_CFA_OFFSET(4)"\n\t" \
334 CFI_ADJUST_CFA_OFFSET(4)"\n\t" \
335 __issue_syscall (LIB_SYSCALL) \
337 CFI_ADJUST_CFA_OFFSET(-4)"\n\t" \
338 "addi10.sp\t #4\n\t" \
339 CFI_ADJUST_CFA_OFFSET(-4)"\n\t" \
340 : "=r" (__res) /* output operands */ \
341 : "r" (__no) /* input operands */ \
342 , "r" (__arg1) /* input operands */ \
343 , "r" (__arg2) /* input operands */ \
344 , "r" (__arg3) /* input operands */ \
345 , "r" (__arg4) /* input operands */ \
346 , "r" (__arg5) /* input operands */ \
347 , "r" (arg6) /* input operands */ \
348 : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
352 #define __SYSCALL_CLOBBERS "$lp", "memory"
353 #endif /* ! __ASSEMBLER__ */
354 #endif /* _BITS_SYSCALLS_H */