summaryrefslogtreecommitdiff
path: root/libc/sysdeps
diff options
context:
space:
mode:
Diffstat (limited to 'libc/sysdeps')
-rw-r--r--libc/sysdeps/linux/bfin/bits/syscalls.h53
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 */