OSDN Git Service

get rid of linux-headers hack ... rip code from glibc
authorMike Frysinger <vapier@gentoo.org>
Wed, 16 Mar 2005 01:43:17 +0000 (01:43 -0000)
committerMike Frysinger <vapier@gentoo.org>
Wed, 16 Mar 2005 01:43:17 +0000 (01:43 -0000)
libc/sysdeps/linux/m68k/bits/syscalls.h

index 62541b8..c833cf7 100644 (file)
 # error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
 #endif
 
-#include <features.h>
-
-/* Do something very evil for now.  Until we create our own syscall
- * macros, short circuit bits/sysnum.h  and use asm/unistd.h instead */
-#include <asm/unistd.h>
-
 /* This includes the `__NR_<name>' syscall numbers taken from the Linux kernel
  * header files.  It also defines the traditional `SYS_<name>' macros for older
  * programs.  */
 #include <bits/sysnum.h>
 
-#endif /* _BITS_SYSCALLS_H */
+#ifndef __set_errno
+# define __set_errno(val) (*__errno_location ()) = (val)
+#endif
+
+/*
+   Some of the sneaky macros in the code were taken from 
+   glibc-2.2.5/sysdeps/unix/sysv/linux/m68k/sysdep.h
+*/
+
+#ifndef __ASSEMBLER__
+
+#undef _syscall0
+#define _syscall0(type,name) \
+type name(void) \
+{ \
+return (type) (INLINE_SYSCALL(name, 0)); \
+}
+
+#undef _syscall1
+#define _syscall1(type,name,type1,arg1) \
+type name(type1 arg1) \
+{ \
+return (type) (INLINE_SYSCALL(name, 1, arg1)); \
+}
+
+#undef _syscall2
+#define _syscall2(type,name,type1,arg1,type2,arg2) \
+type name(type1 arg1,type2 arg2) \
+{ \
+return (type) (INLINE_SYSCALL(name, 2, arg1, arg2)); \
+}
+
+#undef _syscall3
+#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
+type name(type1 arg1,type2 arg2,type3 arg3) \
+{ \
+return (type) (INLINE_SYSCALL(name, 3, arg1, arg2, arg3)); \
+}
+
+#undef _syscall4
+#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
+type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
+{ \
+return (type) (INLINE_SYSCALL(name, 4, arg1, arg2, arg3, arg4)); \
+} 
+
+#undef _syscall5
+#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+         type5,arg5) \
+type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
+{ \
+return (type) (INLINE_SYSCALL(name, 5, arg1, arg2, arg3, arg4, arg5)); \
+}
+
+#undef _syscall6
+#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+         type5,arg5,type6,arg6) \
+type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \
+{ \
+return (type) (INLINE_SYSCALL(name, 6, arg1, arg2, arg3, arg4, arg5, arg6)); \
+}
 
