1*5d9d9091SRichard Lowe/* 2*5d9d9091SRichard Lowe * CDDL HEADER START 3*5d9d9091SRichard Lowe * 4*5d9d9091SRichard Lowe * The contents of this file are subject to the terms of the 5*5d9d9091SRichard Lowe * Common Development and Distribution License (the "License"). 6*5d9d9091SRichard Lowe * You may not use this file except in compliance with the License. 7*5d9d9091SRichard Lowe * 8*5d9d9091SRichard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*5d9d9091SRichard Lowe * or http://www.opensolaris.org/os/licensing. 10*5d9d9091SRichard Lowe * See the License for the specific language governing permissions 11*5d9d9091SRichard Lowe * and limitations under the License. 12*5d9d9091SRichard Lowe * 13*5d9d9091SRichard Lowe * When distributing Covered Code, include this CDDL HEADER in each 14*5d9d9091SRichard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*5d9d9091SRichard Lowe * If applicable, add the following below this CDDL HEADER, with the 16*5d9d9091SRichard Lowe * fields enclosed by brackets "[]" replaced with your own identifying 17*5d9d9091SRichard Lowe * information: Portions Copyright [yyyy] [name of copyright owner] 18*5d9d9091SRichard Lowe * 19*5d9d9091SRichard Lowe * CDDL HEADER END 20*5d9d9091SRichard Lowe */ 21*5d9d9091SRichard Lowe/* 22*5d9d9091SRichard Lowe * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 23*5d9d9091SRichard Lowe * Use is subject to license terms. 24*5d9d9091SRichard Lowe */ 25*5d9d9091SRichard Lowe 26*5d9d9091SRichard Lowe .file "tls_get_addr.s" 27*5d9d9091SRichard Lowe 28*5d9d9091SRichard Lowe/* 29*5d9d9091SRichard Lowe * To make thread-local storage accesses as fast as possible, we 30*5d9d9091SRichard Lowe * hand-craft the __tls_get_addr() function below, from this C code: 31*5d9d9091SRichard Lowe * void * 32*5d9d9091SRichard Lowe * __tls_get_addr(TLS_index *tls_index) 33*5d9d9091SRichard Lowe * { 34*5d9d9091SRichard Lowe * ulwp_t *self = curthread; 35*5d9d9091SRichard Lowe * tls_t *tlsent = self->ul_tlsent; 36*5d9d9091SRichard Lowe * ulong_t moduleid; 37*5d9d9091SRichard Lowe * caddr_t base; 38*5d9d9091SRichard Lowe * 39*5d9d9091SRichard Lowe * if ((moduleid = tls_index->ti_moduleid) < self->ul_ntlsent && 40*5d9d9091SRichard Lowe * (base = tlsent[moduleid].tls_data) != NULL) 41*5d9d9091SRichard Lowe * return (base + tls_index->ti_tlsoffset); 42*5d9d9091SRichard Lowe * 43*5d9d9091SRichard Lowe * return (slow_tls_get_addr(tls_index)); 44*5d9d9091SRichard Lowe * } 45*5d9d9091SRichard Lowe * 46*5d9d9091SRichard Lowe * ___tls_get_addr() is identical to __tls_get_addr() except that it 47*5d9d9091SRichard Lowe * assumes its argument is passed in %eax rather than on the stack. 48*5d9d9091SRichard Lowe */ 49*5d9d9091SRichard Lowe 50*5d9d9091SRichard Lowe#include "SYS.h" 51*5d9d9091SRichard Lowe#include <../assym.h> 52*5d9d9091SRichard Lowe 53*5d9d9091SRichard Lowe ENTRY_NP(__tls_get_addr) 54*5d9d9091SRichard Lowe ALTENTRY(___tls_get_addr) 55*5d9d9091SRichard Lowe movq %fs:UL_TLSENT, %rax 56*5d9d9091SRichard Lowe movq TI_MODULEID (%rdi), %rdx 57*5d9d9091SRichard Lowe cmpq %fs:UL_NTLSENT, %rdx 58*5d9d9091SRichard Lowe jae slow_tls_get_addr /* tail call */ 59*5d9d9091SRichard Lowe /* movq TLS_DATA (%rax,%rdx,SIZEOF_TLS_T), %rax */ 60*5d9d9091SRichard Lowe shlq $4, %rdx /* SIZEOF_TLS_T == 16 */ 61*5d9d9091SRichard Lowe movq TLS_DATA (%rax,%rdx), %rax 62*5d9d9091SRichard Lowe testq %rax, %rax 63*5d9d9091SRichard Lowe je slow_tls_get_addr /* tail call */ 64*5d9d9091SRichard Lowe addq TI_TLSOFFSET (%rdi), %rax 65*5d9d9091SRichard Lowe ret 66*5d9d9091SRichard Lowe SET_SIZE(___tls_get_addr) 67*5d9d9091SRichard Lowe SET_SIZE(__tls_get_addr) 68