1121074Salc/*- 2121074Salc * Copyright (c) 2000 Peter Wemm <peter@FreeBSD.org> 3121074Salc * Copyright (c) 2003 Alan L. Cox <alc@cs.rice.edu> 4121074Salc * All rights reserved. 5121074Salc * 6121074Salc * Redistribution and use in source and binary forms, with or without 7121074Salc * modification, are permitted provided that the following conditions 8121074Salc * are met: 9121074Salc * 1. Redistributions of source code must retain the above copyright 10121074Salc * notice, this list of conditions and the following disclaimer. 11121074Salc * 2. Redistributions in binary form must reproduce the above copyright 12121074Salc * notice, this list of conditions and the following disclaimer in the 13121074Salc * documentation and/or other materials provided with the distribution. 14121074Salc * 15121074Salc * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16121074Salc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17121074Salc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18121074Salc * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19121074Salc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20121074Salc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21121074Salc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22121074Salc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23121074Salc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24121074Salc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25121074Salc * SUCH DAMAGE. 26121074Salc */ 27121074Salc 28121074Salc#include <machine/asm.h> 29121074Salc__FBSDID("$FreeBSD: releng/10.2/lib/libc/amd64/gen/rfork_thread.S 240178 2012-09-06 20:59:49Z jilles $"); 30121074Salc 31121074Salc/* 32121074Salc * With thanks to John Dyson for the original version of this. 33121074Salc */ 34121074Salc 35121074Salc#include <SYS.h> 36121074Salc 37121074Salc/* 38121074Salc * %edi %rsi %rdx %rcx 39121074Salc * rfork_thread(flags, stack_addr, start_fnc, start_arg); 40121074Salc * 41121074Salc * flags: Flags to rfork system call. See rfork(2). 42121074Salc * stack_addr: Top of stack for thread. 43121074Salc * start_fnc: Address of thread function to call in child. 44121074Salc * start_arg: Argument to pass to the thread function in child. 45121074Salc */ 46121074Salc 47121074SalcENTRY(rfork_thread) 48121074Salc pushq %rbx 49121074Salc pushq %r12 50121074Salc movq %rdx, %rbx 51121074Salc movq %rcx, %r12 52121074Salc 53121074Salc /* 54121074Salc * Prepare and execute the thread creation syscall 55121074Salc */ 56121074Salc movq $SYS_rfork, %rax 57121074Salc KERNCALL 58121074Salc jb 2f 59121074Salc 60121074Salc /* 61121074Salc * Check to see if we are in the parent or child 62121074Salc */ 63121074Salc cmpl $0, %edx 64121074Salc jnz 1f 65121074Salc popq %r12 66121074Salc popq %rbx 67121074Salc ret 68121074Salc 69121074Salc /* 70121074Salc * If we are in the child (new thread), then 71121074Salc * set-up the call to the internal subroutine. If it 72121074Salc * returns, then call __exit. 73121074Salc */ 74121074Salc1: 75121074Salc movq %rsi, %rsp 76121074Salc movq %r12, %rdi 77121074Salc call *%rbx 78121074Salc movl %eax, %edi 79121074Salc 80121074Salc /* 81121074Salc * Exit system call 82121074Salc */ 83121074Salc#ifdef SYS_exit 84121074Salc movq $SYS_exit, %rax 85121074Salc#else 86121074Salc movq $SYS_sys_exit, %rax 87121074Salc#endif 88121074Salc KERNCALL 89121074Salc 90121074Salc /* 91121074Salc * Branch here if the thread creation fails: 92121074Salc */ 93121074Salc2: 94121074Salc popq %r12 95121074Salc popq %rbx 96121074Salc jmp HIDENAME(cerror) 97184547SpeterEND(rfork_thread) 98217106Skib 99217106Skib .section .note.GNU-stack,"",%progbits 100