xref: /dflybsd-src/lib/libc/x86_64/gen/rfork_thread.S (revision 8b927cb7b72266b97393ee565d882d7fddfa4375)
1b2b3ffcdSSimon Schubert/*-
2b2b3ffcdSSimon Schubert * Copyright (c) 2000 Peter Wemm <peter@FreeBSD.org>
3b2b3ffcdSSimon Schubert * Copyright (c) 2003 Alan L. Cox <alc@cs.rice.edu>
4b2b3ffcdSSimon Schubert * All rights reserved.
5b2b3ffcdSSimon Schubert *
6b2b3ffcdSSimon Schubert * Redistribution and use in source and binary forms, with or without
7b2b3ffcdSSimon Schubert * modification, are permitted provided that the following conditions
8b2b3ffcdSSimon Schubert * are met:
9b2b3ffcdSSimon Schubert * 1. Redistributions of source code must retain the above copyright
10b2b3ffcdSSimon Schubert *    notice, this list of conditions and the following disclaimer.
11b2b3ffcdSSimon Schubert * 2. Redistributions in binary form must reproduce the above copyright
12b2b3ffcdSSimon Schubert *    notice, this list of conditions and the following disclaimer in the
13b2b3ffcdSSimon Schubert *    documentation and/or other materials provided with the distribution.
14b2b3ffcdSSimon Schubert *
15b2b3ffcdSSimon Schubert * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16b2b3ffcdSSimon Schubert * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17b2b3ffcdSSimon Schubert * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18b2b3ffcdSSimon Schubert * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19b2b3ffcdSSimon Schubert * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20b2b3ffcdSSimon Schubert * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21b2b3ffcdSSimon Schubert * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22b2b3ffcdSSimon Schubert * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23b2b3ffcdSSimon Schubert * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24b2b3ffcdSSimon Schubert * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25b2b3ffcdSSimon Schubert * SUCH DAMAGE.
26b2b3ffcdSSimon Schubert *
27b2b3ffcdSSimon Schubert * $FreeBSD: src/lib/libc/amd64/gen/rfork_thread.S,v 1.2 2008/11/02 01:10:54 peter Exp $
28b2b3ffcdSSimon Schubert */
29b2b3ffcdSSimon Schubert
30b2b3ffcdSSimon Schubert#include <machine/asm.h>
31b2b3ffcdSSimon Schubert
32b2b3ffcdSSimon Schubert/*
33b2b3ffcdSSimon Schubert * With thanks to John Dyson for the original version of this.
34b2b3ffcdSSimon Schubert */
35b2b3ffcdSSimon Schubert
36b2b3ffcdSSimon Schubert#include <SYS.h>
37b2b3ffcdSSimon Schubert
38b2b3ffcdSSimon Schubert/*
39b2b3ffcdSSimon Schubert *              %edi   %rsi        %rdx       %rcx
40b2b3ffcdSSimon Schubert * rfork_thread(flags, stack_addr, start_fnc, start_arg);
41b2b3ffcdSSimon Schubert *
42b2b3ffcdSSimon Schubert * flags:		Flags to rfork system call.  See rfork(2).
43b2b3ffcdSSimon Schubert * stack_addr:		Top of stack for thread.
44b2b3ffcdSSimon Schubert * start_fnc:		Address of thread function to call in child.
45b2b3ffcdSSimon Schubert * start_arg:		Argument to pass to the thread function in child.
46b2b3ffcdSSimon Schubert */
47b2b3ffcdSSimon Schubert
48b2b3ffcdSSimon SchubertENTRY(rfork_thread)
49b2b3ffcdSSimon Schubert	pushq	%rbx
50b2b3ffcdSSimon Schubert	pushq	%r12
51b2b3ffcdSSimon Schubert	movq	%rdx, %rbx
52b2b3ffcdSSimon Schubert	movq	%rcx, %r12
53b2b3ffcdSSimon Schubert
54b2b3ffcdSSimon Schubert	/*
55b2b3ffcdSSimon Schubert	 * Prepare and execute the thread creation syscall
56b2b3ffcdSSimon Schubert	 */
57b2b3ffcdSSimon Schubert	movq	$SYS_rfork, %rax
58b2b3ffcdSSimon Schubert	KERNCALL
59b2b3ffcdSSimon Schubert	jb 	2f
60b2b3ffcdSSimon Schubert
61b2b3ffcdSSimon Schubert	/*
62b2b3ffcdSSimon Schubert	 * Check to see if we are in the parent or child
63b2b3ffcdSSimon Schubert	 */
64b2b3ffcdSSimon Schubert	cmpl	$0, %edx
65b2b3ffcdSSimon Schubert	jnz	1f
66b2b3ffcdSSimon Schubert	popq	%r12
67b2b3ffcdSSimon Schubert	popq	%rbx
68b2b3ffcdSSimon Schubert	ret
69b2b3ffcdSSimon Schubert
70b2b3ffcdSSimon Schubert	/*
71b2b3ffcdSSimon Schubert	 * If we are in the child (new thread), then
72b2b3ffcdSSimon Schubert	 * set-up the call to the internal subroutine.  If it
73b2b3ffcdSSimon Schubert	 * returns, then call __exit.
74b2b3ffcdSSimon Schubert	 */
75b2b3ffcdSSimon Schubert1:
76b2b3ffcdSSimon Schubert	movq	%rsi, %rsp
77b2b3ffcdSSimon Schubert	movq	%r12, %rdi
78b2b3ffcdSSimon Schubert	call	*%rbx
79b2b3ffcdSSimon Schubert	movl	%eax, %edi
80b2b3ffcdSSimon Schubert
81b2b3ffcdSSimon Schubert	/*
82b2b3ffcdSSimon Schubert	 * Exit system call
83b2b3ffcdSSimon Schubert	 */
84b2b3ffcdSSimon Schubert#ifdef SYS_exit
85b2b3ffcdSSimon Schubert	movq	$SYS_exit, %rax
86b2b3ffcdSSimon Schubert#else
87b2b3ffcdSSimon Schubert	movq	$SYS_sys_exit, %rax
88b2b3ffcdSSimon Schubert#endif
89b2b3ffcdSSimon Schubert	KERNCALL
90b2b3ffcdSSimon Schubert
91b2b3ffcdSSimon Schubert	/*
92b2b3ffcdSSimon Schubert	 * Branch here if the thread creation fails:
93b2b3ffcdSSimon Schubert	 */
94b2b3ffcdSSimon Schubert2:
95b2b3ffcdSSimon Schubert	popq	%r12
96b2b3ffcdSSimon Schubert	popq	%rbx
97b2b3ffcdSSimon Schubert#ifdef PIC
98b2b3ffcdSSimon Schubert	movq	PIC_GOT(HIDENAME(cerror)), %rdx
99b2b3ffcdSSimon Schubert	jmp	*%rdx
100b2b3ffcdSSimon Schubert#else
101b2b3ffcdSSimon Schubert	jmp	HIDENAME(cerror)
102b2b3ffcdSSimon Schubert#endif
103b2b3ffcdSSimon SchubertEND(rfork_thread)
104*8b927cb7SJohn Marino
105*8b927cb7SJohn Marino	.section .note.GNU-stack,"",%progbits
106