From patchwork Thu Aug 17 21:20:22 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aurelien Jarno X-Patchwork-Id: 802914 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-83410-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="gQ9y8YRm"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3xYJzK24dcz9t3B for ; Fri, 18 Aug 2017 07:20:45 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:from:to:cc:subject:message-id:references :mime-version:content-type:in-reply-to; q=dns; s=default; b=ZUBh sW60fFCRHzhWDszRIAc7utqxCh5O++U9UZLetaZSc7HW/8gv9hQmNr1+VDELi5Ae TJ3V36RcxCbEA683BRGsRMEqIOpaBzQqHWD/zhiyk8oZtRULS3J7kNNIaf5A7vRQ iQG3wzkteNkG5kK8Rv3XXYnZW6MC6pV3H+ApwTw= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:from:to:cc:subject:message-id:references :mime-version:content-type:in-reply-to; s=default; bh=Hu/0mBn1yr RDzR9z1Acm9yIJAls=; b=gQ9y8YRmbeRipjYffPcPQvksBoHRbZDPtmVlaKe3M3 rfCSxgAVTqtjDOJhzXJDk6sdyw1zXAwYs/sex01zXxmhR0lMxXo2yXcUQetgw2z8 1tQG54KQezUnWtkhpJdDoFknDTm9ZQazWgLYqGt+oKml74cyhCo/aNAjfigim9IO 4= Received: (qmail 86012 invoked by alias); 17 Aug 2017 21:20:38 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 85913 invoked by uid 89); 17 Aug 2017 21:20:34 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=7th X-HELO: hall.aurel32.net Date: Thu, 17 Aug 2017 23:20:22 +0200 From: Aurelien Jarno To: Adhemerval Zanella Cc: "Maciej W. Rozycki" , Joseph Myers , libc-alpha@sourceware.org Subject: Re: [PATCH] mips/o32: fix internal_syscall5/6/7 Message-ID: <20170817212022.nz6wv6d55xlvubez@aurel32.net> Mail-Followup-To: Adhemerval Zanella , "Maciej W. Rozycki" , Joseph Myers , libc-alpha@sourceware.org References: <20170815200812.6kmv554yfga2x4al@aurel32.net> <39ca6099-2a86-f5f4-30fe-e86bb4cd736b@linaro.org> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <39ca6099-2a86-f5f4-30fe-e86bb4cd736b@linaro.org> User-Agent: NeoMutt/20170609 (1.8.3) On 2017-08-17 18:09, Adhemerval Zanella wrote: > > > On 17/08/2017 17:34, Maciej W. Rozycki wrote: > > On Thu, 17 Aug 2017, Adhemerval Zanella wrote: > > > >> My point is I think we should aim for compiler optimization safeness > >> (to avoid code breakage over compiler defined default flags) and taking > >> as base current approach to *avoid* VLA on GLIBC I do not think it is > >> good approach to use it as a bridge to force GCC to generate the expected > >> code. > > > > You certainly have a point here overall, although I don't think a VLA > > whose size is always 0 really hurts. And we've used the approach with > > `alloca' since forever with no adverse effects until we added a place > > where the caller invokes the syscall wrapper in a loop. So I wouldn't > > necessarily call it an issue. Mind that this is target-specific code, so > > we can rely on a target-specific execution model rather than limiting > > ourselves to what generic ISO C guarantees. > > > > Aurelien's figures indicating a clear size reduction certainly count as a > > pro though. > > Joseph pointed out another advantage of avoid VLAs (building with > -Werror=alloca -Werror=vla). My main problem here is we are betting that > compiler won't mess with our assumptions and generate the desirable code > without trying to adhere what it is suppose to provide. Target generic > ISO C give us a better guarantee and any deviation indicates a possible > compiler issue, not otherwise (such this case). My another point is we > can optimize if required later if this is the case and imho this is hardly > the case here (at least for latency). > > If I understood correctly Aurelien's suggestion of returning err in v1 > is not ABI strictly so it will end up calling __libc_do_syscall with a > non-conformant ABI convention (similar to pipe implementation where requires > assembly specific implementation for a lot of architectures to get this > right). Again this is something I would really to avoid. > > > > >> I still thinking trying to optimize for 5/6/7 syscall argument is over > >> engineering in this *specific* case. As I put in my last message, > >> 5/6/7 argument syscalls are used for > >> > >> pread, pwrite, lseek, llseek, ppoll, posix_fadvice, posix_fallocate, > >> sync_file_range, fallocate, preadv, pwritev, preadv2, pwritev2, select, > >> pselect, mmap, readahead, epoll_pwait, splice, recvfrom, sendto, recvmmsg, > >> msgsnd, msgrcv, msgget, msgctl, semop, semget, semctl, semtimedop, shmat, > >> shmdt, shmget, and shmctl. > >> > >> Which are the one generated from C implementation (some are still auto > >> generated). The majority of them are blocking syscalls, so both context > >> switch plus the required work for syscall completion itself will taking > >> proportionally all the required time. So trying to squeeze some cycles > >> don't really pay off comparing to code maintainability (just all this > >> discussion of which C construct would be safe enough to generate the > >> correct stack spill plus the current issue should indicate we should > >> aim for correctness first). > > > > TBH, I find it questionable whether it's really the approach I proposed > > that requires more engineering (and long-term maintenance) effort rather > > than using a separate handwritten assembly-language call stub. Especially > > if a non-standard calling convention is used. > > IMHO I find the VLA suggestion more fragile in long term. > > > > > If everyone but me thinks there's a clear advantage in using such a > > handcoded stub though, then as I previously noted please adjust the > > affected MIPS16 stubs to avoid the extra indirection, i.e. you can call > > `__libc_do_syscall' directly from MIPS16 code as you'd do from regular > > MIPS or microMIPS code, as the lone reason for the existence of the MIPS16 > > stubs is the inexistence of a MIPS16 SYSCALL instruction. > > Ok, I will try to at least check it on qemu. If you have any points on how > correctly build a mips16 glibc it could be helpful. The patch below, based on Adhemerval's version should do it. The changes I have done: - return err through v1 instead of using a negative value - fix build of mips16-syscallX.c - route mips16 syscalls with 5 to 7th arguments through __libc_do_syscall I see no regression on mipsel o32. I have only lightly tested mips o32 (the testsuite is still running). I haven't been able to fully compile mips16 due to the following error compiling dl-tunables.c: /tmp/ccI2NMgJ.s: Assembler messages: /tmp/ccI2NMgJ.s:1376: Error: branch to a symbol in another ISA mode It doesn't seem to be related to my changes. Aurelien diff --git a/sysdeps/unix/sysv/linux/mips/mips32/Makefile b/sysdeps/unix/sysv/linux/mips/mips32/Makefile index 33b461500c..cbdf032c3a 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/Makefile +++ b/sysdeps/unix/sysv/linux/mips/mips32/Makefile @@ -1,8 +1,26 @@ +ifeq ($(subdir),elf) +sysdep-dl-routines += libc-do-syscall +endif + ifeq ($(subdir),conform) # For bugs 17786 and 21278. conformtest-xfail-conds += mips-o32-linux endif +ifeq ($(subdir),io) +sysdep_routines += libc-do-syscall +endif + +ifeq ($(subdir),nptl) +libpthread-sysdep_routines += libc-do-syscall +libpthread-shared-only-routines += libc-do-syscall +endif + +ifeq ($(subdir),rt) +librt-sysdep_routines += libc-do-syscall +librt-shared-only-routines += libc-do-syscall +endif + ifeq ($(subdir),stdlib) tests += bug-getcontext-mips-gp endif diff --git a/sysdeps/unix/sysv/linux/mips/mips32/libc-do-syscall.S b/sysdeps/unix/sysv/linux/mips/mips32/libc-do-syscall.S new file mode 100644 index 0000000000..c02f507008 --- /dev/null +++ b/sysdeps/unix/sysv/linux/mips/mips32/libc-do-syscall.S @@ -0,0 +1,52 @@ +/* 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 + . */ + +#include +#include +#include +#include + + +/* long int __libc_do_syscall (long int, ...) */ + +#define FRAMESZ 32 + + .text + .set nomips16 + .hidden __libc_do_syscall +ENTRY(__libc_do_syscall) + move v0, a0 + move a0, a1 + move a1, a2 + move a2, a3 + lw a3, 16(sp) + lw t0, 20(sp) + lw t1, 24(sp) + lw t2, 28(sp) + .set noreorder + PTR_SUBU sp, FRAMESZ + cfi_adjust_cfa_offset (FRAMESZ) + sw t0, 16(sp) + sw t1, 20(sp) + sw t2, 24(sp) + syscall + PTR_ADDU sp, FRAMESZ + cfi_adjust_cfa_offset (-FRAMESZ) + .set reorder + move v1, a3 +1: ret +END (__libc_do_syscall) diff --git a/sysdeps/unix/sysv/linux/mips/mips32/mips16/Makefile b/sysdeps/unix/sysv/linux/mips/mips32/mips16/Makefile index fa9fcb7e6f..6869bf4f7c 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/mips16/Makefile +++ b/sysdeps/unix/sysv/linux/mips/mips32/mips16/Makefile @@ -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 diff --git a/sysdeps/unix/sysv/linux/mips/mips32/mips16/Versions b/sysdeps/unix/sysv/linux/mips/mips32/mips16/Versions index 73bcfb566c..bb21747f44 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/mips16/Versions +++ b/sysdeps/unix/sysv/linux/mips/mips32/mips16/Versions @@ -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; } } diff --git a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h b/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h index 880e9908e8..60f856d248 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h +++ b/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h @@ -21,17 +21,6 @@ #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)) diff --git a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall0.c b/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall0.c index 490245b34e..b9f78e875f 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall0.c +++ b/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall0.c @@ -24,7 +24,7 @@ long long __nomips16 __mips16_syscall0 (long number) { - union __mips16_syscall_return ret; + union __libc_do_syscall_return ret; ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 0); return ret.val; } diff --git a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall1.c b/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall1.c index 3061e8accb..284ce712cc 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall1.c +++ b/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall1.c @@ -25,7 +25,7 @@ long long __nomips16 __mips16_syscall1 (long a0, long number) { - union __mips16_syscall_return ret; + union __libc_do_syscall_return ret; ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 1, a0); return ret.val; diff --git a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall2.c b/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall2.c index 440a4ed285..4e76329239 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall2.c +++ b/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall2.c @@ -25,7 +25,7 @@ long long __nomips16 __mips16_syscall2 (long a0, long a1, long number) { - union __mips16_syscall_return ret; + union __libc_do_syscall_return ret; ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 2, a0, a1); return ret.val; diff --git a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall3.c b/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall3.c index c3f83fc1f6..dbb31d2f20 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall3.c +++ b/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall3.c @@ -25,7 +25,7 @@ long long __nomips16 __mips16_syscall3 (long a0, long a1, long a2, long number) { - union __mips16_syscall_return ret; + union __libc_do_syscall_return ret; ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 3, a0, a1, a2); return ret.val; diff --git a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall4.c b/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall4.c index 496297d296..a5dade3b3f 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall4.c +++ b/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall4.c @@ -25,7 +25,7 @@ long long __nomips16 __mips16_syscall4 (long a0, long a1, long a2, long a3, long number) { - union __mips16_syscall_return ret; + union __libc_do_syscall_return ret; ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 4, a0, a1, a2, a3); return ret.val; diff --git a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall5.c b/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall5.c deleted file mode 100644 index ad265d88e2..0000000000 --- a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall5.c +++ /dev/null @@ -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 - . */ - -#include -#include - -#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; -} diff --git a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall6.c b/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall6.c deleted file mode 100644 index bfbd395ed3..0000000000 --- a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall6.c +++ /dev/null @@ -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 - . */ - -#include -#include - -#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; -} diff --git a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall7.c b/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall7.c deleted file mode 100644 index e1267616dc..0000000000 --- a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall7.c +++ /dev/null @@ -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 - . */ - -#include -#include - -#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; -} diff --git a/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h b/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h index e9e3ee7e82..8e55538a5c 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h +++ b/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h @@ -49,9 +49,9 @@ /* Define a macro which expands into the inline wrapper code for a system call. */ #undef INLINE_SYSCALL -#define INLINE_SYSCALL(name, nr, args...) \ +#define INLINE_SYSCALL(name, nr, ...) \ ({ INTERNAL_SYSCALL_DECL (_sc_err); \ - long result_var = INTERNAL_SYSCALL (name, _sc_err, nr, args); \ + long result_var = INTERNAL_SYSCALL (name, _sc_err, nr, ## __VA_ARGS__); \ if ( INTERNAL_SYSCALL_ERROR_P (result_var, _sc_err) ) \ { \ __set_errno (INTERNAL_SYSCALL_ERRNO (result_var, _sc_err)); \ @@ -98,6 +98,19 @@ #undef INTERNAL_SYSCALL #undef INTERNAL_SYSCALL_NCS +long long __attribute__ ((nomips16)) __libc_do_syscall (long int, ...) attribute_hidden; + +union __libc_do_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, @@ -107,13 +120,16 @@ # include -# define INTERNAL_SYSCALL(name, err, nr, args...) \ - INTERNAL_SYSCALL_NCS (SYS_ify (name), err, nr, args) +# define INTERNAL_SYSCALL(name, err, nr, ...) \ + INTERNAL_SYSCALL_NCS (SYS_ify (name), err, nr, ## __VA_ARGS__) -# define INTERNAL_SYSCALL_NCS(number, err, nr, args...) \ +# define INTERNAL_SYSCALL_NCS(number, err, nr, ...) \ ({ \ - union __mips16_syscall_return _sc_ret; \ - _sc_ret.val = __mips16_syscall##nr (args, number); \ + union __libc_do_syscall_return _sc_ret; \ + if (nr <= 4) \ + _sc_ret.val = __mips16_syscall##nr (__VA_ARGS__, number); \ + else \ + _sc_ret.val = __libc_do_syscall (number, ## __VA_ARGS__); \ err = _sc_ret.reg.v1; \ _sc_ret.reg.v0; \ }) @@ -121,13 +137,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", \ @@ -136,6 +152,7 @@ #endif /* !__mips16 */ + #define internal_syscall0(v0_init, input, number, err, dummy...) \ ({ \ long _sys_result; \ @@ -262,110 +279,34 @@ _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) - #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 __libc_do_syscall_return _sys_result; \ + _sys_result.val = __libc_do_syscall (number, arg1, arg2, arg3, \ + arg4, arg5); \ + err = _sys_result.reg.v1; \ + _sys_result.reg.v0; \ }) #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 __libc_do_syscall_return _sys_result; \ + _sys_result.val = __libc_do_syscall (number, arg1, arg2, arg3, \ + arg4, arg5, arg6); \ + err = _sys_result.reg.v1; \ + _sys_result.reg.v0; \ }) #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 __libc_do_syscall_return _sys_result; \ + _sys_result.val = __libc_do_syscall (number, arg1, arg2, arg3, \ + arg4, arg5, arg6, arg7); \ + err = _sys_result.reg.v1; \ + _sys_result.reg.v0; \ }) #define __SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", \