summaryrefslogtreecommitdiff
path: root/libc/sysdeps/linux/sh/vfork.S
blob: c9cc12da7fad50514b8c95247ee48d78493a5625 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/* Copyright (C) 1999, 2000 Free Software Foundation, Inc.
   Copyright (C) 2001 Hewlett-Packard Australia

 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU Library General Public License as published by the Free
 Software Foundation; either version 2 of the License, or (at your option) any
 later version.

 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more
 details.

 You should have received a copy of the GNU Library General Public License
 along with this program; if not, write to the Free Software Foundation, Inc.,
 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

 Derived in part from the Linux-8086 C library, the GNU C Library, and several
 other sundry sources.  Files within this library are copyright by their
 respective copyright holders.
*/

#define _ERRNO_H	1
#include <bits/errno.h>

/* Clone the calling process, but without copying the whole address space.
   The calling process is suspended until the new process exits or is
   replaced by a call to `execve'.  Return -1 for errors, 0 to the new process,
   and the process ID of the new process to the old process.  */

.global errno

.text
.align 5
.type	__vfork,@function
.globl	__vfork;
__vfork:
	mov.l	@r15+,r3		// pop value from the stack
	mov.l	.L5,r1
	mov.l	r3,@r1			// save it in .sav_stack

	mov.w	.L3, r3

#ifdef HIOS
	trapa	#0x28
#else
	trapa	#0x10
#endif

	mov     r0, r1
// 12 arithmetic shifts for the crappy sh2, because shad doesn't exist!	
	shar	r1
	shar	r1
	shar	r1
	shar	r1
	shar	r1
	shar	r1
	shar	r1
	shar	r1
	shar	r1
	shar	r1
	shar	r1
	shar	r1

//	mov	#-12, r2
//	shad	r2, r1
	not	r1, r1			// r1=0 means r0 = -1 to -4095
	tst	r1, r1			// i.e. error in linux
	bf	1f
	mov.w	.L1, r1
	cmp/eq	r1, r0
	bt	2f
	mov.l	.L2, r1
	jmp	@r1
	 mov	r0, r4

	.align	4

1:
	mov.l	.L5,r1
	mov.l	@r1,r3			// get it from .sav_stack
	mov.l	r3,@-r15		// restore value to the stack

	rts
	 nop

	.align	4

2:
.global __syscall_error
__syscall_error:
	/* Store it in errno... */
	mov.l	.L4, r1
	mov.l	r0, @r1

	mov.l	.L5,r1
	mov.l	@r1,r3			// get it from .sav_stack
	mov.l	r3,@-r15		// restore value to the stack

	/* And just kick back a -1.  */
	rts
	 mov	#-1, r0

	.align	4
.L1:
	.word	-ENOSYS
.L3:
	.word	190			//__NR_vfork

	.align	4			// Shouldn't be necessary as previously with have two words
.L2:
	.long	__syscall_error

.L4:	.long	errno

.L5:	.long	.sav_stack

	.data

	.align 4

.sav_stack:					//area to temporary save the stach
	.long	0

.weak	vfork
vfork = __vfork