xref: /onnv-gate/usr/src/lib/libc/i386/threads/tls_get_addr.s (revision 7298:b69e27387f74)
10Sstevel@tonic-gate/*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*7298SMark.J.Nelson@Sun.COM * Common Development and Distribution License (the "License").
6*7298SMark.J.Nelson@Sun.COM * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate/*
220Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate * Use is subject to license terms.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
26*7298SMark.J.Nelson@Sun.COM	.file	"tls_get_addr.s"
270Sstevel@tonic-gate
280Sstevel@tonic-gate/*
290Sstevel@tonic-gate * To make thread-local storage accesses as fast as possible, we
300Sstevel@tonic-gate * hand-craft the __tls_get_addr() function below, from this C code:
310Sstevel@tonic-gate * void *
320Sstevel@tonic-gate * __tls_get_addr(TLS_index *tls_index)
330Sstevel@tonic-gate * {
340Sstevel@tonic-gate *	ulwp_t *self = curthread;
350Sstevel@tonic-gate *	tls_t *tlsent = self->ul_tlsent;
360Sstevel@tonic-gate *	ulong_t moduleid;
370Sstevel@tonic-gate *	caddr_t	base;
380Sstevel@tonic-gate *
390Sstevel@tonic-gate *	if ((moduleid = tls_index->ti_moduleid) < self->ul_ntlsent &&
400Sstevel@tonic-gate *	    (base = tlsent[moduleid].tls_data) != NULL)
410Sstevel@tonic-gate *		return (base + tls_index->ti_tlsoffset);
420Sstevel@tonic-gate *
430Sstevel@tonic-gate *	return (slow_tls_get_addr(tls_index));
440Sstevel@tonic-gate * }
450Sstevel@tonic-gate *
460Sstevel@tonic-gate * ___tls_get_addr() is identical to __tls_get_addr() except that it
470Sstevel@tonic-gate * assumes its argument is passed in %eax rather than on the stack.
480Sstevel@tonic-gate */
490Sstevel@tonic-gate
500Sstevel@tonic-gate#include "SYS.h"
510Sstevel@tonic-gate#include <assym.h>
520Sstevel@tonic-gate
530Sstevel@tonic-gate	ENTRY_NP(__tls_get_addr)
540Sstevel@tonic-gate	movl	4(%esp), %eax
550Sstevel@tonic-gate	ALTENTRY(___tls_get_addr)
560Sstevel@tonic-gate	movl	%gs:UL_TLSENT, %edx
570Sstevel@tonic-gate	movl	TI_MODULEID (%eax), %ecx
580Sstevel@tonic-gate	cmpl	%gs:UL_NTLSENT, %ecx
590Sstevel@tonic-gate	jae	1f
600Sstevel@tonic-gate	movl	TLS_DATA (%edx,%ecx,SIZEOF_TLS_T), %edx
610Sstevel@tonic-gate	testl	%edx, %edx
620Sstevel@tonic-gate	je	1f
630Sstevel@tonic-gate	addl	TI_TLSOFFSET (%eax), %edx
640Sstevel@tonic-gate	movl	%edx, %eax
650Sstevel@tonic-gate	ret
660Sstevel@tonic-gate1:
670Sstevel@tonic-gate	pushl	%ebp
680Sstevel@tonic-gate	movl	%esp, %ebp
690Sstevel@tonic-gate	pushl	%eax
700Sstevel@tonic-gate	call	slow_tls_get_addr
710Sstevel@tonic-gate	addl	$4, %esp
720Sstevel@tonic-gate	leave
730Sstevel@tonic-gate	ret
740Sstevel@tonic-gate	SET_SIZE(___tls_get_addr)
750Sstevel@tonic-gate	SET_SIZE(__tls_get_addr)
76