xref: /titanic_50/usr/src/lib/libc/sparc/threads/asm_subr.s (revision 3cd8a1a62a3a0a1219f9dd12e5700e1dff5ca79f)
17c478bd9Sstevel@tonic-gate/*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
58cd45542Sraf * Common Development and Distribution License (the "License").
68cd45542Sraf * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
218cd45542Sraf
227c478bd9Sstevel@tonic-gate/*
23*3cd8a1a6SRoger A. Faulkner * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
269a70fc3bSMark J. Nelson	.file	"asm_subr.s"
277c478bd9Sstevel@tonic-gate
287257d1b4Sraf#include "SYS.h"
297c478bd9Sstevel@tonic-gate#include <sys/trap.h>
307c478bd9Sstevel@tonic-gate#include <../assym.h>
317c478bd9Sstevel@tonic-gate
327c478bd9Sstevel@tonic-gate	! This is where execution resumes when a thread created with
337c478bd9Sstevel@tonic-gate	! thr_create() or pthread_create() returns (see setup_context()).
347257d1b4Sraf	! We pass the (void *) return value to _thrp_terminate().
357c478bd9Sstevel@tonic-gate	ENTRY(_lwp_start)
367c478bd9Sstevel@tonic-gate	nop	! this is the location from which the func() was "called"
377c478bd9Sstevel@tonic-gate	nop
387257d1b4Sraf	call	_thrp_terminate	! %o0 contains the return value
397c478bd9Sstevel@tonic-gate	nop
407c478bd9Sstevel@tonic-gate	SET_SIZE(_lwp_start)
417c478bd9Sstevel@tonic-gate
427c478bd9Sstevel@tonic-gate	ENTRY(_lwp_terminate)
437c478bd9Sstevel@tonic-gate	! Flush the register windows so the stack can be reused.
447c478bd9Sstevel@tonic-gate	ta	ST_FLUSH_WINDOWS
457c478bd9Sstevel@tonic-gate	! All we need to do now is (carefully) call lwp_exit().
467c478bd9Sstevel@tonic-gate	mov	SYS_lwp_exit, %g1
477c478bd9Sstevel@tonic-gate	ta	SYSCALL_TRAPNUM
487c478bd9Sstevel@tonic-gate	RET		! if we return, it is very bad
497c478bd9Sstevel@tonic-gate	SET_SIZE(_lwp_terminate)
507c478bd9Sstevel@tonic-gate
517c478bd9Sstevel@tonic-gate	ENTRY(set_curthread)
527c478bd9Sstevel@tonic-gate	retl
537c478bd9Sstevel@tonic-gate	mov	%o0, %g7
547c478bd9Sstevel@tonic-gate	SET_SIZE(set_curthread)
557c478bd9Sstevel@tonic-gate
567c478bd9Sstevel@tonic-gate#ifdef __sparcv9
577c478bd9Sstevel@tonic-gate#define	GREGSIZE	8
587c478bd9Sstevel@tonic-gate#else
597c478bd9Sstevel@tonic-gate#define	GREGSIZE	4
607c478bd9Sstevel@tonic-gate#endif
617c478bd9Sstevel@tonic-gate	! void _fetch_globals(greg_t *);
627c478bd9Sstevel@tonic-gate	! (called from siglongjmp())
637c478bd9Sstevel@tonic-gate	ENTRY(_fetch_globals)
647c478bd9Sstevel@tonic-gate	stn	%g1, [%o0 + 0*GREGSIZE]
657c478bd9Sstevel@tonic-gate	stn	%g2, [%o0 + 1*GREGSIZE]
667c478bd9Sstevel@tonic-gate	stn	%g3, [%o0 + 2*GREGSIZE]
677c478bd9Sstevel@tonic-gate	stn	%g4, [%o0 + 3*GREGSIZE]
687c478bd9Sstevel@tonic-gate	stn	%g5, [%o0 + 4*GREGSIZE]
697c478bd9Sstevel@tonic-gate	stn	%g6, [%o0 + 5*GREGSIZE]
707c478bd9Sstevel@tonic-gate	retl
717c478bd9Sstevel@tonic-gate	stn	%g7, [%o0 + 6*GREGSIZE]
727c478bd9Sstevel@tonic-gate	SET_SIZE(_fetch_globals)
737c478bd9Sstevel@tonic-gate
747c478bd9Sstevel@tonic-gate#ifdef __sparcv9
757c478bd9Sstevel@tonic-gate	ENTRY(_getfprs)
767c478bd9Sstevel@tonic-gate	retl
777c478bd9Sstevel@tonic-gate	mov	%fprs, %o0
787c478bd9Sstevel@tonic-gate	SET_SIZE(_getfprs)
797c478bd9Sstevel@tonic-gate#else
807c478bd9Sstevel@tonic-gate	ENTRY(_getpsr)
817c478bd9Sstevel@tonic-gate	retl
827c478bd9Sstevel@tonic-gate	ta	ST_GETPSR
837c478bd9Sstevel@tonic-gate	SET_SIZE(_getpsr)
8435e6f27aSRoger A. Faulkner
8535e6f27aSRoger A. Faulkner	ENTRY(_do_fix_align)
8635e6f27aSRoger A. Faulkner	retl
8735e6f27aSRoger A. Faulkner	ta	ST_FIX_ALIGN
8835e6f27aSRoger A. Faulkner	SET_SIZE(_do_fix_align)
897c478bd9Sstevel@tonic-gate#endif
907c478bd9Sstevel@tonic-gate
917c478bd9Sstevel@tonic-gate	ENTRY(_getfsr)
927c478bd9Sstevel@tonic-gate	retl
937c478bd9Sstevel@tonic-gate	stn	%fsr, [%o0]
947c478bd9Sstevel@tonic-gate	SET_SIZE(_getfsr)
957c478bd9Sstevel@tonic-gate
967c478bd9Sstevel@tonic-gate	ENTRY(_setfsr)
977c478bd9Sstevel@tonic-gate	retl
987c478bd9Sstevel@tonic-gate	ldn	[%o0], %fsr
997c478bd9Sstevel@tonic-gate	SET_SIZE(_setfsr)
1007c478bd9Sstevel@tonic-gate
1017c478bd9Sstevel@tonic-gate	ENTRY(_flush_windows)
1027c478bd9Sstevel@tonic-gate	retl
1037c478bd9Sstevel@tonic-gate	ta	ST_FLUSH_WINDOWS
1047c478bd9Sstevel@tonic-gate	SET_SIZE(_flush_windows)
1057c478bd9Sstevel@tonic-gate
1067c478bd9Sstevel@tonic-gate	ENTRY(__lwp_park)
1077c478bd9Sstevel@tonic-gate	mov	%o1, %o2
1087c478bd9Sstevel@tonic-gate	mov	%o0, %o1
1097c478bd9Sstevel@tonic-gate	mov	0, %o0
1107c478bd9Sstevel@tonic-gate	SYSTRAP_RVAL1(lwp_park)
1117c478bd9Sstevel@tonic-gate	SYSLWPERR
1127c478bd9Sstevel@tonic-gate	RET
1137c478bd9Sstevel@tonic-gate	SET_SIZE(__lwp_park)
1147c478bd9Sstevel@tonic-gate
1157c478bd9Sstevel@tonic-gate	ENTRY(__lwp_unpark)
1167c478bd9Sstevel@tonic-gate	mov	%o0, %o1
1177c478bd9Sstevel@tonic-gate	mov	1, %o0
1187c478bd9Sstevel@tonic-gate	SYSTRAP_RVAL1(lwp_park)
1197c478bd9Sstevel@tonic-gate	SYSLWPERR
1207c478bd9Sstevel@tonic-gate	RET
1217c478bd9Sstevel@tonic-gate	SET_SIZE(__lwp_unpark)
1227c478bd9Sstevel@tonic-gate
1237c478bd9Sstevel@tonic-gate	ENTRY(__lwp_unpark_all)
1247c478bd9Sstevel@tonic-gate	mov	%o1, %o2
1257c478bd9Sstevel@tonic-gate	mov	%o0, %o1
1267c478bd9Sstevel@tonic-gate	mov	2, %o0
1277c478bd9Sstevel@tonic-gate	SYSTRAP_RVAL1(lwp_park)
1287c478bd9Sstevel@tonic-gate	SYSLWPERR
1297c478bd9Sstevel@tonic-gate	RET
1307c478bd9Sstevel@tonic-gate	SET_SIZE(__lwp_unpark_all)
1317c478bd9Sstevel@tonic-gate
1327c478bd9Sstevel@tonic-gate/*
1337c478bd9Sstevel@tonic-gate * __sighndlr(int sig, siginfo_t *si, ucontex_t *uc, void (*hndlr)())
1347c478bd9Sstevel@tonic-gate *
1357c478bd9Sstevel@tonic-gate * This is called from sigacthandler() for the entire purpose of
1367c478bd9Sstevel@tonic-gate * communicating the ucontext to java's stack tracing functions.
1377c478bd9Sstevel@tonic-gate */
1387c478bd9Sstevel@tonic-gate	ENTRY(__sighndlr)
1397c478bd9Sstevel@tonic-gate	.globl	__sighndlrend
1407c478bd9Sstevel@tonic-gate	save	%sp, -SA(MINFRAME), %sp
1417c478bd9Sstevel@tonic-gate	mov	%i0, %o0
1427c478bd9Sstevel@tonic-gate	mov	%i1, %o1
1437c478bd9Sstevel@tonic-gate	jmpl	%i3, %o7
1447c478bd9Sstevel@tonic-gate	mov	%i2, %o2
1457c478bd9Sstevel@tonic-gate	ret
1467c478bd9Sstevel@tonic-gate	restore
1477c478bd9Sstevel@tonic-gate__sighndlrend:
1487c478bd9Sstevel@tonic-gate	SET_SIZE(__sighndlr)
1497c478bd9Sstevel@tonic-gate
1507c478bd9Sstevel@tonic-gate/*
1517c478bd9Sstevel@tonic-gate * int _sigsetjmp(sigjmp_buf env, int savemask)
1527c478bd9Sstevel@tonic-gate *
1537c478bd9Sstevel@tonic-gate * This version is faster than the old non-threaded version because we
1547c478bd9Sstevel@tonic-gate * don't normally have to call __getcontext() to get the signal mask.
1557c478bd9Sstevel@tonic-gate * (We have a copy of it in the ulwp_t structure.)
1567c478bd9Sstevel@tonic-gate */
1577c478bd9Sstevel@tonic-gate
1587c478bd9Sstevel@tonic-gate#undef	sigsetjmp
1597c478bd9Sstevel@tonic-gate
1607c478bd9Sstevel@tonic-gate	ENTRY2(sigsetjmp,_sigsetjmp)
1617c478bd9Sstevel@tonic-gate	stn	%sp, [%o0 + SJS_SP]	! save caller's sp into env->sjs_sp
1627c478bd9Sstevel@tonic-gate	add	%o7, 8, %o2		! calculate caller's return pc
1637c478bd9Sstevel@tonic-gate	stn	%o2, [%o0 + SJS_PC]	! save caller's pc into env->sjs_pc
1647c478bd9Sstevel@tonic-gate	stn	%fp, [%o0 + SJS_FP]	! save caller's return linkage
1657c478bd9Sstevel@tonic-gate	stn	%i7, [%o0 + SJS_I7]
166*3cd8a1a6SRoger A. Faulkner#ifdef __sparcv9
167*3cd8a1a6SRoger A. Faulkner	rd	%asi, %o3
168*3cd8a1a6SRoger A. Faulkner	rd	%fprs, %o4
169*3cd8a1a6SRoger A. Faulkner	stx	%o3, [%o0 + SJS_ASI]
170*3cd8a1a6SRoger A. Faulkner	stx	%o4, [%o0 + SJS_FPRS]
171*3cd8a1a6SRoger A. Faulkner#endif
1727c478bd9Sstevel@tonic-gate	call	__csigsetjmp
1737c478bd9Sstevel@tonic-gate	sub	%o2, 8, %o7		! __csigsetjmp returns to caller
1747c478bd9Sstevel@tonic-gate	SET_SIZE(sigsetjmp)
1757c478bd9Sstevel@tonic-gate	SET_SIZE(_sigsetjmp)
176