/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ .file "asm_subr.s" #include / This is where execution resumes when a thread created with / thr_create() or pthread_create() returns (see setup_context()). / We pass the (void *) return value to _thrp_terminate(). ENTRY(_lwp_start) addl $4, %esp pushl %eax call _thrp_terminate addl $4, %esp / actually, never returns SET_SIZE(_lwp_start) / All we need to do now is (carefully) call lwp_exit(). ENTRY(_lwp_terminate) SYSTRAP_RVAL1(lwp_exit) RET / if we return, it is very bad SET_SIZE(_lwp_terminate) ENTRY(set_curthread) movl 4(%esp), %eax movl %eax, %gs:0 ret SET_SIZE(set_curthread) ENTRY(__lwp_park) popl %edx / add subcode; save return address pushl $0 pushl %edx SYSTRAP_RVAL1(lwp_park) SYSLWPERR popl %edx / restore return address movl %edx, 0(%esp) RET SET_SIZE(__lwp_park) ENTRY(__lwp_unpark) popl %edx / add subcode; save return address pushl $1 pushl %edx SYSTRAP_RVAL1(lwp_park) SYSLWPERR popl %edx / restore return address movl %edx, 0(%esp) RET SET_SIZE(__lwp_unpark) ENTRY(__lwp_unpark_all) popl %edx / add subcode; save return address pushl $2 pushl %edx SYSTRAP_RVAL1(lwp_park) SYSLWPERR popl %edx / restore return address movl %edx, 0(%esp) RET SET_SIZE(__lwp_unpark_all) /* * __sighndlr(int sig, siginfo_t *si, ucontext_t *uc, void (*hndlr)()) * * This is called from sigacthandler() for the purpose of * communicating the ucontext to java's stack tracing functions * and to ensure a 16-byte aligned stack pointer for the benefit * of gcc-compiled floating point code */ ENTRY(__sighndlr) .globl __sighndlrend pushl %ebp movl %esp, %ebp andl $-16,%esp / make sure handler is called with subl $4,%esp / a 16-byte aligned stack pointer pushl 16(%ebp) pushl 12(%ebp) pushl 8(%ebp) call *20(%ebp) leave ret __sighndlrend: SET_SIZE(__sighndlr) /* * int _sigsetjmp(sigjmp_buf env, int savemask) * * This version is faster than the old non-threaded version because we * don't normally have to call __getcontext() to get the signal mask. * (We have a copy of it in the ulwp_t structure.) */ #undef sigsetjmp ENTRY2(sigsetjmp,_sigsetjmp) / EIP already pushed pusha / EAX .. EDI push %ds / segment registers push %es push %fs push %gs push %ss push %cs / args: cs, ss, gs, ..., eip, env, savemask call __csigsetjmp addl $56, %esp / pop 14 words ret SET_SIZE(sigsetjmp) SET_SIZE(_sigsetjmp)