xref: /openbsd-src/lib/libc/arch/mips64/sys/tfork_thread.S (revision 8162193374858e8d7dceca506657f13b21b8be44)
1*81621933Sguenther/*	$OpenBSD: tfork_thread.S,v 1.5 2022/12/08 01:25:43 guenther Exp $	*/
2c6f64c6fSguenther
3c6f64c6fSguenther/*
4c6f64c6fSguenther * Copyright (c) 2005, Miodrag Vallat
5c6f64c6fSguenther *
6c6f64c6fSguenther * Redistribution and use in source and binary forms, with or without
7c6f64c6fSguenther * modification, are permitted provided that the following conditions
8c6f64c6fSguenther * are met:
9c6f64c6fSguenther * 1. Redistributions of source code must retain the above copyright
10c6f64c6fSguenther *    notice, this list of conditions and the following disclaimer.
11c6f64c6fSguenther * 2. Redistributions in binary form must reproduce the above copyright
12c6f64c6fSguenther *    notice, this list of conditions and the following disclaimer in the
13c6f64c6fSguenther *    documentation and/or other materials provided with the distribution.
14c6f64c6fSguenther *
15c6f64c6fSguenther * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16c6f64c6fSguenther * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17c6f64c6fSguenther * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18c6f64c6fSguenther * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
19c6f64c6fSguenther * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20c6f64c6fSguenther * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21c6f64c6fSguenther * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22c6f64c6fSguenther * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
23c6f64c6fSguenther * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
24c6f64c6fSguenther * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25c6f64c6fSguenther * POSSIBILITY OF SUCH DAMAGE.
26c6f64c6fSguenther */
27c6f64c6fSguenther
28c6f64c6fSguenther#include "SYS.h"
29c6f64c6fSguenther
30c6f64c6fSguenther/*
3116b62b6aSguenther * int __tfork_thread(const struct __tfork *param, size_t psize, void (*func)(void *), void *arg);
32c6f64c6fSguenther */
33c6f64c6fSguentherFRAMESZ=4*REGSZ
34c6f64c6fSguentherGPOFF=FRAMESZ-2*REGSZ
35c6f64c6fSguentherLEAF(__tfork_thread, FRAMESZ)
3616b62b6aSguenther	/* a0 = param, a1 = psize, a2 = func, a3 = arg */
37c6f64c6fSguenther	PTR_SUBU sp, FRAMESZ
38*81621933Sguenther	SETUP_GP64(GPOFF, __tfork_thread)
39c6f64c6fSguenther	.set	reorder
40c6f64c6fSguenther
41c6f64c6fSguenther	move	t1, a3		/* arg */
42c6f64c6fSguenther
43c6f64c6fSguenther	__DO_SYSCALL(__tfork)
44c6f64c6fSguenther	bnez	a3, 9f
45c6f64c6fSguenther
4616b62b6aSguenther	beqz	v0, 1f
4716b62b6aSguenther
48c6f64c6fSguenther	RESTORE_GP64
49c6f64c6fSguenther	PTR_ADDU sp, FRAMESZ
50c6f64c6fSguenther
51c6f64c6fSguenther	/*
52c6f64c6fSguenther	 * In parent process: just return.
53c6f64c6fSguenther	 */
54c6f64c6fSguenther	j	ra
55c6f64c6fSguenther
56c6f64c6fSguenther1:
57c6f64c6fSguenther	/*
5816b62b6aSguenther	 * In child process: invoke function, then exit.
59c6f64c6fSguenther	 */
60c6f64c6fSguenther
61c6f64c6fSguenther	move	t9, a2		/* func */
62c6f64c6fSguenther	move	a0, t1		/* arg */
63c6f64c6fSguenther	move	v0, zero
64c6f64c6fSguenther	jal	ra, t9
65c6f64c6fSguenther
66c6f64c6fSguenther	move	a0, zero
67c6f64c6fSguenther	__DO_SYSCALL(__threxit)
6880466ddeSvisa	teq	zero, zero, 0x52
69c6f64c6fSguenther
70c6f64c6fSguenther9:
71c6f64c6fSguenther	/*
72c6f64c6fSguenther	 * System call failure.
73c6f64c6fSguenther	 */
74c6f64c6fSguenther	LA	t9, CERROR
75c6f64c6fSguenther
76c6f64c6fSguenther	RESTORE_GP64
77c6f64c6fSguenther	PTR_ADDU sp, FRAMESZ
78c6f64c6fSguenther	jr	t9
79c6f64c6fSguentherEND(__tfork_thread)
80