Эх сурвалжийг харах

Blackfin: declare {INLINE,INTERNAL}_SYSCALL() and friends

Mike Frysinger 16 жил өмнө
parent
commit
b8894106ef

+ 53 - 0
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 */