summaryrefslogtreecommitdiffstats
path: root/libc/sysdeps/linux/mips/sysdep.h
diff options
context:
space:
mode:
Diffstat (limited to 'libc/sysdeps/linux/mips/sysdep.h')
-rw-r--r--libc/sysdeps/linux/mips/sysdep.h334
1 files changed, 259 insertions, 75 deletions
diff --git a/libc/sysdeps/linux/mips/sysdep.h b/libc/sysdeps/linux/mips/sysdep.h
index f9778b2d1..8f4262196 100644
--- a/libc/sysdeps/linux/mips/sysdep.h
+++ b/libc/sysdeps/linux/mips/sysdep.h
@@ -23,38 +23,10 @@ Cambridge, MA 02139, USA. */
/* Not that using a `PASTE' macro loses. */
#ifdef __STDC__
-#ifdef __ELF__
-
#define SYSCALL_WEAK_ALIAS(alias,orig) \
.weak alias; \
alias=__libc_##orig
-/*
-#ifdef _POSIX_THREADS
-*/
-
-#if 1
-
-#ifdef PTHREAD_KERNEL
-
-/* Use the regular ELF conventions about underscores, and provide the
- weak symbol, as required */
-#define SYSCALL__(name,args) PSEUDO (__machdep_sys_##name, name, args) \
-.weak machdep_sys_##name; \
- machdep_sys_##name = __machdep_sys_##name; \
-.type __machdep_sys_##name,@function; \
-.type machdep_sys_##name,@function; \
-.L__machdep_sys_##name##end: .size __machdep_sys_##name,.L__machdep_sys_##name##end - __machdep_sys_##name
-
-#define SYSCALL(name,args) PSEUDO (__machdep_sys_##name, name, args) \
-.weak machdep_sys_##name; \
- machdep_sys_##name = __machdep_sys_##name; \
-.type __machdep_sys_##name,@function; \
-.type machdep_sys_##name,@function; \
-.L__machdep_sys_##name##end: .size __machdep_sys_##name,.L__machdep_sys_##name##end - __machdep_sys_##name
-
-#else /* PTHREAD_KERNEL */
-
/* Use the regular ELF conventions about underscores, and provide the
weak symbol, as required */
#define SYSCALL__(name,args) PSEUDO (__libc_##name, name, args) \
@@ -74,39 +46,6 @@ Cambridge, MA 02139, USA. */
.type name,@function; \
.L__libc_##name##end: .size __libc_##name,.L__libc_##name##end - __libc_##name
-#endif /* PTHREAD_KERNEL */
-
-#else /* _POSIX_THREADS */
-
-/* Use the regular ELF conventions about underscores, and provide the
- weak symbol, as required */
-#define SYSCALL__(name,args) PSEUDO (__libc_##name, name, args) \
-.weak name; \
- __##name = __libc_##name; \
- name = __libc_##name; \
-.type __libc_##name,@function; \
-.type name,@function; \
-.type __##name,@function; \
-.L__libc_##name##end: .size __libc_##name,.L__libc_##name##end - __libc_##name
-
-#define SYSCALL(name,args) PSEUDO (__libc_##name, name, args) \
- name = __libc_##name; \
-.type __libc_##name,@function; \
-.type name,@function; \
-.L__libc_##name##end: .size __libc_##name,.L__libc_##name##end - __libc_##name
-
-#endif /* _POSIX_THREADS */
-
-#else /* __ELF__ */
-
-#define SYSCALL_WEAK_ALIAS(alias,orig)
-
-/* Regular a.out definition */
-#define SYSCALL__(name,args) PSEUDO (__##name, name, args)
-#define SYSCALL(name,args) PSEUDO (name, name, args)
-
-#endif /* __ELF__ */
-
#else /* __STDC__ */
#define SYSCALL__(name,args) PSEUDO (__/**/name, name, args)
@@ -114,22 +53,267 @@ Cambridge, MA 02139, USA. */
#endif /* __STDC__ */
-/* Machine-dependent sysdep.h files are expected to define the macro
- PSEUDO (function_name, syscall_name) to emit assembly code to define the
- C-callable function FUNCTION_NAME to do system call SYSCALL_NAME.
- r0 and r1 are the system call outputs. movl should be defined as
- an instruction such that "movl r1, r0" works. ret should be defined
- as the return instruction. */
-
-
-#if !defined(HAVE_GNU_LD) && !defined (__ELF__)
-#define ___errno _errno
+#ifndef __ASSEMBLER__
+/* Define a macro which expands into the inline wrapper code for a system
+ call. */
+#undef INLINE_SYSCALL
+#if 0
+#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; })
+#else
+#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) ) \
+ { \
+ result_var = __syscall_error((int) result_var); \
+ } \
+ result_var; })
#endif
-#define HAVE_SYSCALLS
-
-#ifdef __PTHREADS_NATIVE__
-#include <sysdep-nptl.h>
+#undef INTERNAL_SYSCALL_DECL
+#define INTERNAL_SYSCALL_DECL(err) long err
+
+#undef INTERNAL_SYSCALL_ERROR_P
+#define INTERNAL_SYSCALL_ERROR_P(val, err) ((long) (err))
+
+#undef INTERNAL_SYSCALL_ERRNO
+#define INTERNAL_SYSCALL_ERRNO(val, err) (val)
+
+#undef INTERNAL_SYSCALL
+#define INTERNAL_SYSCALL(name, err, nr, args...) \
+ internal_syscall##nr (, "li\t$2, %2\t\t\t# " #name "\n\t", \
+ "i" (SYS_ify (name)), err, args)
+
+#undef INTERNAL_SYSCALL_NCS
+#define INTERNAL_SYSCALL_NCS(number, err, nr, args...) \
+ internal_syscall##nr (= number, , "r" (__v0), err, args)
+
+#define internal_syscall0(ncs_init, cs_init, input, err, dummy...) \
+({ \
+ long _sys_result; \
+ \
+ { \
+ register long __v0 asm("$2") ncs_init; \
+ register long __a3 asm("$7"); \
+ __asm__ volatile ( \
+ ".set\tnoreorder\n\t" \
+ cs_init \
+ "syscall\n\t" \
+ ".set reorder" \
+ : "=r" (__v0), "=r" (__a3) \
+ : input \
+ : __SYSCALL_CLOBBERS); \
+ err = __a3; \
+ _sys_result = __v0; \
+ } \
+ _sys_result; \
+})
+
+#define internal_syscall1(ncs_init, cs_init, input, err, arg1) \
+({ \
+ long _sys_result; \
+ \
+ { \
+ register long __v0 asm("$2") ncs_init; \
+ register long __a0 asm("$4") = (long) arg1; \
+ register long __a3 asm("$7"); \
+ __asm__ volatile ( \
+ ".set\tnoreorder\n\t" \
+ cs_init \
+ "syscall\n\t" \
+ ".set reorder" \
+ : "=r" (__v0), "=r" (__a3) \
+ : input, "r" (__a0) \
+ : __SYSCALL_CLOBBERS); \
+ err = __a3; \
+ _sys_result = __v0; \
+ } \
+ _sys_result; \
+})
+
+#define internal_syscall2(ncs_init, cs_init, input, err, arg1, arg2) \
+({ \
+ long _sys_result; \
+ \
+ { \
+ register long __v0 asm("$2") ncs_init; \
+ register long __a0 asm("$4") = (long) arg1; \
+ register long __a1 asm("$5") = (long) arg2; \
+ register long __a3 asm("$7"); \
+ __asm__ volatile ( \
+ ".set\tnoreorder\n\t" \
+ cs_init \
+ "syscall\n\t" \
+ ".set\treorder" \
+ : "=r" (__v0), "=r" (__a3) \
+ : input, "r" (__a0), "r" (__a1) \
+ : __SYSCALL_CLOBBERS); \
+ err = __a3; \
+ _sys_result = __v0; \
+ } \
+ _sys_result; \
+})
+
+#define internal_syscall3(ncs_init, cs_init, input, err, arg1, arg2, arg3)\
+({ \
+ long _sys_result; \
+ \
+ { \
+ register long __v0 asm("$2") ncs_init; \
+ register long __a0 asm("$4") = (long) arg1; \
+ register long __a1 asm("$5") = (long) arg2; \
+ register long __a2 asm("$6") = (long) arg3; \
+ register long __a3 asm("$7"); \
+ __asm__ volatile ( \
+ ".set\tnoreorder\n\t" \
+ cs_init \
+ "syscall\n\t" \
+ ".set\treorder" \
+ : "=r" (__v0), "=r" (__a3) \
+ : input, "r" (__a0), "r" (__a1), "r" (__a2) \
+ : __SYSCALL_CLOBBERS); \
+ err = __a3; \
+ _sys_result = __v0; \
+ } \
+ _sys_result; \
+})
+
+#define internal_syscall4(ncs_init, cs_init, input, err, arg1, arg2, arg3, arg4)\
+({ \
+ long _sys_result; \
+ \
+ { \
+ register long __v0 asm("$2") ncs_init; \
+ register long __a0 asm("$4") = (long) arg1; \
+ register long __a1 asm("$5") = (long) arg2; \
+ register long __a2 asm("$6") = (long) arg3; \
+ register long __a3 asm("$7") = (long) arg4; \
+ __asm__ volatile ( \
+ ".set\tnoreorder\n\t" \
+ cs_init \
+ "syscall\n\t" \
+ ".set\treorder" \
+ : "=r" (__v0), "+r" (__a3) \
+ : input, "r" (__a0), "r" (__a1), "r" (__a2) \
+ : __SYSCALL_CLOBBERS); \
+ err = __a3; \
+ _sys_result = __v0; \
+ } \
+ _sys_result; \
+})
+
+/* We need to use a frame pointer for the functions in which we
+ adjust $sp around the syscall, or debug information and unwind
+ information will be $sp relative and thus wrong during the syscall. As
+ of GCC 3.4.3, this is sufficient. */
+#define FORCE_FRAME_POINTER alloca (4)
+
+#define internal_syscall5(ncs_init, cs_init, input, err, arg1, arg2, arg3, arg4, arg5)\
+({ \
+ long _sys_result; \
+ \
+ FORCE_FRAME_POINTER; \
+ { \
+ register long __v0 asm("$2") ncs_init; \
+ register long __a0 asm("$4") = (long) arg1; \
+ register long __a1 asm("$5") = (long) arg2; \
+ register long __a2 asm("$6") = (long) arg3; \
+ register long __a3 asm("$7") = (long) arg4; \
+ __asm__ volatile ( \
+ ".set\tnoreorder\n\t" \
+ "subu\t$29, 32\n\t" \
+ "sw\t%6, 16($29)\n\t" \
+ cs_init \
+ "syscall\n\t" \
+ "addiu\t$29, 32\n\t" \
+ ".set\treorder" \
+ : "=r" (__v0), "+r" (__a3) \
+ : input, "r" (__a0), "r" (__a1), "r" (__a2), \
+ "r" ((long)arg5) \
+ : __SYSCALL_CLOBBERS); \
+ err = __a3; \
+ _sys_result = __v0; \
+ } \
+ _sys_result; \
+})
+
+#define internal_syscall6(ncs_init, cs_init, input, err, arg1, arg2, arg3, arg4, arg5, arg6)\
+({ \
+ long _sys_result; \
+ \
+ FORCE_FRAME_POINTER; \
+ { \
+ register long __v0 asm("$2") ncs_init; \
+ register long __a0 asm("$4") = (long) arg1; \
+ register long __a1 asm("$5") = (long) arg2; \
+ register long __a2 asm("$6") = (long) arg3; \
+ register long __a3 asm("$7") = (long) arg4; \
+ __asm__ volatile ( \
+ ".set\tnoreorder\n\t" \
+ "subu\t$29, 32\n\t" \
+ "sw\t%6, 16($29)\n\t" \
+ "sw\t%7, 20($29)\n\t" \
+ cs_init \
+ "syscall\n\t" \
+ "addiu\t$29, 32\n\t" \
+ ".set\treorder" \
+ : "=r" (__v0), "+r" (__a3) \
+ : input, "r" (__a0), "r" (__a1), "r" (__a2), \
+ "r" ((long)arg5), "r" ((long)arg6) \
+ : __SYSCALL_CLOBBERS); \
+ err = __a3; \
+ _sys_result = __v0; \
+ } \
+ _sys_result; \
+})
+
+#define internal_syscall7(ncs_init, cs_init, input, err, arg1, arg2, arg3, arg4, arg5, arg6, arg7)\
+({ \
+ long _sys_result; \
+ \
+ FORCE_FRAME_POINTER; \
+ { \
+ register long __v0 asm("$2") ncs_init; \
+ register long __a0 asm("$4") = (long) arg1; \
+ register long __a1 asm("$5") = (long) arg2; \
+ register long __a2 asm("$6") = (long) arg3; \
+ register long __a3 asm("$7") = (long) arg4; \
+ __asm__ volatile ( \
+ ".set\tnoreorder\n\t" \
+ "subu\t$29, 32\n\t" \
+ "sw\t%6, 16($29)\n\t" \
+ "sw\t%7, 20($29)\n\t" \
+ "sw\t%8, 24($29)\n\t" \
+ cs_init \
+ "syscall\n\t" \
+ "addiu\t$29, 32\n\t" \
+ ".set\treorder" \
+ : "=r" (__v0), "+r" (__a3) \
+ : input, "r" (__a0), "r" (__a1), "r" (__a2), \
+ "r" ((long)arg5), "r" ((long)arg6), "r" ((long)arg7) \
+ : __SYSCALL_CLOBBERS); \
+ err = __a3; \
+ _sys_result = __v0; \
+ } \
+ _sys_result; \
+})
+
+#define __SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", \
+ "$14", "$15", "$24", "$25", "memory"
+#else
+#define ENTRY(name) \
+ .globl name; \
+ .align 2; \
+ .ent name,0; \
+ name##:
#endif
#if _MIPS_SIM == _ABIO32