1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22/* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 .file "tls_get_addr.s" 28 29#include "SYS.h" 30#include <../assym.h> 31 32/* 33 * To make thread-local storage accesses as fast as possible, we 34 * hand-craft the __tls_get_addr() function below, from this C code: 35 * void * 36 * __tls_get_addr(TLS_index *tls_index) 37 * { 38 * ulwp_t *self = curthread; 39 * tls_t *tlsent = self->ul_tlsent; 40 * ulong_t moduleid; 41 * caddr_t base; 42 * 43 * if ((moduleid = tls_index->ti_moduleid) < self->ul_ntlsent && 44 * (base = tlsent[moduleid].tls_data) != NULL) 45 * return (base + tls_index->ti_tlsoffset); 46 * 47 * return (slow_tls_get_addr(tls_index)); 48 * } 49 */ 50 51/* 52 * We assume that the tls_t structure contains two pointer-sized elements. 53 * Cause a build failure if this becomes not true. 54 */ 55#if SIZEOF_TLS_T == 8 && !defined(__sparcv9) 56#define SHIFT 3 57#elif SIZEOF_TLS_T == 16 && defined(__sparcv9) 58#define SHIFT 4 59#else 60#error "Assumption violated: SIZEOF_TLS_T is not 2 * sizeof (uintptr_t)" 61#endif 62 63#if defined(__sparcv9) 64#define PN ,pn %xcc, 65#else 66#define PN 67#endif 68 69 ENTRY(__tls_get_addr) 70 ldn [%o0 + TI_MODULEID], %o1 71 ldn [%g7 + UL_TLSENT], %o2 72 ldn [%g7 + UL_NTLSENT], %o3 73 cmp %o1, %o3 74 bgeu PN 1f 75 slln %o1, SHIFT, %o1 76#if TLS_DATA != 0 77 add %o1, TLS_DATA, %o1 78#endif 79 ldn [%o1 + %o2], %o2 80 cmp %o2, 0 81 be PN 1f 82 ldn [%o0 + TI_TLSOFFSET], %o1 83 retl 84 add %o1, %o2, %o0 851: 86 mov %o7, %g1 87 call slow_tls_get_addr 88 mov %g1, %o7 89 SET_SIZE(__tls_get_addr) 90