summaryrefslogtreecommitdiff
path: root/libc/sysdeps/linux/mips/fork.S
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2002-08-09 13:41:25 +0000
committerEric Andersen <andersen@codepoet.org>2002-08-09 13:41:25 +0000
commit63c324cb11bec09f26d4461242bb20040491bc8b (patch)
tree52bb5c23c2579cc36e0ed6fcde95ae2923414825 /libc/sysdeps/linux/mips/fork.S
parent61cb9d4ef5873fdd671e7c044240c410317877d4 (diff)
New and improved fork for mips, thanks to the fine folks
at Brecis Communications.
Diffstat (limited to 'libc/sysdeps/linux/mips/fork.S')
-rw-r--r--libc/sysdeps/linux/mips/fork.S65
1 files changed, 65 insertions, 0 deletions
diff --git a/libc/sysdeps/linux/mips/fork.S b/libc/sysdeps/linux/mips/fork.S
new file mode 100644
index 000000000..6d2b33dba
--- /dev/null
+++ b/libc/sysdeps/linux/mips/fork.S
@@ -0,0 +1,65 @@
+#include <features.h>
+
+#define ALIGN 2
+
+/* Note: .abicalls goes at top of routine, and only one of them. */
+#if defined(USER_ABICALLS)
+#define ABISETUP \
+ .set noreorder; \
+ .cpload t9; \
+ .set reorder;
+
+ .abicalls
+#else
+#define ABISETUP
+#endif
+
+#ifndef __UCLIBC_USE_UNIFIED_SYSCALL__
+#define SYSCALL__(name) \
+ .text; \
+ .align ALIGN; \
+ .globl name; \
+ .ent name, 0; \
+ name: ; \
+ ABISETUP \
+ li v0, __NR_##name ; \
+ syscall; \
+ la t3, errno; \
+ beqz a3, 1f; \
+ negu a1, v0; \
+ sw a1, 0(t3); \
+ li v0, -1; \
+ 1: ; \
+ j ra; \
+ .end name; \
+ .size name,.-name;
+#else /* Unified syscall */
+#define SYSCALL__(name) \
+ .text; \
+/* .align ALIGN;*/ \
+ .globl name; \
+ .ent name, 0; \
+ name: ; \
+ ABISETUP \
+ .set push; \
+ .set noreorder; \
+ j __uClibc_syscall; \
+ addiu v0, zero, __NR_##name ; \
+ .set pop; \
+ .end name; \
+ .size name,.-name;
+#endif /* __UCLIBC_USE_UNIFIED_SYSCALL__ */
+
+#undef ALIGN
+#define __ASSEMBLY__
+#include <asm/asm.h>
+#include <asm/unistd.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+/* #include <asm/stackframe.h> */
+
+#undef ALIGN
+#define ALIGN 2
+#define _SYSCALL0(type,name) SYSCALL__(name)
+_SYSCALL0(pid_t, fork);
+