diff options
Diffstat (limited to 'libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips')
9 files changed, 401 insertions, 0 deletions
| diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/CVS/Entries b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/CVS/Entries new file mode 100644 index 000000000..2a6821ecf --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/CVS/Entries @@ -0,0 +1,4 @@ +D/mips64//// +/Makefile/1.3/Tue Nov 15 14:20:47 2005// +/sysdep-cancel.h/1.3/Tue Nov 15 14:20:47 2005// +/vfork.S/1.2/Tue Nov 15 14:20:47 2005// diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/CVS/Repository b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/CVS/Repository new file mode 100644 index 000000000..dbbb76a98 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/CVS/Repository @@ -0,0 +1 @@ +ports/linuxthreads/sysdeps/unix/sysv/linux/mips diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/CVS/Root b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/CVS/Root new file mode 100644 index 000000000..ca45c5d4d --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/CVS/Root @@ -0,0 +1 @@ +:pserver:anoncvs@sources.redhat.com:/cvs/glibc diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/mips64/CVS/Entries b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/mips64/CVS/Entries new file mode 100644 index 000000000..d06ed36e2 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/mips64/CVS/Entries @@ -0,0 +1,2 @@ +/sysdep-cancel.h/1.2/Tue Nov 15 14:20:47 2005// +D diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/mips64/CVS/Repository b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/mips64/CVS/Repository new file mode 100644 index 000000000..3169327d3 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/mips64/CVS/Repository @@ -0,0 +1 @@ +ports/linuxthreads/sysdeps/unix/sysv/linux/mips/mips64 diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/mips64/CVS/Root b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/mips64/CVS/Root new file mode 100644 index 000000000..ca45c5d4d --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/mips64/CVS/Root @@ -0,0 +1 @@ +:pserver:anoncvs@sources.redhat.com:/cvs/glibc diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/mips64/sysdep-cancel.h b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/mips64/sysdep-cancel.h new file mode 100644 index 000000000..fc5177425 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/mips64/sysdep-cancel.h @@ -0,0 +1,144 @@ +/* system call stubs with cancellation handling.  Linux/MIPS version. +   Copyright (C) 2003, 2004 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Chris Demetriou of Broadcom Corporation, +   based on work by Guido Guenther <agx@sigxcpu.org>. + +   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> +#ifndef __ASSEMBLER__ +# include <linuxthreads/internals.h> +#endif +#include <sys/asm.h> + +#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt + +#ifdef __PIC__ +# undef PSEUDO +# define PSEUDO(name, syscall_name, args)				      \ +  .align 2;								      \ +  99:									      \ +  PTR_LA t9,__syscall_error;					 	      \ +  /* manual cpreturn.  */						      \ +  REG_L gp, STKOFF_GP(sp);						      \ +  RESTORESTK ;								      \ +  jr t9;								      \ +  ENTRY (name)								      \ +    SAVESTK ;								      \ +    .cpsetup t9, STKOFF_GP, name ;					      \ +    .set reorder;							      \ +    SINGLE_THREAD_P(t0);						      \ +    bne zero, t0, L(pseudo_cancel);					      \ +    .set noreorder;							      \ +    li v0, SYS_ify(syscall_name);					      \ +    syscall;								      \ +    .set reorder;							      \ +    bne a3, zero, SYSCALL_ERROR_LABEL;			       		      \ +    /* manual cpreturn.  */						      \ +    REG_L gp, STKOFF_GP(sp);						      \ +    RESTORESTK ;							      \ +    ret;								      \ +  L(pseudo_cancel):							      \ +    REG_S ra, STKOFF_RA(sp);						      \ +    PUSHARGS_##args;			/* save syscall args */	      	      \ +    CENABLE;								      \ +    REG_S v0, STKOFF_SVMSK(sp);		/* save mask */			      \ +    POPARGS_##args;			/* restore syscall args */	      \ +    .set noreorder;							      \ +    li v0, SYS_ify (syscall_name);				      	      \ +    syscall;								      \ +    .set reorder;							      \ +    REG_S v0, STKOFF_SC_V0(sp);		/* save syscall result */             \ +    REG_S a3, STKOFF_SC_ERR(sp);	/* save syscall error flag */	      \ +    REG_L a0, STKOFF_SVMSK(sp);		/* pass mask as arg1 */		      \ +    CDISABLE;								      \ +    REG_L a3, STKOFF_SC_ERR(sp);	/* restore syscall error flag */      \ +    REG_L ra, STKOFF_RA(sp);		/* restore return address */	      \ +    REG_L v0, STKOFF_SC_V0(sp);		/* restore syscall result */          \ +    bne a3, zero, SYSCALL_ERROR_LABEL;					      \ +    /* manual cpreturn.  */						      \ +    REG_L gp, STKOFF_GP(sp);						      \ +    RESTORESTK ;							      \ +  L(pseudo_end): +#endif + +# define PUSHARGS_0	/* nothing to do */ +# define PUSHARGS_1	PUSHARGS_0 REG_S a0, STKOFF_A0(sp); +# define PUSHARGS_2	PUSHARGS_1 REG_S a1, STKOFF_A1(sp); +# define PUSHARGS_3	PUSHARGS_2 REG_S a2, STKOFF_A2(sp); +# define PUSHARGS_4	PUSHARGS_3 REG_S a3, STKOFF_A3(sp); +# define PUSHARGS_5	PUSHARGS_4 REG_S a4, STKOFF_A4(sp); +# define PUSHARGS_6	PUSHARGS_5 REG_S a5, STKOFF_A5(sp); + +# define POPARGS_0	/* nothing to do */ +# define POPARGS_1	POPARGS_0 REG_L a0, STKOFF_A0(sp); +# define POPARGS_2	POPARGS_1 REG_L a1, STKOFF_A1(sp); +# define POPARGS_3	POPARGS_2 REG_L a2, STKOFF_A2(sp); +# define POPARGS_4	POPARGS_3 REG_L a3, STKOFF_A3(sp); +# define POPARGS_5	POPARGS_4 REG_L a4, STKOFF_A4(sp); +# define POPARGS_6	POPARGS_5 REG_L a5, STKOFF_A5(sp); + +/* Save an even number of slots.  Should be 0 if an even number of slots +   are used below, or SZREG if an odd number are used.  */ +# define STK_PAD	SZREG + +/* Place values that we are more likely to use later in this sequence, i.e. +   closer to the SP at function entry.  If you do that, the are more +   likely to already be in your d-cache.  */ +# define STKOFF_A5	(STK_PAD) +# define STKOFF_A4	(STKOFF_A5 + SZREG) +# define STKOFF_A3	(STKOFF_A4 + SZREG) +# define STKOFF_A2	(STKOFF_A3 + SZREG)	/* MT and more args.  */ +# define STKOFF_A1	(STKOFF_A2 + SZREG)	/* MT and 2 args.  */ +# define STKOFF_A0	(STKOFF_A1 + SZREG)	/* MT and 1 arg.  */ +# define STKOFF_RA	(STKOFF_A0 + SZREG)	/* Used if MT.  */ +# define STKOFF_SC_V0	(STKOFF_RA + SZREG)	/* Used if MT.  */ +# define STKOFF_SC_ERR	(STKOFF_SC_V0 + SZREG)	/* Used if MT.  */ +# define STKOFF_SVMSK	(STKOFF_SC_ERR + SZREG)	/* Used if MT.  */ +# define STKOFF_GP	(STKOFF_SVMSK + SZREG)	/* Always used.  */ + +# define STKSPACE	(STKOFF_GP + SZREG) +# define SAVESTK 	PTR_SUBU sp, STKSPACE +# define RESTORESTK 	PTR_ADDU sp, STKSPACE + +# ifdef IS_IN_libpthread +#  define CENABLE	PTR_LA t9, __pthread_enable_asynccancel; jalr t9; +#  define CDISABLE	PTR_LA t9, __pthread_disable_asynccancel; jalr t9; +#  define __local_multiple_threads __pthread_multiple_threads +# elif defined IS_IN_librt +#  define CENABLE	PTR_LA t9, __librt_enable_asynccancel; jalr t9; +#  define CDISABLE	PTR_LA t9, __librt_disable_asynccancel; jalr t9; +#  define __local_multiple_threads __librt_multiple_threads +# else +#  define CENABLE	PTR_LA t9, __libc_enable_asynccancel; jalr t9; +#  define CDISABLE	PTR_LA t9, __libc_disable_asynccancel; jalr t9; +#  define __local_multiple_threads __libc_multiple_threads +# endif + +# ifndef __ASSEMBLER__ +extern int __local_multiple_threads attribute_hidden; +#  define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1) +# else +#  define SINGLE_THREAD_P(reg) lw reg, __local_multiple_threads +#endif + +#elif !defined __ASSEMBLER__ + +/* This code should never be used but we define it anyhow.  */ +# define SINGLE_THREAD_P (1) + +#endif diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/sysdep-cancel.h b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/sysdep-cancel.h new file mode 100644 index 000000000..1fff78239 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/sysdep-cancel.h @@ -0,0 +1,143 @@ +/* Copyright (C) 2003, 2004 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Guido Guenther <agx@sigxcpu.org>, 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 <sysdep.h> +#ifndef __ASSEMBLER__ +# include <linuxthreads/internals.h> +#endif + +#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt + +#ifdef __PIC__ +# undef PSEUDO +# define PSEUDO(name, syscall_name, args)				      \ +  .align 2;								      \ +  99: la t9,__syscall_error;						      \ +  jr t9;								      \ +  ENTRY (name)								      \ +    .set noreorder;							      \ +    .cpload t9;								      \ +    .set reorder;							      \ +    SINGLE_THREAD_P(t0);						      \ +    bne zero, t0, L(pseudo_cancel);					      \ +    .set noreorder;							      \ +    li v0, SYS_ify(syscall_name);					      \ +    syscall;								      \ +    .set reorder;							      \ +    bne a3, zero, SYSCALL_ERROR_LABEL;			       		      \ +    ret;								      \ +  L(pseudo_cancel):							      \ +    SAVESTK_##args;						              \ +    sw ra, 28(sp);							      \ +    sw gp, 32(sp);							      \ +    PUSHARGS_##args;			/* save syscall args */	      	      \ +    CENABLE;								      \ +    lw gp, 32(sp);							      \ +    sw v0, 44(sp);			/* save mask */			      \ +    POPARGS_##args;			/* restore syscall args */	      \ +    .set noreorder;							      \ +    li v0, SYS_ify (syscall_name);				      	      \ +    syscall;								      \ +    .set reorder;							      \ +    sw v0, 36(sp);			/* save syscall result */             \ +    sw a3, 40(sp);			/* save syscall error flag */	      \ +    lw a0, 44(sp);			/* pass mask as arg1 */		      \ +    CDISABLE;								      \ +    lw gp, 32(sp);							      \ +    lw v0, 36(sp);			/* restore syscall result */          \ +    lw a3, 40(sp);			/* restore syscall error flag */      \ +    lw ra, 28(sp);			/* restore return address */	      \ +    RESTORESTK;							              \ +    bne a3, zero, SYSCALL_ERROR_LABEL;					      \ +  L(pseudo_end): +#endif + +# define PUSHARGS_0	/* nothing to do */ +# define PUSHARGS_1	PUSHARGS_0 sw a0, 0(sp); +# define PUSHARGS_2	PUSHARGS_1 sw a1, 4(sp); +# define PUSHARGS_3	PUSHARGS_2 sw a2, 8(sp); +# define PUSHARGS_4	PUSHARGS_3 sw a3, 12(sp); +# define PUSHARGS_5	PUSHARGS_4 /* handeld by SAVESTK_## */ +# define PUSHARGS_6	PUSHARGS_5 +# define PUSHARGS_7	PUSHARGS_6 + +# define POPARGS_0	/* nothing to do */ +# define POPARGS_1	POPARGS_0 lw a0, 0(sp); +# define POPARGS_2	POPARGS_1 lw a1, 4(sp); +# define POPARGS_3	POPARGS_2 lw a2, 8(sp); +# define POPARGS_4	POPARGS_3 lw a3, 12(sp); +# define POPARGS_5	POPARGS_4 /* args already in new stackframe */ +# define POPARGS_6	POPARGS_5 +# define POPARGS_7	POPARGS_6 + + +# define STKSPACE	48 +# define SAVESTK_0 	subu sp, STKSPACE +# define SAVESTK_1      SAVESTK_0 +# define SAVESTK_2      SAVESTK_1 +# define SAVESTK_3      SAVESTK_2 +# define SAVESTK_4      SAVESTK_3 +# define SAVESTK_5      lw t0, 16(sp);		\ +			subu sp, STKSPACE;	\ +			sw t0, 16(sp) + +# define SAVESTK_6      lw t0, 16(sp);		\ +			lw t1, 20(sp);		\ +			subu sp, STKSPACE;	\ +			sw t0, 16(sp);		\ +			sw t1, 20(sp) + +# define SAVESTK_7      lw t0, 16(sp);		\ +			lw t1, 20(sp);		\ +			lw t2, 24(sp);		\ +			subu sp, STKSPACE;	\ +			sw t0, 16(sp);		\ +			sw t1, 20(sp);		\ +			sw t2, 24(sp) + +# define RESTORESTK 	addu sp, STKSPACE + + +# ifdef IS_IN_libpthread +#  define CENABLE	la t9, __pthread_enable_asynccancel; jalr t9; +#  define CDISABLE	la t9, __pthread_disable_asynccancel; jalr t9; +#  define __local_multiple_threads __pthread_multiple_threads +# elif defined IS_IN_librt +#  define CENABLE	la t9, __librt_enable_asynccancel; jalr t9; +#  define CDISABLE	la t9, __librt_disable_asynccancel; jalr t9; +#  define __local_multiple_threads __librt_multiple_threads +# else +#  define CENABLE	la t9, __libc_enable_asynccancel; jalr t9; +#  define CDISABLE	la t9, __libc_disable_asynccancel; jalr t9; +#  define __local_multiple_threads __libc_multiple_threads +# endif + +# ifndef __ASSEMBLER__ +extern int __local_multiple_threads attribute_hidden; +#  define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1) +# else +#  define SINGLE_THREAD_P(reg) lw reg, __local_multiple_threads +#endif + +#elif !defined __ASSEMBLER__ + +/* This code should never be used but we define it anyhow.  */ +# define SINGLE_THREAD_P (1) + +#endif diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/vfork.S b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/vfork.S new file mode 100644 index 000000000..7bbab5c59 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/vfork.S @@ -0,0 +1,104 @@ +/* Copyright (C) 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.  */ + +/* vfork() is just a special case of clone().  */ + +#include <sys/asm.h> +#include <sysdep.h> +#include <asm/unistd.h> + +/* int vfork() */ + +	.text +LOCALSZ= 1 +FRAMESZ= (((NARGSAVE+LOCALSZ)*SZREG)+ALSZ)&ALMASK +GPOFF= FRAMESZ-(1*SZREG) +NESTED(__vfork,FRAMESZ,sp) +#ifdef __PIC__ +	SETUP_GP +#endif +	PTR_SUBU sp, FRAMESZ +	SETUP_GP64 (a5, __vfork) +#ifdef __PIC__ +	SAVE_GP (GPOFF) +#endif +#ifdef PROF +# if (_MIPS_SIM != _ABIO32) +	PTR_S		a5, GPOFF(sp) +# endif +	.set		noat +	move		$1, ra +# if (_MIPS_SIM == _ABIO32) +	subu		sp,sp,8 +# endif +	jal		_mcount +	.set		at +# if (_MIPS_SIM != _ABIO32) +	PTR_L		a5, GPOFF(sp) +# endif +#endif + +	/* If libpthread is loaded, we need to call fork instead.  */ +#ifdef SHARED +	PTR_L		a0, __libc_pthread_functions +#else +	.weak		pthread_create +	PTR_LA		a0, pthread_create +#endif + +	PTR_ADDU	sp, FRAMESZ + +	bnez		a0, L(call_fork) + +	li		a0, 0x4112	/* CLONE_VM | CLONE_VFORK | SIGCHLD */ +	move		a1, sp + +	/* Do the system call */ +	li		v0,__NR_clone +	syscall + +	bnez		a3,L(error) + +	/* Successful return from the parent or child.  */ +	RESTORE_GP64 +	ret + +	/* Something bad happened -- no child created.  */ +L(error): +#ifdef __PIC__ +	PTR_LA		t9, __syscall_error +	RESTORE_GP64 +	jr		t9 +#else +	RESTORE_GP64 +	j		__syscall_error +#endif + +L(call_fork): +#ifdef __PIC__ +	PTR_LA		t9, fork +	RESTORE_GP64 +	jr		t9 +#else +	RESTORE_GP64 +	j		fork +#endif +	END(__vfork) + +libc_hidden_def(__vfork) +weak_alias (__vfork, vfork) | 
