* [PATCH] INTERNAL_SYSCALL for linux-mips
@ 2003-01-14 23:06 Guido Guenther
2003-01-15 1:03 ` Ulrich Drepper
2003-01-15 12:48 ` Ralf Baechle
0 siblings, 2 replies; 3+ messages in thread
From: Guido Guenther @ 2003-01-14 23:06 UTC (permalink / raw)
To: libc-alpha; +Cc: linux-mips
[-- Attachment #1: Type: text/plain, Size: 573 bytes --]
Hi,
the attached patch brings mips up to date concerning the
{INTERNAL,INLINE}_SYSCALL macros. I'm aware that we can probably
save some more cycles by defining INLINE_SYSCALL directly and avoiding
the err variable, but I'd like to leave this asside until the
cancelation handling is fixed.
With the attached patch glibc passess all the tests it passes without it
and is able to "replicate itself" (compile glibc with a glibc installed
that uses this patch).
I'm cc'ing the linux-mips list for comments.
-- Guido
P.S.: many thanks to Thiemo and aj for their explanations.
[-- Attachment #2: inline-syscall-mips.diff --]
[-- Type: text/plain, Size: 8179 bytes --]
2003-01-14 Guido Guenther <agx@sigxcpu.org>
* sysdeps/unix/sysv/linux/mips/sysdep.h
(INTERNAL_SYSCALL, INTERNAL_SYSCALL_DECL,
INTERNAL_SYSCALL_ERRNO, INTERNAL_SYSCALL_ERROR_P,
INLINE_SYSCALL): Define.
Index: sysdeps/unix/sysv/linux/mips/sysdep.h
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/mips/sysdep.h,v
retrieving revision 1.2
diff -u -r1.2 sysdep.h
--- sysdeps/unix/sysv/linux/mips/sysdep.h 6 Jul 2001 04:56:18 -0000 1.2
+++ sysdeps/unix/sysv/linux/mips/sysdep.h 13 Jan 2003 20:35:27 -0000
@@ -33,4 +33,242 @@
# define SYS_ify(syscall_name) __NR_/**/syscall_name
#endif
+#ifndef __ASSEMBLER__
+
+/* Define a macro which expands into the inline wrapper code for a system
+ call. */
+#undef INLINE_SYSCALL
+#define INLINE_SYSCALL(name, nr, args...) \
+ ({ INTERNAL_SYSCALL_DECL(err); \
+ long result_var = INTERNAL_SYSCALL (name, err, nr, args); \
+ if ( INTERNAL_SYSCALL_ERROR_P (result_var, err) ) \
+ { \
+ __set_errno (INTERNAL_SYSCALL_ERRNO (result_var, err)); \
+ result_var = -1L; \
+ } \
+ result_var; })
+
+#undef INTERNAL_SYSCALL_DECL
+#define INTERNAL_SYSCALL_DECL(err) long err
+
+#undef INTERNAL_SYSCALL_ERROR_P
+#define INTERNAL_SYSCALL_ERROR_P(val, err) ((long) (err))
+
+#undef INTERNAL_SYSCALL_ERRNO
+#define INTERNAL_SYSCALL_ERRNO(val, err) (val)
+
+#undef INTERNAL_SYSCALL
+#define INTERNAL_SYSCALL(name, err, nr, args...) internal_syscall##nr(name, err, args)
+
+#define internal_syscall0(name, err, dummy...) \
+({ \
+ long _sys_result; \
+ \
+ { \
+ register long __v0 asm("$2"); \
+ register long __a3 asm("$7"); \
+ __asm__ volatile ( \
+ ".set\tnoreorder\n\t" \
+ "li\t$2, %2\t\t\t# " #name "\n\t" \
+ "syscall\n\t" \
+ ".set reorder" \
+ : "=r" (__v0), "=r" (__a3) \
+ : "i" (SYS_ify(name)) \
+ : __SYSCALL_CLOBBERS); \
+ err = __a3; \
+ _sys_result = __v0; \
+ } \
+ _sys_result; \
+})
+
+#define internal_syscall1(name, err, arg1) \
+({ \
+ long _sys_result; \
+ \
+ { \
+ register long __v0 asm("$2"); \
+ register long __a0 asm("$4") = (long) arg1; \
+ register long __a3 asm("$7"); \
+ __asm__ volatile ( \
+ ".set\tnoreorder\n\t" \
+ "li\t$2, %3\t\t\t# " #name "\n\t" \
+ "syscall\n\t" \
+ ".set reorder" \
+ : "=r" (__v0), "=r" (__a3) \
+ : "r" (__a0), "i" (SYS_ify(name)) \
+ : __SYSCALL_CLOBBERS); \
+ err = __a3; \
+ _sys_result = __v0; \
+ } \
+ _sys_result; \
+})
+
+#define internal_syscall2(name, err, arg1, arg2) \
+({ \
+ long _sys_result; \
+ \
+ { \
+ register long __v0 asm("$2"); \
+ register long __a0 asm("$4") = (long) arg1; \
+ register long __a1 asm("$5") = (long) arg2; \
+ register long __a3 asm("$7"); \
+ __asm__ volatile ( \
+ ".set\tnoreorder\n\t" \
+ "li\t$2, %4\t\t\t# " #name "\n\t" \
+ "syscall\n\t" \
+ ".set\treorder" \
+ : "=r" (__v0), "=r" (__a3) \
+ : "r" (__a0), "r" (__a1), "i" (SYS_ify(name)) \
+ : __SYSCALL_CLOBBERS); \
+ err = __a3; \
+ _sys_result = __v0; \
+ } \
+ _sys_result; \
+})
+
+#define internal_syscall3(name, err, arg1, arg2, arg3) \
+({ \
+ 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"); \
+ __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)) \
+ : __SYSCALL_CLOBBERS); \
+ err = __a3; \
+ _sys_result = __v0; \
+ } \
+ _sys_result; \
+})
+
+#define internal_syscall4(name, err, arg1, arg2, arg3, arg4) \
+({ \
+ 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; \
+ __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)) \
+ : __SYSCALL_CLOBBERS); \
+ err = __a3; \
+ _sys_result = __v0; \
+ } \
+ _sys_result; \
+})
+
+#define internal_syscall5(name, err, arg1, arg2, arg3, arg4, arg5) \
+({ \
+ 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; \
+ __asm__ volatile ( \
+ ".set\tnoreorder\n\t" \
+ "lw\t$2, %6\n\t" \
+ "subu\t$29, 32\n\t" \
+ "sw\t$2, 16($29)\n\t" \
+ "li\t$2, %5\t\t\t# " #name "\n\t" \
+ "syscall\n\t" \
+ "addiu\t$29, 32\n\t" \
+ ".set\treorder" \
+ : "=r" (__v0), "+r" (__a3) \
+ : "r" (__a0), "r" (__a1), "r" (__a2), "i" (SYS_ify(name)), \
+ "m" ((long)arg5) \
+ : __SYSCALL_CLOBBERS); \
+ err = __a3; \
+ _sys_result = __v0; \
+ } \
+ _sys_result; \
+})
+
+#define internal_syscall6(name, err, arg1, arg2, arg3, arg4, arg5, arg6)\
+({ \
+ 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; \
+ __asm__ volatile ( \
+ ".set\tnoreorder\n\t" \
+ "lw\t$2, %6\n\t" \
+ "lw\t$8, %7\n\t" \
+ "subu\t$29, 32\n\t" \
+ "sw\t$2, 16($29)\n\t" \
+ "sw\t$8, 20($29)\n\t" \
+ "li\t$2, %5\t\t\t# " #name "\n\t" \
+ "syscall\n\t" \
+ "addiu\t$29, 32\n\t" \
+ ".set\treorder" \
+ : "=r" (__v0), "+r" (__a3) \
+ : "r" (__a0), "r" (__a1), "r" (__a2), "i" (SYS_ify(name)), \
+ "m" ((long)arg5), "m" ((long)arg6) \
+ : __SYSCALL_CLOBBERS); \
+ err = __a3; \
+ _sys_result = __v0; \
+ } \
+ _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; \
+ __asm__ volatile ( \
+ ".set\tnoreorder\n\t" \
+ "lw\t$2, %6\n\t" \
+ "lw\t$8, %7\n\t" \
+ "lw\t$9, %8\n\t" \
+ "subu\t$29, 32\n\t" \
+ "sw\t$2, 16($29)\n\t" \
+ "sw\t$8, 20($29)\n\t" \
+ "sw\t$9, 24($29)\n\t" \
+ "li\t$2, %5\t\t\t# " #name "\n\t" \
+ "syscall\n\t" \
+ "addiu\t$29, 32\n\t" \
+ ".set\treorder" \
+ : "=r" (__v0), "+r" (__a3) \
+ : "r" (__a0), "r" (__a1), "r" (__a2), "i" (SYS_ify(name)), \
+ "m" ((long)arg5), "m" ((long)arg6), "m" ((long)arg7) \
+ : __SYSCALL_CLOBBERS); \
+ err = __a3; \
+ _sys_result = __v0; \
+ } \
+ _sys_result; \
+})
+
+#define __SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25"
+
+#endif /* __ASSEMBLER__ */
+
#endif /* linux/mips/sysdep.h */
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] INTERNAL_SYSCALL for linux-mips
2003-01-14 23:06 [PATCH] INTERNAL_SYSCALL for linux-mips Guido Guenther
@ 2003-01-15 1:03 ` Ulrich Drepper
2003-01-15 12:48 ` Ralf Baechle
1 sibling, 0 replies; 3+ messages in thread
From: Ulrich Drepper @ 2003-01-15 1:03 UTC (permalink / raw)
To: Guido Guenther; +Cc: libc-alpha, linux-mips
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Guido Guenther wrote:
> the attached patch brings mips up to date concerning the
> {INTERNAL,INLINE}_SYSCALL macros.
I've applied the patch. Thanks,
- --
- --------------. ,-. 444 Castro Street
Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA
Red Hat `--' drepper at redhat.com `---------------------------
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (GNU/Linux)
iD8DBQE+JLNF2ijCOnn/RHQRAnPxAKCTNJyDBtLmvZtP7Eq5Zf4d9F2GaQCglf3+
EX9+rGlNZUpvkcIR7aBl14U=
=OVjY
-----END PGP SIGNATURE-----
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] INTERNAL_SYSCALL for linux-mips
2003-01-14 23:06 [PATCH] INTERNAL_SYSCALL for linux-mips Guido Guenther
2003-01-15 1:03 ` Ulrich Drepper
@ 2003-01-15 12:48 ` Ralf Baechle
1 sibling, 0 replies; 3+ messages in thread
From: Ralf Baechle @ 2003-01-15 12:48 UTC (permalink / raw)
To: Guido Guenther; +Cc: libc-alpha, linux-mips
On Wed, Jan 15, 2003 at 12:06:08AM +0100, Guido Guenther wrote:
> + register long __v0 asm("$2"); \
> + register long __a3 asm("$7"); \
The patch looks fine to me but as a word of warning - I'm using the same
code construct is also being used in the kernel but I've found it very
fragile wrt. misscompilation by gcc over the years ...
Ralf
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2003-01-15 12:58 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-01-14 23:06 [PATCH] INTERNAL_SYSCALL for linux-mips Guido Guenther
2003-01-15 1:03 ` Ulrich Drepper
2003-01-15 12:48 ` Ralf Baechle
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.