about summary refs log tree commit diff
path: root/sysdeps/mips/mips64
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2004-12-22 20:10:10 +0000
committerUlrich Drepper <drepper@redhat.com>2004-12-22 20:10:10 +0000
commita334319f6530564d22e775935d9c91663623a1b4 (patch)
treeb5877475619e4c938e98757d518bb1e9cbead751 /sysdeps/mips/mips64
parent0ecb606cb6cf65de1d9fc8a919bceb4be476c602 (diff)
downloadglibc-a334319f6530564d22e775935d9c91663623a1b4.tar.gz
glibc-a334319f6530564d22e775935d9c91663623a1b4.tar.xz
glibc-a334319f6530564d22e775935d9c91663623a1b4.zip
(CFLAGS-tst-align.c): Add -mpreferred-stack-boundary=4.
Diffstat (limited to 'sysdeps/mips/mips64')
-rw-r--r--sysdeps/mips/mips64/Dist1
-rw-r--r--sysdeps/mips/mips64/Implies3
-rw-r--r--sysdeps/mips/mips64/__longjmp.c98
-rw-r--r--sysdeps/mips/mips64/add_n.S130
-rw-r--r--sysdeps/mips/mips64/addmul_1.S107
-rw-r--r--sysdeps/mips/mips64/bsd-_setjmp.S49
-rw-r--r--sysdeps/mips/mips64/bsd-setjmp.S47
-rw-r--r--sysdeps/mips/mips64/gmp-mparam.h31
-rw-r--r--sysdeps/mips/mips64/lshift.S105
-rw-r--r--sysdeps/mips/mips64/memcpy.S140
-rw-r--r--sysdeps/mips/mips64/memset.S92
-rw-r--r--sysdeps/mips/mips64/mul_1.S96
-rw-r--r--sysdeps/mips/mips64/n32/Implies4
-rw-r--r--sysdeps/mips/mips64/n32/Makefile6
-rw-r--r--sysdeps/mips/mips64/n64/Implies4
-rw-r--r--sysdeps/mips/mips64/n64/Makefile6
-rw-r--r--sysdeps/mips/mips64/rshift.S102
-rw-r--r--sysdeps/mips/mips64/setjmp.S46
-rw-r--r--sysdeps/mips/mips64/setjmp_aux.c78
-rw-r--r--sysdeps/mips/mips64/soft-fp/Dist1
-rw-r--r--sysdeps/mips/mips64/soft-fp/sfp-machine.h47
-rw-r--r--sysdeps/mips/mips64/sub_n.S130
-rw-r--r--sysdeps/mips/mips64/submul_1.S108
23 files changed, 1431 insertions, 0 deletions
diff --git a/sysdeps/mips/mips64/Dist b/sysdeps/mips/mips64/Dist
new file mode 100644
index 0000000000..ad6ea0313a
--- /dev/null
+++ b/sysdeps/mips/mips64/Dist
@@ -0,0 +1 @@
+setjmp_aux.c
diff --git a/sysdeps/mips/mips64/Implies b/sysdeps/mips/mips64/Implies
new file mode 100644
index 0000000000..8c18cb3034
--- /dev/null
+++ b/sysdeps/mips/mips64/Implies
@@ -0,0 +1,3 @@
+# MIPS uses IEEE 754 floating point.
+ieee754/flt-32
+ieee754/dbl-64
diff --git a/sysdeps/mips/mips64/__longjmp.c b/sysdeps/mips/mips64/__longjmp.c
new file mode 100644
index 0000000000..546493f842
--- /dev/null
+++ b/sysdeps/mips/mips64/__longjmp.c
@@ -0,0 +1,98 @@
+/* Copyright (C) 1992, 1995, 1997, 2000, 2003, 2004
+   Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Brendan Kehoe (brendan@zen.org).
+
+   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 <setjmp.h>
+#include <sgidefs.h>
+#include <stdlib.h>
+
+#undef __longjmp
+
+#ifndef	__GNUC__
+  #error This file uses GNU C extensions; you must compile with GCC.
+#endif
+
+void
+__longjmp (env, val_arg)
+     __jmp_buf env;
+     int val_arg;
+{
+  /* gcc 1.39.19 miscompiled the longjmp routine (as it did setjmp before
+     the hack around it); force it to use $a1 for the longjmp value.
+     Without this it saves $a1 in a register which gets clobbered
+     along the way.  */
+  register int val asm ("a1");
+
+  /* Pull back the floating point callee-saved registers.  */
+#if _MIPS_SIM == _ABI64
+  asm volatile ("l.d $f24, %0" : : "m" (env[0].__fpregs[0]));
+  asm volatile ("l.d $f25, %0" : : "m" (env[0].__fpregs[1]));
+  asm volatile ("l.d $f26, %0" : : "m" (env[0].__fpregs[2]));
+  asm volatile ("l.d $f27, %0" : : "m" (env[0].__fpregs[3]));
+  asm volatile ("l.d $f28, %0" : : "m" (env[0].__fpregs[4]));
+  asm volatile ("l.d $f29, %0" : : "m" (env[0].__fpregs[5]));
+  asm volatile ("l.d $f30, %0" : : "m" (env[0].__fpregs[6]));
+  asm volatile ("l.d $f31, %0" : : "m" (env[0].__fpregs[7]));
+#else
+  asm volatile ("l.d $f20, %0" : : "m" (env[0].__fpregs[0]));
+  asm volatile ("l.d $f22, %0" : : "m" (env[0].__fpregs[1]));
+  asm volatile ("l.d $f24, %0" : : "m" (env[0].__fpregs[2]));
+  asm volatile ("l.d $f26, %0" : : "m" (env[0].__fpregs[3]));
+  asm volatile ("l.d $f28, %0" : : "m" (env[0].__fpregs[4]));
+  asm volatile ("l.d $f30, %0" : : "m" (env[0].__fpregs[5]));
+#endif
+
+  /* Get and reconstruct the floating point csr.  */
+  asm volatile ("lw $2, %0" : : "m" (env[0].__fpc_csr));
+  asm volatile ("ctc1 $2, $31");
+
+  /* Get the GP. */
+  asm volatile ("ld $gp, %0" : : "m" (env[0].__gp));
+
+  /* Get the callee-saved registers.  */
+  asm volatile ("ld $16, %0" : : "m" (env[0].__regs[0]));
+  asm volatile ("ld $17, %0" : : "m" (env[0].__regs[1]));
+  asm volatile ("ld $18, %0" : : "m" (env[0].__regs[2]));
+  asm volatile ("ld $19, %0" : : "m" (env[0].__regs[3]));
+  asm volatile ("ld $20, %0" : : "m" (env[0].__regs[4]));
+  asm volatile ("ld $21, %0" : : "m" (env[0].__regs[5]));
+  asm volatile ("ld $22, %0" : : "m" (env[0].__regs[6]));
+  asm volatile ("ld $23, %0" : : "m" (env[0].__regs[7]));
+
+  /* Get the PC.  */
+  asm volatile ("ld $31, %0" : : "m" (env[0].__pc));
+
+
+  /* Restore the stack pointer and the FP.  They have to be restored
+     last and in a single asm as gcc, depending on options used, may
+     use either of them to access env.  */
+  asm volatile ("ld $29, %0\n\t"
+		"ld $30, %1\n\t" : : "m" (env[0].__sp), "m" (env[0].__fp));
+
+/* Give setjmp 1 if given a 0, or what they gave us if non-zero.  */
+  if (val == 0)
+    asm volatile ("dli $2, 1");
+  else
+    asm volatile ("move $2, %0" : : "r" (val));
+
+  asm volatile ("j $31");
+
+  /* Avoid `volatile function does return' warnings.  */
+  for (;;);
+}
diff --git a/sysdeps/mips/mips64/add_n.S b/sysdeps/mips/mips64/add_n.S
new file mode 100644
index 0000000000..072f4f0b73
--- /dev/null
+++ b/sysdeps/mips/mips64/add_n.S
@@ -0,0 +1,130 @@
+/* MIPS3 __mpn_add_n -- Add two limb vectors of the same length > 0 and
+ * store sum in a third limb vector.
+ *
+ * Copyright (C) 1995, 2000, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of the GNU MP Library.
+ *
+ * The GNU MP 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 MP 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 MP 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 <sys/asm.h>
+
+/*
+ * INPUT PARAMETERS
+ * res_ptr	$4
+ * s1_ptr	$5
+ * s2_ptr	$6
+ * size		$7
+ */
+#ifdef __PIC__
+	.option pic2
+#endif
+	.text
+	.align	2
+	.globl	__mpn_add_n
+	.ent	__mpn_add_n
+__mpn_add_n:
+#ifdef __PIC__
+	SETUP_GP /* ??? unused */
+#endif
+	.set	noreorder
+	.set	nomacro
+
+	ld	$10,0($5)
+	ld	$11,0($6)
+
+	daddiu	$7,$7,-1
+	and	$9,$7,4-1	# number of limbs in first loop
+	beq	$9,$0,L(L0)	# if multiple of 4 limbs, skip first loop
+	move	$2,$0
+
+	dsubu	$7,$7,$9
+
+L(Loop0):	daddiu	$9,$9,-1
+	ld	$12,8($5)
+	daddu	$11,$11,$2
+	ld	$13,8($6)
+	sltu	$8,$11,$2
+	daddu	$11,$10,$11
+	sltu	$2,$11,$10
+	sd	$11,0($4)
+	or	$2,$2,$8
+
+	daddiu	$5,$5,8
+	daddiu	$6,$6,8
+	move	$10,$12
+	move	$11,$13
+	bne	$9,$0,L(Loop0)
+	daddiu	$4,$4,8
+
+L(L0):	beq	$7,$0,L(Lend)
+	nop
+
+L(Loop):	daddiu	$7,$7,-4
+
+	ld	$12,8($5)
+	daddu	$11,$11,$2
+	ld	$13,8($6)
+	sltu	$8,$11,$2
+	daddu	$11,$10,$11
+	sltu	$2,$11,$10
+	sd	$11,0($4)
+	or	$2,$2,$8
+
+	ld	$10,16($5)
+	daddu	$13,$13,$2
+	ld	$11,16($6)
+	sltu	$8,$13,$2
+	daddu	$13,$12,$13
+	sltu	$2,$13,$12
+	sd	$13,8($4)
+	or	$2,$2,$8
+
+	ld	$12,24($5)
+	daddu	$11,$11,$2
+	ld	$13,24($6)
+	sltu	$8,$11,$2
+	daddu	$11,$10,$11
+	sltu	$2,$11,$10
+	sd	$11,16($4)
+	or	$2,$2,$8
+
+	ld	$10,32($5)
+	daddu	$13,$13,$2
+	ld	$11,32($6)
+	sltu	$8,$13,$2
+	daddu	$13,$12,$13
+	sltu	$2,$13,$12
+	sd	$13,24($4)
+	or	$2,$2,$8
+
+	daddiu	$5,$5,32
+	daddiu	$6,$6,32
+
+	bne	$7,$0,L(Loop)
+	daddiu	$4,$4,32
+
+L(Lend):	daddu	$11,$11,$2
+	sltu	$8,$11,$2
+	daddu	$11,$10,$11
+	sltu	$2,$11,$10
+	sd	$11,0($4)
+	j	$31
+	or	$2,$2,$8
+
+	.end	__mpn_add_n
diff --git a/sysdeps/mips/mips64/addmul_1.S b/sysdeps/mips/mips64/addmul_1.S
new file mode 100644
index 0000000000..f5ecd83702
--- /dev/null
+++ b/sysdeps/mips/mips64/addmul_1.S
@@ -0,0 +1,107 @@
+/* MIPS3 __mpn_addmul_1 -- Multiply a limb vector with a single limb and
+ * add the product to a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of the GNU MP Library.
+ *
+ * The GNU MP 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 MP 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 MP 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 <sys/asm.h>
+
+/* INPUT PARAMETERS
+ * res_ptr	$4
+ * s1_ptr	$5
+ * size		$6
+ * s2_limb	$7
+ */
+
+#ifdef PIC
+	.option pic2
+#endif
+	.text
+	.align	4
+	.globl	__mpn_addmul_1
+	.ent	__mpn_addmul_1
+__mpn_addmul_1:
+#ifdef PIC
+	SETUP_GP /* ??? unused */
+#endif
+	.set    noreorder
+	.set    nomacro
+
+ # warm up phase 0
+	ld	$8,0($5)
+
+ # warm up phase 1
+	daddiu	$5,$5,8
+	dmultu	$8,$7
+
+	daddiu	$6,$6,-1
+	beq	$6,$0,L(LC0)
+	move	$2,$0		# zero cy2
+
+	daddiu	$6,$6,-1
+	beq	$6,$0,L(LC1)
+	ld	$8,0($5)	# load new s1 limb as early as possible
+
+L(Loop):	ld	$10,0($4)
+	mflo	$3
+	mfhi	$9
+	daddiu	$5,$5,8
+	daddu	$3,$3,$2	# add old carry limb to low product limb
+	dmultu	$8,$7
+	ld	$8,0($5)	# load new s1 limb as early as possible
+	daddiu	$6,$6,-1	# decrement loop counter
+	sltu	$2,$3,$2	# carry from previous addition -> $2
+	daddu	$3,$10,$3
+	sltu	$10,$3,$10
+	daddu	$2,$2,$10
+	sd	$3,0($4)
+	daddiu	$4,$4,8
+	bne	$6,$0,L(Loop)
+	daddu	$2,$9,$2	# add high product limb and carry from addition
+
+ # cool down phase 1
+L(LC1):	ld	$10,0($4)
+	mflo	$3
+	mfhi	$9
+	daddu	$3,$3,$2
+	sltu	$2,$3,$2
+	dmultu	$8,$7
+	daddu	$3,$10,$3
+	sltu	$10,$3,$10
+	daddu	$2,$2,$10
+	sd	$3,0($4)
+	daddiu	$4,$4,8
+	daddu	$2,$9,$2	# add high product limb and carry from addition
+
+ # cool down phase 0
+L(LC0):	ld	$10,0($4)
+	mflo	$3
+	mfhi	$9
+	daddu	$3,$3,$2
+	sltu	$2,$3,$2
+	daddu	$3,$10,$3
+	sltu	$10,$3,$10
+	daddu	$2,$2,$10
+	sd	$3,0($4)
+	j	$31
+	daddu	$2,$9,$2	# add high product limb and carry from addition
+
+	.end	__mpn_addmul_1
diff --git a/sysdeps/mips/mips64/bsd-_setjmp.S b/sysdeps/mips/mips64/bsd-_setjmp.S
new file mode 100644
index 0000000000..7620cf391f
--- /dev/null
+++ b/sysdeps/mips/mips64/bsd-_setjmp.S
@@ -0,0 +1,49 @@
+/* BSD `_setjmp' entry point to `sigsetjmp (..., 0)'.  MIPS64 version.
+   Copyright (C) 1996, 1997, 2000, 2002, 2003, 2004
+	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.  */
+
+/* This just does a tail-call to `__sigsetjmp (ARG, 0)'.
+   We cannot do it in C because it must be a tail-call, so frame-unwinding
+   in setjmp doesn't clobber the state restored by longjmp.  */
+
+#include <sgidefs.h>
+#include <sysdep.h>
+#include <sys/asm.h>
+
+#ifdef __PIC__
+	.option pic2
+#endif
+ENTRY (_setjmp)
+#ifdef __PIC__
+	SETUP_GP
+#endif
+	SETUP_GP64 (v0, C_SYMBOL_NAME (_setjmp))
+	PTR_LA t9, C_SYMBOL_NAME (__sigsetjmp)
+#if _MIPS_SIM == _ABIO32
+	nop
+#endif	
+	RESTORE_GP64
+	move	a1, zero		/* Pass a second argument of zero.  */
+#ifdef __PIC__
+	jr	t9
+#else
+	j	C_SYMBOL_NAME (__sigsetjmp)
+#endif
+	.end	_setjmp
+libc_hidden_def (_setjmp)
diff --git a/sysdeps/mips/mips64/bsd-setjmp.S b/sysdeps/mips/mips64/bsd-setjmp.S
new file mode 100644
index 0000000000..2a1fd9ce71
--- /dev/null
+++ b/sysdeps/mips/mips64/bsd-setjmp.S
@@ -0,0 +1,47 @@
+/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'.  MIPS64 version.
+   Copyright (C) 1996, 1997, 2002, 2003, 2004 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.  */
+
+/* This just does a tail-call to `__sigsetjmp (ARG, 1)'.
+   We cannot do it in C because it must be a tail-call, so frame-unwinding
+   in setjmp doesn't clobber the state restored by longjmp.  */
+
+#include <sgidefs.h>
+#include <sysdep.h>
+#include <sys/asm.h>
+
+#ifdef PIC
+	.option pic2
+#endif
+ENTRY (setjmp)
+#ifdef __PIC__
+	SETUP_GP
+#endif
+	SETUP_GP64 (v0, C_SYMBOL_NAME (setjmp))
+	PTR_LA t9, C_SYMBOL_NAME (__sigsetjmp)
+#if _MIPS_SIM == _ABIO32
+	nop
+#endif	
+	RESTORE_GP64
+	dli a1, 1		/* Pass a second argument of one.  */
+#ifdef __PIC__
+	jr	t9
+#else
+	j	C_SYMBOL_NAME (__sigsetjmp)
+#endif
+	.end	setjmp
diff --git a/sysdeps/mips/mips64/gmp-mparam.h b/sysdeps/mips/mips64/gmp-mparam.h
new file mode 100644
index 0000000000..7666137a21
--- /dev/null
+++ b/sysdeps/mips/mips64/gmp-mparam.h
@@ -0,0 +1,31 @@
+/* gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright (C) 1991, 1993, 1994, 2002, 2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP Library; see the file COPYING.LIB.  If not, write to
+the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#if defined __GMP_H__ && ! defined _LONG_LONG_LIMB
+#error "Included too late for _LONG_LONG_LIMB to take effect"
+#endif
+
+#define _LONG_LONG_LIMB
+#define BITS_PER_MP_LIMB 64
+#define BYTES_PER_MP_LIMB 8
+#define BITS_PER_LONGINT __WORDSIZE
+#define BITS_PER_INT 32
+#define BITS_PER_SHORTINT 16
+#define BITS_PER_CHAR 8
diff --git a/sysdeps/mips/mips64/lshift.S b/sysdeps/mips/mips64/lshift.S
new file mode 100644
index 0000000000..20f9e3da19
--- /dev/null
+++ b/sysdeps/mips/mips64/lshift.S
@@ -0,0 +1,105 @@
+/* MIPS3 __mpn_lshift --
+ *
+ * Copyright (C) 1995, 2000, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of the GNU MP Library.
+ *
+ * The GNU MP 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 MP 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 MP 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 <sys/asm.h>
+
+/* INPUT PARAMETERS
+ * res_ptr	$4
+ * src_ptr	$5
+ * size		$6
+ * cnt		$7
+ */
+
+#ifdef __PIC__
+	.option pic2
+#endif
+	.text
+	.align	2
+	.globl	__mpn_lshift
+	.ent	__mpn_lshift
+__mpn_lshift:
+#ifdef __PIC__
+	SETUP_GP /* ??? unused */
+#endif
+	.set	noreorder
+	.set	nomacro
+
+	dsll	$2,$6,3
+	daddu	$5,$5,$2	# make r5 point at end of src
+	ld	$10,-8($5)	# load first limb
+	dsubu	$13,$0,$7
+	daddu	$4,$4,$2	# make r4 point at end of res
+	daddiu	$6,$6,-1
+	and	$9,$6,4-1	# number of limbs in first loop
+	beq	$9,$0,L(L0)	# if multiple of 4 limbs, skip first loop
+	dsrl	$2,$10,$13	# compute function result
+
+	dsubu	$6,$6,$9
+
+L(Loop0):	ld	$3,-16($5)
+	daddiu	$4,$4,-8
+	daddiu	$5,$5,-8
+	daddiu	$9,$9,-1
+	dsll	$11,$10,$7
+	dsrl	$12,$3,$13
+	move	$10,$3
+	or	$8,$11,$12
+	bne	$9,$0,L(Loop0)
+	sd	$8,0($4)
+
+L(L0):	beq	$6,$0,L(Lend)
+	nop
+
+L(Loop):	ld	$3,-16($5)
+	daddiu	$4,$4,-32
+	daddiu	$6,$6,-4
+	dsll	$11,$10,$7
+	dsrl	$12,$3,$13
+
+	ld	$10,-24($5)
+	dsll	$14,$3,$7
+	or	$8,$11,$12
+	sd	$8,24($4)
+	dsrl	$9,$10,$13
+
+	ld	$3,-32($5)
+	dsll	$11,$10,$7
+	or	$8,$14,$9
+	sd	$8,16($4)
+	dsrl	$12,$3,$13
+
+	ld	$10,-40($5)
+	dsll	$14,$3,$7
+	or	$8,$11,$12
+	sd	$8,8($4)
+	dsrl	$9,$10,$13
+
+	daddiu	$5,$5,-32
+	or	$8,$14,$9
+	bgtz	$6,L(Loop)
+	sd	$8,0($4)
+
+L(Lend):	dsll	$8,$10,$7
+	j	$31
+	sd	$8,-8($4)
+	.end	__mpn_lshift
diff --git a/sysdeps/mips/mips64/memcpy.S b/sysdeps/mips/mips64/memcpy.S
new file mode 100644
index 0000000000..eab9463f86
--- /dev/null
+++ b/sysdeps/mips/mips64/memcpy.S
@@ -0,0 +1,140 @@
+/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Hartvig Ekner <hartvige@mips.com>, 2002.
+   Ported to mips3 n32/n64 by Alexandre Oliva <aoliva@redhat.com>
+
+   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>
+#include <endian.h>
+#include <sys/asm.h>
+
+
+/* void *memcpy(void *s1, const void *s2, size_t n);
+	
+   This could probably be optimized further.  */
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#  define LDHI	ldl		/* high part is left in big-endian	*/
+#  define SDHI	sdl		/* high part is left in big-endian	*/
+#  define LDLO	ldr		/* low part is right in big-endian	*/
+#  define SDLO	sdr		/* low part is right in big-endian	*/
+#else
+#  define LDHI	ldr		/* high part is right in little-endian	*/
+#  define SDHI	sdr		/* high part is right in little-endian	*/
+#  define LDLO	ldl		/* low part is left in little-endian	*/
+#  define SDLO	sdl		/* low part is left in little-endian	*/
+#endif
+
+ENTRY (memcpy)
+	.set	noreorder
+
+	slti	t0, a2, 16		# Less than 16?
+	bne	t0, zero, L(last16)
+	move	v0, a0			# Setup exit value before too late
+
+	xor	t0, a1, a0		# Find a0/a1 displacement
+	andi	t0, 0x7
+	bne	t0, zero, L(shift)	# Go handle the unaligned case
+	PTR_SUBU t1, zero, a1
+	andi	t1, 0x7			# a0/a1 are aligned, but are we
+	beq	t1, zero, L(chk8w)	#  starting in the middle of a word?
+	PTR_SUBU a2, t1
+	LDHI	t0, 0(a1)		# Yes we are... take care of that
+	PTR_ADDU a1, t1
+	SDHI	t0, 0(a0)
+	PTR_ADDU a0, t1
+
+L(chk8w):
+	andi	t0, a2, 0x3f		# 64 or more bytes left?
+	beq	t0, a2, L(chk1w)
+	PTR_SUBU a3, a2, t0		# Yes
+	PTR_ADDU a3, a1			# a3 = end address of loop
+	move	a2, t0			# a2 = what will be left after loop
+L(lop8w):	
+	ld	t0,  0(a1)		# Loop taking 8 words at a time
+	ld	t1,  8(a1)
+	ld	t2, 16(a1)
+	ld	t3, 24(a1)
+	ld	ta0, 32(a1)
+	ld	ta1, 40(a1)
+	ld	ta2, 48(a1)
+	ld	ta3, 56(a1)
+	PTR_ADDIU a0, 64
+	PTR_ADDIU a1, 64
+	sd	t0, -64(a0)
+	sd	t1, -56(a0)
+	sd	t2, -48(a0)
+	sd	t3, -40(a0)
+	sd	ta0, -32(a0)
+	sd	ta1, -24(a0)
+	sd	ta2, -16(a0)
+	bne	a1, a3, L(lop8w)
+	sd	ta3,  -8(a0)
+
+L(chk1w):
+	andi	t0, a2, 0x7		# 8 or more bytes left?
+	beq	t0, a2, L(last16)
+	PTR_SUBU a3, a2, t0		# Yes, handle them one dword at a time
+	PTR_ADDU a3, a1			# a3 again end address
+	move	a2, t0
+L(lop1w):
+	ld	t0, 0(a1)
+	PTR_ADDIU a0, 8
+	PTR_ADDIU a1, 8
+	bne	a1, a3, L(lop1w)
+	sd	t0, -8(a0)
+
+L(last16):
+	blez	a2, L(lst16e)		# Handle last 16 bytes, one at a time
+	PTR_ADDU a3, a2, a1
+L(lst16l):
+	lb	t0, 0(a1)
+	PTR_ADDIU a0, 1
+	PTR_ADDIU a1, 1
+	bne	a1, a3, L(lst16l)
+	sb	t0, -1(a0)
+L(lst16e):
+	jr	ra			# Bye, bye
+	nop
+
+L(shift):
+	PTR_SUBU a3, zero, a0		# Src and Dest unaligned 
+	andi	a3, 0x7			#  (unoptimized case...)
+	beq	a3, zero, L(shft1)
+	PTR_SUBU a2, a3			# a2 = bytes left
+	LDHI	t0, 0(a1)		# Take care of first odd part
+	LDLO	t0, 7(a1)
+	PTR_ADDU a1, a3
+	SDHI	t0, 0(a0)
+	PTR_ADDU a0, a3
+L(shft1):
+	andi	t0, a2, 0x7
+	PTR_SUBU a3, a2, t0
+	PTR_ADDU a3, a1
+L(shfth):
+	LDHI	t1, 0(a1)		# Limp through, dword by dword
+	LDLO	t1, 7(a1)
+	PTR_ADDIU a0, 8
+	PTR_ADDIU a1, 8
+	bne	a1, a3, L(shfth)
+	sd	t1, -8(a0)
+	b	L(last16)		# Handle anything which may be left
+	move	a2, t0
+
+	.set	reorder
+END (memcpy)
+libc_hidden_builtin_def (memcpy)
diff --git a/sysdeps/mips/mips64/memset.S b/sysdeps/mips/mips64/memset.S
new file mode 100644
index 0000000000..b50aaba816
--- /dev/null
+++ b/sysdeps/mips/mips64/memset.S
@@ -0,0 +1,92 @@
+/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Hartvig Ekner <hartvige@mips.com>, 2002.
+   Ported to mips3 n32/n64 by Alexandre Oliva <aoliva@redhat.com>
+
+   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>
+#include <endian.h>
+#include <sys/asm.h>
+
+
+/* void *memset(void *s, int c, size_t n);
+	
+   This could probably be optimized further.  */
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+# define SDHI	sdl		/* high part is left in big-endian	*/
+#else
+# define SDHI	sdr		/* high part is right in little-endian	*/
+#endif
+
+ENTRY (memset)
+	.set	noreorder
+
+	slti	ta1, a2, 16		# Less than 16?
+	bne	ta1, zero, L(last16)
+	move	v0, a0			# Setup exit value before too late
+
+	beq	a1, zero, L(ueven)	# If zero pattern, no need to extend
+	andi	a1, 0xff		# Avoid problems with bogus arguments
+	dsll	ta0, a1, 8
+	or	a1, ta0
+	dsll	ta0, a1, 16
+	or	a1, ta0			# a1 is now pattern in full word
+	dsll	ta0, a1, 32
+	or	a1, ta0			# a1 is now pattern in double word
+
+L(ueven):
+	PTR_SUBU ta0, zero, a0		# Unaligned address?
+	andi	ta0, 0x7
+	beq	ta0, zero, L(chkw)
+	PTR_SUBU a2, ta0
+	SDHI	a1, 0(a0)		# Yes, handle first unaligned part
+	PTR_ADDU a0, ta0		# Now both a0 and a2 are updated
+
+L(chkw):
+	andi	ta0, a2, 0xf		# Enough left for one loop iteration?
+	beq	ta0, a2, L(chkl)
+	PTR_SUBU a3, a2, ta0
+	PTR_ADDU a3, a0			# a3 is last loop address +1
+	move	a2, ta0			# a2 is now # of bytes left after loop
+L(loopw):
+	PTR_ADDIU a0, 16		# Handle 2 dwords pr. iteration
+	sd	a1, -16(a0)
+	bne	a0, a3, L(loopw)
+	sd	a1,  -8(a0)
+
+L(chkl):
+	andi	ta0, a2, 0x8		# Check if there is at least a double
+	beq	ta0, zero, L(last16)	#  word remaining after the loop
+	PTR_SUBU a2, ta0
+	sd	a1, 0(a0)		# Yes...
+	PTR_ADDIU a0, 8
+
+L(last16):
+	blez	a2, L(exit)		# Handle last 16 bytes (if cnt>0)
+	PTR_ADDU a3, a2, a0		# a3 is last address +1
+L(lst16l):
+	PTR_ADDIU a0, 1
+	bne	a0, a3, L(lst16l)
+	sb	a1, -1(a0)
+L(exit):
+	j	ra			# Bye, bye
+	nop
+
+	.set	reorder
+END (memset)
+libc_hidden_builtin_def (memset)
diff --git a/sysdeps/mips/mips64/mul_1.S b/sysdeps/mips/mips64/mul_1.S
new file mode 100644
index 0000000000..c711783001
--- /dev/null
+++ b/sysdeps/mips/mips64/mul_1.S
@@ -0,0 +1,96 @@
+/* MIPS3 __mpn_mul_1 -- Multiply a limb vector with a single limb and
+ * store the product in a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 2000, 2002, 2003
+ * Free Software Foundation, Inc.
+ *
+ * This file is part of the GNU MP Library.
+ *
+ * The GNU MP 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 MP 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 MP 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 <sys/asm.h>
+
+/* INPUT PARAMETERS
+ * res_ptr	$4
+ * s1_ptr	$5
+ * size		$6
+ * s2_limb	$7
+ */
+
+#ifdef __PIC__
+	.option pic2
+#endif
+	.text
+	.align	4
+	.globl	__mpn_mul_1
+	.ent	__mpn_mul_1
+__mpn_mul_1:
+#ifdef __PIC__
+	SETUP_GP /* ??? unused */
+#endif
+	.set    noreorder
+	.set    nomacro
+
+ # warm up phase 0
+	ld	$8,0($5)
+
+ # warm up phase 1
+	daddiu	$5,$5,8
+	dmultu	$8,$7
+
+	daddiu	$6,$6,-1
+	beq	$6,$0,L(LC0)
+	move	$2,$0		# zero cy2
+
+	daddiu	$6,$6,-1
+	beq	$6,$0,L(LC1)
+	ld	$8,0($5)	# load new s1 limb as early as possible
+
+L(Loop):	mflo	$10
+	mfhi	$9
+	daddiu	$5,$5,8
+	daddu	$10,$10,$2	# add old carry limb to low product limb
+	dmultu	$8,$7
+	ld	$8,0($5)	# load new s1 limb as early as possible
+	daddiu	$6,$6,-1	# decrement loop counter
+	sltu	$2,$10,$2	# carry from previous addition -> $2
+	sd	$10,0($4)
+	daddiu	$4,$4,8
+	bne	$6,$0,L(Loop)
+	daddu	$2,$9,$2	# add high product limb and carry from addition
+
+ # cool down phase 1
+L(LC1):	mflo	$10
+	mfhi	$9
+	daddu	$10,$10,$2
+	sltu	$2,$10,$2
+	dmultu	$8,$7
+	sd	$10,0($4)
+	daddiu	$4,$4,8
+	daddu	$2,$9,$2	# add high product limb and carry from addition
+
+ # cool down phase 0
+L(LC0):	mflo	$10
+	mfhi	$9
+	daddu	$10,$10,$2
+	sltu	$2,$10,$2
+	sd	$10,0($4)
+	j	$31
+	daddu	$2,$9,$2	# add high product limb and carry from addition
+
+	.end	__mpn_mul_1
diff --git a/sysdeps/mips/mips64/n32/Implies b/sysdeps/mips/mips64/n32/Implies
new file mode 100644
index 0000000000..a7cb280ec4
--- /dev/null
+++ b/sysdeps/mips/mips64/n32/Implies
@@ -0,0 +1,4 @@
+ieee754/ldbl-128
+mips/mips64
+mips
+wordsize-32
diff --git a/sysdeps/mips/mips64/n32/Makefile b/sysdeps/mips/mips64/n32/Makefile
new file mode 100644
index 0000000000..a84d2a51bd
--- /dev/null
+++ b/sysdeps/mips/mips64/n32/Makefile
@@ -0,0 +1,6 @@
+# `long double' is a distinct type we support.
+long-double-fcts = yes
+
+ifeq ($(filter -mabi=n32,$(CC)),)
+CC += -mabi=n32
+endif
diff --git a/sysdeps/mips/mips64/n64/Implies b/sysdeps/mips/mips64/n64/Implies
new file mode 100644
index 0000000000..e507786789
--- /dev/null
+++ b/sysdeps/mips/mips64/n64/Implies
@@ -0,0 +1,4 @@
+ieee754/ldbl-128
+mips/mips64
+mips
+wordsize-64
diff --git a/sysdeps/mips/mips64/n64/Makefile b/sysdeps/mips/mips64/n64/Makefile
new file mode 100644
index 0000000000..a823f32b53
--- /dev/null
+++ b/sysdeps/mips/mips64/n64/Makefile
@@ -0,0 +1,6 @@
+# `long double' is a distinct type we support.
+long-double-fcts = yes
+
+ifeq ($(filter -mabi=64,$(CC)),)
+CC += -mabi=64
+endif
diff --git a/sysdeps/mips/mips64/rshift.S b/sysdeps/mips/mips64/rshift.S
new file mode 100644
index 0000000000..e6a8a06d3d
--- /dev/null
+++ b/sysdeps/mips/mips64/rshift.S
@@ -0,0 +1,102 @@
+/* MIPS3 __mpn_rshift --
+ *
+ * Copyright (C) 1995, 2000, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of the GNU MP Library.
+ *
+ * The GNU MP 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 MP 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 MP 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 <sys/asm.h>
+
+/* INPUT PARAMETERS
+ * res_ptr	$4
+ * src_ptr	$5
+ * size		$6
+ * cnt		$7
+ */
+
+#ifdef __PIC__
+	.option pic2
+#endif
+	.text
+	.align	2
+	.globl	__mpn_rshift
+	.ent	__mpn_rshift
+__mpn_rshift:
+#ifdef __PIC__
+	SETUP_GP /* ??? unused */
+#endif
+	.set	noreorder
+	.set	nomacro
+
+	ld	$10,0($5)	# load first limb
+	dsubu	$13,$0,$7
+	daddiu	$6,$6,-1
+	and	$9,$6,4-1	# number of limbs in first loop
+	beq	$9,$0,L(L0)	# if multiple of 4 limbs, skip first loop
+	dsll	$2,$10,$13	# compute function result
+
+	dsubu	$6,$6,$9
+
+L(Loop0):	ld	$3,8($5)
+	daddiu	$4,$4,8
+	daddiu	$5,$5,8
+	daddiu	$9,$9,-1
+	dsrl	$11,$10,$7
+	dsll	$12,$3,$13
+	move	$10,$3
+	or	$8,$11,$12
+	bne	$9,$0,L(Loop0)
+	sd	$8,-8($4)
+
+L(L0):	beq	$6,$0,L(Lend)
+	nop
+
+L(Loop):	ld	$3,8($5)
+	daddiu	$4,$4,32
+	daddiu	$6,$6,-4
+	dsrl	$11,$10,$7
+	dsll	$12,$3,$13
+
+	ld	$10,16($5)
+	dsrl	$14,$3,$7
+	or	$8,$11,$12
+	sd	$8,-32($4)
+	dsll	$9,$10,$13
+
+	ld	$3,24($5)
+	dsrl	$11,$10,$7
+	or	$8,$14,$9
+	sd	$8,-24($4)
+	dsll	$12,$3,$13
+
+	ld	$10,32($5)
+	dsrl	$14,$3,$7
+	or	$8,$11,$12
+	sd	$8,-16($4)
+	dsll	$9,$10,$13
+
+	daddiu	$5,$5,32
+	or	$8,$14,$9
+	bgtz	$6,L(Loop)
+	sd	$8,-8($4)
+
+L(Lend):	dsrl	$8,$10,$7
+	j	$31
+	sd	$8,0($4)
+	.end	__mpn_rshift
diff --git a/sysdeps/mips/mips64/setjmp.S b/sysdeps/mips/mips64/setjmp.S
new file mode 100644
index 0000000000..bdfd9cd51c
--- /dev/null
+++ b/sysdeps/mips/mips64/setjmp.S
@@ -0,0 +1,46 @@
+/* Copyright (C) 1996, 1997, 2000, 2002, 2003, 2004
+	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 <sgidefs.h>
+#include <sysdep.h>
+#include <sys/asm.h>
+
+/* The function __sigsetjmp_aux saves all the registers, but it can't
+   reliably access the stack or frame pointers, so we pass them in as
+   extra arguments.  */
+#ifdef __PIC__
+	.option pic2
+#endif
+ENTRY (__sigsetjmp)
+#ifdef __PIC__
+	SETUP_GP
+#endif
+	SETUP_GP64 (v0, C_SYMBOL_NAME (__sigsetjmp))
+	move a2, sp
+	move a3, fp
+	PTR_LA t9, __sigsetjmp_aux
+#if _MIPS_SIM == _ABIO32
+	nop
+#endif	
+	RESTORE_GP64
+#if _MIPS_SIM != _ABIO32
+	move a4, gp
+#endif
+	jr t9
+	.end __sigsetjmp
diff --git a/sysdeps/mips/mips64/setjmp_aux.c b/sysdeps/mips/mips64/setjmp_aux.c
new file mode 100644
index 0000000000..26b4739c32
--- /dev/null
+++ b/sysdeps/mips/mips64/setjmp_aux.c
@@ -0,0 +1,78 @@
+/* Copyright (C) 1996, 1997, 2003, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Brendan Kehoe (brendan@zen.org).
+
+   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 <setjmp.h>
+#include <sgidefs.h>
+
+/* This function is only called via the assembly language routine
+   __sigsetjmp, which arranges to pass in the stack pointer and the frame
+   pointer.  We do things this way because it's difficult to reliably
+   access them in C.  */
+
+int
+__sigsetjmp_aux (jmp_buf env, int savemask, long long sp, long long fp,
+		 long long gp)
+{
+  /* Store the floating point callee-saved registers...  */
+#if _MIPS_SIM == _ABI64
+  asm volatile ("s.d $f24, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[0]));
+  asm volatile ("s.d $f25, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[1]));
+  asm volatile ("s.d $f26, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[2]));
+  asm volatile ("s.d $f27, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[3]));
+  asm volatile ("s.d $f28, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[4]));
+  asm volatile ("s.d $f29, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[5]));
+  asm volatile ("s.d $f30, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[6]));
+  asm volatile ("s.d $f31, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[7]));
+#else
+  asm volatile ("s.d $f20, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[0]));
+  asm volatile ("s.d $f22, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[1]));
+  asm volatile ("s.d $f24, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[2]));
+  asm volatile ("s.d $f26, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[3]));
+  asm volatile ("s.d $f28, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[4]));
+  asm volatile ("s.d $f30, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[5]));
+#endif
+
+  /* .. and the PC;  */
+  asm volatile ("sd $31, %0" : : "m" (env[0].__jmpbuf[0].__pc));
+
+  /* .. and the stack pointer;  */
+  env[0].__jmpbuf[0].__sp = sp;
+
+  /* .. and the FP; it'll be in s8. */
+  env[0].__jmpbuf[0].__fp = fp;
+
+  /* .. and the GP; */
+  env[0].__jmpbuf[0].__gp = gp;
+
+  /* .. and the callee-saved registers; */
+  asm volatile ("sd $16, %0" : : "m" (env[0].__jmpbuf[0].__regs[0]));
+  asm volatile ("sd $17, %0" : : "m" (env[0].__jmpbuf[0].__regs[1]));
+  asm volatile ("sd $18, %0" : : "m" (env[0].__jmpbuf[0].__regs[2]));
+  asm volatile ("sd $19, %0" : : "m" (env[0].__jmpbuf[0].__regs[3]));
+  asm volatile ("sd $20, %0" : : "m" (env[0].__jmpbuf[0].__regs[4]));
+  asm volatile ("sd $21, %0" : : "m" (env[0].__jmpbuf[0].__regs[5]));
+  asm volatile ("sd $22, %0" : : "m" (env[0].__jmpbuf[0].__regs[6]));
+  asm volatile ("sd $23, %0" : : "m" (env[0].__jmpbuf[0].__regs[7]));
+
+  /* .. and finally get and reconstruct the floating point csr.  */
+  asm ("cfc1 %0, $31" : "=r" (env[0].__jmpbuf[0].__fpc_csr));
+
+  /* Save the signal mask if requested.  */
+  return __sigjmp_save (env, savemask);
+}
diff --git a/sysdeps/mips/mips64/soft-fp/Dist b/sysdeps/mips/mips64/soft-fp/Dist
new file mode 100644
index 0000000000..7e9914fe58
--- /dev/null
+++ b/sysdeps/mips/mips64/soft-fp/Dist
@@ -0,0 +1 @@
+sfp-machine.h
diff --git a/sysdeps/mips/mips64/soft-fp/sfp-machine.h b/sysdeps/mips/mips64/soft-fp/sfp-machine.h
new file mode 100644
index 0000000000..309a14a5f8
--- /dev/null
+++ b/sysdeps/mips/mips64/soft-fp/sfp-machine.h
@@ -0,0 +1,47 @@
+#define _FP_W_TYPE_SIZE		64
+#define _FP_W_TYPE		unsigned long long
+#define _FP_WS_TYPE		signed long long
+#define _FP_I_TYPE		long long
+
+#define _FP_MUL_MEAT_S(R,X,Y)					\
+  _FP_MUL_MEAT_1_imm(_FP_WFRACBITS_S,R,X,Y)
+#define _FP_MUL_MEAT_D(R,X,Y)					\
+  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_Q(R,X,Y)					\
+  _FP_MUL_MEAT_2_wide_3mul(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_S(R,X,Y)	_FP_DIV_MEAT_1_imm(S,R,X,Y,_FP_DIV_HELP_imm)
+#define _FP_DIV_MEAT_D(R,X,Y)	_FP_DIV_MEAT_1_udiv_norm(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y)	_FP_DIV_MEAT_2_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S		((_FP_QNANBIT_S << 1) - 1)
+#define _FP_NANFRAC_D		((_FP_QNANBIT_D << 1) - 1)
+#define _FP_NANFRAC_Q		((_FP_QNANBIT_Q << 1) - 1), -1
+#define _FP_NANSIGN_S		0
+#define _FP_NANSIGN_D		0
+#define _FP_NANSIGN_Q		0
+
+#define _FP_KEEPNANFRACP 1
+/* From my experiments it seems X is chosen unless one of the
+   NaNs is sNaN,  in which case the result is NANSIGN/NANFRAC.  */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
+  do {								\
+    if ((_FP_FRAC_HIGH_RAW_##fs(X) |				\
+	 _FP_FRAC_HIGH_RAW_##fs(Y)) & _FP_QNANBIT_##fs)		\
+      {								\
+	R##_s = _FP_NANSIGN_##fs;				\
+        _FP_FRAC_SET_##wc(R,_FP_NANFRAC_##fs);			\
+      }								\
+    else							\
+      {								\
+	R##_s = X##_s;						\
+        _FP_FRAC_COPY_##wc(R,X);				\
+      }								\
+    R##_c = FP_CLS_NAN;						\
+  } while (0)
+
+#define FP_EX_INVALID           (1 << 4)
+#define FP_EX_DIVZERO           (1 << 3)
+#define FP_EX_OVERFLOW          (1 << 2)
+#define FP_EX_UNDERFLOW         (1 << 1)
+#define FP_EX_INEXACT           (1 << 0)
diff --git a/sysdeps/mips/mips64/sub_n.S b/sysdeps/mips/mips64/sub_n.S
new file mode 100644
index 0000000000..aa8b0dcf9a
--- /dev/null
+++ b/sysdeps/mips/mips64/sub_n.S
@@ -0,0 +1,130 @@
+/* MIPS3 __mpn_sub_n -- Subtract two limb vectors of the same length > 0 and
+ * store difference in a third limb vector.
+ *
+ * Copyright (C) 1995, 2000, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of the GNU MP Library.
+ *
+ * The GNU MP 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 MP 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 MP 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 <sys/asm.h>
+
+/* INPUT PARAMETERS
+ * res_ptr	$4
+ * s1_ptr	$5
+ * s2_ptr	$6
+ * size		$7
+ */
+
+#ifdef __PIC__
+	.option pic2
+#endif
+	.text
+	.align	2
+	.globl	__mpn_sub_n
+	.ent	__mpn_sub_n
+__mpn_sub_n:
+#ifdef __PIC__
+	SETUP_GP /* ??? unused */
+#endif
+	.set	noreorder
+	.set	nomacro
+
+	ld	$10,0($5)
+	ld	$11,0($6)
+
+	daddiu	$7,$7,-1
+	and	$9,$7,4-1	# number of limbs in first loop
+	beq	$9,$0,L(L0)	# if multiple of 4 limbs, skip first loop
+	move	$2,$0
+
+	dsubu	$7,$7,$9
+
+L(Loop0):	daddiu	$9,$9,-1
+	ld	$12,8($5)
+	daddu	$11,$11,$2
+	ld	$13,8($6)
+	sltu	$8,$11,$2
+	dsubu	$11,$10,$11
+	sltu	$2,$10,$11
+	sd	$11,0($4)
+	or	$2,$2,$8
+
+	daddiu	$5,$5,8
+	daddiu	$6,$6,8
+	move	$10,$12
+	move	$11,$13
+	bne	$9,$0,L(Loop0)
+	daddiu	$4,$4,8
+
+L(L0):	beq	$7,$0,L(Lend)
+	nop
+
+L(Loop):	daddiu	$7,$7,-4
+
+	ld	$12,8($5)
+	daddu	$11,$11,$2
+	ld	$13,8($6)
+	sltu	$8,$11,$2
+	dsubu	$11,$10,$11
+	sltu	$2,$10,$11
+	sd	$11,0($4)
+	or	$2,$2,$8
+
+	ld	$10,16($5)
+	daddu	$13,$13,$2
+	ld	$11,16($6)
+	sltu	$8,$13,$2
+	dsubu	$13,$12,$13
+	sltu	$2,$12,$13
+	sd	$13,8($4)
+	or	$2,$2,$8
+
+	ld	$12,24($5)
+	daddu	$11,$11,$2
+	ld	$13,24($6)
+	sltu	$8,$11,$2
+	dsubu	$11,$10,$11
+	sltu	$2,$10,$11
+	sd	$11,16($4)
+	or	$2,$2,$8
+
+	ld	$10,32($5)
+	daddu	$13,$13,$2
+	ld	$11,32($6)
+	sltu	$8,$13,$2
+	dsubu	$13,$12,$13
+	sltu	$2,$12,$13
+	sd	$13,24($4)
+	or	$2,$2,$8
+
+	daddiu	$5,$5,32
+	daddiu	$6,$6,32
+
+	bne	$7,$0,L(Loop)
+	daddiu	$4,$4,32
+
+L(Lend):	daddu	$11,$11,$2
+	sltu	$8,$11,$2
+	dsubu	$11,$10,$11
+	sltu	$2,$10,$11
+	sd	$11,0($4)
+	j	$31
+	or	$2,$2,$8
+
+	.end	__mpn_sub_n
diff --git a/sysdeps/mips/mips64/submul_1.S b/sysdeps/mips/mips64/submul_1.S
new file mode 100644
index 0000000000..4971b992a1
--- /dev/null
+++ b/sysdeps/mips/mips64/submul_1.S
@@ -0,0 +1,108 @@
+/* MIPS3 __mpn_submul_1 -- Multiply a limb vector with a single limb and
+ * subtract the product from a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 2000, 2002, 2003
+ * Free Software Foundation, Inc.
+ *
+ * This file is part of the GNU MP Library.
+ *
+ * The GNU MP 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 MP 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 MP 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 <sys/asm.h>
+
+/* INPUT PARAMETERS
+ * res_ptr	$4
+ * s1_ptr	$5
+ * size		$6
+ * s2_limb	$7
+ */
+
+#ifdef __PIC__
+	.option pic2
+#endif
+	.text
+	.align	4
+	.globl	__mpn_submul_1
+	.ent	__mpn_submul_1
+__mpn_submul_1:
+#ifdef __PIC__
+	SETUP_GP /* ??? unused */
+#endif
+	.set    noreorder
+	.set    nomacro
+
+ # warm up phase 0
+	ld	$8,0($5)
+
+ # warm up phase 1
+	daddiu	$5,$5,8
+	dmultu	$8,$7
+
+	daddiu	$6,$6,-1
+	beq	$6,$0,L(LC0)
+	move	$2,$0		# zero cy2
+
+	daddiu	$6,$6,-1
+	beq	$6,$0,L(LC1)
+	ld	$8,0($5)	# load new s1 limb as early as possible
+
+L(Loop):	ld	$10,0($4)
+	mflo	$3
+	mfhi	$9
+	daddiu	$5,$5,8
+	daddu	$3,$3,$2	# add old carry limb to low product limb
+	dmultu	$8,$7
+	ld	$8,0($5)	# load new s1 limb as early as possible
+	daddiu	$6,$6,-1	# decrement loop counter
+	sltu	$2,$3,$2	# carry from previous addition -> $2
+	dsubu	$3,$10,$3
+	sgtu	$10,$3,$10
+	daddu	$2,$2,$10
+	sd	$3,0($4)
+	daddiu	$4,$4,8
+	bne	$6,$0,L(Loop)
+	daddu	$2,$9,$2	# add high product limb and carry from addition
+
+ # cool down phase 1
+L(LC1):	ld	$10,0($4)
+	mflo	$3
+	mfhi	$9
+	daddu	$3,$3,$2
+	sltu	$2,$3,$2
+	dmultu	$8,$7
+	dsubu	$3,$10,$3
+	sgtu	$10,$3,$10
+	daddu	$2,$2,$10
+	sd	$3,0($4)
+	daddiu	$4,$4,8
+	daddu	$2,$9,$2	# add high product limb and carry from addition
+
+ # cool down phase 0
+L(LC0):	ld	$10,0($4)
+	mflo	$3
+	mfhi	$9
+	daddu	$3,$3,$2
+	sltu	$2,$3,$2
+	dsubu	$3,$10,$3
+	sgtu	$10,$3,$10
+	daddu	$2,$2,$10
+	sd	$3,0($4)
+	j	$31
+	daddu	$2,$9,$2	# add high product limb and carry from addition
+
+	.end	__mpn_submul_1