support INLINE_SYSCALL & INTERNAL_SYSCALL via new ia64 syscall stub

From: David Mosberger <davidm_at_napali.hpl.hp.com>
Date: 2003-09-27 14:23:17
[Resend due to mistyped linux-ia64 address; my fingers must be suffering
 from repressed memories as they typed linux-ia64@vger.rutgers.edu... ;-]

The patch below is relative to the CVS sysdep.h and adds support for
doing INLINE_SYSCALL and INTERNAL_SYSCALL via the new ia64 syscall
stubs (which enable light-weight system calls).  It's hasn't been
thoroughly tested (I'm just about to go on a trip and wanted to
getthis out), but it ought to work in theory and it has held up so
far.

With this patch, the number of "break" syscalls in libc.so drops from
~160 down to about 40 and those that are left probably won't go away
(they're in places where the new syscall stubs can't be used, e.g.,
clone2()).

Ian, do you think you could make the equivalent changes for your
NPTL-enabled libc packages?

	--david

diff -u -r1.17 sysdep.h
--- sysdeps/unix/sysv/linux/ia64/sysdep.h	16 Aug 2003 08:00:24 -0000	1.17
+++ sysdeps/unix/sysv/linux/ia64/sysdep.h	27 Sep 2003 04:12:02 -0000
@@ -23,6 +23,7 @@
 
 #include <sysdeps/unix/sysdep.h>
 #include <sysdeps/ia64/sysdep.h>
+#include <tls.h>
 
 /* For Linux we can use the system call table in the header file
 	/usr/include/asm/unistd.h
@@ -95,9 +96,32 @@
 	cmp.eq p6,p0=-1,r10;			\
 (p6)	br.cond.spnt.few __syscall_error;
 
-#define DO_CALL(num)				\
+#define DO_CALL_VIA_BREAK(num)			\
 	mov r15=num;				\
-	break __BREAK_SYSCALL;
+	break __BREAK_SYSCALL
+
+#if defined HAVE_TLS_SUPPORT && (!defined NOT_IN_libc || defined IS_IN_libpthread)
+
+/* Use the lightweight stub only if (a) we have a suitably modern
+   thread-control block (HAVE_TLS_SUPPORT) and (b) we're not compiling
+   the runtime loader (which might do syscalls before being fully
+   relocated). */
+
+#define DO_CALL(num)				\
+	.prologue;				\
+        adds r2 = SYSINFO_OFFSET, r13;;		\
+        ld8 r2 = [r2];				\
+	.save ar.pfs, r11;			\
+        mov r11 = ar.pfs;;			\
+	.body;					\
+	mov r15 = num;				\
+        mov b7 = r2;				\
+        br.call.sptk.many b6 = b7;;		\
+	.restore sp;				\
+        mov ar.pfs = r11
+#else
+#define DO_CALL(num)				DO_CALL_VIA_BREAK(num)
+#endif
 
 #undef PSEUDO_END
 #define PSEUDO_END(name)	.endp C_SYMBOL_NAME(name);
@@ -144,6 +168,47 @@
    (non-negative) errno on error or the return value on success.
  */
 #undef INLINE_SYSCALL
+#undef INTERNAL_SYSCALL
+#if defined HAVE_TLS_SUPPORT && (!defined NOT_IN_libc || defined IS_IN_libpthread)
+
+#define DO_INLINE_SYSCALL(name, nr, args...)							\
+    register long _r8 __asm ("r8");								\
+    register long _r10 __asm ("r10");								\
+    register long _r15 __asm ("r15") = __NR_##name;						\
+    long _retval;										\
+    LOAD_ARGS_##nr (args);									\
+    /*												\
+     * Don't specify any unwind info here.  We mark ar.pfs as clobbered.  This will force	\
+     * the compiler to save ar.pfs somewhere and emit appropriate unwind info for that		\
+     * save.											\
+     */												\
+    __asm __volatile ("adds r2 = -8, r13;;\n"							\
+		      "ld8 r2 = [r2];;\n"							\
+		      "mov b7=r2;\n"								\
+		      "br.call.sptk.many b6=b7;;\n"						\
+                      : "=r" (_r8), "=r" (_r10), "=r" (_r15) ASM_OUTARGS_##nr			\
+                      : "2" (_r15) ASM_ARGS_##nr						\
+		      : "memory", "ar.pfs" ASM_CLOBBERS_##nr);					\
+    _retval = _r8;
+
+#define INLINE_SYSCALL(name, nr, args...)	\
+  ({						\
+    DO_INLINE_SYSCALL(name, nr, args)		\
+    if (_r10 == -1)				\
+      {						\
+        __set_errno (_retval);			\
+        _retval = -1;				\
+      }						\
+    _retval; })
+
+#define INTERNAL_SYSCALL(name, err, nr, args...)	\
+  ({							\
+    DO_INLINE_SYSCALL(name, nr, args)			\
+    err = _r10;						\
+    _retval; })
+
+#else /* !new syscall-stub */
+
 #define INLINE_SYSCALL(name, nr, args...)			\
   ({								\
     register long _r8 asm ("r8");				\
@@ -164,10 +229,6 @@
       }								\
     _retval; })
 
-#undef INTERNAL_SYSCALL_DECL
-#define INTERNAL_SYSCALL_DECL(err) long int err
-
-#undef INTERNAL_SYSCALL
 #define INTERNAL_SYSCALL(name, err, nr, args...)		\
   ({								\
     register long _r8 asm ("r8");				\
@@ -183,6 +244,11 @@
     _retval = _r8;						\
     err = _r10;							\
     _retval; })
+
+#endif /* !new syscall-stub */
+
+#undef INTERNAL_SYSCALL_DECL
+#define INTERNAL_SYSCALL_DECL(err) long int err
 
 #undef INTERNAL_SYSCALL_ERROR_P
 #define INTERNAL_SYSCALL_ERROR_P(val, err)	(err == -1)
-
To unsubscribe from this list: send the line "unsubscribe linux-ia64" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Received on Sat Sep 27 00:23:31 2003

This archive was generated by hypermail 2.1.8 : 2005-08-02 09:20:18 EST