mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-29 05:51:10 +00:00
688903eb3e
* All files with FSF copyright notices: Update copyright dates using scripts/update-copyrights. * locale/programs/charmap-kw.h: Regenerated. * locale/programs/locfile-kw.h: Likewise.
142 lines
4.6 KiB
ArmAsm
142 lines
4.6 KiB
ArmAsm
/* Copyright (C) 2011-2018 Free Software Foundation, Inc.
|
|
This file is part of the GNU C Library.
|
|
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
|
|
|
The GNU C Library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2.1 of the License, or (at your option) any later version.
|
|
|
|
The GNU C Library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with the GNU C Library. If not, see
|
|
<http://www.gnu.org/licenses/>. */
|
|
|
|
#include <sysdep.h>
|
|
#include <tls.h>
|
|
#include <bits/wordsize.h>
|
|
|
|
#if __WORDSIZE == 64
|
|
#define LOG_SIZEOF_DTV_T 4
|
|
#else
|
|
#define LOG_SIZEOF_DTV_T 3
|
|
#endif
|
|
|
|
/* On entry, r0 points to two words, the module and the offset.
|
|
On return, r0 holds the pointer to the relevant TLS memory.
|
|
Only registers r25..r29 are clobbered by the call. */
|
|
|
|
.text
|
|
ENTRY (__tls_get_addr)
|
|
{
|
|
lnk r25
|
|
ADDI_PTR r27, tp, DTV_OFFSET
|
|
}
|
|
.Llnk:
|
|
{
|
|
LD_PTR r27, r27 /* r27 = THREAD_DTV() */
|
|
moveli r26, hw1_last(_rtld_local + TLS_GENERATION_OFFSET - .Llnk)
|
|
}
|
|
shl16insli r26, r26, hw0(_rtld_local + TLS_GENERATION_OFFSET - .Llnk)
|
|
{
|
|
ADD_PTR r25, r25, r26
|
|
LD_PTR r26, r0 /* r26 = ti_module */
|
|
}
|
|
LD_PTR r25, r25 /* r25 = DL(dl_tls_generation) */
|
|
{
|
|
LD_PTR r28, r27 /* r28 = THREAD_DTV()->counter */
|
|
ADDI_PTR r29, r0, __SIZEOF_POINTER__
|
|
}
|
|
{
|
|
LD_PTR r29, r29 /* r29 = ti_offset */
|
|
cmpeq r25, r28, r25 /* r25 nonzero if generation OK */
|
|
shli r28, r26, LOG_SIZEOF_DTV_T /* byte index into dtv array */
|
|
}
|
|
{
|
|
beqz r25, .Lslowpath
|
|
cmpeqi r25, r26, -1 /* r25 nonzero if ti_module invalid */
|
|
}
|
|
{
|
|
bnez r25, .Lslowpath
|
|
ADD_PTR r28, r28, r27 /* pointer into module array */
|
|
}
|
|
LD_PTR r26, r28 /* r26 = module TLS pointer */
|
|
cmpeqi r25, r26, -1 /* check r26 == TLS_DTV_UNALLOCATED */
|
|
bnez r25, .Lslowpath
|
|
{
|
|
ADD_PTR r0, r26, r29
|
|
jrp lr
|
|
}
|
|
|
|
.Lslowpath:
|
|
{
|
|
st sp, lr
|
|
ADDLI_PTR r29, sp, - (25 * REGSIZE)
|
|
}
|
|
cfi_offset (lr, 0)
|
|
{
|
|
st r29, sp
|
|
ADDLI_PTR sp, sp, - (26 * REGSIZE)
|
|
}
|
|
cfi_def_cfa_offset (26 * REGSIZE)
|
|
ADDI_PTR r29, sp, (2 * REGSIZE)
|
|
{ st r29, r1; ADDI_PTR r29, r29, REGSIZE }
|
|
{ st r29, r2; ADDI_PTR r29, r29, REGSIZE }
|
|
{ st r29, r3; ADDI_PTR r29, r29, REGSIZE }
|
|
{ st r29, r4; ADDI_PTR r29, r29, REGSIZE }
|
|
{ st r29, r5; ADDI_PTR r29, r29, REGSIZE }
|
|
{ st r29, r6; ADDI_PTR r29, r29, REGSIZE }
|
|
{ st r29, r7; ADDI_PTR r29, r29, REGSIZE }
|
|
{ st r29, r8; ADDI_PTR r29, r29, REGSIZE }
|
|
{ st r29, r9; ADDI_PTR r29, r29, REGSIZE }
|
|
{ st r29, r10; ADDI_PTR r29, r29, REGSIZE }
|
|
{ st r29, r11; ADDI_PTR r29, r29, REGSIZE }
|
|
{ st r29, r12; ADDI_PTR r29, r29, REGSIZE }
|
|
{ st r29, r13; ADDI_PTR r29, r29, REGSIZE }
|
|
{ st r29, r14; ADDI_PTR r29, r29, REGSIZE }
|
|
{ st r29, r15; ADDI_PTR r29, r29, REGSIZE }
|
|
{ st r29, r16; ADDI_PTR r29, r29, REGSIZE }
|
|
{ st r29, r17; ADDI_PTR r29, r29, REGSIZE }
|
|
{ st r29, r18; ADDI_PTR r29, r29, REGSIZE }
|
|
{ st r29, r19; ADDI_PTR r29, r29, REGSIZE }
|
|
{ st r29, r20; ADDI_PTR r29, r29, REGSIZE }
|
|
{ st r29, r21; ADDI_PTR r29, r29, REGSIZE }
|
|
{ st r29, r22; ADDI_PTR r29, r29, REGSIZE }
|
|
{ st r29, r23; ADDI_PTR r29, r29, REGSIZE }
|
|
{ st r29, r24; ADDI_PTR r29, r29, REGSIZE }
|
|
.hidden __tls_get_addr_slow
|
|
jal __tls_get_addr_slow
|
|
ADDI_PTR r29, sp, (2 * REGSIZE)
|
|
{ ld r1, r29; ADDI_PTR r29, r29, REGSIZE }
|
|
{ ld r2, r29; ADDI_PTR r29, r29, REGSIZE }
|
|
{ ld r3, r29; ADDI_PTR r29, r29, REGSIZE }
|
|
{ ld r4, r29; ADDI_PTR r29, r29, REGSIZE }
|
|
{ ld r5, r29; ADDI_PTR r29, r29, REGSIZE }
|
|
{ ld r6, r29; ADDI_PTR r29, r29, REGSIZE }
|
|
{ ld r7, r29; ADDI_PTR r29, r29, REGSIZE }
|
|
{ ld r8, r29; ADDI_PTR r29, r29, REGSIZE }
|
|
{ ld r9, r29; ADDI_PTR r29, r29, REGSIZE }
|
|
{ ld r10, r29; ADDI_PTR r29, r29, REGSIZE }
|
|
{ ld r11, r29; ADDI_PTR r29, r29, REGSIZE }
|
|
{ ld r12, r29; ADDI_PTR r29, r29, REGSIZE }
|
|
{ ld r13, r29; ADDI_PTR r29, r29, REGSIZE }
|
|
{ ld r14, r29; ADDI_PTR r29, r29, REGSIZE }
|
|
{ ld r15, r29; ADDI_PTR r29, r29, REGSIZE }
|
|
{ ld r16, r29; ADDI_PTR r29, r29, REGSIZE }
|
|
{ ld r17, r29; ADDI_PTR r29, r29, REGSIZE }
|
|
{ ld r18, r29; ADDI_PTR r29, r29, REGSIZE }
|
|
{ ld r19, r29; ADDI_PTR r29, r29, REGSIZE }
|
|
{ ld r20, r29; ADDI_PTR r29, r29, REGSIZE }
|
|
{ ld r21, r29; ADDI_PTR r29, r29, REGSIZE }
|
|
{ ld r22, r29; ADDI_PTR r29, r29, REGSIZE }
|
|
{ ld r23, r29; ADDI_PTR r29, r29, REGSIZE }
|
|
{ ld r24, r29; ADDLI_PTR sp, sp, (26 * REGSIZE) }
|
|
cfi_def_cfa_offset (0)
|
|
ld lr, sp
|
|
jrp lr
|
|
END (__tls_get_addr)
|