about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>2003-10-01 07:00:03 +0000
committerRoland McGrath <roland@gnu.org>2003-10-01 07:00:03 +0000
commitd057b5e76c240e3475ad12f36ca95c118c8a6fe9 (patch)
tree5052c4b992bc53e38926cafbffc45ca9e8ee0faa
parent4106a40380570e423bb86ba5097a4374750d84bb (diff)
downloadglibc-d057b5e76c240e3475ad12f36ca95c118c8a6fe9.tar.gz
glibc-d057b5e76c240e3475ad12f36ca95c118c8a6fe9.tar.xz
glibc-d057b5e76c240e3475ad12f36ca95c118c8a6fe9.zip
* sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h: Remove
	"#if 0" surrounding most of contents.
	(SYSCALL_ERROR_LABEL): Define.
	(__SYSCALL_CLOBBERS): Add $10.
	(internal_syscall7): Remove.
	* sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h: Likewise.
-rw-r--r--ChangeLog9
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/mips/mips64/sysdep-cancel.h146
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h42
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h42
4 files changed, 175 insertions, 64 deletions
diff --git a/ChangeLog b/ChangeLog
index 07c1ad0cec..09403842b9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2003-09-10  Chris Demetriou  <cgd@broadcom.com>
+
+	* sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h: Remove
+	"#if 0" surrounding most of contents.
+	(SYSCALL_ERROR_LABEL): Define.
+	(__SYSCALL_CLOBBERS): Add $10.
+	(internal_syscall7): Remove.
+	* sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h: Likewise.
+
 2003-09-30  Ulrich Drepper  <drepper@redhat.com>
 
 	* elf/rtld.c (dl_main): Also set l_map_start.
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/mips/mips64/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/mips/mips64/sysdep-cancel.h
new file mode 100644
index 0000000000..8949877963
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/mips/mips64/sysdep-cancel.h
@@ -0,0 +1,146 @@
+/* system call stubs with cancellation handling.  Linux/MIPS version.
+   Copyright (C) 2003 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
+# 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
+
+# if !defined NOT_IN_libc
+#  define __local_multiple_threads __libc_multiple_threads
+# else
+#  define __local_multiple_threads __pthread_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/sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h b/sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h
index 71099711d0..2b2aefa15d 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h
@@ -33,9 +33,16 @@
 # define SYS_ify(syscall_name)	__NR_N32_/**/syscall_name
 #endif
 
+#ifdef __ASSEMBLER__
+
+/* We don't want the label for the error handler to be visible in the symbol
+   table when we define it here.  */
+#ifdef __PIC__
+# define SYSCALL_ERROR_LABEL 99b
+#endif
+
+#else   /* ! __ASSEMBLER__ */
 
-#ifndef __ASSEMBLER__
-#if 0 /* untested */
 /* Define a macro which expands into the inline wrapper code for a system
    call.  */
 #undef INLINE_SYSCALL
@@ -228,36 +235,7 @@
 	_sys_result;							\
 })
 
-#define internal_syscall7(name, err, arg1, arg2, arg3, arg4, arg5, arg6, arg7)\
-({ 									\
-	long _sys_result;						\
-									\
-	{								\
-	register long long __v0 asm("$2"); 				\
-	register long long __a0 asm("$4") = (long long) arg1; 		\
-	register long long __a1 asm("$5") = (long long) arg2; 		\
-	register long long __a2 asm("$6") = (long long) arg3; 		\
-	register long long __a3 asm("$7") = (long long) arg4; 		\
-	register long long __a4 asm("$8") = (long long) arg5; 		\
-	register long long __a5 asm("$9") = (long long) arg6; 		\
-	register long long __a6 asm("$10") = (long long) arg7; 		\
-	__asm__ volatile ( 						\
-	".set\tnoreorder\n\t" 						\
-	"li\t$2, %5\t\t\t# " #name "\n\t" 				\
-	"syscall\n\t" 							\
-	".set\treorder" 						\
-	: "=r" (__v0), "+r" (__a3) 					\
-	: "r" (__a0), "r" (__a1), "r" (__a2), "i" (SYS_ify(name)), 	\
-	  "r" (__a4), "r" (__a5), "r" (__a6)				\
-	: __SYSCALL_CLOBBERS); 						\
-	err = __a3;							\
-	_sys_result = __v0;						\
-	}								\
-	_sys_result;							\
-})
-
-#define __SYSCALL_CLOBBERS "$1", "$3", "$11", "$12", "$13", "$14", "$15", "$24", "$25"
-#endif /* untested */
+#define __SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25"
 #endif /* __ASSEMBLER__ */
 
 #endif /* linux/mips/sysdep.h */
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h b/sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h
index 4341c18345..e2d8707d25 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h
@@ -33,9 +33,16 @@
 # define SYS_ify(syscall_name)	__NR_N64_/**/syscall_name
 #endif
 
+#ifdef __ASSEMBLER__
+
+/* We don't want the label for the error handler to be visible in the symbol
+   table when we define it here.  */
+#ifdef __PIC__
+# define SYSCALL_ERROR_LABEL 99b
+#endif
+
+#else   /* ! __ASSEMBLER__ */
 
-#ifndef __ASSEMBLER__
-#if 0 /* untested */
 /* Define a macro which expands into the inline wrapper code for a system
    call.  */
 #undef INLINE_SYSCALL
@@ -228,36 +235,7 @@
 	_sys_result;							\
 })
 
-#define internal_syscall7(name, err, arg1, arg2, arg3, arg4, arg5, arg6, arg7)\
-({ 									\
-	long _sys_result;						\
-									\
-	{								\
-	register long __v0 asm("$2"); 					\
-	register long __a0 asm("$4") = (long) arg1; 			\
-	register long __a1 asm("$5") = (long) arg2; 			\
-	register long __a2 asm("$6") = (long) arg3; 			\
-	register long __a3 asm("$7") = (long) arg4; 			\
-	register long __a4 asm("$8") = (long) arg5; 			\
-	register long __a5 asm("$9") = (long) arg6; 			\
-	register long __a6 asm("$10") = (long) arg7; 			\
-	__asm__ volatile ( 						\
-	".set\tnoreorder\n\t" 						\
-	"li\t$2, %5\t\t\t# " #name "\n\t" 				\
-	"syscall\n\t" 							\
-	".set\treorder" 						\
-	: "=r" (__v0), "+r" (__a3) 					\
-	: "r" (__a0), "r" (__a1), "r" (__a2), "i" (SYS_ify(name)), 	\
-	  "r" (__a4), "r" (__a5), "r" (__a6)				\
-	: __SYSCALL_CLOBBERS); 						\
-	err = __a3;							\
-	_sys_result = __v0;						\
-	}								\
-	_sys_result;							\
-})
-
-#define __SYSCALL_CLOBBERS "$1", "$3", "$11", "$12", "$13", "$14", "$15", "$24", "$25"
-#endif /* untested */
+#define __SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25"
 #endif /* __ASSEMBLER__ */
 
 #endif /* linux/mips/sysdep.h */