diff options
Diffstat (limited to 'libpthread/nptl/sysdeps/sh')
| -rw-r--r-- | libpthread/nptl/sysdeps/sh/Makefile | 3 | ||||
| -rw-r--r-- | libpthread/nptl/sysdeps/sh/Makefile.arch | 56 | ||||
| -rw-r--r-- | libpthread/nptl/sysdeps/sh/dl-tls.h | 29 | ||||
| -rw-r--r-- | libpthread/nptl/sysdeps/sh/jmpbuf-unwind.h | 33 | ||||
| -rw-r--r-- | libpthread/nptl/sysdeps/sh/pthread_spin_init.c | 20 | ||||
| -rw-r--r-- | libpthread/nptl/sysdeps/sh/pthread_spin_lock.c | 35 | ||||
| -rw-r--r-- | libpthread/nptl/sysdeps/sh/pthread_spin_trylock.S | 32 | ||||
| -rw-r--r-- | libpthread/nptl/sysdeps/sh/pthread_spin_unlock.S | 30 | ||||
| -rw-r--r-- | libpthread/nptl/sysdeps/sh/pthreaddef.h | 49 | ||||
| -rw-r--r-- | libpthread/nptl/sysdeps/sh/sysdep.h | 82 | ||||
| -rw-r--r-- | libpthread/nptl/sysdeps/sh/tcb-offsets.sym | 11 | ||||
| -rw-r--r-- | libpthread/nptl/sysdeps/sh/tls.h | 142 | 
12 files changed, 522 insertions, 0 deletions
| 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 <sjhill@uclibc.org> +# +# 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 <jakub@redhat.com>, 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 <setjmp.h> +#include <stdint.h> +#include <unwind.h> + +#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 <drepper@redhat.com>, 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 <pthread-errnos.h> + +	.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 <sysdep.h> + +/* 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 <sysdeps/generic/sysdep.h> + +#include <features.h> +#include <libc-internal.h> + +#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 <sysdep.h> +#include <tls.h> + +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 <stdbool.h> +# include <stddef.h> +# include <stdint.h> + +/* 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 <tcb-offsets.h> +#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 <sysdep.h> + +/* 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 <descr.h> + +/* 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 */ | 
