1/* Copyright (C) 1999, 2000 Free Software Foundation, Inc.
2   Copyright (C) 2001 Hewlett-Packard Australia
3
4 This program is free software; you can redistribute it and/or modify it under
5 the terms of the GNU Library General Public License as published by the Free
6 Software Foundation; either version 2 of the License, or (at your option) any
7 later version.
8
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more
12 details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this program; if not, see <http://www.gnu.org/licenses/>.
16
17 Derived in part from the Linux-8086 C library, the GNU C Library, and several
18 other sundry sources.  Files within this library are copyright by their
19 respective copyright holders.
20*/
21
22#include <sys/syscall.h>
23#define _ERRNO_H
24#include <bits/errno.h>
25
26/* Clone the calling process, but without copying the whole address space.
27   The calling process is suspended until the new process exits or is
28   replaced by a call to `execve'.  Return -1 for errors, 0 to the new process,
29   and the process ID of the new process to the old process.  */
30
31.text
32.globl	__vfork
33.hidden	__vfork
34.type	__vfork,@function
35.align 4
36
37__vfork:
38	mov.w	.L2, r3
39	trapa	#__SH_SYSCALL_TRAP_BASE
40	mov     r0, r1
41#ifdef __sh2__
42/* 12 arithmetic shifts for the crappy sh2, because shad doesn't exist!	 */
43	shar	r1
44	shar	r1
45	shar	r1
46	shar	r1
47	shar	r1
48	shar	r1
49	shar	r1
50	shar	r1
51	shar	r1
52	shar	r1
53	shar	r1
54	shar	r1
55#else
56	mov	#-12, r2
57	shad	r2, r1
58#endif
59
60	not	r1, r1			/* r1=0 means r0 = -1 to -4095 */
61	tst	r1, r1			/* i.e. error in linux */
62	bf	2f
63	mov.w	.L1, r1
64	cmp/eq	r1, r0
65	bf/s	__syscall_error
66	 mov	r0, r4
67
68	/* If we don't have vfork, use fork.  */
69	mov.w	.L3, r3
70	trapa	#__SH_SYSCALL_TRAP_BASE
71	mov     r0, r1
72#ifdef __sh2__
73/* 12 arithmetic shifts for the crappy sh2, because shad doesn't exist!	 */
74	shar	r1
75	shar	r1
76	shar	r1
77	shar	r1
78	shar	r1
79	shar	r1
80	shar	r1
81	shar	r1
82	shar	r1
83	shar	r1
84	shar	r1
85	shar	r1
86#else
87	mov	#-12, r2
88	shad	r2, r1
89#endif
90
91	not	r1, r1			/* r1=0 means r0 = -1 to -4095 */
92	tst	r1, r1			/* i.e. error in linux */
93	bt/s	__syscall_error
94	 mov	r0, r4
952:
96	rts
97	 nop
98
99	.align	2
100.L1:
101	.word	-ENOSYS
102.L2:
103	.word	__NR_vfork
104.L3:
105	.word	__NR_fork
106
107.size   __vfork, .-__vfork
108weak_alias(__vfork,vfork)
109libc_hidden_def(vfork)
110
111#include "syscall_error.S"
112