From c68d0fa2d88fc2134a38d99e7e944828384a7671 Mon Sep 17 00:00:00 2001 From: Austin Foxley Date: Sat, 17 Oct 2009 12:26:24 -0700 Subject: libpthread/nptl: core of the "Native Posix Threading Library" for uClibc targetting arm,sh,i386,mips,sparc for now Signed-off-by: Austin Foxley --- libpthread/nptl/sysdeps/sh/Makefile | 3 + libpthread/nptl/sysdeps/sh/Makefile.arch | 56 +++++++++ libpthread/nptl/sysdeps/sh/dl-tls.h | 29 +++++ libpthread/nptl/sysdeps/sh/jmpbuf-unwind.h | 33 +++++ libpthread/nptl/sysdeps/sh/pthread_spin_init.c | 20 +++ libpthread/nptl/sysdeps/sh/pthread_spin_lock.c | 35 ++++++ libpthread/nptl/sysdeps/sh/pthread_spin_trylock.S | 32 +++++ libpthread/nptl/sysdeps/sh/pthread_spin_unlock.S | 30 +++++ libpthread/nptl/sysdeps/sh/pthreaddef.h | 49 ++++++++ libpthread/nptl/sysdeps/sh/sysdep.h | 82 +++++++++++++ libpthread/nptl/sysdeps/sh/tcb-offsets.sym | 11 ++ libpthread/nptl/sysdeps/sh/tls.h | 142 ++++++++++++++++++++++ 12 files changed, 522 insertions(+) create mode 100644 libpthread/nptl/sysdeps/sh/Makefile create mode 100644 libpthread/nptl/sysdeps/sh/Makefile.arch create mode 100644 libpthread/nptl/sysdeps/sh/dl-tls.h create mode 100644 libpthread/nptl/sysdeps/sh/jmpbuf-unwind.h create mode 100644 libpthread/nptl/sysdeps/sh/pthread_spin_init.c create mode 100644 libpthread/nptl/sysdeps/sh/pthread_spin_lock.c create mode 100644 libpthread/nptl/sysdeps/sh/pthread_spin_trylock.S create mode 100644 libpthread/nptl/sysdeps/sh/pthread_spin_unlock.S create mode 100644 libpthread/nptl/sysdeps/sh/pthreaddef.h create mode 100644 libpthread/nptl/sysdeps/sh/sysdep.h create mode 100644 libpthread/nptl/sysdeps/sh/tcb-offsets.sym create mode 100644 libpthread/nptl/sysdeps/sh/tls.h (limited to 'libpthread/nptl/sysdeps/sh') diff --git a/libpthread/nptl/sysdeps/sh/Makefile b/libpthread/nptl/sysdeps/sh/Makefile new file mode 100644 index 000000000..81bddf688 --- /dev/null +++ b/libpthread/nptl/sysdeps/sh/Makefile @@ -0,0 +1,3 @@ +ifeq ($(subdir),csu) +gen-as-const-headers += tcb-offsets.sym +endif diff --git a/libpthread/nptl/sysdeps/sh/Makefile.arch b/libpthread/nptl/sysdeps/sh/Makefile.arch new file mode 100644 index 000000000..83db10fbe --- /dev/null +++ b/libpthread/nptl/sysdeps/sh/Makefile.arch @@ -0,0 +1,56 @@ +# Makefile for uClibc NPTL +# +# Copyright (C) 2005 Steven J. Hill +# +# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. +# + +libpthread_SSRC = pthread_spin_unlock.S pthread_spin_trylock.S +libpthread_CSRC = pthread_spin_lock.c pthread_spin_init.c + +ASFLAGS-pthread_spin_unlock.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 +ASFLAGS-pthread_spin_trylock.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 + +CFLAGS-pthread_spin_lock.c += -D_GNU_SOURCE + +CFLAGS-sh = $(SSP_ALL_CFLAGS) +#CFLAGS:=$(CFLAGS:-O1=-O2) + +PTHREAD_ARCH_DIR := $(top_srcdir)libpthread/nptl/sysdeps/sh +PTHREAD_ARCH_OUT := $(top_builddir)libpthread/nptl/sysdeps/sh +PTHREAD_ARCH_OBJ := $(patsubst %.S,$(PTHREAD_ARCH_OUT)/%.o,$(libpthread_SSRC)) +PTHREAD_ARCH_OBJ += $(patsubst %.c,$(PTHREAD_ARCH_OUT)/%.o,$(libpthread_CSRC)) + +ifeq ($(DOPIC),y) +libpthread-a-y += $(PTHREAD_ARCH_OBJ:.o=.os) +else +libpthread-a-y += $(PTHREAD_ARCH_OBJ) +endif +libpthread-so-y += $(PTHREAD_ARCH_OBJ:.o=.oS) + +libpthread-nomulti-y += $(PTHREAD_ARCH_OBJ) + +objclean-y += nptl_arch_clean +headers_clean-y += nptl_arch_headers_clean + +# +# Create 'tcb-offsets.h' header file. +# +CFLAGS-tcb-offsets.c = -S + +$(PTHREAD_ARCH_OUT)/tcb-offsets.c: $(PTHREAD_ARCH_DIR)/tcb-offsets.sym + $(do_awk) $(top_srcdir)extra/scripts/gen-as-const.awk $< > $@ + +$(PTHREAD_ARCH_OUT)/tcb-offsets.s: $(PTHREAD_ARCH_OUT)/tcb-offsets.c + $(compile.c) + +$(PTHREAD_ARCH_OUT)/tcb-offsets.h: $(PTHREAD_ARCH_OUT)/tcb-offsets.s + $(do_sed) -n "s/^.*@@@name@@@\([^@]*\)@@@value@@@[^0-9Xxa-fA-F-]*\([0-9Xxa-fA-F-][0-9Xxa-fA-F-]*\).*@@@end@@@.*$\/#define \1 \2/p" $< > $@ + +nptl_arch_headers: $(PTHREAD_ARCH_OUT)/tcb-offsets.h + +nptl_arch_headers_clean: + $(do_rm) $(addprefix $(PTHREAD_ARCH_OUT)/tcb-offsets., c s h) + +nptl_arch_clean: + $(do_rm) $(addprefix $(PTHREAD_ARCH_OUT)/*., o os oS) diff --git a/libpthread/nptl/sysdeps/sh/dl-tls.h b/libpthread/nptl/sysdeps/sh/dl-tls.h new file mode 100644 index 000000000..98e2f1904 --- /dev/null +++ b/libpthread/nptl/sysdeps/sh/dl-tls.h @@ -0,0 +1,29 @@ +/* Thread-local storage handling in the ELF dynamic linker. SH version. + Copyright (C) 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + + +/* Type used for the representation of TLS information in the GOT. */ +typedef struct +{ + unsigned long int ti_module; + unsigned long int ti_offset; +} tls_index; + + +extern void *__tls_get_addr (tls_index *ti); diff --git a/libpthread/nptl/sysdeps/sh/jmpbuf-unwind.h b/libpthread/nptl/sysdeps/sh/jmpbuf-unwind.h new file mode 100644 index 000000000..41c3c3984 --- /dev/null +++ b/libpthread/nptl/sysdeps/sh/jmpbuf-unwind.h @@ -0,0 +1,33 @@ +/* Copyright (C) 2003, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek , 2003. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include +#include + +#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \ + _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj) + +#define _JMPBUF_UNWINDS_ADJ(jmpbuf, address, adj) \ + ((uintptr_t) (address) - (adj) < (uintptr_t) (jmpbuf)[0].__regs[7] - (adj)) + +extern __typeof(longjmp) __libc_longjmp attribute_noreturn; + +/* We use the normal lobngjmp for unwinding. */ +#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val) diff --git a/libpthread/nptl/sysdeps/sh/pthread_spin_init.c b/libpthread/nptl/sysdeps/sh/pthread_spin_init.c new file mode 100644 index 000000000..0a47981aa --- /dev/null +++ b/libpthread/nptl/sysdeps/sh/pthread_spin_init.c @@ -0,0 +1,20 @@ +/* Copyright (C) 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 2002. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* Not needed. pthread_spin_init is an alias for pthread_spin_unlock. */ diff --git a/libpthread/nptl/sysdeps/sh/pthread_spin_lock.c b/libpthread/nptl/sysdeps/sh/pthread_spin_lock.c new file mode 100644 index 000000000..d158183f0 --- /dev/null +++ b/libpthread/nptl/sysdeps/sh/pthread_spin_lock.c @@ -0,0 +1,35 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "pthreadP.h" + +int +pthread_spin_lock (lock) + pthread_spinlock_t *lock; +{ + unsigned int val; + + do + __asm__ volatile ("tas.b @%1; movt %0" + : "=&r" (val) + : "r" (lock) + : "memory"); + while (val == 0); + + return 0; +} diff --git a/libpthread/nptl/sysdeps/sh/pthread_spin_trylock.S b/libpthread/nptl/sysdeps/sh/pthread_spin_trylock.S new file mode 100644 index 000000000..18112ba23 --- /dev/null +++ b/libpthread/nptl/sysdeps/sh/pthread_spin_trylock.S @@ -0,0 +1,32 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + + .globl pthread_spin_trylock + .type pthread_spin_trylock,@function + .align 5 +pthread_spin_trylock: + tas.b @r4 + bf/s 1f + mov #EBUSY, r0 + mov #0, r0 +1: + rts + nop + .size pthread_spin_trylock,.-pthread_spin_trylock diff --git a/libpthread/nptl/sysdeps/sh/pthread_spin_unlock.S b/libpthread/nptl/sysdeps/sh/pthread_spin_unlock.S new file mode 100644 index 000000000..c77acaffe --- /dev/null +++ b/libpthread/nptl/sysdeps/sh/pthread_spin_unlock.S @@ -0,0 +1,30 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + + .globl pthread_spin_unlock + .type pthread_spin_unlock,@function + .align 5 +pthread_spin_unlock: + mov #0,r0 + rts + mov.l r0,@r4 + .size pthread_spin_unlock,.-pthread_spin_unlock + + /* The implementation of pthread_spin_init is identical. */ + .globl pthread_spin_init +pthread_spin_init = pthread_spin_unlock diff --git a/libpthread/nptl/sysdeps/sh/pthreaddef.h b/libpthread/nptl/sysdeps/sh/pthreaddef.h new file mode 100644 index 000000000..c1902fb54 --- /dev/null +++ b/libpthread/nptl/sysdeps/sh/pthreaddef.h @@ -0,0 +1,49 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +/* Default stack size. */ +#define ARCH_STACK_DEFAULT_SIZE (2 * 1024 * 1024) + +/* Required stack pointer alignment at beginning. */ +#define STACK_ALIGN 8 + +/* Minimal stack size after allocating thread descriptor and guard size. */ +#define MINIMAL_REST_STACK 2048 + +/* Alignment requirement for TCB. */ +#define TCB_ALIGNMENT 8 + + +/* Location of current stack frame. */ +#define CURRENT_STACK_FRAME __builtin_frame_address (0) + + +/* XXX Until we have a better place keep the definitions here. */ + +/* While there is no such syscall. */ +#define __exit_thread_inline(val) \ + while (1) { \ + if (__builtin_constant_p (val) && (val) == 0) \ + __asm__ volatile ("mov #0,r4; mov %0,r3; trapa #0x11\n\t" SYSCALL_INST_PAD \ + :: "i" (__NR_exit)); \ + else \ + __asm__ volatile ("mov %1,r4; mov %0,r3; trapa #0x11\n\t" SYSCALL_INST_PAD \ + :: "i" (__NR_exit), "r" (val)); \ + } diff --git a/libpthread/nptl/sysdeps/sh/sysdep.h b/libpthread/nptl/sysdeps/sh/sysdep.h new file mode 100644 index 000000000..5b75198f9 --- /dev/null +++ b/libpthread/nptl/sysdeps/sh/sysdep.h @@ -0,0 +1,82 @@ +/* Assembler macros for SH. + Copyright (C) 1999, 2000, 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +#include +#include + +#ifdef __ASSEMBLER__ + +/* Syntactic details of assembler. */ + +#define ALIGNARG(log2) log2 +/* For ELF we need the `.type' directive to make shared libs work right. */ +#define ASM_TYPE_DIRECTIVE(name,typearg) .type name,@##typearg; +#define ASM_SIZE_DIRECTIVE(name) .size name,.-name + +#ifdef SHARED +#define PLTJMP(_x) _x##@PLT +#else +#define PLTJMP(_x) _x +#endif + +/* Define an entry point visible from C. */ +#define ENTRY(name) \ + ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \ + ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),function) \ + .align ALIGNARG(5); \ + C_LABEL(name) \ + cfi_startproc; \ + CALL_MCOUNT + +#undef END +#define END(name) \ + cfi_endproc; \ + ASM_SIZE_DIRECTIVE(C_SYMBOL_NAME(name)) + +/* If compiled for profiling, call `mcount' at the start of each function. */ +#ifdef PROF +#define CALL_MCOUNT \ + mov.l 1f,r1; \ + sts.l pr,@-r15; \ + cfi_adjust_cfa_offset (4); \ + cfi_rel_offset (pr, 0); \ + mova 2f,r0; \ + jmp @r1; \ + lds r0,pr; \ + .align 2; \ +1: .long mcount; \ +2: lds.l @r15+,pr; \ + cfi_adjust_cfa_offset (-4); \ + cfi_restore (pr) + +#else +#define CALL_MCOUNT /* Do nothing. */ +#endif + +#ifdef __UCLIBC_UNDERSCORES__ +/* Since C identifiers are not normally prefixed with an underscore + on this system, the asm identifier `syscall_error' intrudes on the + C name space. Make sure we use an innocuous name. */ +#define syscall_error __syscall_error +#define mcount _mcount +#endif + +#endif /* __ASSEMBLER__ */ diff --git a/libpthread/nptl/sysdeps/sh/tcb-offsets.sym b/libpthread/nptl/sysdeps/sh/tcb-offsets.sym new file mode 100644 index 000000000..539789a81 --- /dev/null +++ b/libpthread/nptl/sysdeps/sh/tcb-offsets.sym @@ -0,0 +1,11 @@ +#include +#include + +RESULT offsetof (struct pthread, result) +TID offsetof (struct pthread, tid) +PID offsetof (struct pthread, pid) +CANCELHANDLING offsetof (struct pthread, cancelhandling) +CLEANUP_JMP_BUF offsetof (struct pthread, cleanup_jmp_buf) +MULTIPLE_THREADS_OFFSET offsetof (struct pthread, header.multiple_threads) +TLS_PRE_TCB_SIZE sizeof (struct pthread) +MUTEX_FUTEX offsetof (pthread_mutex_t, __data.__lock) diff --git a/libpthread/nptl/sysdeps/sh/tls.h b/libpthread/nptl/sysdeps/sh/tls.h new file mode 100644 index 000000000..5e5ce12b0 --- /dev/null +++ b/libpthread/nptl/sysdeps/sh/tls.h @@ -0,0 +1,142 @@ +/* Definition for thread-local data handling. NPTL/SH version. + Copyright (C) 2003, 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _TLS_H +#define _TLS_H + +#ifndef __ASSEMBLER__ +# include +# include +# include + +/* Type for the dtv. */ +typedef union dtv +{ + size_t counter; + struct + { + void *val; + bool is_static; + } pointer; +} dtv_t; + +typedef struct +{ + dtv_t *dtv; + void *private; +} tcbhead_t; + +# define TLS_MULTIPLE_THREADS_IN_TCB 1 + +#else /* __ASSEMBLER__ */ +# include +#endif /* __ASSEMBLER__ */ + + +/* We require TLS support in the tools. */ +#define HAVE_TLS_SUPPORT +#define HAVE___THREAD 1 +#define HAVE_TLS_MODEL_ATTRIBUTE 1 +/* Signal that TLS support is available. */ +# define USE_TLS 1 + +#ifndef __ASSEMBLER__ + +/* Get system call information. */ +# include + +/* This is the size of the initial TCB. */ +# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t) + +/* Alignment requirements for the initial TCB. */ +# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t) + +/* This is the size of the TCB. */ +# define TLS_TCB_SIZE sizeof (tcbhead_t) + +/* This is the size we need before TCB. */ +# define TLS_PRE_TCB_SIZE sizeof (struct pthread) + +/* Alignment requirements for the TCB. */ +# define TLS_TCB_ALIGN __alignof__ (struct pthread) + +/* The TLS blocks start right after the TCB. */ +# define TLS_DTV_AT_TP 1 + +/* Get the thread descriptor definition. */ +# include + +/* Install the dtv pointer. The pointer passed is to the element with + index -1 which contain the length. */ +# define INSTALL_DTV(tcbp, dtvp) \ + ((tcbhead_t *) (tcbp))->dtv = (dtvp) + 1 + +/* Install new dtv for current thread. */ +# define INSTALL_NEW_DTV(dtv) \ + ({ tcbhead_t *__tcbp; \ + __asm __volatile ("stc gbr,%0" : "=r" (__tcbp)); \ + __tcbp->dtv = (dtv);}) + +/* Return dtv of given thread descriptor. */ +# define GET_DTV(tcbp) \ + (((tcbhead_t *) (tcbp))->dtv) + +/* Code to initially initialize the thread pointer. This might need + special attention since 'errno' is not yet available and if the + operation can cause a failure 'errno' must not be touched. */ +# define TLS_INIT_TP(tcbp, secondcall) \ + ({ __asm __volatile ("ldc %0,gbr" : : "r" (tcbp)); 0; }) + +/* Return the address of the dtv for the current thread. */ +# define THREAD_DTV() \ + ({ tcbhead_t *__tcbp; \ + __asm __volatile ("stc gbr,%0" : "=r" (__tcbp)); \ + __tcbp->dtv;}) + +/* Return the thread descriptor for the current thread. + The contained asm must *not* be marked volatile since otherwise + assignments like + struct pthread *self = thread_self(); + do not get optimized away. */ +# define THREAD_SELF \ + ({ struct pthread *__thread_self; \ + __asm ("stc gbr,%0" : "=r" (__thread_self)); \ + __thread_self - 1;}) + +/* Magic for libthread_db to know how to do THREAD_SELF. */ +# define DB_THREAD_SELF \ + REGISTER (32, 32, REG_GBR * 4, -sizeof (struct pthread)) + +/* Read member of the thread descriptor directly. */ +# define THREAD_GETMEM(descr, member) (descr->member) + +/* Same as THREAD_GETMEM, but the member offset can be non-constant. */ +# define THREAD_GETMEM_NC(descr, member, idx) (descr->member[idx]) + +/* Set member of the thread descriptor directly. */ +# define THREAD_SETMEM(descr, member, value) \ + descr->member = (value) + +/* Same as THREAD_SETMEM, but the member offset can be non-constant. */ +# define THREAD_SETMEM_NC(descr, member, idx, value) \ + descr->member[idx] = (value) + +#endif /* __ASSEMBLER__ */ + +#endif /* tls.h */ -- cgit v1.2.3