+/* Linux takes system call arguments in registers:
+
+       syscall number  %d0          call-clobbered
+       arg 1           %d1          call-clobbered
+       arg 2           %d2          call-saved
+       arg 3           %d3          call-saved
+       arg 4           %d4          call-saved
+       arg 5           %d5          call-saved
+
+   The stack layout upon entering the function is:
+
+       20(%sp)         Arg# 5
+       16(%sp)         Arg# 4
+       12(%sp)         Arg# 3
+        8(%sp)         Arg# 2
+        4(%sp)         Arg# 1
+         (%sp)         Return address
+
+   (Of course a function with say 3 arguments does not have entries for
+   arguments 4 and 5.)
+
+   Separate move's are faster than movem, but need more space.  Since
+   speed is more important, we don't use movem.  Since %a0 and %a1 are
+   scratch registers, we can use them for saving as well.  */
+
+#undef INLINE_SYSCALL
+#define INLINE_SYSCALL(name, nr, args...)                              \
+  ({ unsigned int _sys_result = INTERNAL_SYSCALL (name, , nr, args);   \
+     if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (_sys_result, ), 0))\
+       {                                                               \
+        __set_errno (INTERNAL_SYSCALL_ERRNO (_sys_result, ));          \
+        _sys_result = (unsigned int) -1;                               \
+       }                                                               \
+     (int) _sys_result; })
+
+#undef INTERNAL_SYSCALL
+#define INTERNAL_SYSCALL(name, err, nr, args...)       \
+  ({ unsigned int _sys_result;                         \
+     {                                                 \
+       /* Load argument values in temporary variables
+         to perform side effects like function calls
+         before the call used registers are set.  */   \
+       LOAD_ARGS_##nr (args)                           \
+       LOAD_REGS_##nr                                  \
+       register int _d0 asm ("%d0") = __NR_##name;     \
+       asm volatile ("trap #0"                         \
+                    : "=d" (_d0)                       \
+                    : "0" (_d0) ASM_ARGS_##nr          \
+                    : "memory");                       \
+       _sys_result = _d0;                              \
+     }                                                 \
+     (int) _sys_result; })
+
+#undef INTERNAL_SYSCALL_ERROR_P
+#define INTERNAL_SYSCALL_ERROR_P(val, err)             \
+  ((unsigned int) (val) >= -4095U)
+
+#undef INTERNAL_SYSCALL_ERRNO
+#define INTERNAL_SYSCALL_ERRNO(val, err)       (-(val))
+
+#define LOAD_ARGS_0()
+#define LOAD_REGS_0
+#define ASM_ARGS_0
+#define LOAD_ARGS_1(a1)                                \
+  LOAD_ARGS_0 ()                               \
+  int __arg1 = (int) (a1);
+#define LOAD_REGS_1                            \
+  register int _d1 asm ("d1") = __arg1;                \
+  LOAD_REGS_0
+#define ASM_ARGS_1     ASM_ARGS_0, "d" (_d1)
+#define LOAD_ARGS_2(a1, a2)                    \
+  LOAD_ARGS_1 (a1)                             \
+  int __arg2 = (int) (a2);
+#define LOAD_REGS_2                            \
+  register int _d2 asm ("d2") = __arg2;                \
+  LOAD_REGS_1
+#define ASM_ARGS_2     ASM_ARGS_1, "d" (_d2)
+#define LOAD_ARGS_3(a1, a2, a3)                        \
+  LOAD_ARGS_2 (a1, a2)                         \
+  int __arg3 = (int) (a3);
+#define LOAD_REGS_3                            \
+  register int _d3 asm ("d3") = __arg3;                \
+  LOAD_REGS_2
+#define ASM_ARGS_3     ASM_ARGS_2, "d" (_d3)
+#define LOAD_ARGS_4(a1, a2, a3, a4)            \
+  LOAD_ARGS_3 (a1, a2, a3)                     \
+  int __arg4 = (int) (a4);
+#define LOAD_REGS_4                            \
+  register int _d4 asm ("d4") = __arg4;                \
+  LOAD_REGS_3
+#define ASM_ARGS_4     ASM_ARGS_3, "d" (_d4)
+#define LOAD_ARGS_5(a1, a2, a3, a4, a5)                \
+  LOAD_ARGS_4 (a1, a2, a3, a4)                 \
+  int __arg5 = (int) (a5);
+#define LOAD_REGS_5                            \
+  register int _d5 asm ("d5") = __arg5;                \
+  LOAD_REGS_4
+#define ASM_ARGS_5     ASM_ARGS_4, "d" (_d5)
+#define LOAD_ARGS_6(a1, a2, a3, a4, a5, a6)    \
+  LOAD_ARGS_5 (a1, a2, a3, a4, a5)             \
+  int __arg6 = (int) (a6);
+#define LOAD_REGS_6                            \
+  register int _a0 asm ("a0") = __arg6;                \
+  LOAD_REGS_5
+#define ASM_ARGS_6     ASM_ARGS_5, "a" (_a0)
+
+#endif /* __ASSEMBLER__ */
+#endif /* _BITS_SYSCALLS_H */