summary refs log tree commit diff
path: root/sysdeps/unix/sysv/linux/powerpc
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>2002-09-17 23:50:03 +0000
committerRoland McGrath <roland@gnu.org>2002-09-17 23:50:03 +0000
commitcfc91acd418d2ea62a4520b42406a16ef07257c3 (patch)
treec7d291182781c1534a03528b33d417983b8d2e54 /sysdeps/unix/sysv/linux/powerpc
parent81cb0d8214c425e356c3f79b4b024caab36540b8 (diff)
downloadglibc-cfc91acd418d2ea62a4520b42406a16ef07257c3.tar.gz
glibc-cfc91acd418d2ea62a4520b42406a16ef07257c3.tar.xz
glibc-cfc91acd418d2ea62a4520b42406a16ef07257c3.zip
2002-09-17 Steven Munroe <sjmunroe@us.ibm.com>
	Ported to PowerPC64 running Linux.
	* sysdeps/powerpc/powerpc64/Dist: New file.
	* sysdeps/powerpc/powerpc64/Implies: New file.
	* sysdeps/powerpc/powerpc64/Makefile: New file.
	* sysdeps/powerpc/powerpc64/__longjmp.S: New file.
	* sysdeps/powerpc/powerpc64/atomicity.h: New file.
	* sysdeps/powerpc/powerpc64/backtrace.c: New file.
	* sysdeps/powerpc/powerpc64/bp-asm.h: New file.
	* sysdeps/powerpc/powerpc64/bsd-_setjmp.S: New file.
	* sysdeps/powerpc/powerpc64/bsd-setjmp.S: New file.
	* sysdeps/powerpc/powerpc64/dl-dtprocnum.h: New file.
	* sysdeps/powerpc/powerpc64/dl-lookupcfg.h: New file.
	* sysdeps/powerpc/powerpc64/dl-machine.c: New file.
	* sysdeps/powerpc/powerpc64/dl-machine.h: New file.
	* sysdeps/powerpc/powerpc64/memset.S: New file.
	* sysdeps/powerpc/powerpc64/ppc-mcount.S: New file.
	* sysdeps/powerpc/powerpc64/register-dump.h: New file.
	* sysdeps/powerpc/powerpc64/setjmp.S: New file.
	* sysdeps/powerpc/powerpc64/stpcpy.S: New file.
	* sysdeps/powerpc/powerpc64/strchr.S: New file.
	* sysdeps/powerpc/powerpc64/strcmp.S: New file.
	* sysdeps/powerpc/powerpc64/strcpy.S: New file.
	* sysdeps/powerpc/powerpc64/strlen.S: New file.
	* sysdeps/powerpc/powerpc64/elf/bzero.S: New file.
	* sysdeps/powerpc/powerpc64/elf/start.S: New file.
	* sysdeps/powerpc/powerpc64/fpu/s_copysign.S: New file.
	* sysdeps/powerpc/powerpc64/fpu/s_copysignf.S: New file.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions: New File.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S: New file.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S: New file.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/glob64.c: New file.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S: New file.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/syscalls.list: New file.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h: New file.
