diff options
Diffstat (limited to 'libc/sysdeps/linux/bfin')
-rw-r--r-- | libc/sysdeps/linux/bfin/bits/syscalls.h | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/libc/sysdeps/linux/bfin/bits/syscalls.h b/libc/sysdeps/linux/bfin/bits/syscalls.h index 0833a1fc1..37e564d2c 100644 --- a/libc/sysdeps/linux/bfin/bits/syscalls.h +++ b/libc/sysdeps/linux/bfin/bits/syscalls.h @@ -134,5 +134,58 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6 __syscall_return(type,__res); \ } + +/* Define a macro which expands into the inline wrapper code for a system call */ +#define INLINE_SYSCALL(name, nr, args...) \ +({ \ + INTERNAL_SYSCALL_DECL(err); \ + long result_var = INTERNAL_SYSCALL(name, err, nr, args); \ + if (INTERNAL_SYSCALL_ERROR_P(result_var, err)) { \ + __set_errno(INTERNAL_SYSCALL_ERRNO(result_var, err)); \ + result_var = -1L; \ + } \ + result_var; \ +}) + +#define INTERNAL_SYSCALL_DECL(err) do { } while (0) +#define INTERNAL_SYSCALL_ERROR_P(val, err) ((unsigned long)val >= (unsigned long)(-4095)) +#define INTERNAL_SYSCALL_ERRNO(val, err) (-(val)) + +#define INTERNAL_SYSCALL(name, err, nr, args...) \ +({ \ + long __res; \ + __asm__ __volatile__ ( \ + "excpt 0;\n\t" \ + : "=q0" (__res) \ + : "qA" (__NR_##name) ASMFMT_##nr(args) \ + : "memory","CC"); \ + __res; \ +}) + +#define ASMFMT_0() + +#define ASMFMT_1(arg1) \ + , "q0" ((long)(arg1)) + +#define ASMFMT_2(arg1, arg2) \ + ASMFMT_1(arg1) \ + , "q1" ((long)(arg2)) + +#define ASMFMT_3(arg1, arg2, arg3) \ + ASMFMT_2(arg1, arg2) \ + , "q2" ((long)(arg3)) + +#define ASMFMT_4(arg1, arg2, arg3, arg4) \ + ASMFMT_3(arg1, arg2, arg3) \ + , "q3" ((long)(arg4)) + +#define ASMFMT_5(arg1, arg2, arg3, arg4, arg5) \ + ASMFMT_4(arg1, arg2, arg3, arg4) \ + , "q4" ((long)(arg5)) + +#define ASMFMT_6(arg1, arg2, arg3, arg4, arg5, arg6) \ + ASMFMT_5(arg1, arg2, arg3, arg4, arg5) \ + , "q5" ((long)(arg6)) + #endif /* __ASSEMBLER__ */ #endif /* _BITS_SYSCALLS_H */ |