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