mips/o32: fix internal_syscall5/6/7
Commit Message
On Sat, 19 Aug 2017, Aurelien Jarno wrote:
> > > The workaround didn't work.
> >
> > Hmm, that means there's something wrong with binutils which needs fixing.
> > Can you please send me the failing .s file and the command line used to
> > assemble it (from `gcc -v')?
>
> Please find that attached.
Thanks. There's indeed a bug in GAS, a MIPS16 path of execution has been
missed in the handling of this option. I have a preliminary fix, however
I yet have to prepare test suite cases (originally the option was
mistakenly only covered by regular MIPS and microMIPS testing, which is
clearly why the MIPS16 case has been missed). I expect this fix to be
included in the upcoming 2.29.1 release, and also backported to 2.28
(although no new 2.28 release is scheduled).
> > The MIPS16 wrappers were split into individual files so that only ones
> > that are actually used by `ld.so' are pulled. I think it would be good if
> > we preserved that. I'll see if I can experiment with keeping the original
> > MIPS16 0-3 wrappers.
>
> For what I have seen, ld.so already uses syscalls with 1 to 4 arguments.
> It doesn't use any syscall without argument though. So it's only 4
> instructions overhead.
Why make things worse where they don't have to be and there's no benefit
elsewhere that would balance the regression?
Here's what I had in mind. The key was updating the macros appropriately
in sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h. Beyond
that I made a number of clean-ups:
1. I renamed `__libc_do_syscall?' to `__mips_syscall?', for consistency
with `__mips16_syscall?', and consequently `__libc_do_syscall_return'
to `__mips_syscall_return'.
2. I exported `__mips_syscall?' wrappers from `libc.so' rather than making
them hidden. This is also consistent with `__mips16_syscall?' wrappers
and reduces code duplication of doubtful benefit -- it could be that
some calls, if internal, could be subject to the JALR->BAL
optimisation, however only those that are in range and only in regular
MIPS code, for a minimal execution time saving on some processors only.
Exporting these entries makes the maintenance effort much easier
though, as we don't have to track and record their use in the
individual subdirectories in Makefile.
3. I renamed `_sys_result' to `_sc_ret' where it is declared as `union
__mips_syscall_return', again for clarity and consistency with MIPS16
INTERNAL_SYSCALL_NCS.
4. I wrapped `number' in parentheses in `internal_syscall5',
`internal_syscall6' and `internal_syscall7', and cast it to `long'.
5. I have adjusted some comments.
Please let me know if you have any questions or concerns about this
update.
This passes o32 regular MIPS regression testing, however my GCC 8 binary
seems to miscompile support_test_main.c in the MIPS16 mode, causing all
the relevant test cases to crash with SIGILL (in the `support_set_test_dir
(test_dir)' invocation it's `test_dir' that is jumped to rather than
`support_set_test_dir'; I'll file a bug separately). I'll find a way to
run MIPS16 testing eventually, however meanwhile I will appreciate if you
do it for me.
Maciej
2017-08-21 Adhemerval Zanella <adhemerval.zanella@linaro.org>
Aurelien Jarno <aurelien@aurel32.net>
Maciej W. Rozycki <macro@imgtec.com>
[BZ #21956]
* sysdeps/unix/sysv/linux/mips/mips32/mips16/Makefile
[subdir = misc] (sysdep_routines): Remove `mips16-syscall5',
`mips16-syscall6' and `mips16-syscall7'.
(CFLAGS-mips16-syscall5.c, CFLAGS-mips16-syscall6.c)
(CFLAGS-mips16-syscall7.c): Remove.
* sysdeps/unix/sysv/linux/mips/mips32/mips16/Versions (libc):
Remove `__mips16_syscall5', `__mips16_syscall6' and
`__mips16_syscall7'.
* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall0.c
(__mips16_syscall0): Rename `__mips16_syscall_return' to
`__mips_syscall_return'.
* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall1.c
(__mips16_syscall1): Likewise.
* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall2.c
(__mips16_syscall2): Likewise.
* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall3.c
(__mips16_syscall3): Likewise.
* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall4.c
(__mips16_syscall4): Likewise.
* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall5.c:
Remove.
* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall6.c:
Remove.
* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall7.c:
Remove.
* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h
(__mips16_syscall5): Expand to `__mips_syscall5' rather than
`__mips16_syscall5'. Remove prototype.
(__mips16_syscall6): Expand to `__mips_syscall6' rather than
`__mips16_syscall6'. Remove prototype.
(__mips16_syscall7): Expand to `__mips_syscall7' rather than
`__mips16_syscall7'. Remove prototype.
(__nomips16, __mips16_syscall_return): Move to...
* sysdeps/unix/sysv/linux/mips/mips32/sysdep.h
(__nomips16, __mips_syscall_return): ... here.
[__mips16] (INTERNAL_SYSCALL_NCS): Rename
`__mips16_syscall_return' to `__mips_syscall_return'.
[__mips16] (INTERNAL_SYSCALL_MIPS16): Pass `number' to
`internal_syscall##nr'.
[!__mips16] (INTERNAL_SYSCALL): Pass `SYS_ify (name)' to
`internal_syscall##nr'.
(FORCE_FRAME_POINTER): Remove.
(__mips_syscall5): New prototype.
(internal_syscall5): Rewrite to call `__mips_syscall5'.
(__mips_syscall6): New prototype.
(internal_syscall6): Rewrite to call `__mips_syscall6'.
(__mips_syscall7): New prototype.
(internal_syscall7): Rewrite to call `__mips_syscall7'.
* sysdeps/unix/sysv/linux/mips/mips32/mips-syscall5.S: New file.
* sysdeps/unix/sysv/linux/mips/mips32/mips-syscall6.S: New file.
* sysdeps/unix/sysv/linux/mips/mips32/mips-syscall7.S: New file.
* sysdeps/unix/sysv/linux/mips/mips32/Makefile [subdir = misc]
(sysdep_routines): Add libc-do-syscall.
* sysdeps/unix/sysv/linux/mips/mips32/Versions (libc): Add
`__mips_syscall5', `__mips_syscall6' and `__mips_syscall7'.
---
sysdeps/unix/sysv/linux/mips/mips32/Makefile | 4
sysdeps/unix/sysv/linux/mips/mips32/Versions | 3
sysdeps/unix/sysv/linux/mips/mips32/mips-syscall5.S | 33 ++
sysdeps/unix/sysv/linux/mips/mips32/mips-syscall6.S | 33 ++
sysdeps/unix/sysv/linux/mips/mips32/mips-syscall7.S | 33 ++
sysdeps/unix/sysv/linux/mips/mips32/mips16/Makefile | 6
sysdeps/unix/sysv/linux/mips/mips32/mips16/Versions | 2
sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h | 44 ---
sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall0.c | 3
sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall1.c | 3
sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall2.c | 3
sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall3.c | 3
sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall4.c | 3
sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall5.c | 33 --
sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall6.c | 33 --
sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall7.c | 33 --
sysdeps/unix/sysv/linux/mips/mips32/sysdep.h | 154 ++++-------
17 files changed, 186 insertions(+), 240 deletions(-)
glibc-aurelien-mips-o32-syscall.diff
Comments
On 21/08/2017 07:48, Maciej W. Rozycki wrote:
> On Sat, 19 Aug 2017, Aurelien Jarno wrote:
>
>>>> The workaround didn't work.
>>>
>>> Hmm, that means there's something wrong with binutils which needs fixing.
>>> Can you please send me the failing .s file and the command line used to
>>> assemble it (from `gcc -v')?
>>
>> Please find that attached.
>
> Thanks. There's indeed a bug in GAS, a MIPS16 path of execution has been
> missed in the handling of this option. I have a preliminary fix, however
> I yet have to prepare test suite cases (originally the option was
> mistakenly only covered by regular MIPS and microMIPS testing, which is
> clearly why the MIPS16 case has been missed). I expect this fix to be
> included in the upcoming 2.29.1 release, and also backported to 2.28
> (although no new 2.28 release is scheduled).
>
>>> The MIPS16 wrappers were split into individual files so that only ones
>>> that are actually used by `ld.so' are pulled. I think it would be good if
>>> we preserved that. I'll see if I can experiment with keeping the original
>>> MIPS16 0-3 wrappers.
>>
>> For what I have seen, ld.so already uses syscalls with 1 to 4 arguments.
>> It doesn't use any syscall without argument though. So it's only 4
>> instructions overhead.
>
> Why make things worse where they don't have to be and there's no benefit
> elsewhere that would balance the regression?
>
> Here's what I had in mind. The key was updating the macros appropriately
> in sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h. Beyond
> that I made a number of clean-ups:
>
> 1. I renamed `__libc_do_syscall?' to `__mips_syscall?', for consistency
> with `__mips16_syscall?', and consequently `__libc_do_syscall_return'
> to `__mips_syscall_return'.
Ok.
>
> 2. I exported `__mips_syscall?' wrappers from `libc.so' rather than making
> them hidden. This is also consistent with `__mips16_syscall?' wrappers
> and reduces code duplication of doubtful benefit -- it could be that
> some calls, if internal, could be subject to the JALR->BAL
> optimisation, however only those that are in range and only in regular
> MIPS code, for a minimal execution time saving on some processors only.
> Exporting these entries makes the maintenance effort much easier
> though, as we don't have to track and record their use in the
> individual subdirectories in Makefile.
In this case we can still have internal hidden calls for libc with the cost
of code duplication by using hiden alias with:
libc_hidden_proto (__mips_syscall{5,6,7}, nomips16)
And with the pairing
libc_hidden_def (__mips_syscall{5,6,7});
On implementation.
>
> 3. I renamed `_sys_result' to `_sc_ret' where it is declared as `union
> __mips_syscall_return', again for clarity and consistency with MIPS16
> INTERNAL_SYSCALL_NCS.
Ok.
>
> 4. I wrapped `number' in parentheses in `internal_syscall5',
> `internal_syscall6' and `internal_syscall7', and cast it to `long'.
Ok.
>
> 5. I have adjusted some comments.
I think it still worth to add some more explanation (see below).
>
> Please let me know if you have any questions or concerns about this
> update.
>
> This passes o32 regular MIPS regression testing, however my GCC 8 binary
> seems to miscompile support_test_main.c in the MIPS16 mode, causing all
> the relevant test cases to crash with SIGILL (in the `support_set_test_dir
> (test_dir)' invocation it's `test_dir' that is jumped to rather than
> `support_set_test_dir'; I'll file a bug separately). I'll find a way to
> run MIPS16 testing eventually, however meanwhile I will appreciate if you
> do it for me.
>
> Maciej
>
> 2017-08-21 Adhemerval Zanella <adhemerval.zanella@linaro.org>
> Aurelien Jarno <aurelien@aurel32.net>
> Maciej W. Rozycki <macro@imgtec.com>
>
> [BZ #21956]
> * sysdeps/unix/sysv/linux/mips/mips32/mips16/Makefile
> [subdir = misc] (sysdep_routines): Remove `mips16-syscall5',
> `mips16-syscall6' and `mips16-syscall7'.
> (CFLAGS-mips16-syscall5.c, CFLAGS-mips16-syscall6.c)
> (CFLAGS-mips16-syscall7.c): Remove.
> * sysdeps/unix/sysv/linux/mips/mips32/mips16/Versions (libc):
> Remove `__mips16_syscall5', `__mips16_syscall6' and
> `__mips16_syscall7'.
> * sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall0.c
> (__mips16_syscall0): Rename `__mips16_syscall_return' to
> `__mips_syscall_return'.
> * sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall1.c
> (__mips16_syscall1): Likewise.
> * sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall2.c
> (__mips16_syscall2): Likewise.
> * sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall3.c
> (__mips16_syscall3): Likewise.
> * sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall4.c
> (__mips16_syscall4): Likewise.
> * sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall5.c:
> Remove.
> * sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall6.c:
> Remove.
> * sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall7.c:
> Remove.
> * sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h
> (__mips16_syscall5): Expand to `__mips_syscall5' rather than
> `__mips16_syscall5'. Remove prototype.
> (__mips16_syscall6): Expand to `__mips_syscall6' rather than
> `__mips16_syscall6'. Remove prototype.
> (__mips16_syscall7): Expand to `__mips_syscall7' rather than
> `__mips16_syscall7'. Remove prototype.
> (__nomips16, __mips16_syscall_return): Move to...
> * sysdeps/unix/sysv/linux/mips/mips32/sysdep.h
> (__nomips16, __mips_syscall_return): ... here.
> [__mips16] (INTERNAL_SYSCALL_NCS): Rename
> `__mips16_syscall_return' to `__mips_syscall_return'.
> [__mips16] (INTERNAL_SYSCALL_MIPS16): Pass `number' to
> `internal_syscall##nr'.
> [!__mips16] (INTERNAL_SYSCALL): Pass `SYS_ify (name)' to
> `internal_syscall##nr'.
> (FORCE_FRAME_POINTER): Remove.
> (__mips_syscall5): New prototype.
> (internal_syscall5): Rewrite to call `__mips_syscall5'.
> (__mips_syscall6): New prototype.
> (internal_syscall6): Rewrite to call `__mips_syscall6'.
> (__mips_syscall7): New prototype.
> (internal_syscall7): Rewrite to call `__mips_syscall7'.
> * sysdeps/unix/sysv/linux/mips/mips32/mips-syscall5.S: New file.
> * sysdeps/unix/sysv/linux/mips/mips32/mips-syscall6.S: New file.
> * sysdeps/unix/sysv/linux/mips/mips32/mips-syscall7.S: New file.
> * sysdeps/unix/sysv/linux/mips/mips32/Makefile [subdir = misc]
> (sysdep_routines): Add libc-do-syscall.
> * sysdeps/unix/sysv/linux/mips/mips32/Versions (libc): Add
> `__mips_syscall5', `__mips_syscall6' and `__mips_syscall7'.
>
> ---
> sysdeps/unix/sysv/linux/mips/mips32/Makefile | 4
> sysdeps/unix/sysv/linux/mips/mips32/Versions | 3
> sysdeps/unix/sysv/linux/mips/mips32/mips-syscall5.S | 33 ++
> sysdeps/unix/sysv/linux/mips/mips32/mips-syscall6.S | 33 ++
> sysdeps/unix/sysv/linux/mips/mips32/mips-syscall7.S | 33 ++
> sysdeps/unix/sysv/linux/mips/mips32/mips16/Makefile | 6
> sysdeps/unix/sysv/linux/mips/mips32/mips16/Versions | 2
> sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h | 44 ---
> sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall0.c | 3
> sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall1.c | 3
> sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall2.c | 3
> sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall3.c | 3
> sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall4.c | 3
> sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall5.c | 33 --
> sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall6.c | 33 --
> sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall7.c | 33 --
> sysdeps/unix/sysv/linux/mips/mips32/sysdep.h | 154 ++++-------
> 17 files changed, 186 insertions(+), 240 deletions(-)
>
> glibc-aurelien-mips-o32-syscall.diff
> Index: glibc/sysdeps/unix/sysv/linux/mips/mips32/Makefile
> ===================================================================
> --- glibc.orig/sysdeps/unix/sysv/linux/mips/mips32/Makefile 2017-08-20 01:30:23.485088512 +0100
> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/Makefile 2017-08-20 01:34:46.716443161 +0100
> @@ -3,6 +3,10 @@ ifeq ($(subdir),conform)
> conformtest-xfail-conds += mips-o32-linux
> endif
>
> +ifeq ($(subdir),misc)
> +sysdep_routines += mips-syscall5 mips-syscall6 mips-syscall7
> +endif
> +
> ifeq ($(subdir),stdlib)
> tests += bug-getcontext-mips-gp
> endif
> Index: glibc/sysdeps/unix/sysv/linux/mips/mips32/Versions
> ===================================================================
> --- glibc.orig/sysdeps/unix/sysv/linux/mips/mips32/Versions 2017-08-20 01:30:23.617089669 +0100
> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/Versions 2017-08-20 01:34:46.740608292 +0100
> @@ -3,4 +3,7 @@ libc {
> getrlimit64;
> setrlimit64;
> }
> + GLIBC_PRIVATE {
> + __mips_syscall5; __mips_syscall6; __mips_syscall7;
> + }
> }
> Index: glibc/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall5.S
> ===================================================================
> --- /dev/null 1970-01-01 00:00:00.000000000 +0000
> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall5.S 2017-08-20 03:02:13.583854495 +0100
> @@ -0,0 +1,33 @@
One line comment to describe this file.
> +/* Copyright (C) 2017 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, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#include <sysdep.h>
> +#include <sys/asm.h>
> +
> + .text
> + .set nomips16
> +
> +/* long long __mips_syscall5 (long arg1, long arg2, long arg3, long arg4,
> + long arg5,
> + long number) */
> +
> +ENTRY(__mips_syscall5)
> + lw v0, 20(sp)
> + syscall
> + move v1, a3
> + jr ra
> +END(__mips_syscall5)
> Index: glibc/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall6.S
> ===================================================================
> --- /dev/null 1970-01-01 00:00:00.000000000 +0000
> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall6.S 2017-08-20 03:02:17.294755273 +0100
> @@ -0,0 +1,33 @@
Same as before.
> +/* Copyright (C) 2017 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, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#include <sysdep.h>
> +#include <sys/asm.h>
> +
> + .text
> + .set nomips16
> +
> +/* long long __mips_syscall6 (long arg1, long arg2, long arg3, long arg4,
> + long arg5, long arg6,
> + long number) */
> +
> +ENTRY(__mips_syscall6)
> + lw v0, 24(sp)
> + syscall
> + move v1, a3
> + jr ra
> +END(__mips_syscall6)
> Index: glibc/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall7.S
> ===================================================================
> --- /dev/null 1970-01-01 00:00:00.000000000 +0000
> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall7.S 2017-08-20 03:02:20.617120331 +0100
> @@ -0,0 +1,33 @@
Same as before.
> +/* Copyright (C) 2017 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, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#include <sysdep.h>
> +#include <sys/asm.h>
> +
> + .text
> + .set nomips16
> +
> +/* long long __mips_syscall7 (long arg1, long arg2, long arg3, long arg4,
> + long arg5, long arg6, long arg7,
> + long number) */
> +
> +ENTRY(__mips_syscall7)
> + lw v0, 28(sp)
> + syscall
> + move v1, a3
> + jr ra
> +END(__mips_syscall7)
> Index: glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/Makefile
> ===================================================================
> --- glibc.orig/sysdeps/unix/sysv/linux/mips/mips32/mips16/Makefile 2017-08-20 01:30:23.490163141 +0100
> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/Makefile 2017-08-20 01:34:46.819433661 +0100
> @@ -1,13 +1,9 @@
> ifeq ($(subdir),misc)
> sysdep_routines += mips16-syscall0 mips16-syscall1 mips16-syscall2
> -sysdep_routines += mips16-syscall3 mips16-syscall4 mips16-syscall5
> -sysdep_routines += mips16-syscall6 mips16-syscall7
> +sysdep_routines += mips16-syscall3 mips16-syscall4
> CFLAGS-mips16-syscall0.c += -fexceptions
> CFLAGS-mips16-syscall1.c += -fexceptions
> CFLAGS-mips16-syscall2.c += -fexceptions
> CFLAGS-mips16-syscall3.c += -fexceptions
> CFLAGS-mips16-syscall4.c += -fexceptions
> -CFLAGS-mips16-syscall5.c += -fexceptions
> -CFLAGS-mips16-syscall6.c += -fexceptions
> -CFLAGS-mips16-syscall7.c += -fexceptions
> endif
> Index: glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/Versions
> ===================================================================
> --- glibc.orig/sysdeps/unix/sysv/linux/mips/mips32/mips16/Versions 2017-08-20 01:30:23.494195070 +0100
> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/Versions 2017-08-20 01:34:46.830600751 +0100
> @@ -1,6 +1,6 @@
> libc {
> GLIBC_PRIVATE {
> __mips16_syscall0; __mips16_syscall1; __mips16_syscall2; __mips16_syscall3;
> - __mips16_syscall4; __mips16_syscall5; __mips16_syscall6; __mips16_syscall7;
> + __mips16_syscall4;
> }
> }
> Index: glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h
> ===================================================================
> --- glibc.orig/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h 2017-08-20 01:30:23.505269052 +0100
> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h 2017-08-20 01:34:46.845845282 +0100
> @@ -19,19 +19,6 @@
> #ifndef MIPS16_SYSCALL_H
> #define MIPS16_SYSCALL_H 1
>
> -#define __nomips16 __attribute__ ((nomips16))
> -
> -union __mips16_syscall_return
> - {
> - long long val;
> - struct
> - {
> - long v0;
> - long v1;
> - }
> - reg;
> - };
> -
> long long __nomips16 __mips16_syscall0 (long number);
> #define __mips16_syscall0(dummy, number) \
> __mips16_syscall0 ((long) (number))
> @@ -61,29 +48,22 @@ long long __nomips16 __mips16_syscall4 (
> (long) (a3), \
> (long) (number))
>
> -long long __nomips16 __mips16_syscall5 (long a0, long a1, long a2, long a3,
> - long a4,
> - long number);
> +/* The remaining ones use regular MIPS wrappers. */
> +
> #define __mips16_syscall5(a0, a1, a2, a3, a4, number) \
> - __mips16_syscall5 ((long) (a0), (long) (a1), (long) (a2), \
> - (long) (a3), (long) (a4), \
> - (long) (number))
> + __mips_syscall5 ((long) (a0), (long) (a1), (long) (a2), \
> + (long) (a3), (long) (a4), \
> + (long) (number))
>
> -long long __nomips16 __mips16_syscall6 (long a0, long a1, long a2, long a3,
> - long a4, long a5,
> - long number);
> #define __mips16_syscall6(a0, a1, a2, a3, a4, a5, number) \
> - __mips16_syscall6 ((long) (a0), (long) (a1), (long) (a2), \
> - (long) (a3), (long) (a4), (long) (a5), \
> - (long) (number))
> + __mips_syscall6 ((long) (a0), (long) (a1), (long) (a2), \
> + (long) (a3), (long) (a4), (long) (a5), \
> + (long) (number))
>
> -long long __nomips16 __mips16_syscall7 (long a0, long a1, long a2, long a3,
> - long a4, long a5, long a6,
> - long number);
> #define __mips16_syscall7(a0, a1, a2, a3, a4, a5, a6, number) \
> - __mips16_syscall7 ((long) (a0), (long) (a1), (long) (a2), \
> - (long) (a3), (long) (a4), (long) (a5), \
> - (long) (a6), \
> - (long) (number))
> + __mips_syscall7 ((long) (a0), (long) (a1), (long) (a2), \
> + (long) (a3), (long) (a4), (long) (a5), \
> + (long) (a6), \
> + (long) (number))
>
> #endif
> Index: glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall0.c
> ===================================================================
> --- glibc.orig/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall0.c 2017-08-20 01:30:23.564450375 +0100
> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall0.c 2017-08-20 01:34:46.849881768 +0100
> @@ -17,14 +17,13 @@
> <http://www.gnu.org/licenses/>. */
>
> #include <sysdep.h>
> -#include <mips16-syscall.h>
>
> #undef __mips16_syscall0
>
> long long __nomips16
> __mips16_syscall0 (long number)
> {
> - union __mips16_syscall_return ret;
> + union __mips_syscall_return ret;
> ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 0);
> return ret.val;
> }
> Index: glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall1.c
> ===================================================================
> --- glibc.orig/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall1.c 2017-08-20 01:30:23.568506526 +0100
> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall1.c 2017-08-20 01:34:46.860061453 +0100
> @@ -17,7 +17,6 @@
> <http://www.gnu.org/licenses/>. */
>
> #include <sysdep.h>
> -#include <mips16-syscall.h>
>
> #undef __mips16_syscall1
>
> @@ -25,7 +24,7 @@ long long __nomips16
> __mips16_syscall1 (long a0,
> long number)
> {
> - union __mips16_syscall_return ret;
> + union __mips_syscall_return ret;
> ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 1,
> a0);
> return ret.val;
> Index: glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall2.c
> ===================================================================
> --- glibc.orig/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall2.c 2017-08-20 01:30:23.578642154 +0100
> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall2.c 2017-08-20 01:34:46.865155941 +0100
> @@ -17,7 +17,6 @@
> <http://www.gnu.org/licenses/>. */
>
> #include <sysdep.h>
> -#include <mips16-syscall.h>
>
> #undef __mips16_syscall2
>
> @@ -25,7 +24,7 @@ long long __nomips16
> __mips16_syscall2 (long a0, long a1,
> long number)
> {
> - union __mips16_syscall_return ret;
> + union __mips_syscall_return ret;
> ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 2,
> a0, a1);
> return ret.val;
> Index: glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall3.c
> ===================================================================
> --- glibc.orig/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall3.c 2017-08-20 01:30:23.582725033 +0100
> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall3.c 2017-08-20 01:34:46.873273352 +0100
> @@ -17,7 +17,6 @@
> <http://www.gnu.org/licenses/>. */
>
> #include <sysdep.h>
> -#include <mips16-syscall.h>
>
> #undef __mips16_syscall3
>
> @@ -25,7 +24,7 @@ long long __nomips16
> __mips16_syscall3 (long a0, long a1, long a2,
> long number)
> {
> - union __mips16_syscall_return ret;
> + union __mips_syscall_return ret;
> ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 3,
> a0, a1, a2);
> return ret.val;
> Index: glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall4.c
> ===================================================================
> --- glibc.orig/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall4.c 2017-08-20 01:30:23.591846747 +0100
> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall4.c 2017-08-20 01:34:46.894612901 +0100
> @@ -17,7 +17,6 @@
> <http://www.gnu.org/licenses/>. */
>
> #include <sysdep.h>
> -#include <mips16-syscall.h>
>
> #undef __mips16_syscall4
>
> @@ -25,7 +24,7 @@ long long __nomips16
> __mips16_syscall4 (long a0, long a1, long a2, long a3,
> long number)
> {
> - union __mips16_syscall_return ret;
> + union __mips_syscall_return ret;
> ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 4,
> a0, a1, a2, a3);
> return ret.val;
> Index: glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall5.c
> ===================================================================
> --- glibc.orig/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall5.c 2017-08-20 01:30:23.522504662 +0100
> +++ /dev/null 1970-01-01 00:00:00.000000000 +0000
> @@ -1,33 +0,0 @@
> -/* MIPS16 syscall wrappers.
> - Copyright (C) 2013-2017 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, see
> - <http://www.gnu.org/licenses/>. */
> -
> -#include <sysdep.h>
> -#include <mips16-syscall.h>
> -
> -#undef __mips16_syscall5
> -
> -long long __nomips16
> -__mips16_syscall5 (long a0, long a1, long a2, long a3,
> - long a4,
> - long number)
> -{
> - union __mips16_syscall_return ret;
> - ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 5,
> - a0, a1, a2, a3, a4);
> - return ret.val;
> -}
> Index: glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall6.c
> ===================================================================
> --- glibc.orig/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall6.c 2017-08-20 01:30:23.536931914 +0100
> +++ /dev/null 1970-01-01 00:00:00.000000000 +0000
> @@ -1,33 +0,0 @@
> -/* MIPS16 syscall wrappers.
> - Copyright (C) 2013-2017 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, see
> - <http://www.gnu.org/licenses/>. */
> -
> -#include <sysdep.h>
> -#include <mips16-syscall.h>
> -
> -#undef __mips16_syscall6
> -
> -long long __nomips16
> -__mips16_syscall6 (long a0, long a1, long a2, long a3,
> - long a4, long a5,
> - long number)
> -{
> - union __mips16_syscall_return ret;
> - ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 6,
> - a0, a1, a2, a3, a4, a5);
> - return ret.val;
> -}
> Index: glibc/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall7.c
> ===================================================================
> --- glibc.orig/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall7.c 2017-08-20 01:30:23.546046859 +0100
> +++ /dev/null 1970-01-01 00:00:00.000000000 +0000
> @@ -1,33 +0,0 @@
> -/* MIPS16 syscall wrappers.
> - Copyright (C) 2013-2017 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, see
> - <http://www.gnu.org/licenses/>. */
> -
> -#include <sysdep.h>
> -#include <mips16-syscall.h>
> -
> -#undef __mips16_syscall7
> -
> -long long __nomips16
> -__mips16_syscall7 (long a0, long a1, long a2, long a3,
> - long a4, long a5, long a6,
> - long number)
> -{
> - union __mips16_syscall_return ret;
> - ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 7,
> - a0, a1, a2, a3, a4, a5, a6);
> - return ret.val;
> -}
> Index: glibc/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h
> ===================================================================
> --- glibc.orig/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h 2017-08-20 01:30:23.602967356 +0100
> +++ glibc/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h 2017-08-20 14:15:03.369838111 +0100
> @@ -98,6 +98,19 @@
> #undef INTERNAL_SYSCALL
> #undef INTERNAL_SYSCALL_NCS
>
> +#define __nomips16 __attribute__ ((nomips16))
> +
> +union __mips_syscall_return
> + {
> + long long val;
> + struct
> + {
> + long v0;
> + long v1;
> + }
> + reg;
> + };
> +
> #ifdef __mips16
> /* There's no MIPS16 syscall instruction, so we go through out-of-line
> standard MIPS wrappers. These do use inline snippets below though,
> @@ -112,7 +125,7 @@
>
> # define INTERNAL_SYSCALL_NCS(number, err, nr, args...) \
> ({ \
> - union __mips16_syscall_return _sc_ret; \
> + union __mips_syscall_return _sc_ret; \
> _sc_ret.val = __mips16_syscall##nr (args, number); \
> err = _sc_ret.reg.v1; \
> _sc_ret.reg.v0; \
> @@ -121,13 +134,13 @@
> # define INTERNAL_SYSCALL_MIPS16(number, err, nr, args...) \
> internal_syscall##nr ("lw\t%0, %2\n\t", \
> "R" (number), \
> - 0, err, args)
> + number, err, args)
>
> #else /* !__mips16 */
> # define INTERNAL_SYSCALL(name, err, nr, args...) \
> internal_syscall##nr ("li\t%0, %2\t\t\t# " #name "\n\t", \
> "IK" (SYS_ify (name)), \
> - 0, err, args)
> + SYS_ify (name), err, args)
>
> # define INTERNAL_SYSCALL_NCS(number, err, nr, args...) \
> internal_syscall##nr (MOVE32 "\t%0, %2\n\t", \
> @@ -262,110 +275,65 @@
> _sys_result; \
> })
>
> -/* We need to use a frame pointer for the functions in which we
> - adjust $sp around the syscall, or debug information and unwind
> - information will be $sp relative and thus wrong during the syscall. As
> - of GCC 4.7, this is sufficient. */
> -#define FORCE_FRAME_POINTER \
> - void *volatile __fp_force __attribute__ ((unused)) = alloca (4)
> +/* Out-of-line standard MIPS wrappers used for 5, 6, and 7 argument
> + syscalls, which require stack arguments. */
I think it is worth to add a comment why we are using out-of-line wrappers
for syscalls with 5, 6, and 7 arguments.
> +
> +long long __nomips16 __mips_syscall5 (long arg1, long arg2, long arg3,
> + long arg4, long arg5,
> + long number)
>
> #define internal_syscall5(v0_init, input, number, err, \
> arg1, arg2, arg3, arg4, arg5) \
> ({ \
> - long _sys_result; \
> - \
> - FORCE_FRAME_POINTER; \
> - { \
> - register long __s0 asm ("$16") __attribute__ ((unused)) \
> - = (number); \
> - 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" \
> - "subu\t$29, 32\n\t" \
> - "sw\t%6, 16($29)\n\t" \
> - v0_init \
> - "syscall\n\t" \
> - "addiu\t$29, 32\n\t" \
> - ".set\treorder" \
> - : "=r" (__v0), "+r" (__a3) \
> - : input, "r" (__a0), "r" (__a1), "r" (__a2), \
> - "r" ((long) (arg5)) \
> - : __SYSCALL_CLOBBERS); \
> - err = __a3; \
> - _sys_result = __v0; \
> - } \
> - _sys_result; \
> + union __mips_syscall_return _sc_ret; \
> + _sc_ret.val = __mips_syscall5 ((long) (arg1), \
> + (long) (arg2), \
> + (long) (arg3), \
> + (long) (arg4), \
> + (long) (arg5), \
> + (long) (number)); \
> + err = _sc_ret.reg.v1; \
> + _sc_ret.reg.v0; \
> })
>
> +long long __nomips16 __mips_syscall6 (long arg1, long arg2, long arg3,
> + long arg4, long arg5, long arg6,
> + long number);
> +
> #define internal_syscall6(v0_init, input, number, err, \
> arg1, arg2, arg3, arg4, arg5, arg6) \
> ({ \
> - long _sys_result; \
> - \
> - FORCE_FRAME_POINTER; \
> - { \
> - register long __s0 asm ("$16") __attribute__ ((unused)) \
> - = (number); \
> - 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" \
> - "subu\t$29, 32\n\t" \
> - "sw\t%6, 16($29)\n\t" \
> - "sw\t%7, 20($29)\n\t" \
> - v0_init \
> - "syscall\n\t" \
> - "addiu\t$29, 32\n\t" \
> - ".set\treorder" \
> - : "=r" (__v0), "+r" (__a3) \
> - : input, "r" (__a0), "r" (__a1), "r" (__a2), \
> - "r" ((long) (arg5)), "r" ((long) (arg6)) \
> - : __SYSCALL_CLOBBERS); \
> - err = __a3; \
> - _sys_result = __v0; \
> - } \
> - _sys_result; \
> + union __mips_syscall_return _sc_ret; \
> + _sc_ret.val = __mips_syscall6 ((long) (arg1), \
> + (long) (arg2), \
> + (long) (arg3), \
> + (long) (arg4), \
> + (long) (arg5), \
> + (long) (arg6), \
> + (long) (number)); \
> + err = _sc_ret.reg.v1; \
> + _sc_ret.reg.v0; \
> })
>
> +long long __nomips16 __mips_syscall7 (long arg1, long arg2, long arg3,
> + long arg4, long arg5, long arg6,
> + long arg7,
> + long number);
> +
> #define internal_syscall7(v0_init, input, number, err, \
> arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
> ({ \
> - long _sys_result; \
> - \
> - FORCE_FRAME_POINTER; \
> - { \
> - register long __s0 asm ("$16") __attribute__ ((unused)) \
> - = (number); \
> - 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" \
> - "subu\t$29, 32\n\t" \
> - "sw\t%6, 16($29)\n\t" \
> - "sw\t%7, 20($29)\n\t" \
> - "sw\t%8, 24($29)\n\t" \
> - v0_init \
> - "syscall\n\t" \
> - "addiu\t$29, 32\n\t" \
> - ".set\treorder" \
> - : "=r" (__v0), "+r" (__a3) \
> - : input, "r" (__a0), "r" (__a1), "r" (__a2), \
> - "r" ((long) (arg5)), "r" ((long) (arg6)), "r" ((long) (arg7)) \
> - : __SYSCALL_CLOBBERS); \
> - err = __a3; \
> - _sys_result = __v0; \
> - } \
> - _sys_result; \
> + union __mips_syscall_return _sc_ret; \
> + _sc_ret.val = __mips_syscall7 ((long) (arg1), \
> + (long) (arg2), \
> + (long) (arg3), \
> + (long) (arg4), \
> + (long) (arg5), \
> + (long) (arg6), \
> + (long) (arg7), \
> + (long) (number)); \
> + err = _sc_ret.reg.v1; \
> + _sc_ret.reg.v0; \
> })
>
> #define __SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", \
>
On 2017-08-21 11:48, Maciej W. Rozycki wrote:
> On Sat, 19 Aug 2017, Aurelien Jarno wrote:
> > > The MIPS16 wrappers were split into individual files so that only ones
> > > that are actually used by `ld.so' are pulled. I think it would be good if
> > > we preserved that. I'll see if I can experiment with keeping the original
> > > MIPS16 0-3 wrappers.
> >
> > For what I have seen, ld.so already uses syscalls with 1 to 4 arguments.
> > It doesn't use any syscall without argument though. So it's only 4
> > instructions overhead.
>
> Why make things worse where they don't have to be and there's no benefit
> elsewhere that would balance the regression?
>
> Here's what I had in mind. The key was updating the macros appropriately
> in sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h. Beyond
> that I made a number of clean-ups:
>
> 1. I renamed `__libc_do_syscall?' to `__mips_syscall?', for consistency
> with `__mips16_syscall?', and consequently `__libc_do_syscall_return'
> to `__mips_syscall_return'.
>
> 2. I exported `__mips_syscall?' wrappers from `libc.so' rather than making
> them hidden. This is also consistent with `__mips16_syscall?' wrappers
> and reduces code duplication of doubtful benefit -- it could be that
> some calls, if internal, could be subject to the JALR->BAL
> optimisation, however only those that are in range and only in regular
> MIPS code, for a minimal execution time saving on some processors only.
> Exporting these entries makes the maintenance effort much easier
> though, as we don't have to track and record their use in the
> individual subdirectories in Makefile.
>
> 3. I renamed `_sys_result' to `_sc_ret' where it is declared as `union
> __mips_syscall_return', again for clarity and consistency with MIPS16
> INTERNAL_SYSCALL_NCS.
>
> 4. I wrapped `number' in parentheses in `internal_syscall5',
> `internal_syscall6' and `internal_syscall7', and cast it to `long'.
>
> 5. I have adjusted some comments.
>
> Please let me know if you have any questions or concerns about this
> update.
>
> This passes o32 regular MIPS regression testing, however my GCC 8 binary
> seems to miscompile support_test_main.c in the MIPS16 mode, causing all
> the relevant test cases to crash with SIGILL (in the `support_set_test_dir
> (test_dir)' invocation it's `test_dir' that is jumped to rather than
> `support_set_test_dir'; I'll file a bug separately). I'll find a way to
> run MIPS16 testing eventually, however meanwhile I will appreciate if you
> do it for me.
Thanks, this looks fine for me. I don't have more comments than the ones
already done by Adhemerval. I have tested it on MIPS O32 BE and LE, I
don't see any regression.
I can do a test build for MIPS16 and run basic testing under QEMU, but I
don't have the hardware to do more.
Aurelien
On Tue, 22 Aug 2017, Aurelien Jarno wrote:
> > This passes o32 regular MIPS regression testing, however my GCC 8 binary
> > seems to miscompile support_test_main.c in the MIPS16 mode, causing all
> > the relevant test cases to crash with SIGILL (in the `support_set_test_dir
> > (test_dir)' invocation it's `test_dir' that is jumped to rather than
> > `support_set_test_dir'; I'll file a bug separately). I'll find a way to
> > run MIPS16 testing eventually, however meanwhile I will appreciate if you
> > do it for me.
>
> Thanks, this looks fine for me. I don't have more comments than the ones
> already done by Adhemerval. I have tested it on MIPS O32 BE and LE, I
> don't see any regression.
Great, thanks! I'll yet make the adjustments Adhemerval suggested.
> I can do a test build for MIPS16 and run basic testing under QEMU, but I
> don't have the hardware to do more.
Thanks. I have now identified the cause of my code generation problem
(it was actually a register encoding bug in LD relaxation I have
implemented in preparation to handle PR ld/21375, and which I thought I
had removed from the binutils build used for this verification), so I will
be able to run MIPS16 testing myself once I have the updated patch ready.
Maciej
On Mon, 21 Aug 2017, Maciej W. Rozycki wrote:
> Thanks. There's indeed a bug in GAS, a MIPS16 path of execution has been
> missed in the handling of this option. I have a preliminary fix, however
> I yet have to prepare test suite cases (originally the option was
> mistakenly only covered by regular MIPS and microMIPS testing, which is
> clearly why the MIPS16 case has been missed). I expect this fix to be
> included in the upcoming 2.29.1 release, and also backported to 2.28
> (although no new 2.28 release is scheduled).
The fix has passed QA and has now been applied as commit 278fcf38584d
("MIPS/GAS: Also respect `-mignore-branch-isa' with MIPS16 code") to
master, and backported to 2.29 and 2.28. A binutils 2.29.1 release is
scheduled mid September.
Maciej
On 2017-08-30 16:35, Maciej W. Rozycki wrote:
> On Mon, 21 Aug 2017, Maciej W. Rozycki wrote:
>
> > Thanks. There's indeed a bug in GAS, a MIPS16 path of execution has been
> > missed in the handling of this option. I have a preliminary fix, however
> > I yet have to prepare test suite cases (originally the option was
> > mistakenly only covered by regular MIPS and microMIPS testing, which is
> > clearly why the MIPS16 case has been missed). I expect this fix to be
> > included in the upcoming 2.29.1 release, and also backported to 2.28
> > (although no new 2.28 release is scheduled).
>
> The fix has passed QA and has now been applied as commit 278fcf38584d
> ("MIPS/GAS: Also respect `-mignore-branch-isa' with MIPS16 code") to
> master, and backported to 2.29 and 2.28. A binutils 2.29.1 release is
> scheduled mid September.
Thanks!
===================================================================
@@ -3,6 +3,10 @@ ifeq ($(subdir),conform)
conformtest-xfail-conds += mips-o32-linux
endif
+ifeq ($(subdir),misc)
+sysdep_routines += mips-syscall5 mips-syscall6 mips-syscall7
+endif
+
ifeq ($(subdir),stdlib)
tests += bug-getcontext-mips-gp
endif
===================================================================
@@ -3,4 +3,7 @@ libc {
getrlimit64;
setrlimit64;
}
+ GLIBC_PRIVATE {
+ __mips_syscall5; __mips_syscall6; __mips_syscall7;
+ }
}
===================================================================
@@ -0,0 +1,33 @@
+/* Copyright (C) 2017 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include <sys/asm.h>
+
+ .text
+ .set nomips16
+
+/* long long __mips_syscall5 (long arg1, long arg2, long arg3, long arg4,
+ long arg5,
+ long number) */
+
+ENTRY(__mips_syscall5)
+ lw v0, 20(sp)
+ syscall
+ move v1, a3
+ jr ra
+END(__mips_syscall5)
===================================================================
@@ -0,0 +1,33 @@
+/* Copyright (C) 2017 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include <sys/asm.h>
+
+ .text
+ .set nomips16
+
+/* long long __mips_syscall6 (long arg1, long arg2, long arg3, long arg4,
+ long arg5, long arg6,
+ long number) */
+
+ENTRY(__mips_syscall6)
+ lw v0, 24(sp)
+ syscall
+ move v1, a3
+ jr ra
+END(__mips_syscall6)
===================================================================
@@ -0,0 +1,33 @@
+/* Copyright (C) 2017 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include <sys/asm.h>
+
+ .text
+ .set nomips16
+
+/* long long __mips_syscall7 (long arg1, long arg2, long arg3, long arg4,
+ long arg5, long arg6, long arg7,
+ long number) */
+
+ENTRY(__mips_syscall7)
+ lw v0, 28(sp)
+ syscall
+ move v1, a3
+ jr ra
+END(__mips_syscall7)
===================================================================
@@ -1,13 +1,9 @@
ifeq ($(subdir),misc)
sysdep_routines += mips16-syscall0 mips16-syscall1 mips16-syscall2
-sysdep_routines += mips16-syscall3 mips16-syscall4 mips16-syscall5
-sysdep_routines += mips16-syscall6 mips16-syscall7
+sysdep_routines += mips16-syscall3 mips16-syscall4
CFLAGS-mips16-syscall0.c += -fexceptions
CFLAGS-mips16-syscall1.c += -fexceptions
CFLAGS-mips16-syscall2.c += -fexceptions
CFLAGS-mips16-syscall3.c += -fexceptions
CFLAGS-mips16-syscall4.c += -fexceptions
-CFLAGS-mips16-syscall5.c += -fexceptions
-CFLAGS-mips16-syscall6.c += -fexceptions
-CFLAGS-mips16-syscall7.c += -fexceptions
endif
===================================================================
@@ -1,6 +1,6 @@
libc {
GLIBC_PRIVATE {
__mips16_syscall0; __mips16_syscall1; __mips16_syscall2; __mips16_syscall3;
- __mips16_syscall4; __mips16_syscall5; __mips16_syscall6; __mips16_syscall7;
+ __mips16_syscall4;
}
}
===================================================================
@@ -19,19 +19,6 @@
#ifndef MIPS16_SYSCALL_H
#define MIPS16_SYSCALL_H 1
-#define __nomips16 __attribute__ ((nomips16))
-
-union __mips16_syscall_return
- {
- long long val;
- struct
- {
- long v0;
- long v1;
- }
- reg;
- };
-
long long __nomips16 __mips16_syscall0 (long number);
#define __mips16_syscall0(dummy, number) \
__mips16_syscall0 ((long) (number))
@@ -61,29 +48,22 @@ long long __nomips16 __mips16_syscall4 (
(long) (a3), \
(long) (number))
-long long __nomips16 __mips16_syscall5 (long a0, long a1, long a2, long a3,
- long a4,
- long number);
+/* The remaining ones use regular MIPS wrappers. */
+
#define __mips16_syscall5(a0, a1, a2, a3, a4, number) \
- __mips16_syscall5 ((long) (a0), (long) (a1), (long) (a2), \
- (long) (a3), (long) (a4), \
- (long) (number))
+ __mips_syscall5 ((long) (a0), (long) (a1), (long) (a2), \
+ (long) (a3), (long) (a4), \
+ (long) (number))
-long long __nomips16 __mips16_syscall6 (long a0, long a1, long a2, long a3,
- long a4, long a5,
- long number);
#define __mips16_syscall6(a0, a1, a2, a3, a4, a5, number) \
- __mips16_syscall6 ((long) (a0), (long) (a1), (long) (a2), \
- (long) (a3), (long) (a4), (long) (a5), \
- (long) (number))
+ __mips_syscall6 ((long) (a0), (long) (a1), (long) (a2), \
+ (long) (a3), (long) (a4), (long) (a5), \
+ (long) (number))
-long long __nomips16 __mips16_syscall7 (long a0, long a1, long a2, long a3,
- long a4, long a5, long a6,
- long number);
#define __mips16_syscall7(a0, a1, a2, a3, a4, a5, a6, number) \
- __mips16_syscall7 ((long) (a0), (long) (a1), (long) (a2), \
- (long) (a3), (long) (a4), (long) (a5), \
- (long) (a6), \
- (long) (number))
+ __mips_syscall7 ((long) (a0), (long) (a1), (long) (a2), \
+ (long) (a3), (long) (a4), (long) (a5), \
+ (long) (a6), \
+ (long) (number))
#endif
===================================================================
@@ -17,14 +17,13 @@
<http://www.gnu.org/licenses/>. */
#include <sysdep.h>
-#include <mips16-syscall.h>
#undef __mips16_syscall0
long long __nomips16
__mips16_syscall0 (long number)
{
- union __mips16_syscall_return ret;
+ union __mips_syscall_return ret;
ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 0);
return ret.val;
}
===================================================================
@@ -17,7 +17,6 @@
<http://www.gnu.org/licenses/>. */
#include <sysdep.h>
-#include <mips16-syscall.h>
#undef __mips16_syscall1
@@ -25,7 +24,7 @@ long long __nomips16
__mips16_syscall1 (long a0,
long number)
{
- union __mips16_syscall_return ret;
+ union __mips_syscall_return ret;
ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 1,
a0);
return ret.val;
===================================================================
@@ -17,7 +17,6 @@
<http://www.gnu.org/licenses/>. */
#include <sysdep.h>
-#include <mips16-syscall.h>
#undef __mips16_syscall2
@@ -25,7 +24,7 @@ long long __nomips16
__mips16_syscall2 (long a0, long a1,
long number)
{
- union __mips16_syscall_return ret;
+ union __mips_syscall_return ret;
ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 2,
a0, a1);
return ret.val;
===================================================================
@@ -17,7 +17,6 @@
<http://www.gnu.org/licenses/>. */
#include <sysdep.h>
-#include <mips16-syscall.h>
#undef __mips16_syscall3
@@ -25,7 +24,7 @@ long long __nomips16
__mips16_syscall3 (long a0, long a1, long a2,
long number)
{
- union __mips16_syscall_return ret;
+ union __mips_syscall_return ret;
ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 3,
a0, a1, a2);
return ret.val;
===================================================================
@@ -17,7 +17,6 @@
<http://www.gnu.org/licenses/>. */
#include <sysdep.h>
-#include <mips16-syscall.h>
#undef __mips16_syscall4
@@ -25,7 +24,7 @@ long long __nomips16
__mips16_syscall4 (long a0, long a1, long a2, long a3,
long number)
{
- union __mips16_syscall_return ret;
+ union __mips_syscall_return ret;
ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 4,
a0, a1, a2, a3);
return ret.val;
===================================================================
@@ -1,33 +0,0 @@
-/* MIPS16 syscall wrappers.
- Copyright (C) 2013-2017 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, see
- <http://www.gnu.org/licenses/>. */
-
-#include <sysdep.h>
-#include <mips16-syscall.h>
-
-#undef __mips16_syscall5
-
-long long __nomips16
-__mips16_syscall5 (long a0, long a1, long a2, long a3,
- long a4,
- long number)
-{
- union __mips16_syscall_return ret;
- ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 5,
- a0, a1, a2, a3, a4);
- return ret.val;
-}
===================================================================
@@ -1,33 +0,0 @@
-/* MIPS16 syscall wrappers.
- Copyright (C) 2013-2017 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, see
- <http://www.gnu.org/licenses/>. */
-
-#include <sysdep.h>
-#include <mips16-syscall.h>
-
-#undef __mips16_syscall6
-
-long long __nomips16
-__mips16_syscall6 (long a0, long a1, long a2, long a3,
- long a4, long a5,
- long number)
-{
- union __mips16_syscall_return ret;
- ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 6,
- a0, a1, a2, a3, a4, a5);
- return ret.val;
-}
===================================================================
@@ -1,33 +0,0 @@
-/* MIPS16 syscall wrappers.
- Copyright (C) 2013-2017 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, see
- <http://www.gnu.org/licenses/>. */
-
-#include <sysdep.h>
-#include <mips16-syscall.h>
-
-#undef __mips16_syscall7
-
-long long __nomips16
-__mips16_syscall7 (long a0, long a1, long a2, long a3,
- long a4, long a5, long a6,
- long number)
-{
- union __mips16_syscall_return ret;
- ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 7,
- a0, a1, a2, a3, a4, a5, a6);
- return ret.val;
-}
===================================================================
@@ -98,6 +98,19 @@
#undef INTERNAL_SYSCALL
#undef INTERNAL_SYSCALL_NCS
+#define __nomips16 __attribute__ ((nomips16))
+
+union __mips_syscall_return
+ {
+ long long val;
+ struct
+ {
+ long v0;
+ long v1;
+ }
+ reg;
+ };
+
#ifdef __mips16
/* There's no MIPS16 syscall instruction, so we go through out-of-line
standard MIPS wrappers. These do use inline snippets below though,
@@ -112,7 +125,7 @@
# define INTERNAL_SYSCALL_NCS(number, err, nr, args...) \
({ \
- union __mips16_syscall_return _sc_ret; \
+ union __mips_syscall_return _sc_ret; \
_sc_ret.val = __mips16_syscall##nr (args, number); \
err = _sc_ret.reg.v1; \
_sc_ret.reg.v0; \
@@ -121,13 +134,13 @@
# define INTERNAL_SYSCALL_MIPS16(number, err, nr, args...) \
internal_syscall##nr ("lw\t%0, %2\n\t", \
"R" (number), \
- 0, err, args)
+ number, err, args)
#else /* !__mips16 */
# define INTERNAL_SYSCALL(name, err, nr, args...) \
internal_syscall##nr ("li\t%0, %2\t\t\t# " #name "\n\t", \
"IK" (SYS_ify (name)), \
- 0, err, args)
+ SYS_ify (name), err, args)
# define INTERNAL_SYSCALL_NCS(number, err, nr, args...) \
internal_syscall##nr (MOVE32 "\t%0, %2\n\t", \
@@ -262,110 +275,65 @@
_sys_result; \
})
-/* We need to use a frame pointer for the functions in which we
- adjust $sp around the syscall, or debug information and unwind
- information will be $sp relative and thus wrong during the syscall. As
- of GCC 4.7, this is sufficient. */
-#define FORCE_FRAME_POINTER \
- void *volatile __fp_force __attribute__ ((unused)) = alloca (4)
+/* Out-of-line standard MIPS wrappers used for 5, 6, and 7 argument
+ syscalls, which require stack arguments. */
+
+long long __nomips16 __mips_syscall5 (long arg1, long arg2, long arg3,
+ long arg4, long arg5,
+ long number);
#define internal_syscall5(v0_init, input, number, err, \
arg1, arg2, arg3, arg4, arg5) \
({ \
- long _sys_result; \
- \
- FORCE_FRAME_POINTER; \
- { \
- register long __s0 asm ("$16") __attribute__ ((unused)) \
- = (number); \
- 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" \
- "subu\t$29, 32\n\t" \
- "sw\t%6, 16($29)\n\t" \
- v0_init \
- "syscall\n\t" \
- "addiu\t$29, 32\n\t" \
- ".set\treorder" \
- : "=r" (__v0), "+r" (__a3) \
- : input, "r" (__a0), "r" (__a1), "r" (__a2), \
- "r" ((long) (arg5)) \
- : __SYSCALL_CLOBBERS); \
- err = __a3; \
- _sys_result = __v0; \
- } \
- _sys_result; \
+ union __mips_syscall_return _sc_ret; \
+ _sc_ret.val = __mips_syscall5 ((long) (arg1), \
+ (long) (arg2), \
+ (long) (arg3), \
+ (long) (arg4), \
+ (long) (arg5), \
+ (long) (number)); \
+ err = _sc_ret.reg.v1; \
+ _sc_ret.reg.v0; \
})
+long long __nomips16 __mips_syscall6 (long arg1, long arg2, long arg3,
+ long arg4, long arg5, long arg6,
+ long number);
+
#define internal_syscall6(v0_init, input, number, err, \
arg1, arg2, arg3, arg4, arg5, arg6) \
({ \
- long _sys_result; \
- \
- FORCE_FRAME_POINTER; \
- { \
- register long __s0 asm ("$16") __attribute__ ((unused)) \
- = (number); \
- 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" \
- "subu\t$29, 32\n\t" \
- "sw\t%6, 16($29)\n\t" \
- "sw\t%7, 20($29)\n\t" \
- v0_init \
- "syscall\n\t" \
- "addiu\t$29, 32\n\t" \
- ".set\treorder" \
- : "=r" (__v0), "+r" (__a3) \
- : input, "r" (__a0), "r" (__a1), "r" (__a2), \
- "r" ((long) (arg5)), "r" ((long) (arg6)) \
- : __SYSCALL_CLOBBERS); \
- err = __a3; \
- _sys_result = __v0; \
- } \
- _sys_result; \
+ union __mips_syscall_return _sc_ret; \
+ _sc_ret.val = __mips_syscall6 ((long) (arg1), \
+ (long) (arg2), \
+ (long) (arg3), \
+ (long) (arg4), \
+ (long) (arg5), \
+ (long) (arg6), \
+ (long) (number)); \
+ err = _sc_ret.reg.v1; \
+ _sc_ret.reg.v0; \
})
+long long __nomips16 __mips_syscall7 (long arg1, long arg2, long arg3,
+ long arg4, long arg5, long arg6,
+ long arg7,
+ long number);
+
#define internal_syscall7(v0_init, input, number, err, \
arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
({ \
- long _sys_result; \
- \
- FORCE_FRAME_POINTER; \
- { \
- register long __s0 asm ("$16") __attribute__ ((unused)) \
- = (number); \
- 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" \
- "subu\t$29, 32\n\t" \
- "sw\t%6, 16($29)\n\t" \
- "sw\t%7, 20($29)\n\t" \
- "sw\t%8, 24($29)\n\t" \
- v0_init \
- "syscall\n\t" \
- "addiu\t$29, 32\n\t" \
- ".set\treorder" \
- : "=r" (__v0), "+r" (__a3) \
- : input, "r" (__a0), "r" (__a1), "r" (__a2), \
- "r" ((long) (arg5)), "r" ((long) (arg6)), "r" ((long) (arg7)) \
- : __SYSCALL_CLOBBERS); \
- err = __a3; \
- _sys_result = __v0; \
- } \
- _sys_result; \
+ union __mips_syscall_return _sc_ret; \
+ _sc_ret.val = __mips_syscall7 ((long) (arg1), \
+ (long) (arg2), \
+ (long) (arg3), \
+ (long) (arg4), \
+ (long) (arg5), \
+ (long) (arg6), \
+ (long) (arg7), \
+ (long) (number)); \
+ err = _sc_ret.reg.v1; \
+ _sc_ret.reg.v0; \
})
#define __SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", \