Diffstat (limited to 'sysdeps/unix/sysv/linux/powerpc')
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions18
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S45
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S101
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/glob64.c2
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S89
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/syscalls.list52
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h178
7 files changed, 485 insertions, 0 deletions
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions b/sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions
new file mode 100644
index 0000000000..0026730c17
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions
@@ -0,0 +1,18 @@
+libc {
+  GLIBC_2.2 {
+    # functions used in other libraries
+    __xstat64; __fxstat64; __lxstat64;
+
+    # g*
+    glob64;
+
+    # New rlimit interface
+    getrlimit; setrlimit; getrlimit64; setrlimit64;
+
+    # r*
+    readdir64; readdir64_r;
+
+    # s*
+    scandir64; 
+  }
+}
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S b/sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S
new file mode 100644
index 0000000000..d8f8bab94d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S
@@ -0,0 +1,45 @@
+/* brk system call for Linux.  PowerPC64 version.
+   Copyright (C) 1995,96,97,99, 2000, 2002 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#define _ERRNO_H	1
+#include <bits/errno.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+	.comm	__curbrk,8,8
+	.section ".text"
+ENTRY (BP_SYM (__brk))
+	DISCARD_BOUNDS (r3)	/* the bounds are meaningless, so toss 'em.  */
+
+	stdu    r1,-64(r1)
+	std	r3,48(r1)
+	DO_CALL(SYS_ify(brk))
+	ld     r6,48(r1)
+	ld	r5,__curbrk@got(r2)
+	std     r3,0(r5)
+	cmpld   r6,r3
+	addi    r1,r1,64
+	li	r3,0
+	blelr+
+	li      r3,ENOMEM
+	b	JUMPTARGET(__syscall_error)
+END (BP_SYM (__brk))
+
+weak_alias (BP_SYM (__brk), BP_SYM (brk))
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S b/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S
new file mode 100644
index 0000000000..97e27f3fbf
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S
@@ -0,0 +1,101 @@
+/* Wrapper around clone system call.  PowerPC64 version.
+   Copyright (C) 1997,98,99,2000,02 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#define _ERRNO_H	1
+#include <bits/errno.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+/* This is the only really unusual system call in PPC linux, but not
+   because of any weirdness in the system call itself; because of
+   all the freaky stuff we have to do to make the call useful.  */
+
+/* int [r3] clone(int (*fn)(void *arg) [r3], void *child_stack [r4],
+   		  int flags [r5], void *arg [r6]); */
+
+ENTRY (BP_SYM (__clone))
+	/* GKM FIXME: add bounds checks, where sensible.  */
+	DISCARD_BOUNDS (r4)
+	DISCARD_BOUNDS (r6)
+
+	/* Check for child_stack == NULL || fn == NULL.  */
+	cmpdi	cr0,r4,0
+	ld	r7,0(r3)
+	cmpdi	cr1,r7,0
+	cror	cr0*4+eq,cr1*4+eq,cr0*4+eq
+	beq-	cr0,L(badargs)
+
+	/* Set up stack frame for parent.  */
+	stdu	r1,-80(r1)
+	std	r29,56(r1)
+	std	r30,64(r1)
+	std	r31,72(r1)
+
+	/* Set up stack frame for child.  */
+	clrrdi	r4,r4,4
+	li	r0,0
+	stdu	r0,-48(r4) /* min stack frame is 48 bytes per ABI */
+
+	/* Save fn, args, stack across syscall.  */
+	mr	r29,r3			/* Function in r29.  */
+	mr	r30,r4			/* Stack pointer in r30.  */
+	mr	r31,r6			/* Argument in r31.  */
+
+	/* 'flags' argument is first parameter to clone syscall. (The other
+	   argument is the stack pointer, already in r4.)  */
+	mr	r3,r5
+
+	/* Do the call.  */
+	DO_CALL(SYS_ify(clone))
+
+	/* Check for child process.  */
+	cmpdi	cr1,r3,0
+	crandc	cr1*4+eq,cr1*4+eq,cr0*4+so
+	bne-	cr1,L(parent)		/* The '-' is to minimise the race.  */
+
+	/* On at least mklinux DR3a5, clone() doesn't actually change
+	   the stack pointer.  I'm pretty sure this is a bug, because
+	   it adds a race condition if a signal is sent to a thread
+	   just after it is created (in the previous three instructions).  */
+	mr	r1,r30
+	/* Call procedure.  */
+	ld	r0,0(r29)
+	ld	r2,8(r29)
+	mtctr	r0
+	mr	r3,r31
+	bctrl
+	/* Call _exit with result from procedure.  */
+	b	JUMPTARGET(_exit)
+
+L(parent):
+	/* Parent.  Restore registers & return.  */
+	ld	r31,72(r1)
+	ld	r30,64(r1)
+	ld	r29,56(r1)
+	addi	r1,r1,80
+	bnslr+
+	b	JUMPTARGET(__syscall_error)
+
+L(badargs):
+	li	r3,EINVAL
+	b	JUMPTARGET(__syscall_error)
+END (BP_SYM (__clone))
+
+weak_alias (BP_SYM (__clone), BP_SYM (clone))
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/glob64.c b/sysdeps/unix/sysv/linux/powerpc/powerpc64/glob64.c
new file mode 100644
index 0000000000..4a3eee9c23
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/glob64.c
@@ -0,0 +1,2 @@
+/* glob64 is in glob.c */
+/* File glob64.c is redundent to glob.c in 64-bit. */
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S b/sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S
new file mode 100644
index 0000000000..08696c3cf3
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S
@@ -0,0 +1,89 @@
+/* Copyright (C) 1995, 1996, 1997, 1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <sysdep.h>
+#include <socketcall.h>
+
+#define P(a, b) P2(a, b)
+#define P2(a, b) a##b
+
+/* The socket-oriented system calls are handled unusally in Linux.
+   They are all gated through the single `socketcall' system call number.
+   `socketcall' takes two arguments: the first is the subcode, specifying
+   which socket function is being called; and the second is a pointer to
+   the arguments to the specific function.
+
+   The .S files for the other calls just #define socket and #include this.
+   They also #define a 'number-of-arguments' word in NARGS, which
+   defaults to 3.  */
+
+#ifndef NARGS
+#ifdef socket
+#error NARGS not defined
+#endif
+#define NARGS 3
+#endif
+
+#define stackblock 48 /* offset to parm save area */
+
+#ifndef socket
+/* If this is just socket.S leave it alone! */
+#else
+#ifndef __socket
+#define __socket P(__,socket) 
+#endif
+#endif
+
+	.text
+ENTRY(__socket)
+	stdu r1,-112(r1)
+#if NARGS >= 1
+	std  r3,stackblock(r1)
+#endif
+#if NARGS >= 2
+	std  r4,8+stackblock(r1)
+#endif
+#if NARGS >= 3
+	std  r5,16+stackblock(r1)
+#endif
+#if NARGS >= 4
+	std  r6,24+stackblock(r1)
+#endif
+#if NARGS >= 5
+	std  r7,32+stackblock(r1)
+#endif
+#if NARGS >= 6
+	std  r8,40+stackblock(r1)
+#endif
+#if NARGS >= 7
+	std  r9,48+stackblock(r1)
+#endif
+#if NARGS >= 8
+	std  r10,56+stackblock(r1)
+#endif
+#if NARGS >= 9
+#error too many arguments!
+#endif
+	li	r3,P(SOCKOP_,socket)
+	addi	r4,r1,stackblock
+	DO_CALL(SYS_ify(socketcall))
+	addi	r1,r1,112
+	PSEUDO_RET
+PSEUDO_END (__socket)
+
+weak_alias (__socket, socket)
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/syscalls.list b/sysdeps/unix/sysv/linux/powerpc/powerpc64/syscalls.list
new file mode 100644
index 0000000000..fd81f0d975
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/syscalls.list
@@ -0,0 +1,52 @@
+# File name	Caller	Syscall name	# args	Strong name	Weak names
+
+# System calls with wrappers.
+s_ioctl		ioctl	ioctl		i:iiI	__syscall_ioctl
+s_ipc		msgget	ipc		i:iiiip	__syscall_ipc
+s_llseek	llseek	_llseek		i:iiipi	__syscall__llseek
+s_readahead	readahead readahead	i:iiii	__syscall_readahead
+s_chown		chown	chown		i:sii	__syscall_chown
+s_execve	execve	execve		i:spp	__syscall_execve
+rt_sigaction	-	rt_sigaction	i:ippi	__syscall_rt_sigaction
+rt_sigpending	-	rt_sigpending	i:pi	__syscall_rt_sigpending
+rt_sigprocmask	-	rt_sigprocmask	i:ippi	__syscall_rt_sigprocmask
+rt_sigqueueinfo	-	rt_sigqueueinfo	i:iip	__syscall_rt_sigqueueinfo
+rt_sigsuspend	-	rt_sigsuspend	i:pi	__syscall_rt_sigsuspend
+rt_sigtimedwait	-	rt_sigtimedwait	i:pppi	__syscall_rt_sigtimedwait
+s_fcntl		fcntl 	fcntl		i:iiF	__syscall_fcntl
+s_fcntl64	fcntl64	fcntl64		i:iiF	__syscall_fcntl64
+s_fstat64	fxstat64 fstat64	i:ip	__syscall_fstat64
+s_ftruncate64	ftruncate64 ftruncate64	i:iii	__syscall_ftruncate64
+s_getcwd	getcwd	getcwd		i:pi	__syscall_getcwd
+s_getdents	getdents getdents	i:ipi	__syscall_getdents
+s_getdents64	getdents getdents64	i:ipi	__syscall_getdents64
+s_getpmsg	getpmsg	getpmsg		i:ipppp	__syscall_getpmsg
+s_getpriority	getpriority getpriority	i:ii	__syscall_getpriority
+getresgid	-	getresgid	i:ppp	getresgid
+getresuid	-	getresuid	i:ppp	getresuid
+s_getrlimit	getrlimit getrlimit	i:ip	__syscall_getrlimit
+s_lstat64	lxstat64 lstat64	i:sp	__syscall_lstat64
+s_mmap2		mmap64	mmap2		b:aniiii __syscall_mmap2
+s_poll		poll	poll		i:pii	__syscall_poll
+s_pread64	pread64	pread		i:ibnii	__syscall_pread
+s_ptrace	ptrace	ptrace		i:iipp	__syscall_ptrace
+s_putpmsg	putpmsg	putpmsg		i:ippii	__syscall_putpmsg
+s_pwrite64	pwrite64 pwrite		i:ibnii	__syscall_pwrite
+s_reboot	reboot	reboot		i:iii	__syscall_reboot
+s_setrlimit	setrlimit setrlimit	i:ip	__syscall_setrlimit
+s_sigaction	sigaction sigaction	i:ipp	__syscall_sigaction
+s_sigpending	sigpending sigpending	i:p	__syscall_sigpending
+s_sigprocmask	sigprocmask sigprocmask	i:ipp	__syscall_sigprocmask
+s_sigsuspend	sigsuspend sigsuspend	i:iii	__syscall_sigsuspend
+s_stat64	xstat64 stat64		i:sp	__syscall_stat64
+s_sysctl	sysctl	_sysctl		i:p	__syscall__sysctl
+s_truncate64	truncate64 truncate64	i:sii	__syscall_truncate64
+s_ugetrlimit	getrlimit ugetrlimit	i:ip	__syscall_ugetrlimit
+s_ustat		ustat	ustat		i:ip	__syscall_ustat
+s_vfork		vfork	vfork		i:	__syscall_vfork
+sys_fstat	fxstat	fstat		i:ip	__syscall_fstat
+sys_lstat	lxstat	lstat		i:sp	__syscall_lstat
+sys_mknod	xmknod	mknod		i:pii	__syscall_mknod
+sys_readv	readv	readv		i:ipi	__syscall_readv
+sys_stat	xstat	stat		i:sp	__syscall_stat
+sys_writev	writev	writev		i:ipi	__syscall_writev
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h
new file mode 100644
index 0000000000..8e43a39c10
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h
@@ -0,0 +1,178 @@
+/* Copyright (C) 1992, 1997, 1998, 1999, 2000, 2001, 2002
+   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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+		
+/* Alan Modra <amodra@bigpond.net.au> rewrote the INLINE_SYSCALL macro */
+
+#ifndef _LINUX_POWERPC_SYSDEP_H
+#define _LINUX_POWERPC_SYSDEP_H 1
+
+#include <sysdeps/unix/powerpc/sysdep.h>
+
+/* Define __set_errno() for INLINE_SYSCALL macro below.  */
+#ifndef __ASSEMBLER__
+#include <errno.h>
+#endif
+
+/* For Linux we can use the system call table in the header file
+	/usr/include/asm/unistd.h
+   of the kernel.  But these symbols do not follow the SYS_* syntax
+   so we have to redefine the `SYS_ify' macro here.  */
+#undef SYS_ify
+#ifdef __STDC__
+# define SYS_ify(syscall_name)	__NR_##syscall_name
+#else
+# define SYS_ify(syscall_name)	__NR_/**/syscall_name
+#endif
+
+#ifdef __ASSEMBLER__
+
+/* This seems to always be the case on PPC.  */
+#define ALIGNARG(log2) log2
+/* For ELF we need the `.type' directive to make shared libs work right.  */
+#define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg;
+#define ASM_SIZE_DIRECTIVE(name) .size name,.-name
+
+#endif	/* __ASSEMBLER__ */
+
+#undef INLINE_SYSCALL
+#if 1
+#define INLINE_SYSCALL(name, nr, args...)	\
+  ({						\
+    DECLARGS_##nr;				\
+    long ret, err;				\
+    LOADARGS_##nr(name, args);			\
+    __asm__ ("sc\n\t"				\
+	     "mfcr	%1\n\t"			\
+	     : "=r" (r3), "=r" (err)		\
+	     : ASM_INPUT_##nr			\
+	     : "cc", "memory");			\
+    ret = r3;					\
+    if (err & 1 << 28)				\
+      {						\
+	__set_errno (ret);			\
+	ret = -1L;				\
+      }						\
+    ret;					\
+  })
+
+#define DECLARGS_0 register long r0 __asm__ ("r0");	\
+		   register long r3 __asm__ ("r3")
+#define DECLARGS_1 DECLARGS_0
+#define DECLARGS_2 DECLARGS_1; register long r4 __asm__ ("r4")
+#define DECLARGS_3 DECLARGS_2; register long r5 __asm__ ("r5")
+#define DECLARGS_4 DECLARGS_3; register long r6 __asm__ ("r6")
+#define DECLARGS_5 DECLARGS_4; register long r7 __asm__ ("r7")
+#define DECLARGS_6 DECLARGS_5; register long r8 __asm__ ("r8")
+
+#define LOADARGS_0(name) \
+	r0 = __NR_##name
+#define LOADARGS_1(name, arg1) \
+	LOADARGS_0(name); \
+	r3 = (long) (arg1)
+#define LOADARGS_2(name, arg1, arg2) \
+	LOADARGS_1(name, arg1); \
+	r4 = (long) (arg2)
+#define LOADARGS_3(name, arg1, arg2, arg3) \
+	LOADARGS_2(name, arg1, arg2); \
+	r5 = (long) (arg3)
+#define LOADARGS_4(name, arg1, arg2, arg3, arg4) \
+	LOADARGS_3(name, arg1, arg2, arg3); \
+	r6 = (long) (arg4)
+#define LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5) \
+	LOADARGS_4(name, arg1, arg2, arg3, arg4); \
+	r7 = (long) (arg5)
+#define LOADARGS_6(name, arg1, arg2, arg3, arg4, arg5, arg6) \
+	LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5); \
+	r8 = (long) (arg6)
+
+#define ASM_INPUT_0 "r" (r0)
+#define ASM_INPUT_1 ASM_INPUT_0, "0" (r3)
+#define ASM_INPUT_2 ASM_INPUT_1, "r" (r4)
+#define ASM_INPUT_3 ASM_INPUT_2, "r" (r5)
+#define ASM_INPUT_4 ASM_INPUT_3, "r" (r6)
+#define ASM_INPUT_5 ASM_INPUT_4, "r" (r7)
+#define ASM_INPUT_6 ASM_INPUT_5, "r" (r8)
+
+#else
+/* This version is for kernels that implement system calls that
+   behave like function calls as far as register saving.  */
+#define INLINE_SYSCALL(name, nr, args...)			\
+  ({								\
+    register long r0 __asm__ ("r0");				\
+    register long r3 __asm__ ("r3");				\
+    register long r4 __asm__ ("r4");				\
+    register long r5 __asm__ ("r5");				\
+    register long r6 __asm__ ("r6");				\
+    register long r7 __asm__ ("r7");				\
+    register long r8 __asm__ ("r8");				\
+    long ret, err;						\
+    LOADARGS_##nr(name, args);					\
+    __asm__ ("sc\n\t"						\
+	     "mfcr	%7\n\t"					\
+	     : "=r" (r0), "=r" (r3), "=r" (r4), "=r" (r5),	\
+	       "=r" (r6), "=r" (r7), "=r" (r8), "=r" (err)	\
+	     : ASM_INPUT_##nr					\
+	     : "r9", "r10", "r11", "r12",			\
+	       "fr0", "fr1", "fr2", "fr3",			\
+	       "fr4", "fr5", "fr6", "fr7",			\
+	       "fr8", "fr9", "fr10", "fr11",			\
+	       "fr12", "fr13",					\
+	       "ctr", "lr",					\
+	       "cr0", "cr1", "cr5", "cr6", "cr7", "memory");	\
+    ret = r3;							\
+    if (err & 1 << 28)						\
+      {								\
+	__set_errno (ret);					\
+	ret = -1L;						\
+      }								\
+    ret;							\
+  })
+
+#define LOADARGS_0(name) \
+	r0 = __NR_##name
+#define LOADARGS_1(name, arg1) \
+	LOADARGS_0(name); \
+	r3 = (long) (arg1)
+#define LOADARGS_2(name, arg1, arg2) \
+	LOADARGS_1(name, arg1); \
+	r4 = (long) (arg2)
+#define LOADARGS_3(name, arg1, arg2, arg3) \
+	LOADARGS_2(name, arg1, arg2); \
+	r5 = (long) (arg3)
+#define LOADARGS_4(name, arg1, arg2, arg3, arg4) \
+	LOADARGS_3(name, arg1, arg2, arg3); \
+	r6 = (long) (arg4)
+#define LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5) \
+	LOADARGS_4(name, arg1, arg2, arg3, arg4); \
+	r7 = (long) (arg5)
+#define LOADARGS_6(name, arg1, arg2, arg3, arg4, arg5, arg6) \
+	LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5); \
+	r8 = (long) (arg6)
+
+#define ASM_INPUT_0 "0" (r0)
+#define ASM_INPUT_1 ASM_INPUT_0, "1" (r3)
+#define ASM_INPUT_2 ASM_INPUT_1, "2" (r4)
+#define ASM_INPUT_3 ASM_INPUT_2, "3" (r5)
+#define ASM_INPUT_4 ASM_INPUT_3, "4" (r6)
+#define ASM_INPUT_5 ASM_INPUT_4, "5" (r7)
+#define ASM_INPUT_6 ASM_INPUT_5, "6" (r8)
+
+#endif
+
+#endif /* linux/powerpc/powerpc64/sysdep.h */