about summary refs log tree commit diff
path: root/sysdeps/mips
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/mips')
-rw-r--r--sysdeps/mips/.cvsignore4
-rw-r--r--sysdeps/mips/Dist8
-rw-r--r--sysdeps/mips/Implies3
-rw-r--r--sysdeps/mips/Makefile12
-rw-r--r--sysdeps/mips/__longjmp.c84
-rw-r--r--sysdeps/mips/abort-instr.h2
-rw-r--r--sysdeps/mips/add_n.S122
-rw-r--r--sysdeps/mips/addmul_1.S99
-rw-r--r--sysdeps/mips/atomicity.h113
-rw-r--r--sysdeps/mips/bits/dlfcn.h66
-rw-r--r--sysdeps/mips/bits/endian.h13
-rw-r--r--sysdeps/mips/bits/fenv.h77
-rw-r--r--sysdeps/mips/bits/ipctypes.h32
-rw-r--r--sysdeps/mips/bits/nan.h56
-rw-r--r--sysdeps/mips/bits/setjmp.h81
-rw-r--r--sysdeps/mips/bits/wordsize.h19
-rw-r--r--sysdeps/mips/bsd-_setjmp.S43
-rw-r--r--sysdeps/mips/bsd-setjmp.S42
-rw-r--r--sysdeps/mips/dl-dtprocnum.h22
-rw-r--r--sysdeps/mips/dl-machine.h777
-rw-r--r--sysdeps/mips/elf/ldsodefs.h109
-rw-r--r--sysdeps/mips/elf/start.S119
-rw-r--r--sysdeps/mips/fpregdef.h24
-rw-r--r--sysdeps/mips/fpu/bits/mathdef.h46
-rw-r--r--sysdeps/mips/fpu/e_sqrt.c38
-rw-r--r--sysdeps/mips/fpu/e_sqrtf.c39
-rw-r--r--sysdeps/mips/fpu/fclrexcpt.c47
-rw-r--r--sysdeps/mips/fpu/fedisblxcpt.c42
-rw-r--r--sysdeps/mips/fpu/feenablxcpt.c42
-rw-r--r--sysdeps/mips/fpu/fegetenv.c31
-rw-r--r--sysdeps/mips/fpu/fegetexcept.c34
-rw-r--r--sysdeps/mips/fpu/fegetround.c33
-rw-r--r--sysdeps/mips/fpu/feholdexcpt.c38
-rw-r--r--sysdeps/mips/fpu/fenv_libc.h32
-rw-r--r--sysdeps/mips/fpu/fesetenv.c43
-rw-r--r--sysdeps/mips/fpu/fesetround.c43
-rw-r--r--sysdeps/mips/fpu/feupdateenv.c43
-rw-r--r--sysdeps/mips/fpu/fgetexcptflg.c40
-rw-r--r--sysdeps/mips/fpu/fraiseexcpt.c47
-rw-r--r--sysdeps/mips/fpu/fsetexcptflg.c43
-rw-r--r--sysdeps/mips/fpu/ftestexcept.c33
-rw-r--r--sysdeps/mips/fpu/libm-test-ulps890
-rw-r--r--sysdeps/mips/fpu_control.h98
-rw-r--r--sysdeps/mips/gccframe.h22
-rw-r--r--sysdeps/mips/ieee754.h325
-rw-r--r--sysdeps/mips/init-first.c64
-rw-r--r--sysdeps/mips/lshift.S98
-rw-r--r--sysdeps/mips/machine-gmon.h141
-rw-r--r--sysdeps/mips/memcpy.S136
-rw-r--r--sysdeps/mips/memset.S86
-rw-r--r--sysdeps/mips/memusage.h21
-rw-r--r--sysdeps/mips/mips32/Implies2
-rw-r--r--sysdeps/mips/mips32/Makefile3
-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
-rw-r--r--sysdeps/mips/mul_1.S87
-rw-r--r--sysdeps/mips/regdef.h27
-rw-r--r--sysdeps/mips/rshift.S95
-rw-r--r--sysdeps/mips/setjmp.S45
-rw-r--r--sysdeps/mips/setjmp_aux.c65
-rw-r--r--sysdeps/mips/sgidefs.h73
-rw-r--r--sysdeps/mips/soft-fp/Dist1
-rw-r--r--sysdeps/mips/soft-fp/sfp-machine.h47
-rw-r--r--sysdeps/mips/stackinfo.h28
-rw-r--r--sysdeps/mips/sub_n.S122
-rw-r--r--sysdeps/mips/submul_1.S99
-rw-r--r--sysdeps/mips/sys/asm.h473
-rw-r--r--sysdeps/mips/sys/fpregdef.h61
-rw-r--r--sysdeps/mips/sys/regdef.h82
-rw-r--r--sysdeps/mips/sys/ucontext.h159
91 files changed, 7422 insertions, 0 deletions
diff --git a/sysdeps/mips/.cvsignore b/sysdeps/mips/.cvsignore
new file mode 100644
index 0000000000..1f69fd919a
--- /dev/null
+++ b/sysdeps/mips/.cvsignore
@@ -0,0 +1,4 @@
+*.gz *.Z *.tar *.tgz
+=*
+TODO COPYING* AUTHORS copyr-* copying.*
+glibc-*
diff --git a/sysdeps/mips/Dist b/sysdeps/mips/Dist
new file mode 100644
index 0000000000..1fbf36aaad
--- /dev/null
+++ b/sysdeps/mips/Dist
@@ -0,0 +1,8 @@
+setjmp_aux.c
+regdef.h
+sgidefs.h
+fpregdef.h
+fpu/fenv_libc.h
+sys/fpregdef.h
+sys/regdef.h
+sys/asm.h
diff --git a/sysdeps/mips/Implies b/sysdeps/mips/Implies
new file mode 100644
index 0000000000..8c18cb3034
--- /dev/null
+++ b/sysdeps/mips/Implies
@@ -0,0 +1,3 @@
+# MIPS uses IEEE 754 floating point.
+ieee754/flt-32
+ieee754/dbl-64
diff --git a/sysdeps/mips/Makefile b/sysdeps/mips/Makefile
new file mode 100644
index 0000000000..49ad3e1b91
--- /dev/null
+++ b/sysdeps/mips/Makefile
@@ -0,0 +1,12 @@
+ifeq ($(subdir),misc)
+sysdep_headers += regdef.h fpregdef.h sys/regdef.h sys/fpregdef.h \
+		  sys/asm.h sgidefs.h
+endif
+
+ifeq ($(subdir),setjmp)
+sysdep_routines += setjmp_aux
+endif
+
+ifeq ($(subdir),rt)
+librt-sysdep_routines += rt-sysdep
+endif
diff --git a/sysdeps/mips/__longjmp.c b/sysdeps/mips/__longjmp.c
new file mode 100644
index 0000000000..750a71fd1e
--- /dev/null
+++ b/sysdeps/mips/__longjmp.c
@@ -0,0 +1,84 @@
+/* Copyright (C) 1992, 1995, 1997, 2000 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 <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.  */
+  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]));
+
+  /* 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 ("lw $gp, %0" : : "m" (env[0].__gp));
+
+  /* Get the callee-saved registers.  */
+  asm volatile ("lw $16, %0" : : "m" (env[0].__regs[0]));
+  asm volatile ("lw $17, %0" : : "m" (env[0].__regs[1]));
+  asm volatile ("lw $18, %0" : : "m" (env[0].__regs[2]));
+  asm volatile ("lw $19, %0" : : "m" (env[0].__regs[3]));
+  asm volatile ("lw $20, %0" : : "m" (env[0].__regs[4]));
+  asm volatile ("lw $21, %0" : : "m" (env[0].__regs[5]));
+  asm volatile ("lw $22, %0" : : "m" (env[0].__regs[6]));
+  asm volatile ("lw $23, %0" : : "m" (env[0].__regs[7]));
+
+  /* Get the PC.  */
+  asm volatile ("lw $25, %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 ("lw $29, %0\n\t"
+		"lw $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 ("li $2, 1");
+  else
+    asm volatile ("move $2, %0" : : "r" (val));
+
+  asm volatile ("jr $25");
+
+  /* Avoid `volatile function does return' warnings.  */
+  for (;;);
+}
diff --git a/sysdeps/mips/abort-instr.h b/sysdeps/mips/abort-instr.h
new file mode 100644
index 0000000000..d7d8d501b3
--- /dev/null
+++ b/sysdeps/mips/abort-instr.h
@@ -0,0 +1,2 @@
+/* An instruction which should crash any program is a breakpoint.  */
+#define ABORT_INSTRUCTION asm ("break 255")
diff --git a/sysdeps/mips/add_n.S b/sysdeps/mips/add_n.S
new file mode 100644
index 0000000000..c82871f701
--- /dev/null
+++ b/sysdeps/mips/add_n.S
@@ -0,0 +1,122 @@
+/* MIPS2 __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>
+
+/* INPUT PARAMETERS
+   res_ptr	$4
+   s1_ptr	$5
+   s2_ptr	$6
+   size		$7
+*/
+#ifdef __PIC__
+	.option pic2
+#endif
+ENTRY (__mpn_add_n)
+	.set	noreorder
+#ifdef __PIC__
+	.cpload t9
+#endif
+	.set	nomacro
+
+	lw	$10,0($5)
+	lw	$11,0($6)
+
+	addiu	$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
+
+	subu	$7,$7,$9
+
+L(Loop0):	addiu	$9,$9,-1
+	lw	$12,4($5)
+	addu	$11,$11,$2
+	lw	$13,4($6)
+	sltu	$8,$11,$2
+	addu	$11,$10,$11
+	sltu	$2,$11,$10
+	sw	$11,0($4)
+	or	$2,$2,$8
+
+	addiu	$5,$5,4
+	addiu	$6,$6,4
+	move	$10,$12
+	move	$11,$13
+	bne	$9,$0,L(Loop0)
+	addiu	$4,$4,4
+
+L(L0):	beq	$7,$0,L(end)
+	nop
+
+L(Loop):	addiu	$7,$7,-4
+
+	lw	$12,4($5)
+	addu	$11,$11,$2
+	lw	$13,4($6)
+	sltu	$8,$11,$2
+	addu	$11,$10,$11
+	sltu	$2,$11,$10
+	sw	$11,0($4)
+	or	$2,$2,$8
+
+	lw	$10,8($5)
+	addu	$13,$13,$2
+	lw	$11,8($6)
+	sltu	$8,$13,$2
+	addu	$13,$12,$13
+	sltu	$2,$13,$12
+	sw	$13,4($4)
+	or	$2,$2,$8
+
+	lw	$12,12($5)
+	addu	$11,$11,$2
+	lw	$13,12($6)
+	sltu	$8,$11,$2
+	addu	$11,$10,$11
+	sltu	$2,$11,$10
+	sw	$11,8($4)
+	or	$2,$2,$8
+
+	lw	$10,16($5)
+	addu	$13,$13,$2
+	lw	$11,16($6)
+	sltu	$8,$13,$2
+	addu	$13,$12,$13
+	sltu	$2,$13,$12
+	sw	$13,12($4)
+	or	$2,$2,$8
+
+	addiu	$5,$5,16
+	addiu	$6,$6,16
+
+	bne	$7,$0,L(Loop)
+	addiu	$4,$4,16
+
+L(end):	addu	$11,$11,$2
+	sltu	$8,$11,$2
+	addu	$11,$10,$11
+	sltu	$2,$11,$10
+	sw	$11,0($4)
+	j	$31
+	or	$2,$2,$8
+	.end __mpn_add_n
diff --git a/sysdeps/mips/addmul_1.S b/sysdeps/mips/addmul_1.S
new file mode 100644
index 0000000000..3e1fc09d10
--- /dev/null
+++ b/sysdeps/mips/addmul_1.S
@@ -0,0 +1,99 @@
+/* MIPS __mpn_addmul_1 -- Multiply a limb vector with a single limb and
+add the product to a second 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>
+
+/* INPUT PARAMETERS
+   res_ptr	$4
+   s1_ptr	$5
+   size		$6
+   s2_limb	$7
+*/
+#ifdef __PIC__
+	.option pic2
+#endif
+ENTRY (__mpn_addmul_1)
+	.set    noreorder
+#ifdef __PIC__
+	.cpload t9
+#endif
+	.set    nomacro
+
+	/* warm up phase 0 */
+	lw	$8,0($5)
+
+	/* warm up phase 1 */
+	addiu	$5,$5,4
+	multu	$8,$7
+
+	addiu	$6,$6,-1
+	beq	$6,$0,L(LC0)
+	move	$2,$0		/* zero cy2 */
+
+	addiu	$6,$6,-1
+	beq	$6,$0,L(LC1)
+	lw	$8,0($5)	/* load new s1 limb as early as possible */
+
+L(Loop):	lw	$10,0($4)
+	mflo	$3
+	mfhi	$9
+	addiu	$5,$5,4
+	addu	$3,$3,$2	/* add old carry limb to low product limb */
+	multu	$8,$7
+	lw	$8,0($5)	/* load new s1 limb as early as possible */
+	addiu	$6,$6,-1	/* decrement loop counter */
+	sltu	$2,$3,$2	/* carry from previous addition -> $2 */
+	addu	$3,$10,$3
+	sltu	$10,$3,$10
+	addu	$2,$2,$10
+	sw	$3,0($4)
+	addiu	$4,$4,4
+	bne	$6,$0,L(Loop)	/* should be "bnel" */
+	addu	$2,$9,$2	/* add high product limb and carry from addition */
+
+	/* cool down phase 1 */
+L(LC1):	lw	$10,0($4)
+	mflo	$3
+	mfhi	$9
+	addu	$3,$3,$2
+	sltu	$2,$3,$2
+	multu	$8,$7
+	addu	$3,$10,$3
+	sltu	$10,$3,$10
+	addu	$2,$2,$10
+	sw	$3,0($4)
+	addiu	$4,$4,4
+	addu	$2,$9,$2	/* add high product limb and carry from addition */
+
+	/* cool down phase 0 */
+L(LC0):	lw	$10,0($4)
+	mflo	$3
+	mfhi	$9
+	addu	$3,$3,$2
+	sltu	$2,$3,$2
+	addu	$3,$10,$3
+	sltu	$10,$3,$10
+	addu	$2,$2,$10
+	sw	$3,0($4)
+	j	$31
+	addu	$2,$9,$2	/* add high product limb and carry from addition */
+	END (__mpn_addmul_1)
diff --git a/sysdeps/mips/atomicity.h b/sysdeps/mips/atomicity.h
new file mode 100644
index 0000000000..7380e1000c
--- /dev/null
+++ b/sysdeps/mips/atomicity.h
@@ -0,0 +1,113 @@
+/* Low-level functions for atomic operations. Mips version.
+   Copyright (C) 2001, 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.  */
+
+#ifndef _MIPS_ATOMICITY_H
+#define _MIPS_ATOMICITY_H    1
+
+#include <inttypes.h>
+#include <sgidefs.h>
+
+static inline int
+__attribute__ ((unused))
+exchange_and_add (volatile uint32_t *mem, int val)
+{
+  int result, tmp;
+
+  __asm__ __volatile__
+    ("/* Inline exchange & add */\n"
+     "1:\n\t"
+     ".set	push\n\t"
+#if _MIPS_SIM == _ABIO32
+     ".set	mips2\n\t"
+#endif
+     "ll	%0,%3\n\t"
+     "addu	%1,%4,%0\n\t"
+     "sc	%1,%2\n\t"
+     ".set	pop\n\t"
+     "beqz	%1,1b\n\t"
+     "/* End exchange & add */"
+     : "=&r"(result), "=&r"(tmp), "=m"(*mem)
+     : "m" (*mem), "r"(val)
+     : "memory");
+
+  return result;
+}
+
+static inline void
+__attribute__ ((unused))
+atomic_add (volatile uint32_t *mem, int val)
+{
+  int result;
+
+  __asm__ __volatile__
+    ("/* Inline atomic add */\n"
+     "1:\n\t"
+     ".set	push\n\t"
+#if _MIPS_SIM == _ABIO32
+     ".set	mips2\n\t"
+#endif
+     "ll	%0,%2\n\t"
+     "addu	%0,%3,%0\n\t"
+     "sc	%0,%1\n\t"
+     ".set	pop\n\t"
+     "beqz	%0,1b\n\t"
+     "/* End atomic add */"
+     : "=&r"(result), "=m"(*mem)
+     : "m" (*mem), "r"(val)
+     : "memory");
+}
+
+static inline int
+__attribute__ ((unused))
+compare_and_swap (volatile long int *p, long int oldval, long int newval)
+{
+  long int ret, temp;
+
+  __asm__ __volatile__
+    ("/* Inline compare & swap */\n"
+     "1:\n\t"
+     ".set	push\n\t"
+#if _MIPS_SIM == _ABIO32
+     ".set	mips2\n\t"
+#endif
+#if _MIPS_SIM == _ABI64
+     "lld	%1,%5\n\t"
+#else
+     "ll	%1,%5\n\t"
+#endif
+     "move	%0,$0\n\t"
+     "bne	%1,%3,2f\n\t"
+     "move	%0,%4\n\t"
+#if _MIPS_SIM == _ABI64
+     "scd	%0,%2\n\t"
+#else
+     "sc	%0,%2\n\t"
+#endif
+     ".set	pop\n\t"
+     "beqz	%0,1b\n"
+     "2:\n\t"
+     "/* End compare & swap */"
+     : "=&r" (ret), "=&r" (temp), "=m" (*p)
+     : "r" (oldval), "r" (newval), "m" (*p)
+     : "memory");
+
+  return ret;
+}
+
+#endif /* atomicity.h */
diff --git a/sysdeps/mips/bits/dlfcn.h b/sysdeps/mips/bits/dlfcn.h
new file mode 100644
index 0000000000..a5b5bf53ff
--- /dev/null
+++ b/sysdeps/mips/bits/dlfcn.h
@@ -0,0 +1,66 @@
+/* System dependent definitions for run-time dynamic loading.
+   Copyright (C) 1996, 1997, 1999, 2000, 2001, 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.  */
+
+#ifndef _DLFCN_H
+# error "Never use <bits/dlfcn.h> directly; include <dlfcn.h> instead."
+#endif
+
+/* The MODE argument to `dlopen' contains one of the following: */
+#define RTLD_LAZY	0x0001	/* Lazy function call binding.  */
+#define RTLD_NOW	0x0002	/* Immediate function call binding.  */
+#define RTLD_BINDING_MASK  0x3	/* Mask of binding time value.  */
+#define RTLD_NOLOAD	0x00008	/* Do not load the object.  */
+#define RTLD_DEEPBIND	0x00010	/* Use deep binding.  */
+
+/* If the following bit is set in the MODE argument to `dlopen',
+   the symbols of the loaded object and its dependencies are made
+   visible as if the object were linked directly into the program.  */
+#define RTLD_GLOBAL	0x0004
+
+/* Unix98 demands the following flag which is the inverse to RTLD_GLOBAL.
+   The implementation does this by default and so we can define the
+   value to zero.  */
+#define RTLD_LOCAL      0
+
+/* Do not delete object when closed.  */
+#define RTLD_NODELETE	0x01000
+
+#ifdef __USE_GNU
+/* To support profiling of shared objects it is a good idea to call
+   the function found using `dlsym' using the following macro since
+   these calls do not use the PLT.  But this would mean the dynamic
+   loader has no chance to find out when the function is called.  The
+   macro applies the necessary magic so that profiling is possible.
+   Rewrite
+	foo = (*fctp) (arg1, arg2);
+   into
+        foo = DL_CALL_FCT (fctp, (arg1, arg2));
+*/
+# define DL_CALL_FCT(fctp, args) \
+  (_dl_mcount_wrapper_check ((void *) (fctp)), (*(fctp)) args)
+
+__BEGIN_DECLS
+
+/* This function calls the profiling functions.  */
+extern void _dl_mcount_wrapper_check (void *__selfpc) __THROW;
+
+__END_DECLS
+
+#endif
diff --git a/sysdeps/mips/bits/endian.h b/sysdeps/mips/bits/endian.h
new file mode 100644
index 0000000000..9586104ccd
--- /dev/null
+++ b/sysdeps/mips/bits/endian.h
@@ -0,0 +1,13 @@
+/* The MIPS architecture has selectable endianness.
+   This file is for a machine using big-endian mode.  */
+
+#ifndef _ENDIAN_H
+# error "Never use <bits/endian.h> directly; include <endian.h> instead."
+#endif
+
+#if __MIPSEB
+# define __BYTE_ORDER __BIG_ENDIAN
+#endif
+#if __MIPSEL
+# define __BYTE_ORDER __LITTLE_ENDIAN
+#endif
diff --git a/sysdeps/mips/bits/fenv.h b/sysdeps/mips/bits/fenv.h
new file mode 100644
index 0000000000..24e0694ca5
--- /dev/null
+++ b/sysdeps/mips/bits/fenv.h
@@ -0,0 +1,77 @@
+/* Copyright (C) 1998, 1999, 2000 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.  */
+
+#ifndef _FENV_H
+# error "Never use <bits/fenv.h> directly; include <fenv.h> instead."
+#endif
+
+
+/* Define bits representing the exception.  We use the bit positions
+   of the appropriate bits in the FPU control word.  */
+enum
+  {
+    FE_INEXACT = 0x04,
+#define FE_INEXACT	FE_INEXACT
+    FE_UNDERFLOW = 0x08,
+#define FE_UNDERFLOW	FE_UNDERFLOW
+    FE_OVERFLOW = 0x10,
+#define FE_OVERFLOW	FE_OVERFLOW
+    FE_DIVBYZERO = 0x20,
+#define FE_DIVBYZERO	FE_DIVBYZERO
+    FE_INVALID = 0x40,
+#define FE_INVALID	FE_INVALID
+  };
+
+#define FE_ALL_EXCEPT \
+	(FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID)
+
+/* The MIPS FPU supports all of the four defined rounding modes.  We
+   use again the bit positions in the FPU control word as the values
+   for the appropriate macros.  */
+enum
+  {
+    FE_TONEAREST = 0x0,
+#define FE_TONEAREST	FE_TONEAREST
+    FE_TOWARDZERO = 0x1,
+#define FE_TOWARDZERO	FE_TOWARDZERO
+    FE_UPWARD = 0x2,
+#define FE_UPWARD	FE_UPWARD
+    FE_DOWNWARD = 0x3
+#define FE_DOWNWARD	FE_DOWNWARD
+  };
+
+
+/* Type representing exception flags.  */
+typedef unsigned short int fexcept_t;
+
+
+/* Type representing floating-point environment.  This function corresponds
+   to the layout of the block written by the `fstenv'.  */
+typedef struct
+  {
+    unsigned int __fp_control_register;
+  }
+fenv_t;
+
+/* If the default argument is used we use this value.  */
+#define FE_DFL_ENV	((__const fenv_t *) -1)
+
+#ifdef __USE_GNU
+/* Floating-point environment where none of the exception is masked.  */
+# define FE_NOMASK_ENV  ((__const fenv_t *) -2)
+#endif
diff --git a/sysdeps/mips/bits/ipctypes.h b/sysdeps/mips/bits/ipctypes.h
new file mode 100644
index 0000000000..0956e7d58c
--- /dev/null
+++ b/sysdeps/mips/bits/ipctypes.h
@@ -0,0 +1,32 @@
+/* bits/ipctypes.h -- Define some types used by SysV IPC/MSG/SHM.  MIPS version
+   Copyright (C) 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.  */
+
+/*
+ * Never include <bits/ipctypes.h> directly.
+ */
+
+#ifndef _BITS_IPCTYPES_H
+#define _BITS_IPCTYPES_H	1
+
+#include <bits/types.h>
+
+typedef __SLONG32_TYPE __ipc_pid_t;
+
+
+#endif /* bits/ipctypes.h */
diff --git a/sysdeps/mips/bits/nan.h b/sysdeps/mips/bits/nan.h
new file mode 100644
index 0000000000..baaaa551fb
--- /dev/null
+++ b/sysdeps/mips/bits/nan.h
@@ -0,0 +1,56 @@
+/* `NAN' constant for IEEE 754 machines.
+   Copyright (C) 1992, 1996, 1997, 1999, 2002, 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.  */
+
+#ifndef _MATH_H
+# error "Never use <bits/nan.h> directly; include <math.h> instead."
+#endif
+
+
+/* IEEE Not A Number (QNaN). Note that MIPS has the QNaN and SNaN patterns
+   reversed compared to most other architectures. The IEEE spec left
+   the definition of this open to implementations, and for MIPS the top
+   bit of the mantissa must be SET to indicate a SNaN.  */
+
+#if __GNUC_PREREQ(3,3)
+
+# define NAN	(__builtin_nanf(""))
+
+#elif defined __GNUC__
+
+# define NAN \
+  (__extension__                                                            \
+   ((union { unsigned __l __attribute__((__mode__(__SI__))); float __d; })  \
+    { __l: 0x7fbfffffUL }).__d)
+
+#else
+
+# include <endian.h>
+
+# if __BYTE_ORDER == __BIG_ENDIAN
+#  define __nan_bytes		{ 0x7f, 0xbf, 0xff, 0xff }
+# endif
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+#  define __nan_bytes		{ 0xff, 0xff, 0xbf, 0x7f }
+# endif
+
+static union { unsigned char __c[4]; float __d; } __nan_union = { __nan_bytes };
+# define NAN	(__nan_union.__d)
+
+#endif	/* GCC.  */
diff --git a/sysdeps/mips/bits/setjmp.h b/sysdeps/mips/bits/setjmp.h
new file mode 100644
index 0000000000..ec0aaa020d
--- /dev/null
+++ b/sysdeps/mips/bits/setjmp.h
@@ -0,0 +1,81 @@
+/* Define the machine-dependent type `jmp_buf'.  MIPS version.
+   Copyright (C) 1992, 1993, 1995, 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.  */
+
+#ifndef _SETJMP_H
+# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
+#endif
+
+#include <sgidefs.h>
+
+typedef struct
+  {
+#if _MIPS_SIM == _ABIO32
+    /* Program counter.  */
+    __ptr_t __pc;
+
+    /* Stack pointer.  */
+    __ptr_t __sp;
+
+    /* Callee-saved registers s0 through s7.  */
+    int __regs[8];
+
+    /* The frame pointer.  */
+    __ptr_t __fp;
+
+    /* The global pointer.  */
+    __ptr_t __gp;
+#else
+    /* Program counter.  */
+    __extension__ long long __pc;
+
+    /* Stack pointer.  */
+    __extension__ long long __sp;
+
+    /* Callee-saved registers s0 through s7.  */
+    __extension__ long long __regs[8];
+
+    /* The frame pointer.  */
+    __extension__ long long __fp;
+
+    /* The global pointer.  */
+    __extension__ long long __gp;
+#endif
+
+    /* Floating point status register.  */
+    int __fpc_csr;
+
+    /* Callee-saved floating point registers.  */
+#if _MIPS_SIM == _ABI64
+    double __fpregs[8];
+#else
+    double __fpregs[6];
+#endif
+  } __jmp_buf[1];
+
+#ifdef __USE_MISC
+/* Offset to the program counter in `jmp_buf'.  */
+# define JB_PC	0
+#endif
+
+
+/* Test if longjmp to JMPBUF would unwind the frame
+   containing a local variable at ADDRESS.  */
+#define _JMPBUF_UNWINDS(jmpbuf, address) \
+  ((void *) (address) < (jmpbuf)[0].__sp)
diff --git a/sysdeps/mips/bits/wordsize.h b/sysdeps/mips/bits/wordsize.h
new file mode 100644
index 0000000000..666c7ad07e
--- /dev/null
+++ b/sysdeps/mips/bits/wordsize.h
@@ -0,0 +1,19 @@
+/* Copyright (C) 2002, 2003 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.  */
+
+#define __WORDSIZE	_MIPS_SZPTR
diff --git a/sysdeps/mips/bsd-_setjmp.S b/sysdeps/mips/bsd-_setjmp.S
new file mode 100644
index 0000000000..5e3ad50305
--- /dev/null
+++ b/sysdeps/mips/bsd-_setjmp.S
@@ -0,0 +1,43 @@
+/* BSD `_setjmp' entry point to `sigsetjmp (..., 0)'.  MIPS version.
+   Copyright (C) 1996, 1997, 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.  */
+
+/* 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 <sysdep.h>
+
+#ifdef __PIC__
+	.option pic2
+#endif
+ENTRY (_setjmp)
+#ifdef __PIC__
+	.set	noreorder
+	.cpload t9
+	.set	reorder
+	la	t9, C_SYMBOL_NAME (__sigsetjmp)
+#endif
+	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/bsd-setjmp.S b/sysdeps/mips/bsd-setjmp.S
new file mode 100644
index 0000000000..0aea011328
--- /dev/null
+++ b/sysdeps/mips/bsd-setjmp.S
@@ -0,0 +1,42 @@
+/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'.  MIPS version.
+   Copyright (C) 1996, 1997, 2000 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 <sysdep.h>
+
+#ifdef __PIC__
+	.option pic2
+#endif
+ENTRY (setjmp)
+	.set	noreorder
+#ifdef __PIC__
+	.cpload t9
+	.set	reorder
+	la	t9, C_SYMBOL_NAME (__sigsetjmp)
+#endif
+	li	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/dl-dtprocnum.h b/sysdeps/mips/dl-dtprocnum.h
new file mode 100644
index 0000000000..dfd03ba317
--- /dev/null
+++ b/sysdeps/mips/dl-dtprocnum.h
@@ -0,0 +1,22 @@
+/* Configuration of lookup functions.  MIPS version.
+   Copyright (C) 2000 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.  */
+
+/* Number of extra dynamic section entries for this architecture.  By
+   default there are none.  */
+#define DT_THISPROCNUM	DT_MIPS_NUM
diff --git a/sysdeps/mips/dl-machine.h b/sysdeps/mips/dl-machine.h
new file mode 100644
index 0000000000..0d87b65691
--- /dev/null
+++ b/sysdeps/mips/dl-machine.h
@@ -0,0 +1,777 @@
+/* Machine-dependent ELF dynamic relocation inline functions.  MIPS version.
+   Copyright (C) 1996-2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Kazumoto Kojima <kkojima@info.kanagawa-u.ac.jp>.
+
+   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.  */
+
+/*  FIXME: Profiling of shared libraries is not implemented yet.  */
+#ifndef dl_machine_h
+#define dl_machine_h
+
+#define ELF_MACHINE_NAME "MIPS"
+
+#define ELF_MACHINE_NO_PLT
+
+#include <entry.h>
+
+#ifndef ENTRY_POINT
+#error ENTRY_POINT needs to be defined for MIPS.
+#endif
+
+#include <sgidefs.h>
+#include <sys/asm.h>
+
+/* The offset of gp from GOT might be system-dependent.  It's set by
+   ld.  The same value is also */
+#define OFFSET_GP_GOT 0x7ff0
+
+#ifndef _RTLD_PROLOGUE
+# define _RTLD_PROLOGUE(entry)						\
+	".globl\t" __STRING(entry) "\n\t"				\
+	".ent\t" __STRING(entry) "\n\t"					\
+	".type\t" __STRING(entry) ", @function\n"			\
+	__STRING(entry) ":\n\t"
+#endif
+
+#ifndef _RTLD_EPILOGUE
+# define _RTLD_EPILOGUE(entry)						\
+	".end\t" __STRING(entry) "\n\t"					\
+	".size\t" __STRING(entry) ", . - " __STRING(entry) "\n\t"
+#endif
+
+/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries.
+   This makes no sense on MIPS but we have to define this to R_MIPS_REL32
+   to avoid the asserts in dl-lookup.c from blowing.  */
+#define ELF_MACHINE_JMP_SLOT			R_MIPS_REL32
+#define elf_machine_type_class(type)		ELF_RTYPE_CLASS_PLT
+
+/* Translate a processor specific dynamic tag to the index
+   in l_info array.  */
+#define DT_MIPS(x) (DT_MIPS_##x - DT_LOPROC + DT_NUM)
+
+/* If there is a DT_MIPS_RLD_MAP entry in the dynamic section, fill it in
+   with the run-time address of the r_debug structure  */
+#define ELF_MACHINE_DEBUG_SETUP(l,r) \
+do { if ((l)->l_info[DT_MIPS (RLD_MAP)]) \
+       *(ElfW(Addr) *)((l)->l_info[DT_MIPS (RLD_MAP)]->d_un.d_ptr) = \
+       (ElfW(Addr)) (r); \
+   } while (0)
+
+/* Return nonzero iff ELF header is compatible with the running host.  */
+static inline int __attribute_used__
+elf_machine_matches_host (const ElfW(Ehdr) *ehdr)
+{
+#if _MIPS_SIM == _ABIO32 || _MIPS_SIM == _ABIN32
+  /* Don't link o32 and n32 together.  */
+  if (((ehdr->e_flags & EF_MIPS_ABI2) != 0) != (_MIPS_SIM == _ABIN32))
+    return 0;
+#endif
+
+  switch (ehdr->e_machine)
+    {
+    case EM_MIPS:
+    case EM_MIPS_RS3_LE:
+      return 1;
+    default:
+      return 0;
+    }
+}
+
+static inline ElfW(Addr) *
+elf_mips_got_from_gpreg (ElfW(Addr) gpreg)
+{
+  /* FIXME: the offset of gp from GOT may be system-dependent. */
+  return (ElfW(Addr) *) (gpreg - OFFSET_GP_GOT);
+}
+
+/* Return the link-time address of _DYNAMIC.  Conveniently, this is the
+   first element of the GOT.  This must be inlined in a function which
+   uses global data.  We assume its $gp points to the primary GOT.  */
+static inline ElfW(Addr)
+elf_machine_dynamic (void)
+{
+  register ElfW(Addr) gp __asm__ ("$28");
+  return *elf_mips_got_from_gpreg (gp);
+}
+
+#define STRINGXP(X) __STRING(X)
+#define STRINGXV(X) STRINGV_(X)
+#define STRINGV_(...) # __VA_ARGS__
+
+/* Return the run-time load address of the shared object.  */
+static inline ElfW(Addr)
+elf_machine_load_address (void)
+{
+  ElfW(Addr) addr;
+  asm ("	.set noreorder\n"
+       "	" STRINGXP (PTR_LA) " %0, 0f\n"
+       "	bltzal $0, 0f\n"
+       "	nop\n"
+       "0:	" STRINGXP (PTR_SUBU) " %0, $31, %0\n"
+       "	.set reorder\n"
+       :	"=r" (addr)
+       :	/* No inputs */
+       :	"$31");
+  return addr;
+}
+
+/* The MSB of got[1] of a gnu object is set to identify gnu objects.  */
+#if _MIPS_SIM == _ABI64
+# define ELF_MIPS_GNU_GOT1_MASK	0x8000000000000000L
+#else
+# define ELF_MIPS_GNU_GOT1_MASK	0x80000000L
+#endif
+
+/* We can't rely on elf_machine_got_rel because _dl_object_relocation_scope
+   fiddles with global data.  */
+#define ELF_MACHINE_BEFORE_RTLD_RELOC(dynamic_info)			\
+do {									\
+  struct link_map *map = &bootstrap_map;				\
+  ElfW(Sym) *sym;							\
+  ElfW(Addr) *got;							\
+  int i, n;								\
+									\
+  got = (ElfW(Addr) *) D_PTR (map, l_info[DT_PLTGOT]);			\
+									\
+  if (__builtin_expect (map->l_addr == 0, 1))				\
+    break;								\
+									\
+  /* got[0] is reserved. got[1] is also reserved for the dynamic object	\
+     generated by gnu ld. Skip these reserved entries from		\
+     relocation.  */							\
+  i = (got[1] & ELF_MIPS_GNU_GOT1_MASK)? 2 : 1;				\
+  n = map->l_info[DT_MIPS (LOCAL_GOTNO)]->d_un.d_val;			\
+									\
+  /* Add the run-time displacement to all local got entries. */		\
+  while (i < n)								\
+    got[i++] += map->l_addr;						\
+									\
+  /* Handle global got entries. */					\
+  got += n;								\
+  sym = (ElfW(Sym) *) D_PTR(map, l_info[DT_SYMTAB])			\
+       + map->l_info[DT_MIPS (GOTSYM)]->d_un.d_val;			\
+  i = (map->l_info[DT_MIPS (SYMTABNO)]->d_un.d_val			\
+       - map->l_info[DT_MIPS (GOTSYM)]->d_un.d_val);			\
+									\
+  while (i--)								\
+    {									\
+      if (sym->st_shndx == SHN_UNDEF || sym->st_shndx == SHN_COMMON)	\
+	*got = map->l_addr + sym->st_value;				\
+      else if (ELFW(ST_TYPE) (sym->st_info) == STT_FUNC			\
+	       && *got != sym->st_value)				\
+	*got += map->l_addr;						\
+      else if (ELFW(ST_TYPE) (sym->st_info) == STT_SECTION)		\
+	{								\
+	  if (sym->st_other == 0)					\
+	    *got += map->l_addr;					\
+	}								\
+      else								\
+	*got = map->l_addr + sym->st_value;				\
+									\
+      got++;								\
+      sym++;								\
+    }									\
+} while(0)
+
+
+/* Get link map for callers object containing STUB_PC.  */
+static inline struct link_map *
+elf_machine_runtime_link_map (ElfW(Addr) gpreg, ElfW(Addr) stub_pc)
+{
+  extern int _dl_mips_gnu_objects;
+
+  /* got[1] is reserved to keep its link map address for the shared
+     object generated by the gnu linker.  If all are such objects, we
+     can find the link map from current GPREG simply.  If not so, get
+     the link map for caller's object containing STUB_PC.  */
+
+  if (_dl_mips_gnu_objects)
+    {
+      ElfW(Addr) *got = elf_mips_got_from_gpreg (gpreg);
+      ElfW(Word) g1;
+
+      g1 = ((ElfW(Word) *) got)[1];
+
+      if ((g1 & ELF_MIPS_GNU_GOT1_MASK) != 0)
+	{
+	  struct link_map *l =
+	    (struct link_map *) (g1 & ~ELF_MIPS_GNU_GOT1_MASK);
+	  ElfW(Addr) base, limit;
+	  const ElfW(Phdr) *p = l->l_phdr;
+	  ElfW(Half) this, nent = l->l_phnum;
+
+	  /* For the common case of a stub being called from the containing
+	     object, STUB_PC will point to somewhere within the object that
+	     is described by the link map fetched via got[1].  Otherwise we
+	     have to scan all maps.  */
+	  for (this = 0; this < nent; this++)
+	    {
+	      if (p[this].p_type == PT_LOAD)
+		{
+		  base = p[this].p_vaddr + l->l_addr;
+		  limit = base + p[this].p_memsz;
+		  if (stub_pc >= base && stub_pc < limit)
+		    return l;
+		}
+	    }
+	}
+    }
+
+    struct link_map *l;
+    Lmid_t nsid;
+
+    for (nsid = 0; nsid < DL_NNS; ++nsid)
+      for (l = GL(dl_ns)[nsid]._ns_loaded; l != NULL; l = l->l_next)
+	{
+	  ElfW(Addr) base, limit;
+	  const ElfW(Phdr) *p = l->l_phdr;
+	  ElfW(Half) this, nent = l->l_phnum;
+
+	  for (this = 0; this < nent; ++this)
+	    {
+	      if (p[this].p_type == PT_LOAD)
+		{
+		  base = p[this].p_vaddr + l->l_addr;
+		  limit = base + p[this].p_memsz;
+		  if (stub_pc >= base && stub_pc < limit)
+		    return l;
+		}
+	    }
+	}
+
+  _dl_signal_error (0, NULL, NULL, "cannot find runtime link map");
+  return NULL;
+}
+
+#if _MIPS_SIM == _ABIO32
+#define ELF_DL_FRAME_SIZE 40
+
+#define ELF_DL_SAVE_ARG_REGS "\
+	sw	$15, 36($29)\n						      \
+	sw	$4, 16($29)\n						      \
+	sw	$5, 20($29)\n						      \
+	sw	$6, 24($29)\n						      \
+	sw	$7, 28($29)\n						      \
+"
+
+#define ELF_DL_RESTORE_ARG_REGS "\
+	lw	$31, 36($29)\n						      \
+	lw	$4, 16($29)\n						      \
+	lw	$5, 20($29)\n						      \
+	lw	$6, 24($29)\n						      \
+	lw	$7, 28($29)\n						      \
+"
+
+#define IFABIO32(X) X
+
+#else /* _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64 */
+
+#define ELF_DL_FRAME_SIZE 80
+
+#define ELF_DL_SAVE_ARG_REGS "\
+	sd	$15, 72($29)\n						      \
+	sd	$4, 8($29)\n						      \
+	sd	$5, 16($29)\n						      \
+	sd	$6, 24($29)\n						      \
+	sd	$7, 32($29)\n						      \
+	sd	$8, 40($29)\n						      \
+	sd	$9, 48($29)\n						      \
+	sd	$10, 56($29)\n						      \
+	sd	$11, 64($29)\n						      \
+"
+
+#define ELF_DL_RESTORE_ARG_REGS "\
+	ld	$31, 72($29)\n						      \
+	ld	$4, 8($29)\n						      \
+	ld	$5, 16($29)\n						      \
+	ld	$6, 24($29)\n						      \
+	ld	$7, 32($29)\n						      \
+	ld	$8, 40($29)\n						      \
+	ld	$9, 48($29)\n						      \
+	ld	$10, 56($29)\n						      \
+	ld	$11, 64($29)\n						      \
+"
+
+#define IFABIO32(X)
+
+#endif
+
+/* Define mips specific runtime resolver. The function __dl_runtime_resolve
+   is called from assembler function _dl_runtime_resolve which converts
+   special argument registers t7 ($15) and t8 ($24):
+     t7  address to return to the caller of the function
+     t8  index for this function symbol in .dynsym
+   to usual c arguments.
+
+   Other architectures call fixup from dl-runtime.c in
+   _dl_runtime_resolve.  MIPS instead calls __dl_runtime_resolve.  We
+   have to use our own version because of the way the got section is
+   treated on MIPS (we've also got ELF_MACHINE_PLT defined).  */
+
+#define ELF_MACHINE_RUNTIME_TRAMPOLINE					      \
+/* The flag _dl_mips_gnu_objects is set if all dynamic objects are	      \
+   generated by the gnu linker. */					      \
+int _dl_mips_gnu_objects = 1;						      \
+									      \
+/* This is called from assembly stubs below which the compiler can't see.  */ \
+static ElfW(Addr)							      \
+__dl_runtime_resolve (ElfW(Word), ElfW(Word), ElfW(Addr), ElfW(Addr))	      \
+		  __attribute_used__;					      \
+									      \
+static ElfW(Addr)							      \
+__dl_runtime_resolve (ElfW(Word) sym_index,				      \
+		      ElfW(Word) return_address,			      \
+		      ElfW(Addr) old_gpreg,				      \
+		      ElfW(Addr) stub_pc)				      \
+{									      \
+  struct link_map *l = elf_machine_runtime_link_map (old_gpreg, stub_pc);     \
+  const ElfW(Sym) *const symtab						      \
+    = (const ElfW(Sym) *) D_PTR (l, l_info[DT_SYMTAB]);			      \
+  const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]);	      \
+  ElfW(Addr) *got							      \
+    = (ElfW(Addr) *) D_PTR (l, l_info[DT_PLTGOT]);			      \
+  const ElfW(Word) local_gotno						      \
+    = (const ElfW(Word)) l->l_info[DT_MIPS (LOCAL_GOTNO)]->d_un.d_val;	      \
+  const ElfW(Word) gotsym						      \
+    = (const ElfW(Word)) l->l_info[DT_MIPS (GOTSYM)]->d_un.d_val;	      \
+  const ElfW(Sym) *sym = &symtab[sym_index];				      \
+  ElfW(Addr) value;							      \
+									      \
+  /* FIXME: The symbol versioning stuff is not tested yet.  */		      \
+  if (__builtin_expect (ELFW(ST_VISIBILITY) (sym->st_other), 0) == 0)	      \
+    {									      \
+      switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)			      \
+	{								      \
+	default:							      \
+	  {								      \
+	    const ElfW(Half) *vernum =					      \
+	      (const void *) D_PTR (l, l_info[VERSYMIDX (DT_VERSYM)]);	      \
+	    ElfW(Half) ndx = vernum[sym_index] & 0x7fff;		      \
+	    const struct r_found_version *version = &l->l_versions[ndx];      \
+									      \
+	    if (version->hash != 0)					      \
+	      {								      \
+		value = _dl_lookup_symbol_x (strtab + sym->st_name, l, 	      \
+					     &sym, l->l_scope, version,	      \
+					     ELF_RTYPE_CLASS_PLT, 0, 0);      \
+		break;							      \
+	      }								      \
+	    /* Fall through.  */					      \
+	  }								      \
+	case 0:								      \
+	  value = _dl_lookup_symbol_x (strtab + sym->st_name, l, &sym,	      \
+				       l->l_scope, 0, ELF_RTYPE_CLASS_PLT,    \
+				       DL_LOOKUP_ADD_DEPENDENCY, 0);	      \
+	}								      \
+									      \
+      /* Currently value contains the base load address of the object	      \
+	 that defines sym.  Now add in the symbol offset.  */		      \
+      value = (sym ? value + sym->st_value : 0);			      \
+    }									      \
+  else									      \
+    /* We already found the symbol.  The module (and therefore its load	      \
+       address) is also known.  */					      \
+    value = l->l_addr + sym->st_value;					      \
+									      \
+  /* Apply the relocation with that value.  */				      \
+  *(got + local_gotno + sym_index - gotsym) = value;			      \
+									      \
+  return value;								      \
+}									      \
+									      \
+asm ("\n								      \
+	.text\n								      \
+	.align	2\n							      \
+	.globl	_dl_runtime_resolve\n					      \
+	.type	_dl_runtime_resolve,@function\n				      \
+	.ent	_dl_runtime_resolve\n					      \
+_dl_runtime_resolve:\n							      \
+	.frame	$29, " STRINGXP(ELF_DL_FRAME_SIZE) ", $31\n		      \
+	.set noreorder\n						      \
+	# Save GP.\n							      \
+	move	$3, $28\n						      \
+	# Save arguments and sp value in stack.\n			      \
+	" STRINGXP(PTR_SUBIU) "  $29, " STRINGXP(ELF_DL_FRAME_SIZE) "\n	      \
+	# Modify t9 ($25) so as to point .cpload instruction.\n		      \
+	" IFABIO32(STRINGXP(PTR_ADDIU) "	$25, 12\n") "		      \
+	# Compute GP.\n							      \
+	" STRINGXP(SETUP_GP) "\n					      \
+	" STRINGXV(SETUP_GP64 (0, _dl_runtime_resolve)) "\n		      \
+	.set reorder\n							      \
+	# Save slot call pc.\n						      \
+	move	$2, $31\n						      \
+	" IFABIO32(STRINGXP(CPRESTORE(32))) "\n				      \
+	" ELF_DL_SAVE_ARG_REGS "					      \
+	move	$4, $24\n						      \
+	move	$5, $15\n						      \
+	move	$6, $3\n						      \
+	move	$7, $2\n						      \
+	jal	__dl_runtime_resolve\n					      \
+	" ELF_DL_RESTORE_ARG_REGS "					      \
+	" STRINGXP(RESTORE_GP64) "\n					      \
+	" STRINGXP(PTR_ADDIU) "	$29, " STRINGXP(ELF_DL_FRAME_SIZE) "\n	      \
+	move	$25, $2\n						      \
+	jr	$25\n							      \
+	.end	_dl_runtime_resolve\n					      \
+	.previous\n							      \
+");
+
+/* Mask identifying addresses reserved for the user program,
+   where the dynamic linker should not map anything.  */
+#define ELF_MACHINE_USER_ADDRESS_MASK	0x80000000UL
+
+
+/* Initial entry point code for the dynamic linker.
+   The C function `_dl_start' is the real entry point;
+   its return value is the user program's entry point.
+   Note how we have to be careful about two things:
+
+   1) That we allocate a minimal stack of 24 bytes for
+      every function call, the MIPS ABI states that even
+      if all arguments are passed in registers the procedure
+      called can use the 16 byte area pointed to by $sp
+      when it is called to store away the arguments passed
+      to it.
+
+   2) That under Linux the entry is named __start
+      and not just plain _start.  */
+
+#define RTLD_START asm (\
+	".text\n"\
+	_RTLD_PROLOGUE(ENTRY_POINT) "\
+	" STRINGXV(SETUP_GPX($25)) "\n\
+	" STRINGXV(SETUP_GPX64($18,$25)) "\n\
+	# i386 ABI book says that the first entry of GOT holds\n\
+	# the address of the dynamic structure. Though MIPS ABI\n\
+	# doesn't say nothing about this, I emulate this here.\n\
+	" STRINGXP(PTR_LA) " $4, _DYNAMIC\n\
+	# Subtract OFFSET_GP_GOT\n\
+	" STRINGXP(PTR_S) " $4, -0x7ff0($28)\n\
+	move $4, $29\n\
+	" STRINGXP(PTR_SUBIU) " $29, 16\n\
+	\n\
+	" STRINGXP(PTR_LA) " $8, .Lcoff\n\
+	bltzal $8, .Lcoff\n\
+.Lcoff:	" STRINGXP(PTR_SUBU) " $8, $31, $8\n\
+	\n\
+	" STRINGXP(PTR_LA) " $25, _dl_start\n\
+	" STRINGXP(PTR_ADDU) " $25, $8\n\
+	jalr $25\n\
+	\n\
+	" STRINGXP(PTR_ADDIU) " $29, 16\n\
+	# Get the value of label '_dl_start_user' in t9 ($25).\n\
+	" STRINGXP(PTR_LA) " $25, _dl_start_user\n\
+	.globl _dl_start_user\n\
+	.type _dl_start_user,@function\n\
+	.aent _dl_start_user\n\
+_dl_start_user:\n\
+	" STRINGXP(SETUP_GP) "\n\
+	" STRINGXV(SETUP_GP64($18,_dl_start_user)) "\n\
+	move $16, $28\n\
+	# Save the user entry point address in a saved register.\n\
+	move $17, $2\n\
+	# See if we were run as a command with the executable file\n\
+	# name as an extra leading argument.\n\
+	lw $2, _dl_skip_args\n\
+	beq $2, $0, 1f\n\
+	# Load the original argument count.\n\
+	" STRINGXP(PTR_L) " $4, 0($29)\n\
+	# Subtract _dl_skip_args from it.\n\
+	subu $4, $2\n\
+	# Adjust the stack pointer to skip _dl_skip_args words.\n\
+	sll $2, " STRINGXP (PTRLOG) "\n\
+	" STRINGXP(PTR_ADDU) " $29, $2\n\
+	# Save back the modified argument count.\n\
+	" STRINGXP(PTR_S) " $4, 0($29)\n\
+1:	# Call _dl_init (struct link_map *main_map, int argc, char **argv, char **env) \n\
+	" STRINGXP(PTR_L) " $4, _rtld_local\n\
+	" STRINGXP(PTR_L) /* or lw???  fixme */ " $5, 0($29)\n\
+	" STRINGXP(PTR_LA) " $6, " STRINGXP (PTRSIZE) "($29)\n\
+	sll $7, $5, " STRINGXP (PTRLOG) "\n\
+	" STRINGXP(PTR_ADDU) " $7, $7, $6\n\
+	" STRINGXP(PTR_ADDU) " $7, $7, " STRINGXP (PTRSIZE) " \n\
+	" STRINGXP(PTR_SUBIU) " $29, 32\n\
+	" STRINGXP(SAVE_GP(16)) "\n\
+	# Call the function to run the initializers.\n\
+	jal _dl_init_internal\n\
+	" STRINGXP(PTR_ADDIU)  " $29, 32\n\
+	# Pass our finalizer function to the user in $2 as per ELF ABI.\n\
+	" STRINGXP(PTR_LA) " $2, _dl_fini\n\
+	# Jump to the user entry point.\n\
+	move $25, $17\n\
+	jr $25\n\t"\
+	_RTLD_EPILOGUE(ENTRY_POINT)\
+	".previous"\
+);
+
+/* The MIPS never uses Elfxx_Rela relocations.  */
+#define ELF_MACHINE_NO_RELA 1
+
+#endif /* !dl_machine_h */
+
+#ifdef RESOLVE
+
+/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
+   MAP is the object containing the reloc.  */
+
+static inline void
+#ifdef RTLD_BOOTSTRAP
+  __attribute__ ((always_inline))
+#endif
+elf_machine_rel (struct link_map *map, const ElfW(Rel) *reloc,
+		 const ElfW(Sym) *sym, const struct r_found_version *version,
+		 void *const reloc_addr)
+{
+  const unsigned long int r_type = ELFW(R_TYPE) (reloc->r_info);
+
+#if !defined RTLD_BOOTSTRAP && !defined SHARED
+  /* This is defined in rtld.c, but nowhere in the static libc.a;
+     make the reference weak so static programs can still link.  This
+     declaration cannot be done when compiling rtld.c (i.e.  #ifdef
+     RTLD_BOOTSTRAP) because rtld.c contains the common defn for
+     _dl_rtld_map, which is incompatible with a weak decl in the same
+     file.  */
+  weak_extern (GL(dl_rtld_map));
+#endif
+
+  switch (r_type)
+    {
+#if _MIPS_SIM == _ABI64
+    case (R_MIPS_64 << 8) | R_MIPS_REL32:
+#else
+    case R_MIPS_REL32:
+#endif
+      {
+	int symidx = ELFW(R_SYM) (reloc->r_info);
+	ElfW(Addr) reloc_value;
+
+	/* Support relocations on mis-aligned offsets.  Should we ever
+	   implement RELA, this should be replaced with an assignment
+	   from reloc->r_addend.  */
+	__builtin_memcpy (&reloc_value, reloc_addr, sizeof (reloc_value));
+
+	if (symidx)
+	  {
+	    const ElfW(Word) gotsym
+	      = (const ElfW(Word)) map->l_info[DT_MIPS (GOTSYM)]->d_un.d_val;
+
+	    if ((ElfW(Word))symidx < gotsym)
+	      {
+		/* This wouldn't work for a symbol imported from other
+		   libraries for which there's no GOT entry, but MIPS
+		   requires every symbol referenced in a dynamic
+		   relocation to have a GOT entry in the primary GOT,
+		   so we only get here for locally-defined symbols.
+		   For section symbols, we should *NOT* be adding
+		   sym->st_value (per the definition of the meaning of
+		   S in reloc expressions in the ELF64 MIPS ABI),
+		   since it should have already been added to
+		   reloc_value by the linker, but older versions of
+		   GNU ld didn't add it, and newer versions don't emit
+		   useless relocations to section symbols any more, so
+		   it is safe to keep on adding sym->st_value, even
+		   though it's not ABI compliant.  Some day we should
+		   bite the bullet and stop doing this.  */
+#ifndef RTLD_BOOTSTRAP
+		if (map != &GL(dl_rtld_map))
+#endif
+		  reloc_value += sym->st_value + map->l_addr;
+	      }
+	    else
+	      {
+#ifndef RTLD_BOOTSTRAP
+		const ElfW(Addr) *got
+		  = (const ElfW(Addr) *) D_PTR (map, l_info[DT_PLTGOT]);
+		const ElfW(Word) local_gotno
+		  = (const ElfW(Word))
+		    map->l_info[DT_MIPS (LOCAL_GOTNO)]->d_un.d_val;
+
+		reloc_value += got[symidx + local_gotno - gotsym];
+#endif
+	      }
+	  }
+	else
+#ifndef RTLD_BOOTSTRAP
+	  if (map != &GL(dl_rtld_map))
+#endif
+	    reloc_value += map->l_addr;
+
+	__builtin_memcpy (reloc_addr, &reloc_value, sizeof (reloc_value));
+      }
+      break;
+    case R_MIPS_NONE:		/* Alright, Wilbur.  */
+      break;
+#if _MIPS_SIM == _ABI64
+    case R_MIPS_64:
+      /* For full compliance with the ELF64 ABI, one must precede the
+	 _REL32/_64 pair of relocations with a _64 relocation, such
+	 that the in-place addend is read as a 64-bit value.  IRIX
+	 didn't pick up on this requirement, so we treat the
+	 _REL32/_64 relocation as a 64-bit relocation even if it's by
+	 itself.  For ABI compliance, we ignore such _64 dummy
+	 relocations.  For RELA, this may be simply removed, since
+	 it's totally unnecessary.  */
+      if (ELFW(R_SYM) (reloc->r_info) == 0)
+	break;
+      /* Fall through.  */
+#endif
+    default:
+      _dl_reloc_bad_type (map, r_type, 0);
+      break;
+    }
+}
+
+static inline void
+elf_machine_rel_relative (ElfW(Addr) l_addr, const ElfW(Rel) *reloc,
+			  void *const reloc_addr)
+{
+  /* XXX Nothing to do.  There is no relative relocation, right?  */
+}
+
+static inline void
+elf_machine_lazy_rel (struct link_map *map,
+		      ElfW(Addr) l_addr, const ElfW(Rel) *reloc)
+{
+  /* Do nothing.  */
+}
+
+#ifndef RTLD_BOOTSTRAP
+/* Relocate GOT. */
+static inline void
+elf_machine_got_rel (struct link_map *map, int lazy)
+{
+  ElfW(Addr) *got;
+  ElfW(Sym) *sym;
+  const ElfW(Half) *vernum;
+  int i, n, symidx;
+
+#define RESOLVE_GOTSYM(sym,vernum,sym_index)				  \
+    ({									  \
+      const ElfW(Sym) *ref = sym;					  \
+      const struct r_found_version *version				  \
+        = vernum ? &map->l_versions[vernum[sym_index] & 0x7fff] : NULL;	  \
+      ElfW(Addr) value;							  \
+      value = RESOLVE (&ref, version, R_MIPS_REL32);			  \
+      (ref)? value + ref->st_value: 0;					  \
+    })
+
+  if (map->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
+    vernum = (const void *) D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]);
+  else
+    vernum = NULL;
+
+  got = (ElfW(Addr) *) D_PTR (map, l_info[DT_PLTGOT]);
+
+  n = map->l_info[DT_MIPS (LOCAL_GOTNO)]->d_un.d_val;
+  /* The dynamic linker's local got entries have already been relocated.  */
+  if (map != &GL(dl_rtld_map))
+    {
+      /* got[0] is reserved. got[1] is also reserved for the dynamic object
+	 generated by gnu ld. Skip these reserved entries from relocation.  */
+      i = (got[1] & ELF_MIPS_GNU_GOT1_MASK)? 2 : 1;
+
+      /* Add the run-time displacement to all local got entries if
+         needed.  */
+      if (__builtin_expect (map->l_addr != 0, 0))
+	{
+	  while (i < n)
+	    got[i++] += map->l_addr;
+	}
+    }
+
+  /* Handle global got entries. */
+  got += n;
+  /* Keep track of the symbol index.  */
+  symidx = map->l_info[DT_MIPS (GOTSYM)]->d_un.d_val;
+  sym = (ElfW(Sym) *) D_PTR (map, l_info[DT_SYMTAB]) + symidx;
+  i = (map->l_info[DT_MIPS (SYMTABNO)]->d_un.d_val
+       - map->l_info[DT_MIPS (GOTSYM)]->d_un.d_val);
+
+  /* This loop doesn't handle Quickstart.  */
+  while (i--)
+    {
+      if (sym->st_shndx == SHN_UNDEF)
+	{
+	  if (ELFW(ST_TYPE) (sym->st_info) == STT_FUNC
+	      && sym->st_value && lazy)
+	    *got = sym->st_value + map->l_addr;
+	  else
+	    *got = RESOLVE_GOTSYM (sym, vernum, symidx);
+	}
+      else if (sym->st_shndx == SHN_COMMON)
+	*got = RESOLVE_GOTSYM (sym, vernum, symidx);
+      else if (ELFW(ST_TYPE) (sym->st_info) == STT_FUNC
+	       && *got != sym->st_value
+	       && lazy)
+	*got += map->l_addr;
+      else if (ELFW(ST_TYPE) (sym->st_info) == STT_SECTION)
+	{
+	  if (sym->st_other == 0)
+	    *got += map->l_addr;
+	}
+      else
+	*got = RESOLVE_GOTSYM (sym, vernum, symidx);
+
+      ++got;
+      ++sym;
+      ++symidx;
+    }
+
+#undef RESOLVE_GOTSYM
+}
+#endif
+
+/* Set up the loaded object described by L so its stub function
+   will jump to the on-demand fixup code __dl_runtime_resolve.  */
+
+static inline int
+elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
+{
+# ifndef RTLD_BOOTSTRAP
+  ElfW(Addr) *got;
+  extern void _dl_runtime_resolve (ElfW(Word));
+  extern int _dl_mips_gnu_objects;
+
+  if (lazy)
+    {
+      /* The GOT entries for functions have not yet been filled in.
+	 Their initial contents will arrange when called to put an
+	 offset into the .dynsym section in t8, the return address
+	 in t7 and then jump to _GLOBAL_OFFSET_TABLE[0].  */
+      got = (ElfW(Addr) *) D_PTR (l, l_info[DT_PLTGOT]);
+
+      /* This function will get called to fix up the GOT entry indicated by
+	 the register t8, and then jump to the resolved address.  */
+      got[0] = (ElfW(Addr)) &_dl_runtime_resolve;
+
+      /* Store l to _GLOBAL_OFFSET_TABLE[1] for gnu object. The MSB
+	 of got[1] of a gnu object is set to identify gnu objects.
+	 Where we can store l for non gnu objects? XXX  */
+      if ((got[1] & ELF_MIPS_GNU_GOT1_MASK) != 0)
+	got[1] = ((ElfW(Addr)) l | ELF_MIPS_GNU_GOT1_MASK);
+      else
+	_dl_mips_gnu_objects = 0;
+    }
+
+  /* Relocate global offset table.  */
+  elf_machine_got_rel (l, lazy);
+
+# endif
+  return lazy;
+}
+
+#endif /* RESOLVE */
diff --git a/sysdeps/mips/elf/ldsodefs.h b/sysdeps/mips/elf/ldsodefs.h
new file mode 100644
index 0000000000..3868b50ff6
--- /dev/null
+++ b/sysdeps/mips/elf/ldsodefs.h
@@ -0,0 +1,109 @@
+/* Run-time dynamic linker data structures for loaded ELF shared objects.
+   Copyright (C) 2000, 2002, 2003 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.  */
+
+#ifndef _MIPS_LDSODEFS_H
+#define _MIPS_LDSODEFS_H
+
+/* The MIPS ABI specifies that the dynamic section has to be read-only.  */
+
+#define DL_RO_DYN_SECTION 1
+
+#include_next <ldsodefs.h>
+
+/* The 64-bit MIPS ELF ABI uses an unusual reloc format.  Each
+   relocation entry specifies up to three actual relocations, all at
+   the same address.  The first relocation which required a symbol
+   uses the symbol in the r_sym field.  The second relocation which
+   requires a symbol uses the symbol in the r_ssym field.  If all
+   three relocations require a symbol, the third one uses a zero
+   value.
+
+   We define these structures in internal headers because we're not
+   sure we want to make them part of the ABI yet.  Eventually, some of
+   this may move into elf/elf.h.  */
+
+/* An entry in a 64 bit SHT_REL section.  */
+
+typedef struct
+{
+  Elf32_Word    r_sym;		/* Symbol index */
+  unsigned char r_ssym;		/* Special symbol for 2nd relocation */
+  unsigned char r_type3;	/* 3rd relocation type */
+  unsigned char r_type2;	/* 2nd relocation type */
+  unsigned char r_type1;	/* 1st relocation type */
+} _Elf64_Mips_R_Info;
+
+typedef union
+{
+  Elf64_Xword	r_info_number;
+  _Elf64_Mips_R_Info r_info_fields;
+} _Elf64_Mips_R_Info_union;
+
+typedef struct
+{
+  Elf64_Addr	r_offset;		/* Address */
+  _Elf64_Mips_R_Info_union r_info;	/* Relocation type and symbol index */
+} Elf64_Mips_Rel;
+
+typedef struct
+{
+  Elf64_Addr	r_offset;		/* Address */
+  _Elf64_Mips_R_Info_union r_info;	/* Relocation type and symbol index */
+  Elf64_Sxword	r_addend;		/* Addend */
+} Elf64_Mips_Rela;
+
+#define ELF64_MIPS_R_SYM(i) \
+  ((__extension__ (_Elf64_Mips_R_Info_union)(i)).r_info_fields.r_sym)
+#define ELF64_MIPS_R_TYPE(i) \
+  (((_Elf64_Mips_R_Info_union)(i)).r_info_fields.r_type1 \
+   | ((Elf32_Word)(__extension__ (_Elf64_Mips_R_Info_union)(i) \
+		   ).r_info_fields.r_type2 << 8) \
+   | ((Elf32_Word)(__extension__ (_Elf64_Mips_R_Info_union)(i) \
+		   ).r_info_fields.r_type3 << 16) \
+   | ((Elf32_Word)(__extension__ (_Elf64_Mips_R_Info_union)(i) \
+		   ).r_info_fields.r_ssym << 24))
+#define ELF64_MIPS_R_INFO(sym, type) \
+  (__extension__ (_Elf64_Mips_R_Info_union) \
+   (__extension__ (_Elf64_Mips_R_Info) \
+   { (sym), ELF64_MIPS_R_SSYM (type), \
+       ELF64_MIPS_R_TYPE3 (type), \
+       ELF64_MIPS_R_TYPE2 (type), \
+       ELF64_MIPS_R_TYPE1 (type) \
+   }).r_info_number)
+/* These macros decompose the value returned by ELF64_MIPS_R_TYPE, and
+   compose it back into a value that it can be used as an argument to
+   ELF64_MIPS_R_INFO.  */
+#define ELF64_MIPS_R_SSYM(i) (((i) >> 24) & 0xff)
+#define ELF64_MIPS_R_TYPE3(i) (((i) >> 16) & 0xff)
+#define ELF64_MIPS_R_TYPE2(i) (((i) >> 8) & 0xff)
+#define ELF64_MIPS_R_TYPE1(i) ((i) & 0xff)
+#define ELF64_MIPS_R_TYPEENC(type1, type2, type3, ssym) \
+  ((type1) \
+   | ((Elf32_Word)(type2) << 8) \
+   | ((Elf32_Word)(type3) << 16) \
+   | ((Elf32_Word)(ssym) << 24))
+
+#undef ELF64_R_SYM
+#define ELF64_R_SYM(i) ELF64_MIPS_R_SYM (i)
+#undef ELF64_R_TYPE
+#define ELF64_R_TYPE(i) ELF64_MIPS_R_TYPE (i)
+#undef ELF64_R_INFO
+#define ELF64_R_INFO(sym, type) ELF64_MIPS_R_INFO ((sym), (type))
+
+#endif
diff --git a/sysdeps/mips/elf/start.S b/sysdeps/mips/elf/start.S
new file mode 100644
index 0000000000..d9cc3b7ee2
--- /dev/null
+++ b/sysdeps/mips/elf/start.S
@@ -0,0 +1,119 @@
+/* Startup code compliant to the ELF Mips ABI.
+   Copyright (C) 1995, 1997, 2000, 2001, 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.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file with other
+   programs, and to distribute those programs without any restriction
+   coming from the use of this file. (The GNU Lesser General Public
+   License restrictions do apply in other respects; for example, they
+   cover modification of the file, and distribution when not linked
+   into another program.)
+
+   Note that people who make modified versions of this file are not
+   obligated to grant this special exception for their modified
+   versions; it is their choice whether to do so. The GNU Lesser
+   General Public License gives permission to release a modified
+   version without this exception; this exception also makes it
+   possible to release a modified version which carries forward this
+   exception.
+
+   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.  */
+
+#define __ASSEMBLY__ 1
+#include <entry.h>
+#include <sgidefs.h>
+#include <sys/asm.h>
+
+#ifndef ENTRY_POINT
+#error ENTRY_POINT needs to be defined for start.S on MIPS/ELF.
+#endif
+
+/* This is the canonical entry point, usually the first thing in the text
+   segment.  The SVR4/Mips ABI (pages 3-31, 3-32) says that when the entry
+   point runs, most registers' values are unspecified, except for:
+
+   v0 ($2)	Contains a function pointer to be registered with `atexit'.
+		This is how the dynamic linker arranges to have DT_FINI
+		functions called for shared libraries that have been loaded
+		before this code runs.
+
+   sp ($29)	The stack contains the arguments and environment:
+		0(%esp)			argc
+		4(%esp)			argv[0]
+		...
+		(4*argc)(%esp)		NULL
+		(4*(argc+1))(%esp)	envp[0]
+		...
+					NULL
+   ra ($31)	The return address register is set to zero so that programs
+		that search backword through stack frames recognize the last
+		stack frame.
+*/
+
+
+/* We need to call:
+   __libc_start_main (int (*main) (int, char **, char **), int argc,
+		      char **argv, void (*init) (void), void (*fini) (void),
+		      void (*rtld_fini) (void), void *stack_end)
+*/
+	
+	.text
+	.globl ENTRY_POINT
+	.type ENTRY_POINT,@function
+ENTRY_POINT:
+#ifdef __PIC__
+	SETUP_GPX($0)
+	SETUP_GPX64($25,$0)
+#else
+	PTR_LA $28, _gp		/* Setup GP correctly if we're non-PIC.  */
+	move $31, $0
+#endif
+
+	PTR_LA $4, main		/* main */
+	PTR_L $5, 0($29)		/* argc */
+	PTR_ADDIU $6, $29, PTRSIZE	/* argv  */
+	
+	/* Allocate space on the stack for seven arguments (o32 only)
+	   and make sure the stack is aligned to double words (8 bytes) 
+	   on o32 and quad words (16 bytes) on n32 and n64.  */
+	
+	and $29, -2 * SZREG
+#if _MIPS_SIM == _ABIO32
+	PTR_SUBIU $29, 32
+#endif
+	PTR_LA $7, __libc_csu_init		/* init */
+	PTR_LA $8, __libc_csu_fini
+#if _MIPS_SIM == _ABIO32
+	PTR_S $8, 16($29)		/* fini */
+	PTR_S $2, 20($29)		/* rtld_fini */
+	PTR_S $29, 24($29)		/* stack_end */
+#else
+	move $9, $2		/* rtld_fini */
+	move $10, $29		/* stack_end */
+#endif
+	jal __libc_start_main
+hlt:	b hlt			/* Crash if somehow it does return.  */
+
+/* Define a symbol for the first piece of initialized data.  */
+	.data
+	.globl __data_start
+__data_start:
+	.long 0
+	.weak data_start
+	data_start = __data_start
diff --git a/sysdeps/mips/fpregdef.h b/sysdeps/mips/fpregdef.h
new file mode 100644
index 0000000000..6f76d1183d
--- /dev/null
+++ b/sysdeps/mips/fpregdef.h
@@ -0,0 +1,24 @@
+/* Copyright (C) 1991, 92, 94, 95, 96 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.  */
+
+#ifndef _FPREGDEF_H
+#define _FPREGDEF_H
+
+#include <sys/fpregdef.h>
+
+#endif /* _FPREGDEF_H */
diff --git a/sysdeps/mips/fpu/bits/mathdef.h b/sysdeps/mips/fpu/bits/mathdef.h
new file mode 100644
index 0000000000..99be0db2b5
--- /dev/null
+++ b/sysdeps/mips/fpu/bits/mathdef.h
@@ -0,0 +1,46 @@
+/* Copyright (C) 1997, 1998, 1999, 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.  */
+
+#if !defined _MATH_H && !defined _COMPLEX_H
+# error "Never use <bits/mathdef.h> directly; include <math.h> instead"
+#endif
+
+#include <sgidefs.h>
+
+#if defined  __USE_ISOC99 && defined _MATH_H && !defined _MATH_H_MATHDEF
+# define _MATH_H_MATHDEF	1
+
+/* Normally, there is no long double type and the `float' and `double'
+   expressions are evaluated as `double'.  */
+typedef double float_t;		/* `float' expressions are evaluated as
+				   `double'.  */
+typedef double double_t;	/* `double' expressions are evaluated as
+				   `double'.  */
+
+/* The values returned by `ilogb' for 0 and NaN respectively.  */
+# define FP_ILOGB0	(-2147483647)
+# define FP_ILOGBNAN	2147483647
+
+#endif	/* ISO C99 */
+
+#if ! defined __NO_LONG_DOUBLE_MATH && _MIPS_SIM == _ABIO32
+/* Signal that we do not really have a `long double'.  This disables the
+   declaration of all the `long double' function variants.  */
+# define __NO_LONG_DOUBLE_MATH	1
+#endif
diff --git a/sysdeps/mips/fpu/e_sqrt.c b/sysdeps/mips/fpu/e_sqrt.c
new file mode 100644
index 0000000000..5449710aff
--- /dev/null
+++ b/sysdeps/mips/fpu/e_sqrt.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Hartvig Ekner <hartvige@mips.com>, 2002.
+
+   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>
+
+
+#if (_MIPS_ISA >= _MIPS_ISA_MIPS2)
+
+double
+__ieee754_sqrt (double x)
+{
+  double z;
+  __asm__ ("sqrt.d %0,%1" : "=f" (z) : "f" (x));
+  return z;
+}
+
+#else
+
+#include <sysdeps/ieee754/dbl-64/e_sqrt.c>
+
+#endif
diff --git a/sysdeps/mips/fpu/e_sqrtf.c b/sysdeps/mips/fpu/e_sqrtf.c
new file mode 100644
index 0000000000..3590ad46d5
--- /dev/null
+++ b/sysdeps/mips/fpu/e_sqrtf.c
@@ -0,0 +1,39 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Hartvig Ekner <hartvige@mips.com>, 2002.
+
+   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>
+
+
+#if (_MIPS_ISA >= _MIPS_ISA_MIPS2)
+
+float
+__ieee754_sqrtf (float x)
+{
+  float z;
+  __asm__ ("sqrt.s %0,%1" : "=f" (z) : "f" (x));
+  return z;
+}
+
+#else
+
+#include <sysdeps/ieee754/flt-32/e_sqrtf.c>
+
+#endif
+
diff --git a/sysdeps/mips/fpu/fclrexcpt.c b/sysdeps/mips/fpu/fclrexcpt.c
new file mode 100644
index 0000000000..f773312b34
--- /dev/null
+++ b/sysdeps/mips/fpu/fclrexcpt.c
@@ -0,0 +1,47 @@
+/* Clear given exceptions in current floating-point environment.
+   Copyright (C) 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Andreas Jaeger <aj@suse.de>, 1998.
+
+   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 <fenv.h>
+#include <fenv_libc.h>
+#include <fpu_control.h>
+
+int
+feclearexcept (int excepts)
+{
+  int cw;
+
+  /* Mask out unsupported bits/exceptions.  */
+  excepts &= FE_ALL_EXCEPT;
+
+  /* Read the complete control word.  */
+  _FPU_GETCW (cw);
+
+  /* Clear exception flag bits and cause bits. If the cause bit is not
+     cleared, the next CTC instruction (just below) will re-generate the
+     exception.  */
+
+  cw &= ~(excepts | (excepts << CAUSE_SHIFT));
+
+  /* Put the new data in effect.  */
+  _FPU_SETCW (cw);
+
+  /* Success.  */
+  return 0;
+}
diff --git a/sysdeps/mips/fpu/fedisblxcpt.c b/sysdeps/mips/fpu/fedisblxcpt.c
new file mode 100644
index 0000000000..62e1a7130a
--- /dev/null
+++ b/sysdeps/mips/fpu/fedisblxcpt.c
@@ -0,0 +1,42 @@
+/* Disable floating-point exceptions.
+   Copyright (C) 2000 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Andreas Jaeger <aj@suse.de>, 2000.
+
+   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 <fenv.h>
+#include <fenv_libc.h>
+#include <fpu_control.h>
+
+int
+fedisableexcept (int excepts)
+{
+  unsigned int new_exc, old_exc;
+
+  /* Get the current control word.  */
+  _FPU_GETCW (new_exc);
+
+  old_exc = (new_exc & ENABLE_MASK) >> ENABLE_SHIFT;
+
+  excepts &= FE_ALL_EXCEPT;
+
+  new_exc &= ~(excepts << ENABLE_SHIFT);
+  new_exc &= ~_FPU_RESERVED;
+  _FPU_SETCW (new_exc);
+
+  return old_exc;
+}
diff --git a/sysdeps/mips/fpu/feenablxcpt.c b/sysdeps/mips/fpu/feenablxcpt.c
new file mode 100644
index 0000000000..4c285811db
--- /dev/null
+++ b/sysdeps/mips/fpu/feenablxcpt.c
@@ -0,0 +1,42 @@
+/* Enable floating-point exceptions.
+   Copyright (C) 2000 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Andreas Jaeger <aj@suse.de>, 2000.
+
+   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 <fenv.h>
+#include <fenv_libc.h>
+#include <fpu_control.h>
+
+int
+feenableexcept (int excepts)
+{
+  unsigned int new_exc, old_exc;
+
+  /* Get the current control word.  */
+  _FPU_GETCW (new_exc);
+
+  old_exc = (new_exc & ENABLE_MASK) >> ENABLE_SHIFT;
+
+  excepts &= FE_ALL_EXCEPT;
+
+  new_exc |= excepts << ENABLE_SHIFT;
+  new_exc &= ~_FPU_RESERVED;
+  _FPU_SETCW (new_exc);
+
+  return old_exc;
+}
diff --git a/sysdeps/mips/fpu/fegetenv.c b/sysdeps/mips/fpu/fegetenv.c
new file mode 100644
index 0000000000..c1741385fd
--- /dev/null
+++ b/sysdeps/mips/fpu/fegetenv.c
@@ -0,0 +1,31 @@
+/* Store current floating-point environment.
+   Copyright (C) 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Andreas Jaeger <aj@suse.de>, 1998.
+
+   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 <fenv.h>
+#include <fpu_control.h>
+
+int
+fegetenv (fenv_t *envp)
+{
+  _FPU_GETCW (*envp);
+
+  /* Success.  */
+  return 0;
+}
diff --git a/sysdeps/mips/fpu/fegetexcept.c b/sysdeps/mips/fpu/fegetexcept.c
new file mode 100644
index 0000000000..14b1241294
--- /dev/null
+++ b/sysdeps/mips/fpu/fegetexcept.c
@@ -0,0 +1,34 @@
+/* Get enabled floating-point exceptions.
+   Copyright (C) 2000 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Andreas Jaeger <aj@suse.de>, 2000.
+
+   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 <fenv.h>
+#include <fenv_libc.h>
+#include <fpu_control.h>
+
+int
+fegetexcept (void)
+{
+  unsigned int exc;
+
+  /* Get the current control word.  */
+  _FPU_GETCW (exc);
+
+  return (exc & ENABLE_MASK) >> ENABLE_SHIFT;
+}
diff --git a/sysdeps/mips/fpu/fegetround.c b/sysdeps/mips/fpu/fegetround.c
new file mode 100644
index 0000000000..efb1ba0dcc
--- /dev/null
+++ b/sysdeps/mips/fpu/fegetround.c
@@ -0,0 +1,33 @@
+/* Return current rounding direction.
+   Copyright (C) 1998 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Andreas Jaeger <aj@arthur.rhein-neckar.de>, 1998.
+
+   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 <fenv.h>
+#include <fpu_control.h>
+
+int
+fegetround (void)
+{
+  int cw;
+
+  /* Get control word.  */
+  _FPU_GETCW (cw);
+
+  return cw & 0x3;
+}
diff --git a/sysdeps/mips/fpu/feholdexcpt.c b/sysdeps/mips/fpu/feholdexcpt.c
new file mode 100644
index 0000000000..bb37148fff
--- /dev/null
+++ b/sysdeps/mips/fpu/feholdexcpt.c
@@ -0,0 +1,38 @@
+/* Store current floating-point environment and clear exceptions.
+   Copyright (C) 2000 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Andreas Jaeger <aj@suse.de>, 2000.
+
+   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 <fenv.h>
+#include <fpu_control.h>
+
+int
+feholdexcept (fenv_t *envp)
+{
+  fpu_control_t cw;
+
+  /* Save the current state.  */
+  _FPU_GETCW (cw);
+  envp->__fp_control_register = cw;
+
+  /* Clear all exception enable bits and flags.  */
+  cw &= ~(_FPU_MASK_V|_FPU_MASK_Z|_FPU_MASK_O|_FPU_MASK_U|_FPU_MASK_I|FE_ALL_EXCEPT);
+  _FPU_SETCW (cw);
+
+  return 0;
+}
diff --git a/sysdeps/mips/fpu/fenv_libc.h b/sysdeps/mips/fpu/fenv_libc.h
new file mode 100644
index 0000000000..d971d2c711
--- /dev/null
+++ b/sysdeps/mips/fpu/fenv_libc.h
@@ -0,0 +1,32 @@
+/* Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Andreas Jaeger <aj@suse.de>.
+
+   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.  */
+
+#ifndef _FENV_LIBC_H
+#define _FENV_LIBC_H    1
+
+/* Mask for enabling exceptions and for the CAUSE bits.  */
+#define ENABLE_MASK	0x00F80U
+#define CAUSE_MASK	0x1F000U
+
+/* Shift for FE_* flags to get up to the ENABLE bits and the CAUSE bits.  */
+#define	ENABLE_SHIFT	5
+#define	CAUSE_SHIFT	10
+
+
+#endif /* _FENV_LIBC_H */
diff --git a/sysdeps/mips/fpu/fesetenv.c b/sysdeps/mips/fpu/fesetenv.c
new file mode 100644
index 0000000000..b71a877ae3
--- /dev/null
+++ b/sysdeps/mips/fpu/fesetenv.c
@@ -0,0 +1,43 @@
+/* Install given floating-point environment.
+   Copyright (C) 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Andreas Jaeger <aj@suse.de>, 1998.
+
+   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 <fenv.h>
+#include <fpu_control.h>
+
+int
+fesetenv (const fenv_t *envp)
+{
+  fpu_control_t cw;
+
+  /* Read first current state to flush fpu pipeline.  */
+  _FPU_GETCW (cw);
+
+  if (envp == FE_DFL_ENV)
+    _FPU_SETCW (_FPU_DEFAULT);
+  else if (envp == FE_NOMASK_ENV)
+    _FPU_SETCW (_FPU_IEEE);
+  else
+    _FPU_SETCW (envp->__fp_control_register);
+
+  /* Success.  */
+  return 0;
+}
+
+libm_hidden_def (fesetenv)
diff --git a/sysdeps/mips/fpu/fesetround.c b/sysdeps/mips/fpu/fesetround.c
new file mode 100644
index 0000000000..af73a720f8
--- /dev/null
+++ b/sysdeps/mips/fpu/fesetround.c
@@ -0,0 +1,43 @@
+/* Set current rounding direction.
+   Copyright (C) 1998 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Andreas Jaeger <aj@arthur.rhein-neckar.de>, 1998.
+
+   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 <fenv.h>
+#include <fpu_control.h>
+
+int
+fesetround (int round)
+{
+  unsigned short int cw;
+
+  if ((round & ~0x3) != 0)
+    /* ROUND is no valid rounding mode.  */
+    return 1;
+
+  /* Get current state.  */
+  _FPU_GETCW (cw);
+
+  /* Set rounding bits.  */
+  cw &= ~0x3;
+  cw |= round;
+  /* Set new state.  */
+  _FPU_SETCW (cw);
+
+  return 0;
+}
diff --git a/sysdeps/mips/fpu/feupdateenv.c b/sysdeps/mips/fpu/feupdateenv.c
new file mode 100644
index 0000000000..20b20e14c0
--- /dev/null
+++ b/sysdeps/mips/fpu/feupdateenv.c
@@ -0,0 +1,43 @@
+/* Install given floating-point environment and raise exceptions.
+   Copyright (C) 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Andreas Jaeger <aj@suse.de>, 1998.
+
+   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 <fenv.h>
+#include <fpu_control.h>
+
+int
+feupdateenv (const fenv_t *envp)
+{
+  int temp;
+
+  /* Save current exceptions.  */
+  _FPU_GETCW (temp);
+  temp &= FE_ALL_EXCEPT;
+
+  /* Install new environment.  */
+  fesetenv (envp);
+
+  /* Raise the safed exception.  Incidently for us the implementation
+     defined format of the values in objects of type fexcept_t is the
+     same as the ones specified using the FE_* constants.  */
+  feraiseexcept (temp);
+
+  /* Success.  */
+  return 0;
+}
diff --git a/sysdeps/mips/fpu/fgetexcptflg.c b/sysdeps/mips/fpu/fgetexcptflg.c
new file mode 100644
index 0000000000..3412159816
--- /dev/null
+++ b/sysdeps/mips/fpu/fgetexcptflg.c
@@ -0,0 +1,40 @@
+/* Store current representation for exceptions.
+   Copyright (C) 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Andreas Jaeger <aj@suse.de>, 1998.
+
+   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 <fenv.h>
+#include <fpu_control.h>
+
+int
+fegetexceptflag (fexcept_t *flagp, int excepts)
+{
+  fexcept_t temp;
+
+  /* Get the current exceptions.  */
+  _FPU_GETCW (temp);
+
+  /* We only save the relevant bits here. In particular, care has to be 
+     taken with the CAUSE bits, as an inadvertent restore later on could
+     generate unexpected exceptions.  */
+
+  *flagp = temp & excepts & FE_ALL_EXCEPT;
+
+  /* Success.  */
+  return 0;
+}
diff --git a/sysdeps/mips/fpu/fraiseexcpt.c b/sysdeps/mips/fpu/fraiseexcpt.c
new file mode 100644
index 0000000000..3e2ebe0fe7
--- /dev/null
+++ b/sysdeps/mips/fpu/fraiseexcpt.c
@@ -0,0 +1,47 @@
+/* Raise given exceptions.
+   Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Andreas Jaeger <aj@suse.de>, 2000.
+
+   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 <fenv.h>
+#include <fenv_libc.h>
+#include <fpu_control.h>
+
+int
+feraiseexcept (int excepts)
+{
+  fpu_control_t cw;
+
+  /* Get current state.  */
+  _FPU_GETCW (cw);
+
+  /* Set flag bits (which are accumulative), and *also* set the 
+     cause bits. The setting of the cause bits is what actually causes
+     the hardware to generate the exception, if the corresponding enable
+     bit is set as well.  */
+
+  excepts &= FE_ALL_EXCEPT;
+  cw |= excepts | (excepts << CAUSE_SHIFT);
+
+  /* Set new state.  */
+  _FPU_SETCW (cw);
+
+  return 0;
+}
+
+libm_hidden_def (feraiseexcept)
diff --git a/sysdeps/mips/fpu/fsetexcptflg.c b/sysdeps/mips/fpu/fsetexcptflg.c
new file mode 100644
index 0000000000..c65d793178
--- /dev/null
+++ b/sysdeps/mips/fpu/fsetexcptflg.c
@@ -0,0 +1,43 @@
+/* Set floating-point environment exception handling.
+   Copyright (C) 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Hartvig Ekner <hartvige@mips.com>, 2002.
+
+   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 <fenv.h>
+#include <fpu_control.h>
+
+int
+fesetexceptflag (const fexcept_t *flagp, int excepts)
+{
+  fexcept_t temp;
+
+  /* Get the current exceptions.  */
+  _FPU_GETCW (temp);
+
+  /* Make sure the flags we want restored are legal.  */
+  excepts &= FE_ALL_EXCEPT;
+
+  /* Now clear the bits called for, and copy them in from flagp. Note that
+     we ignore all non-flag bits from *flagp, so they don't matter.  */
+  temp = (temp & ~excepts) | (*flagp & excepts);
+
+  _FPU_SETCW (temp);
+
+  /* Success.  */
+  return 0;
+}
diff --git a/sysdeps/mips/fpu/ftestexcept.c b/sysdeps/mips/fpu/ftestexcept.c
new file mode 100644
index 0000000000..6a833f7563
--- /dev/null
+++ b/sysdeps/mips/fpu/ftestexcept.c
@@ -0,0 +1,33 @@
+/* Test exception in current environment.
+   Copyright (C) 1998 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Andreas Jaeger <aj@arthur.rhein-neckar.de>, 1998.
+
+   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 <fenv.h>
+#include <fpu_control.h>
+
+int
+fetestexcept (int excepts)
+{
+  int cw;
+
+  /* Get current control word.  */
+  _FPU_GETCW (cw);
+
+  return cw & excepts & FE_ALL_EXCEPT;
+}
diff --git a/sysdeps/mips/fpu/libm-test-ulps b/sysdeps/mips/fpu/libm-test-ulps
new file mode 100644
index 0000000000..73172b49a0
--- /dev/null
+++ b/sysdeps/mips/fpu/libm-test-ulps
@@ -0,0 +1,890 @@
+# Begin of automatic generation
+
+# atan2
+Test "atan2 (-0.75, -1.0) == -2.49809154479650885165983415456218025":
+float: 3
+ifloat: 3
+Test "atan2 (0.75, -1.0) == 2.49809154479650885165983415456218025":
+float: 3
+ifloat: 3
+Test "atan2 (1.390625, 0.9296875) == 0.981498387184244311516296577615519772":
+float: 1
+ifloat: 1
+
+# atanh
+Test "atanh (0.75) == 0.972955074527656652552676371721589865":
+float: 1
+ifloat: 1
+
+# cacosh
+Test "Real part of: cacosh (-2 - 3 i) == -1.9833870299165354323470769028940395 + 2.1414491111159960199416055713254211 i":
+double: 1
+float: 7
+idouble: 1
+ifloat: 7
+Test "Imaginary part of: cacosh (-2 - 3 i) == -1.9833870299165354323470769028940395 + 2.1414491111159960199416055713254211 i":
+double: 1
+float: 3
+idouble: 1
+ifloat: 3
+
+# casin
+Test "Real part of: casin (0.75 + 1.25 i) == 0.453276177638793913448921196101971749 + 1.13239363160530819522266333696834467 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# casinh
+Test "Real part of: casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i":
+double: 5
+float: 1
+idouble: 5
+ifloat: 1
+Test "Imaginary part of: casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i":
+double: 3
+float: 6
+idouble: 3
+ifloat: 6
+Test "Real part of: casinh (0.75 + 1.25 i) == 1.03171853444778027336364058631006594 + 0.911738290968487636358489564316731207 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: casinh (0.75 + 1.25 i) == 1.03171853444778027336364058631006594 + 0.911738290968487636358489564316731207 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# catan
+Test "Real part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i":
+float: 3
+ifloat: 3
+Test "Imaginary part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Real part of: catan (0.75 + 1.25 i) == 1.10714871779409050301706546017853704 + 0.549306144334054845697622618461262852 i":
+float: 4
+ifloat: 4
+
+# catanh
+Test "Real part of: catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i":
+double: 4
+idouble: 4
+Test "Imaginary part of: catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i":
+float: 4
+ifloat: 4
+Test "Real part of: catanh (0.75 + 1.25 i) == 0.261492138795671927078652057366532140 + 0.996825126463918666098902241310446708 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: catanh (0.75 + 1.25 i) == 0.261492138795671927078652057366532140 + 0.996825126463918666098902241310446708 i":
+float: 6
+ifloat: 6
+
+# cbrt
+Test "cbrt (-27.0) == -3.0":
+double: 1
+idouble: 1
+Test "cbrt (0.75) == 0.908560296416069829445605878163630251":
+double: 1
+idouble: 1
+Test "cbrt (0.9921875) == 0.997389022060725270579075195353955217":
+double: 1
+idouble: 1
+
+# ccos
+Test "Imaginary part of: ccos (-2 - 3 i) == -4.18962569096880723013255501961597373 - 9.10922789375533659797919726277886212 i":
+float: 1
+ifloat: 1
+Test "Real part of: ccos (0.75 + 1.25 i) == 1.38173873063425888530729933139078645 - 1.09193013555397466170919531722024128 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: ccos (0.75 + 1.25 i) == 1.38173873063425888530729933139078645 - 1.09193013555397466170919531722024128 i":
+float: 1
+ifloat: 1
+
+# ccosh
+Test "Real part of: ccosh (-2 - 3 i) == -3.72454550491532256547397070325597253 + 0.511822569987384608834463849801875634 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: ccosh (-2 - 3 i) == -3.72454550491532256547397070325597253 + 0.511822569987384608834463849801875634 i":
+float: 1
+ifloat: 1
+Test "Real part of: ccosh (0.75 + 1.25 i) == 0.408242591877968807788852146397499084 + 0.780365930845853240391326216300863152 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: ccosh (0.75 + 1.25 i) == 0.408242591877968807788852146397499084 + 0.780365930845853240391326216300863152 i":
+float: 1
+ifloat: 1
+
+# cexp
+Test "Imaginary part of: cexp (-2.0 - 3.0 i) == -0.13398091492954261346140525546115575 - 0.019098516261135196432576240858800925 i":
+float: 1
+ifloat: 1
+Test "Real part of: cexp (0.75 + 1.25 i) == 0.667537446429131586942201977015932112 + 2.00900045494094876258347228145863909 i":
+float: 1
+ifloat: 1
+
+# clog
+Test "Imaginary part of: clog (-2 - 3 i) == 1.2824746787307683680267437207826593 - 2.1587989303424641704769327722648368 i":
+float: 3
+ifloat: 3
+Test "Real part of: clog (0.75 + 1.25 i) == 0.376885901188190075998919126749298416 + 1.03037682652431246378774332703115153 i":
+float: 1
+ifloat: 1
+
+# clog10
+Test "Imaginary part of: clog10 (-0 + inf i) == inf + pi/2*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-0 - inf i) == inf - pi/2*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-2 - 3 i) == 0.556971676153418384603252578971164214 - 0.937554462986374708541507952140189646 i":
+double: 1
+float: 5
+idouble: 1
+ifloat: 5
+Test "Imaginary part of: clog10 (-3 + inf i) == inf + pi/2*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-3 - inf i) == inf - pi/2*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf + 0 i) == inf + pi*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf + 1 i) == inf + pi*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf - 0 i) == inf - pi*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf - 1 i) == inf - pi*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (0 + inf i) == inf + pi/2*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (0 - inf i) == inf - pi/2*log10(e) i":
+float: 1
+ifloat: 1
+Test "Real part of: clog10 (0.75 + 1.25 i) == 0.163679467193165171449476605077428975 + 0.447486970040493067069984724340855636 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (3 + inf i) == inf + pi/2*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (3 - inf i) == inf - pi/2*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (inf + inf i) == inf + pi/4*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (inf - inf i) == inf - pi/4*log10(e) i":
+float: 1
+ifloat: 1
+
+# cos
+Test "cos (M_PI_6l * 2.0) == 0.5":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "cos (M_PI_6l * 4.0) == -0.5":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "cos (pi/2) == 0":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# cpow
+Test "Real part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i":
+float: 1
+ifloat: 1
+Test "Real part of: cpow (0.75 + 1.25 i, 0.75 + 1.25 i) == 0.117506293914473555420279832210420483 + 0.346552747708338676483025352060418001 i":
+double: 1
+float: 4
+idouble: 1
+ifloat: 4
+Test "Real part of: cpow (0.75 + 1.25 i, 1.0 + 1.0 i) == 0.0846958290317209430433805274189191353 + 0.513285749182902449043287190519090481 i":
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+Test "Real part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i":
+double: 1
+float: 4
+idouble: 1
+ifloat: 4
+Test "Imaginary part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i":
+float: 2
+ifloat: 2
+Test "Imaginary part of: cpow (e + 0 i, 0 + 2 * M_PIl i) == 1.0 + 0.0 i":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+
+# csinh
+Test "Imaginary part of: csinh (-2 - 3 i) == 3.59056458998577995201256544779481679 - 0.530921086248519805267040090660676560 i":
+double: 1
+idouble: 1
+Test "Real part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i":
+float: 1
+ifloat: 1
+
+# csqrt
+Test "Real part of: csqrt (-2 + 3 i) == 0.89597747612983812471573375529004348 + 1.6741492280355400404480393008490519 i":
+float: 1
+ifloat: 1
+Test "Real part of: csqrt (-2 - 3 i) == 0.89597747612983812471573375529004348 - 1.6741492280355400404480393008490519 i":
+float: 1
+ifloat: 1
+
+# ctan
+Test "Real part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: ctan (0.75 + 1.25 i) == 0.160807785916206426725166058173438663 + 0.975363285031235646193581759755216379 i":
+double: 1
+idouble: 1
+
+# ctanh
+Test "Real part of: ctanh (-2 - 3 i) == -0.965385879022133124278480269394560686 + 0.988437503832249372031403430350121098e-2 i":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+Test "Imaginary part of: ctanh (0 + pi/4 i) == 0.0 + 1.0 i":
+float: 1
+ifloat: 1
+Test "Real part of: ctanh (0.75 + 1.25 i) == 1.37260757053378320258048606571226857 + 0.385795952609750664177596760720790220 i":
+double: 1
+idouble: 1
+
+# erf
+Test "erf (1.25) == 0.922900128256458230136523481197281140":
+double: 1
+idouble: 1
+
+# erfc
+Test "erfc (2.0) == 0.00467773498104726583793074363274707139":
+double: 1
+idouble: 1
+Test "erfc (4.125) == 0.542340079956506600531223408575531062e-8":
+double: 1
+idouble: 1
+
+# exp10
+Test "exp10 (-1) == 0.1":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "exp10 (0.75) == 5.62341325190349080394951039776481231":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "exp10 (3) == 1000":
+double: 6
+float: 2
+idouble: 6
+ifloat: 2
+
+# expm1
+Test "expm1 (0.75) == 1.11700001661267466854536981983709561":
+double: 1
+idouble: 1
+Test "expm1 (1) == M_El - 1.0":
+float: 1
+ifloat: 1
+
+# hypot
+Test "hypot (-0.7, -12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (-0.7, 12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (-12.4, -0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (-12.4, 0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (0.7, -12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (0.7, 12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (12.4, -0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (12.4, 0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+
+# j0
+Test "j0 (-4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "j0 (0.75) == 0.864242275166648623555731103820923211":
+float: 1
+ifloat: 1
+Test "j0 (10.0) == -0.245935764451348335197760862485328754":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "j0 (2.0) == 0.223890779141235668051827454649948626":
+float: 2
+ifloat: 2
+Test "j0 (4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "j0 (8.0) == 0.171650807137553906090869407851972001":
+float: 1
+ifloat: 1
+
+# j1
+Test "j1 (10.0) == 0.0434727461688614366697487680258592883":
+float: 2
+ifloat: 2
+Test "j1 (2.0) == 0.576724807756873387202448242269137087":
+double: 1
+idouble: 1
+Test "j1 (8.0) == 0.234636346853914624381276651590454612":
+double: 1
+idouble: 1
+
+# jn
+Test "jn (0, -4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (0, 0.75) == 0.864242275166648623555731103820923211":
+float: 1
+ifloat: 1
+Test "jn (0, 10.0) == -0.245935764451348335197760862485328754":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "jn (0, 2.0) == 0.223890779141235668051827454649948626":
+float: 2
+ifloat: 2
+Test "jn (0, 4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (0, 8.0) == 0.171650807137553906090869407851972001":
+float: 1
+ifloat: 1
+Test "jn (1, 10.0) == 0.0434727461688614366697487680258592883":
+float: 2
+ifloat: 2
+Test "jn (1, 2.0) == 0.576724807756873387202448242269137087":
+double: 1
+idouble: 1
+Test "jn (1, 8.0) == 0.234636346853914624381276651590454612":
+double: 1
+idouble: 1
+Test "jn (10, 0.125) == 0.250543369809369890173993791865771547e-18":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (10, 0.75) == 0.149621713117596814698712483621682835e-10":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (10, 10.0) == 0.207486106633358857697278723518753428":
+double: 4
+float: 3
+idouble: 4
+ifloat: 3
+Test "jn (10, 2.0) == 0.251538628271673670963516093751820639e-6":
+float: 4
+ifloat: 4
+Test "jn (3, 0.125) == 0.406503832554912875023029337653442868e-4":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (3, 0.75) == 0.848438342327410884392755236884386804e-2":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (3, 10.0) == 0.0583793793051868123429354784103409563":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+Test "jn (3, 2.0) == 0.128943249474402051098793332969239835":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+# lgamma
+Test "lgamma (0.7) == 0.260867246531666514385732417016759578":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "lgamma (1.2) == -0.853740900033158497197028392998854470e-1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+# log10
+Test "log10 (0.75) == -0.124938736608299953132449886193870744":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+Test "log10 (e) == log10(e)":
+float: 1
+ifloat: 1
+
+# log1p
+Test "log1p (-0.25) == -0.287682072451780927439219005993827432":
+float: 1
+ifloat: 1
+
+# sincos
+Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.5 in cos_res":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in sin_res":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "sincos (pi/2, &sin_res, &cos_res) puts 0 in cos_res":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "sincos (pi/6, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in cos_res":
+float: 1
+ifloat: 1
+
+# tan
+Test "tan (pi/4) == 1":
+double: 1
+idouble: 1
+
+# tgamma
+Test "tgamma (-0.5) == -2 sqrt (pi)":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "tgamma (0.5) == sqrt (pi)":
+float: 1
+ifloat: 1
+Test "tgamma (0.7) == 1.29805533264755778568117117915281162":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# y0
+Test "y0 (1.0) == 0.0882569642156769579829267660235151628":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "y0 (1.5) == 0.382448923797758843955068554978089862":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "y0 (10.0) == 0.0556711672835993914244598774101900481":
+float: 1
+ifloat: 1
+Test "y0 (8.0) == 0.223521489387566220527323400498620359":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# y1
+Test "y1 (0.125) == -5.19993611253477499595928744876579921":
+double: 1
+idouble: 1
+Test "y1 (1.5) == -0.412308626973911295952829820633445323":
+float: 1
+ifloat: 1
+Test "y1 (10.0) == 0.249015424206953883923283474663222803":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+Test "y1 (2.0) == -0.107032431540937546888370772277476637":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "y1 (8.0) == -0.158060461731247494255555266187483550":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+# yn
+Test "yn (0, 1.0) == 0.0882569642156769579829267660235151628":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "yn (0, 1.5) == 0.382448923797758843955068554978089862":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "yn (0, 10.0) == 0.0556711672835993914244598774101900481":
+float: 1
+ifloat: 1
+Test "yn (0, 8.0) == 0.223521489387566220527323400498620359":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "yn (1, 0.125) == -5.19993611253477499595928744876579921":
+double: 1
+idouble: 1
+Test "yn (1, 1.5) == -0.412308626973911295952829820633445323":
+float: 1
+ifloat: 1
+Test "yn (1, 10.0) == 0.249015424206953883923283474663222803":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+Test "yn (1, 2.0) == -0.107032431540937546888370772277476637":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "yn (1, 8.0) == -0.158060461731247494255555266187483550":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+Test "yn (10, 0.125) == -127057845771019398.252538486899753195":
+double: 1
+idouble: 1
+Test "yn (10, 0.75) == -2133501638.90573424452445412893839236":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "yn (10, 1.0) == -121618014.278689189288130426667971145":
+double: 1
+idouble: 1
+Test "yn (10, 10.0) == -0.359814152183402722051986577343560609":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "yn (10, 2.0) == -129184.542208039282635913145923304214":
+double: 2
+idouble: 2
+Test "yn (3, 0.125) == -2612.69757350066712600220955744091741":
+double: 1
+idouble: 1
+Test "yn (3, 0.75) == -12.9877176234475433186319774484809207":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "yn (3, 10.0) == -0.251362657183837329779204747654240998":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "yn (3, 2.0) == -1.12778377684042778608158395773179238":
+double: 1
+idouble: 1
+
+# Maximal error of functions:
+Function: "atan2":
+float: 3
+ifloat: 3
+
+Function: "atanh":
+float: 1
+ifloat: 1
+
+Function: Real part of "cacosh":
+double: 1
+float: 7
+idouble: 1
+ifloat: 7
+
+Function: Imaginary part of "cacosh":
+double: 1
+float: 3
+idouble: 1
+ifloat: 3
+
+Function: Real part of "casin":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Real part of "casinh":
+double: 5
+float: 1
+idouble: 5
+ifloat: 1
+
+Function: Imaginary part of "casinh":
+double: 3
+float: 6
+idouble: 3
+ifloat: 6
+
+Function: Real part of "catan":
+float: 4
+ifloat: 4
+
+Function: Imaginary part of "catan":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Real part of "catanh":
+double: 4
+idouble: 4
+
+Function: Imaginary part of "catanh":
+float: 6
+ifloat: 6
+
+Function: "cbrt":
+double: 1
+idouble: 1
+
+Function: Real part of "ccos":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Imaginary part of "ccos":
+float: 1
+ifloat: 1
+
+Function: Real part of "ccosh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Imaginary part of "ccosh":
+float: 1
+ifloat: 1
+
+Function: Real part of "cexp":
+float: 1
+ifloat: 1
+
+Function: Imaginary part of "cexp":
+float: 1
+ifloat: 1
+
+Function: Real part of "clog":
+float: 1
+ifloat: 1
+
+Function: Imaginary part of "clog":
+float: 3
+ifloat: 3
+
+Function: Real part of "clog10":
+float: 1
+ifloat: 1
+
+Function: Imaginary part of "clog10":
+double: 1
+float: 5
+idouble: 1
+ifloat: 5
+
+Function: "cos":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+
+Function: Real part of "cpow":
+double: 2
+float: 4
+idouble: 2
+ifloat: 4
+
+Function: Imaginary part of "cpow":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+
+Function: Real part of "csinh":
+float: 1
+ifloat: 1
+
+Function: Imaginary part of "csinh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Real part of "csqrt":
+float: 1
+ifloat: 1
+
+Function: Real part of "ctan":
+double: 1
+idouble: 1
+
+Function: Imaginary part of "ctan":
+double: 1
+idouble: 1
+
+Function: Real part of "ctanh":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+Function: Imaginary part of "ctanh":
+float: 1
+ifloat: 1
+
+Function: "erf":
+double: 1
+idouble: 1
+
+Function: "erfc":
+double: 1
+idouble: 1
+
+Function: "exp10":
+double: 6
+float: 2
+idouble: 6
+ifloat: 2
+
+Function: "expm1":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "hypot":
+float: 1
+ifloat: 1
+
+Function: "j0":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+
+Function: "j1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+Function: "jn":
+double: 4
+float: 4
+idouble: 4
+ifloat: 4
+
+Function: "lgamma":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+Function: "log10":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+Function: "log1p":
+float: 1
+ifloat: 1
+
+Function: "sincos":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "tan":
+double: 1
+idouble: 1
+
+Function: "tgamma":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "y0":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+
+Function: "y1":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+
+Function: "yn":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+
+# end of automatic generation
diff --git a/sysdeps/mips/fpu_control.h b/sysdeps/mips/fpu_control.h
new file mode 100644
index 0000000000..da18deab5a
--- /dev/null
+++ b/sysdeps/mips/fpu_control.h
@@ -0,0 +1,98 @@
+/* FPU control word bits.  Mips version.
+   Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Olaf Flebbe and Ralf Baechle.
+
+   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.  */
+
+#ifndef _FPU_CONTROL_H
+#define _FPU_CONTROL_H
+
+/* MIPS FPU floating point control register bits.
+ *
+ * 31-25  -> floating point conditions code bits 7-1.  These bits are only
+ *           available in MIPS IV.
+ * 24     -> flush denormalized results to zero instead of
+ *           causing unimplemented operation exception.  This bit is only
+ *           available for MIPS III and newer.
+ * 23     -> Condition bit
+ * 22-18  -> reserved (read as 0, write with 0)
+ * 17     -> cause bit for unimplemented operation
+ * 16     -> cause bit for invalid exception
+ * 15     -> cause bit for division by zero exception
+ * 14     -> cause bit for overflow exception
+ * 13     -> cause bit for underflow exception
+ * 12     -> cause bit for inexact exception
+ * 11     -> enable exception for invalid exception
+ * 10     -> enable exception for division by zero exception
+ *  9     -> enable exception for overflow exception
+ *  8     -> enable exception for underflow exception
+ *  7     -> enable exception for inexact exception
+ *  6     -> flag invalid exception
+ *  5     -> flag division by zero exception
+ *  4     -> flag overflow exception
+ *  3     -> flag underflow exception
+ *  2     -> flag inexact exception
+ *  1-0   -> rounding control
+ *
+ *
+ * Rounding Control:
+ * 00 - rounding to nearest (RN)
+ * 01 - rounding toward zero (RZ)
+ * 10 - rounding (up) toward plus infinity (RP)
+ * 11 - rounding (down)toward minus infinity (RM)
+ */
+
+#include <features.h>
+
+/* masking of interrupts */
+#define _FPU_MASK_V     0x0800  /* Invalid operation */
+#define _FPU_MASK_Z     0x0400  /* Division by zero  */
+#define _FPU_MASK_O     0x0200  /* Overflow          */
+#define _FPU_MASK_U     0x0100  /* Underflow         */
+#define _FPU_MASK_I     0x0080  /* Inexact operation */
+
+/* flush denormalized numbers to zero */
+#define _FPU_FLUSH_TZ   0x1000000
+
+/* rounding control */
+#define _FPU_RC_NEAREST 0x0     /* RECOMMENDED */
+#define _FPU_RC_ZERO    0x1
+#define _FPU_RC_UP      0x2
+#define _FPU_RC_DOWN    0x3
+
+#define _FPU_RESERVED 0xfe3c0000  /* Reserved bits in cw */
+
+
+/* The fdlibm code requires strict IEEE double precision arithmetic,
+   and no interrupts for exceptions, rounding to nearest.  */
+
+#define _FPU_DEFAULT  0x00000000
+
+/* IEEE:  same as above, but exceptions */
+#define _FPU_IEEE     0x00000F80
+
+/* Type of the control word.  */
+typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__SI__)));
+
+/* Macros for accessing the hardware control word.  */
+#define _FPU_GETCW(cw) __asm__ ("cfc1 %0,$31" : "=r" (cw))
+#define _FPU_SETCW(cw) __asm__ ("ctc1 %0,$31" : : "r" (cw))
+
+/* Default control word set at startup.  */
+extern fpu_control_t __fpu_control;
+
+#endif	/* fpu_control.h */
diff --git a/sysdeps/mips/gccframe.h b/sysdeps/mips/gccframe.h
new file mode 100644
index 0000000000..ec9311caca
--- /dev/null
+++ b/sysdeps/mips/gccframe.h
@@ -0,0 +1,22 @@
+/* Definition of object in frame unwind info.  mips version.
+   Copyright (C) 2001 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.  */
+
+#define FIRST_PSEUDO_REGISTER 76
+
+#include <sysdeps/generic/gccframe.h>
diff --git a/sysdeps/mips/ieee754.h b/sysdeps/mips/ieee754.h
new file mode 100644
index 0000000000..ed13de2775
--- /dev/null
+++ b/sysdeps/mips/ieee754.h
@@ -0,0 +1,325 @@
+/* Copyright (C) 1992, 1995, 1996, 1999, 2002, 2003
+	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.  */
+
+#ifndef _IEEE754_H
+
+#define _IEEE754_H 1
+#include <features.h>
+
+#include <endian.h>
+
+#include <float.h>
+
+__BEGIN_DECLS
+
+union ieee754_float
+  {
+    float f;
+
+    /* This is the IEEE 754 single-precision format.  */
+    struct
+      {
+#if	__BYTE_ORDER == __BIG_ENDIAN
+	unsigned int negative:1;
+	unsigned int exponent:8;
+	unsigned int mantissa:23;
+#endif				/* Big endian.  */
+#if	__BYTE_ORDER == __LITTLE_ENDIAN
+	unsigned int mantissa:23;
+	unsigned int exponent:8;
+	unsigned int negative:1;
+#endif				/* Little endian.  */
+      } ieee;
+
+    /* This format makes it easier to see if a NaN is a signalling NaN.  */
+    struct
+      {
+#if	__BYTE_ORDER == __BIG_ENDIAN
+	unsigned int negative:1;
+	unsigned int exponent:8;
+	unsigned int quiet_nan:1;
+	unsigned int mantissa:22;
+#endif				/* Big endian.  */
+#if	__BYTE_ORDER == __LITTLE_ENDIAN
+	unsigned int mantissa:22;
+	unsigned int quiet_nan:1;
+	unsigned int exponent:8;
+	unsigned int negative:1;
+#endif				/* Little endian.  */
+      } ieee_nan;
+  };
+
+#define IEEE754_FLOAT_BIAS	0x7f /* Added to exponent.  */
+
+
+union ieee754_double
+  {
+    double d;
+
+    /* This is the IEEE 754 double-precision format.  */
+    struct
+      {
+#if	__BYTE_ORDER == __BIG_ENDIAN
+	unsigned int negative:1;
+	unsigned int exponent:11;
+	/* Together these comprise the mantissa.  */
+	unsigned int mantissa0:20;
+	unsigned int mantissa1:32;
+#endif				/* Big endian.  */
+#if	__BYTE_ORDER == __LITTLE_ENDIAN
+# if	__FLOAT_WORD_ORDER == BIG_ENDIAN
+	unsigned int mantissa0:20;
+	unsigned int exponent:11;
+	unsigned int negative:1;
+	unsigned int mantissa1:32;
+# else
+	/* Together these comprise the mantissa.  */
+	unsigned int mantissa1:32;
+	unsigned int mantissa0:20;
+	unsigned int exponent:11;
+	unsigned int negative:1;
+# endif
+#endif				/* Little endian.  */
+      } ieee;
+
+    /* This format makes it easier to see if a NaN is a signalling NaN.  */
+    struct
+      {
+#if	__BYTE_ORDER == __BIG_ENDIAN
+	unsigned int negative:1;
+	unsigned int exponent:11;
+	unsigned int quiet_nan:1;
+	/* Together these comprise the mantissa.  */
+	unsigned int mantissa0:19;
+	unsigned int mantissa1:32;
+#else
+# if	__FLOAT_WORD_ORDER == BIG_ENDIAN
+	unsigned int mantissa0:19;
+	unsigned int quiet_nan:1;
+	unsigned int exponent:11;
+	unsigned int negative:1;
+	unsigned int mantissa1:32;
+# else
+	/* Together these comprise the mantissa.  */
+	unsigned int mantissa1:32;
+	unsigned int mantissa0:19;
+	unsigned int quiet_nan:1;
+	unsigned int exponent:11;
+	unsigned int negative:1;
+# endif
+#endif
+      } ieee_nan;
+  };
+
+#define IEEE754_DOUBLE_BIAS	0x3ff /* Added to exponent.  */
+
+#if LDBL_MANT_DIG == 113
+
+union ieee854_long_double
+  {
+    long double d;
+
+    /* This is the IEEE 854 quad-precision format.  */
+    struct
+      {
+#if	__BYTE_ORDER == __BIG_ENDIAN
+	unsigned int negative:1;
+	unsigned int exponent:15;
+	/* Together these comprise the mantissa.  */
+	unsigned int mantissa0:16;
+	unsigned int mantissa1:32;
+	unsigned int mantissa2:32;
+	unsigned int mantissa3:32;
+#endif				/* Big endian.  */
+#if	__BYTE_ORDER == __LITTLE_ENDIAN
+	/* Together these comprise the mantissa.  */
+	unsigned int mantissa3:32;
+	unsigned int mantissa2:32;
+	unsigned int mantissa1:32;
+	unsigned int mantissa0:16;
+	unsigned int exponent:15;
+	unsigned int negative:1;
+#endif				/* Little endian.  */
+      } ieee;
+
+    /* This format makes it easier to see if a NaN is a signalling NaN.  */
+    struct
+      {
+#if	__BYTE_ORDER == __BIG_ENDIAN
+	unsigned int negative:1;
+	unsigned int exponent:15;
+	unsigned int quiet_nan:1;
+	/* Together these comprise the mantissa.  */
+	unsigned int mantissa0:15;
+	unsigned int mantissa1:32;
+	unsigned int mantissa2:32;
+	unsigned int mantissa3:32;
+#endif				/* Big endian.  */
+#if	__BYTE_ORDER == __LITTLE_ENDIAN
+	/* Together these comprise the mantissa.  */
+	unsigned int mantissa3:32;
+	unsigned int mantissa2:32;
+	unsigned int mantissa1:32;
+	unsigned int mantissa0:15;
+	unsigned int quiet_nan:1;
+	unsigned int exponent:15;
+	unsigned int negative:1;
+#endif				/* Little endian.  */
+      } ieee_nan;
+  };
+
+#define IEEE854_LONG_DOUBLE_BIAS 0x3fff /* Added to exponent.  */
+
+#elif LDBL_MANT_DIG == 64
+
+union ieee854_long_double
+  {
+    long double d;
+
+    /* This is the IEEE 854 double-extended-precision format.  */
+    struct
+      {
+#if	__BYTE_ORDER == __BIG_ENDIAN
+	unsigned int negative:1;
+	unsigned int exponent:15;
+	unsigned int empty:16;
+	unsigned int mantissa0:32;
+	unsigned int mantissa1:32;
+#endif
+#if	__BYTE_ORDER == __LITTLE_ENDIAN
+# if	__FLOAT_WORD_ORDER == BIG_ENDIAN
+	unsigned int exponent:15;
+	unsigned int negative:1;
+	unsigned int empty:16;
+	unsigned int mantissa0:32;
+	unsigned int mantissa1:32;
+# else
+	unsigned int mantissa1:32;
+	unsigned int mantissa0:32;
+	unsigned int exponent:15;
+	unsigned int negative:1;
+	unsigned int empty:16;
+# endif
+#endif
+      } ieee;
+
+    /* This is for NaNs in the IEEE 854 double-extended-precision format.  */
+    struct
+      {
+#if	__BYTE_ORDER == __BIG_ENDIAN
+	unsigned int negative:1;
+	unsigned int exponent:15;
+	unsigned int empty:16;
+	unsigned int one:1;
+	unsigned int quiet_nan:1;
+	unsigned int mantissa0:30;
+	unsigned int mantissa1:32;
+#endif
+#if	__BYTE_ORDER == __LITTLE_ENDIAN
+# if	__FLOAT_WORD_ORDER == BIG_ENDIAN
+	unsigned int exponent:15;
+	unsigned int negative:1;
+	unsigned int empty:16;
+	unsigned int mantissa0:30;
+	unsigned int quiet_nan:1;
+	unsigned int one:1;
+	unsigned int mantissa1:32;
+# else
+	unsigned int mantissa1:32;
+	unsigned int mantissa0:30;
+	unsigned int quiet_nan:1;
+	unsigned int one:1;
+	unsigned int exponent:15;
+	unsigned int negative:1;
+	unsigned int empty:16;
+# endif
+#endif
+      } ieee_nan;
+  };
+
+#define IEEE854_LONG_DOUBLE_BIAS 0x3fff
+
+#elif LDBL_MANT_DIG == 53
+
+union ieee854_long_double
+  {
+    long double d;
+
+    /* This is the IEEE 754 double-precision format.  */
+    struct
+      {
+#if	__BYTE_ORDER == __BIG_ENDIAN
+	unsigned int negative:1;
+	unsigned int exponent:11;
+	/* Together these comprise the mantissa.  */
+	unsigned int mantissa0:20;
+	unsigned int mantissa1:32;
+#endif				/* Big endian.  */
+#if	__BYTE_ORDER == __LITTLE_ENDIAN
+# if	__FLOAT_WORD_ORDER == BIG_ENDIAN
+	unsigned int mantissa0:20;
+	unsigned int exponent:11;
+	unsigned int negative:1;
+	unsigned int mantissa1:32;
+# else
+	/* Together these comprise the mantissa.  */
+	unsigned int mantissa1:32;
+	unsigned int mantissa0:20;
+	unsigned int exponent:11;
+	unsigned int negative:1;
+# endif
+#endif				/* Little endian.  */
+      } ieee;
+
+    /* This format makes it easier to see if a NaN is a signalling NaN.  */
+    struct
+      {
+#if	__BYTE_ORDER == __BIG_ENDIAN
+	unsigned int negative:1;
+	unsigned int exponent:11;
+	unsigned int quiet_nan:1;
+	/* Together these comprise the mantissa.  */
+	unsigned int mantissa0:19;
+	unsigned int mantissa1:32;
+#else
+# if	__FLOAT_WORD_ORDER == BIG_ENDIAN
+	unsigned int mantissa0:19;
+	unsigned int quiet_nan:1;
+	unsigned int exponent:11;
+	unsigned int negative:1;
+	unsigned int mantissa1:32;
+# else
+	/* Together these comprise the mantissa.  */
+	unsigned int mantissa1:32;
+	unsigned int mantissa0:19;
+	unsigned int quiet_nan:1;
+	unsigned int exponent:11;
+	unsigned int negative:1;
+# endif
+#endif
+      } ieee_nan;
+  };
+
+#define IEEE854_LONG_DOUBLE_BIAS	0x3ff /* Added to exponent.  */
+
+#endif /* LDBL_MANT_DIG == 53 */
+
+__END_DECLS
+
+#endif /* ieee754.h */
diff --git a/sysdeps/mips/init-first.c b/sysdeps/mips/init-first.c
new file mode 100644
index 0000000000..b67a44431c
--- /dev/null
+++ b/sysdeps/mips/init-first.c
@@ -0,0 +1,64 @@
+/* Initialization code run first thing by the ELF startup code.  For mips/Unix.
+   Copyright (C) 1996, 1997 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 <unistd.h>
+
+extern void __libc_init (int, char **, char **);
+extern void __libc_global_ctors (void);
+
+
+static void
+init (int *data)
+{
+  int argc = *data;
+  char **argv = (void *) (data + 1);
+  char **envp = &argv[argc + 1];
+
+  __environ = envp;
+  __libc_init (argc, argv, envp);
+}
+
+#ifdef SHARED
+/* This function is called to initialize the shared C library.
+   It is called just before the user _start code from mips/elf/start.S,
+   with the stack set up as that code gets it.  */
+
+/* NOTE!  The linker notices the magical name `_init' and sets the DT_INIT
+   pointer in the dynamic section based solely on that.  It is convention
+   for this function to be in the `.init' section, but the symbol name is
+   the only thing that really matters!!  */
+/*void _init (int argc, ...) __attribute__ ((unused, section (".init")));*/
+
+void
+_init (int argc, ...)
+{
+  init (&argc);
+
+  __libc_global_ctors ();
+}
+#endif
+
+
+void
+__libc_init_first (int argc __attribute__ ((unused)), ...)
+{
+#ifndef SHARED
+  init (&argc);
+#endif
+}
diff --git a/sysdeps/mips/lshift.S b/sysdeps/mips/lshift.S
new file mode 100644
index 0000000000..0217bfc586
--- /dev/null
+++ b/sysdeps/mips/lshift.S
@@ -0,0 +1,98 @@
+/* MIPS2 __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>
+
+/* INPUT PARAMETERS
+   res_ptr	$4
+   src_ptr	$5
+   size		$6
+   cnt		$7
+*/
+#ifdef __PIC__
+	.option pic2
+#endif
+ENTRY (__mpn_lshift)
+	.set	noreorder
+#ifdef __PIC__
+	.cpload t9
+#endif
+	.set	nomacro
+
+	sll	$2,$6,2
+	addu	$5,$5,$2	/* make r5 point at end of src */
+	lw	$10,-4($5)	/* load first limb */
+	subu	$13,$0,$7
+	addu	$4,$4,$2	/* make r4 point at end of res */
+	addiu	$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 */
+	srl	$2,$10,$13	/* compute function result */
+
+	subu	$6,$6,$9
+
+L(Loop0):	lw	$3,-8($5)
+	addiu	$4,$4,-4
+	addiu	$5,$5,-4
+	addiu	$9,$9,-1
+	sll	$11,$10,$7
+	srl	$12,$3,$13
+	move	$10,$3
+	or	$8,$11,$12
+	bne	$9,$0,L(Loop0)
+	sw	$8,0($4)
+
+L(L0):	beq	$6,$0,L(Lend)
+	nop
+
+L(Loop):	lw	$3,-8($5)
+	addiu	$4,$4,-16
+	addiu	$6,$6,-4
+	sll	$11,$10,$7
+	srl	$12,$3,$13
+
+	lw	$10,-12($5)
+	sll	$14,$3,$7
+	or	$8,$11,$12
+	sw	$8,12($4)
+	srl	$9,$10,$13
+
+	lw	$3,-16($5)
+	sll	$11,$10,$7
+	or	$8,$14,$9
+	sw	$8,8($4)
+	srl	$12,$3,$13
+
+	lw	$10,-20($5)
+	sll	$14,$3,$7
+	or	$8,$11,$12
+	sw	$8,4($4)
+	srl	$9,$10,$13
+
+	addiu	$5,$5,-16
+	or	$8,$14,$9
+	bgtz	$6,L(Loop)
+	sw	$8,0($4)
+
+L(Lend):	sll	$8,$10,$7
+	j	$31
+	sw	$8,-4($4)
+	END (__mpn_lshift)
diff --git a/sysdeps/mips/machine-gmon.h b/sysdeps/mips/machine-gmon.h
new file mode 100644
index 0000000000..7a089fa595
--- /dev/null
+++ b/sysdeps/mips/machine-gmon.h
@@ -0,0 +1,141 @@
+/* Machine-specific calling sequence for `mcount' profiling function.  MIPS
+   Copyright (C) 1996, 1997, 2000, 2001, 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>
+
+#define _MCOUNT_DECL(frompc,selfpc) \
+static void __attribute_used__ __mcount (u_long frompc, u_long selfpc)
+
+/* Call __mcount with the return PC for our caller,
+   and the return PC our caller will return to.  */
+
+#if _MIPS_SIM == _ABIO32
+
+#ifdef __PIC__
+# define CPLOAD ".cpload $25;"
+# define CPRESTORE ".cprestore 44\n\t"
+#else
+# define CPLOAD
+# define CPRESTORE
+#endif
+
+#define MCOUNT asm(\
+	".globl _mcount;\n\t" \
+	".align 2;\n\t" \
+	".type _mcount,@function;\n\t" \
+	".ent _mcount\n\t" \
+        "_mcount:\n\t" \
+        ".frame $sp,44,$31\n\t" \
+        ".set noreorder;\n\t" \
+        ".set noat;\n\t" \
+        CPLOAD \
+	"subu $29,$29,48;\n\t" \
+	CPRESTORE \
+        "sw $4,24($29);\n\t" \
+        "sw $5,28($29);\n\t" \
+        "sw $6,32($29);\n\t" \
+        "sw $7,36($29);\n\t" \
+        "sw $2,40($29);\n\t" \
+        "sw $1,16($29);\n\t" \
+        "sw $31,20($29);\n\t" \
+        "move $5,$31;\n\t" \
+        "move $4,$1;\n\t" \
+        "jal __mcount;\n\t" \
+        "nop;\n\t" \
+        "lw $4,24($29);\n\t" \
+        "lw $5,28($29);\n\t" \
+        "lw $6,32($29);\n\t" \
+        "lw $7,36($29);\n\t" \
+        "lw $2,40($29);\n\t" \
+        "lw $31,20($29);\n\t" \
+        "lw $1,16($29);\n\t" \
+        "addu $29,$29,56;\n\t" \
+        "j $31;\n\t" \
+        "move $31,$1;\n\t" \
+        ".set reorder;\n\t" \
+        ".set at\n\t" \
+        ".end _mcount");
+
+#else
+
+#ifdef __PIC__
+# define CPSETUP ".cpsetup $25, 88, _mcount;"
+# define CPRETURN ".cpreturn;"
+#else
+# define CPSETUP
+# define CPRETURN
+#endif
+
+#if _MIPS_SIM == _ABIN32
+# define PTR_ADDU_STRING "add" /* no u */
+# define PTR_SUBU_STRING "sub" /* no u */
+#elif _MIPS_SIM == _ABI64
+# define PTR_ADDU_STRING "daddu"
+# define PTR_SUBU_STRING "dsubu"
+#else
+# error "Unknown ABI"
+#endif
+
+#define MCOUNT asm(\
+	".globl _mcount;\n\t" \
+	".align 3;\n\t" \
+	".type _mcount,@function;\n\t" \
+	".ent _mcount\n\t" \
+        "_mcount:\n\t" \
+        ".frame $sp,88,$31\n\t" \
+        ".set noreorder;\n\t" \
+        ".set noat;\n\t" \
+        PTR_SUBU_STRING " $29,$29,96;\n\t" \
+        CPSETUP \
+        "sd $4,24($29);\n\t" \
+        "sd $5,32($29);\n\t" \
+        "sd $6,40($29);\n\t" \
+        "sd $7,48($29);\n\t" \
+        "sd $8,56($29);\n\t" \
+        "sd $9,64($29);\n\t" \
+        "sd $10,72($29);\n\t" \
+        "sd $11,80($29);\n\t" \
+        "sd $2,16($29);\n\t" \
+        "sd $1,0($29);\n\t" \
+        "sd $31,8($29);\n\t" \
+        "move $5,$31;\n\t" \
+        "move $4,$1;\n\t" \
+        "jal __mcount;\n\t" \
+        "nop;\n\t" \
+        "ld $4,24($29);\n\t" \
+        "ld $5,32($29);\n\t" \
+        "ld $6,40($29);\n\t" \
+        "ld $7,48($29);\n\t" \
+        "ld $8,56($29);\n\t" \
+        "ld $9,64($29);\n\t" \
+        "ld $10,72($29);\n\t" \
+        "ld $11,80($29);\n\t" \
+        "ld $2,16($29);\n\t" \
+        "ld $31,8($29);\n\t" \
+        "ld $1,0($29);\n\t" \
+        CPRETURN \
+        PTR_ADDU_STRING " $29,$29,96;\n\t" \
+        "j $31;\n\t" \
+        "move $31,$1;\n\t" \
+        ".set reorder;\n\t" \
+        ".set at\n\t" \
+        ".end _mcount");
+
+#endif
diff --git a/sysdeps/mips/memcpy.S b/sysdeps/mips/memcpy.S
new file mode 100644
index 0000000000..2049d05829
--- /dev/null
+++ b/sysdeps/mips/memcpy.S
@@ -0,0 +1,136 @@
+/* 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.
+
+   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>
+
+
+/* void *memcpy(void *s1, const void *s2, size_t n);  */
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#  define LWHI	lwl		/* high part is left in big-endian	*/
+#  define SWHI	swl		/* high part is left in big-endian	*/
+#  define LWLO	lwr		/* low part is right in big-endian	*/
+#  define SWLO	swr		/* low part is right in big-endian	*/
+#else
+#  define LWHI	lwr		/* high part is right in little-endian	*/
+#  define SWHI	swr		/* high part is right in little-endian	*/
+#  define LWLO	lwl		/* low part is left in little-endian	*/
+#  define SWLO	swl		/* low part is left in little-endian	*/
+#endif
+
+ENTRY (memcpy)
+	.set	noreorder
+
+	slti	t0, a2, 8		# Less than 8?
+	bne	t0, zero, L(last8)
+	move	v0, a0			# Setup exit value before too late
+
+	xor	t0, a1, a0		# Find a0/a1 displacement
+	andi	t0, 0x3
+	bne	t0, zero, L(shift)	# Go handle the unaligned case
+	subu	t1, zero, a1
+	andi	t1, 0x3			# a0/a1 are aligned, but are we
+	beq	t1, zero, L(chk8w)	#  starting in the middle of a word?
+	subu	a2, t1
+	LWHI	t0, 0(a1)		# Yes we are... take care of that
+	addu	a1, t1
+	SWHI	t0, 0(a0)
+	addu	a0, t1
+
+L(chk8w):	
+	andi	t0, a2, 0x1f		# 32 or more bytes left?
+	beq	t0, a2, L(chk1w)
+	subu	a3, a2, t0		# Yes
+	addu	a3, a1			# a3 = end address of loop
+	move	a2, t0			# a2 = what will be left after loop
+L(lop8w):	
+	lw	t0,  0(a1)		# Loop taking 8 words at a time
+	lw	t1,  4(a1)
+	lw	t2,  8(a1)
+	lw	t3, 12(a1)
+	lw	t4, 16(a1)
+	lw	t5, 20(a1)
+	lw	t6, 24(a1)
+	lw	t7, 28(a1)
+	addiu	a0, 32
+	addiu	a1, 32
+	sw	t0, -32(a0)
+	sw	t1, -28(a0)
+	sw	t2, -24(a0)
+	sw	t3, -20(a0)
+	sw	t4, -16(a0)
+	sw	t5, -12(a0)
+	sw	t6,  -8(a0)
+	bne	a1, a3, L(lop8w)
+	sw	t7,  -4(a0)
+
+L(chk1w):	
+	andi	t0, a2, 0x3		# 4 or more bytes left?
+	beq	t0, a2, L(last8)
+	subu	a3, a2, t0		# Yes, handle them one word at a time
+	addu	a3, a1			# a3 again end address
+	move	a2, t0
+L(lop1w):	
+	lw	t0, 0(a1)
+	addiu	a0, 4
+	addiu	a1, 4
+	bne	a1, a3, L(lop1w)
+	sw	t0, -4(a0)
+
+L(last8):	
+	blez	a2, L(lst8e)		# Handle last 8 bytes, one at a time
+	addu	a3, a2, a1
+L(lst8l):	
+	lb	t0, 0(a1)
+	addiu	a0, 1
+	addiu	a1, 1
+	bne	a1, a3, L(lst8l)
+	sb	t0, -1(a0)
+L(lst8e):	
+	jr	ra			# Bye, bye
+	nop
+
+L(shift):	
+	subu	a3, zero, a0		# Src and Dest unaligned 
+	andi	a3, 0x3			#  (unoptimized case...)
+	beq	a3, zero, L(shft1)
+	subu	a2, a3			# a2 = bytes left
+	LWHI	t0, 0(a1)		# Take care of first odd part
+	LWLO	t0, 3(a1)
+	addu	a1, a3
+	SWHI	t0, 0(a0)
+	addu	a0, a3
+L(shft1):	
+	andi	t0, a2, 0x3
+	subu	a3, a2, t0
+	addu	a3, a1
+L(shfth):	
+	LWHI	t1, 0(a1)		# Limp through, word by word
+	LWLO	t1, 3(a1)
+	addiu	a0, 4
+	addiu	a1, 4
+	bne	a1, a3, L(shfth)
+	sw	t1, -4(a0)
+	b	L(last8)		# Handle anything which may be left
+	move	a2, t0
+
+	.set	reorder
+END (memcpy)
+libc_hidden_builtin_def (memcpy)
diff --git a/sysdeps/mips/memset.S b/sysdeps/mips/memset.S
new file mode 100644
index 0000000000..694ee8f1dc
--- /dev/null
+++ b/sysdeps/mips/memset.S
@@ -0,0 +1,86 @@
+/* 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.
+
+   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>
+
+
+/* void *memset(void *s, int c, size_t n).  */
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+# define SWHI	swl		/* high part is left in big-endian	*/
+#else
+# define SWHI	swr		/* high part is right in little-endian	*/
+#endif
+
+ENTRY (memset)
+	.set	noreorder
+
+	slti	t1, a2, 8		# Less than 8?
+	bne	t1, zero, L(last8)
+	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
+	sll	t0, a1, 8
+	or	a1, t0
+	sll	t0, a1, 16
+	or	a1, t0			# a1 is now pattern in full word
+
+L(ueven):	
+	subu	t0, zero, a0		# Unaligned address?
+	andi	t0, 0x3
+	beq	t0, zero, L(chkw)
+	subu	a2, t0
+	SWHI	a1, 0(a0)		# Yes, handle first unaligned part
+	addu	a0, t0			# Now both a0 and a2 are updated
+
+L(chkw):	
+	andi	t0, a2, 0x7		# Enough left for one loop iteration?
+	beq	t0, a2, L(chkl)
+	subu	a3, a2, t0
+	addu	a3, a0			# a3 is last loop address +1
+	move	a2, t0			# a2 is now # of bytes left after loop
+L(loopw):	
+	addiu	a0, 8			# Handle 2 words pr. iteration
+	sw	a1, -8(a0)
+	bne	a0, a3, L(loopw)
+	sw	a1, -4(a0)
+
+L(chkl):	
+	andi	t0, a2, 0x4		# Check if there is at least a full
+	beq	t0, zero, L(last8)	#  word remaining after the loop
+	subu	a2, t0
+	sw	a1, 0(a0)		# Yes...
+	addiu	a0, 4
+
+L(last8):	
+	blez	a2, L(exit)		# Handle last 8 bytes (if cnt>0)
+	addu	a3, a2, a0		# a3 is last address +1
+L(lst8l):	
+	addiu	a0, 1
+	bne	a0, a3, L(lst8l)
+	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/memusage.h b/sysdeps/mips/memusage.h
new file mode 100644
index 0000000000..dc1cc9ca14
--- /dev/null
+++ b/sysdeps/mips/memusage.h
@@ -0,0 +1,21 @@
+/* Copyright (C) 2000 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.  */
+
+#define GETSP() ({ register uintptr_t stack_ptr asm ("$29"); stack_ptr; })
+
+#include <sysdeps/generic/memusage.h>
diff --git a/sysdeps/mips/mips32/Implies b/sysdeps/mips/mips32/Implies
new file mode 100644
index 0000000000..fab98d7312
--- /dev/null
+++ b/sysdeps/mips/mips32/Implies
@@ -0,0 +1,2 @@
+mips
+wordsize-32
diff --git a/sysdeps/mips/mips32/Makefile b/sysdeps/mips/mips32/Makefile
new file mode 100644
index 0000000000..dec0b024c3
--- /dev/null
+++ b/sysdeps/mips/mips32/Makefile
@@ -0,0 +1,3 @@
+ifeq ($(filter -mabi=32,$(CC)),)
+CC += -mabi=32
+endif
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
diff --git a/sysdeps/mips/mul_1.S b/sysdeps/mips/mul_1.S
new file mode 100644
index 0000000000..72f538670c
--- /dev/null
+++ b/sysdeps/mips/mul_1.S
@@ -0,0 +1,87 @@
+/* MIPS __mpn_mul_1 -- Multiply a limb vector with a single limb and
+store the product in a second limb vector.
+
+Copyright (C) 1995, 1998, 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>
+
+/* INPUT PARAMETERS
+   res_ptr	$4
+   s1_ptr	$5
+   size		$6
+   s2_limb	$7
+*/
+#ifdef __PIC__
+	.option pic2
+#endif
+ENTRY (__mpn_mul_1)
+	.set    noreorder
+#ifdef __PIC__
+	.cpload t9
+#endif
+	.set    nomacro
+
+	/* warm up phase 0 */
+	lw	$8,0($5)
+
+	/* warm up phase 1 */
+	addiu	$5,$5,4
+	multu	$8,$7
+
+	addiu	$6,$6,-1
+	beq	$6,$0,L(LC0)
+	move	$2,$0		/* zero cy2 */
+
+	addiu	$6,$6,-1
+	beq	$6,$0,L(LC1)
+	lw	$8,0($5)	/* load new s1 limb as early as possible */
+
+L(Loop):	mflo	$10
+	mfhi	$9
+	addiu	$5,$5,4
+	addu	$10,$10,$2	/* add old carry limb to low product limb */
+	multu	$8,$7
+	lw	$8,0($5)	/* load new s1 limb as early as possible */
+	addiu	$6,$6,-1	/* decrement loop counter */
+	sltu	$2,$10,$2	/* carry from previous addition -> $2 */
+	sw	$10,0($4)
+	addiu	$4,$4,4
+	bne	$6,$0,L(Loop)	/* should be "bnel" */
+	addu	$2,$9,$2	/* add high product limb and carry from addition */
+
+	/* cool down phase 1 */
+L(LC1):	mflo	$10
+	mfhi	$9
+	addu	$10,$10,$2
+	sltu	$2,$10,$2
+	multu	$8,$7
+	sw	$10,0($4)
+	addiu	$4,$4,4
+	addu	$2,$9,$2	/* add high product limb and carry from addition */
+
+	/* cool down phase 0 */
+L(LC0):	mflo	$10
+	mfhi	$9
+	addu	$10,$10,$2
+	sltu	$2,$10,$2
+	sw	$10,0($4)
+	j	$31
+	addu	$2,$9,$2	/* add high product limb and carry from addition */
+	END (__mpn_mul_1)
diff --git a/sysdeps/mips/regdef.h b/sysdeps/mips/regdef.h
new file mode 100644
index 0000000000..bc7f13b4b5
--- /dev/null
+++ b/sysdeps/mips/regdef.h
@@ -0,0 +1,27 @@
+/* Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ralf Baechle <ralf@gnu.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.  */
+
+#ifndef _REGDEF_H
+#define _REGDEF_H
+
+#include <sys/regdef.h>
+#include <sys/fpregdef.h>
+
+#endif /* _REGDEF_H */
+
diff --git a/sysdeps/mips/rshift.S b/sysdeps/mips/rshift.S
new file mode 100644
index 0000000000..cb688fe2ac
--- /dev/null
+++ b/sysdeps/mips/rshift.S
@@ -0,0 +1,95 @@
+/* MIPS2 __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>
+
+/* INPUT PARAMETERS
+   res_ptr	$4
+   src_ptr	$5
+   size		$6
+   cnt		$7
+*/
+#ifdef __PIC__
+	.option pic2
+#endif
+ENTRY (__mpn_rshift)
+	.set	noreorder
+#ifdef __PIC__
+	.cpload t9
+#endif
+	.set	nomacro
+
+	lw	$10,0($5)	/* load first limb */
+	subu	$13,$0,$7
+	addiu	$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*/
+	 sll	$2,$10,$13	/* compute function result */
+
+	subu	$6,$6,$9
+
+L(Loop0):	lw	$3,4($5)
+	addiu	$4,$4,4
+	addiu	$5,$5,4
+	addiu	$9,$9,-1
+	srl	$11,$10,$7
+	sll	$12,$3,$13
+	move	$10,$3
+	or	$8,$11,$12
+	bne	$9,$0,L(Loop0)
+	 sw	$8,-4($4)
+
+L(L0):	beq	$6,$0,L(Lend)
+	 nop
+
+L(Loop):	lw	$3,4($5)
+	addiu	$4,$4,16
+	addiu	$6,$6,-4
+	srl	$11,$10,$7
+	sll	$12,$3,$13
+
+	lw	$10,8($5)
+	srl	$14,$3,$7
+	or	$8,$11,$12
+	sw	$8,-16($4)
+	sll	$9,$10,$13
+
+	lw	$3,12($5)
+	srl	$11,$10,$7
+	or	$8,$14,$9
+	sw	$8,-12($4)
+	sll	$12,$3,$13
+
+	lw	$10,16($5)
+	srl	$14,$3,$7
+	or	$8,$11,$12
+	sw	$8,-8($4)
+	sll	$9,$10,$13
+
+	addiu	$5,$5,16
+	or	$8,$14,$9
+	bgtz	$6,L(Loop)
+	 sw	$8,-4($4)
+
+L(Lend):	srl	$8,$10,$7
+	j	$31
+	sw	$8,0($4)
+	END (__mpn_rshift)
diff --git a/sysdeps/mips/setjmp.S b/sysdeps/mips/setjmp.S
new file mode 100644
index 0000000000..01ef313995
--- /dev/null
+++ b/sysdeps/mips/setjmp.S
@@ -0,0 +1,45 @@
+/* Copyright (C) 1996, 1997, 2000 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>
+
+/* 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__
+	.set	noreorder
+	.cpload	t9
+	.set	reorder
+#endif
+	move	a2, sp
+#ifdef fp
+	move	a3, fp
+#else
+	move	a3, $fp
+#endif
+#ifdef __PIC__
+	la	t9, __sigsetjmp_aux
+	jr	t9
+#else
+	j	__sigsetjmp_aux
+#endif
+	.end __sigsetjmp
diff --git a/sysdeps/mips/setjmp_aux.c b/sysdeps/mips/setjmp_aux.c
new file mode 100644
index 0000000000..7125cc4f81
--- /dev/null
+++ b/sysdeps/mips/setjmp_aux.c
@@ -0,0 +1,65 @@
+/* Copyright (C) 1996, 1997, 2000, 2002, 2003 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>
+
+/* 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, int sp, int fp)
+{
+  /* Store the floating point callee-saved registers...  */
+  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]));
+
+  /* .. and the PC;  */
+  asm volatile ("sw $31, %0" : : "m" (env[0].__jmpbuf[0].__pc));
+
+  /* .. and the stack pointer;  */
+  env[0].__jmpbuf[0].__sp = (void *) sp;
+
+  /* .. and the FP; it'll be in s8. */
+  env[0].__jmpbuf[0].__fp = (void *) fp;
+
+  /* .. and the GP; */
+  asm volatile ("sw $gp, %0" : : "m" (env[0].__jmpbuf[0].__gp));
+
+  /* .. and the callee-saved registers; */
+  asm volatile ("sw $16, %0" : : "m" (env[0].__jmpbuf[0].__regs[0]));
+  asm volatile ("sw $17, %0" : : "m" (env[0].__jmpbuf[0].__regs[1]));
+  asm volatile ("sw $18, %0" : : "m" (env[0].__jmpbuf[0].__regs[2]));
+  asm volatile ("sw $19, %0" : : "m" (env[0].__jmpbuf[0].__regs[3]));
+  asm volatile ("sw $20, %0" : : "m" (env[0].__jmpbuf[0].__regs[4]));
+  asm volatile ("sw $21, %0" : : "m" (env[0].__jmpbuf[0].__regs[5]));
+  asm volatile ("sw $22, %0" : : "m" (env[0].__jmpbuf[0].__regs[6]));
+  asm volatile ("sw $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/sgidefs.h b/sysdeps/mips/sgidefs.h
new file mode 100644
index 0000000000..74509fdbd0
--- /dev/null
+++ b/sysdeps/mips/sgidefs.h
@@ -0,0 +1,73 @@
+/* Copyright (C) 1996, 1997, 1998, 2003, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ralf Baechle <ralf@gnu.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.  */
+
+#ifndef _SGIDEFS_H
+#define _SGIDEFS_H	1
+
+/*
+ * A crude hack to stop <asm/sgidefs.h>
+ */
+#undef __ASM_SGIDEFS_H
+#define __ASM_SGIDEFS_H
+
+/*
+ * And remove any damage it might have already done
+ */
+#undef _MIPS_ISA_MIPS1
+#undef _MIPS_ISA_MIPS2
+#undef _MIPS_ISA_MIPS3
+#undef _MIPS_ISA_MIPS4
+#undef _MIPS_ISA_MIPS5
+#undef _MIPS_ISA_MIPS32
+#undef _MIPS_ISA_MIPS64
+
+#undef _MIPS_SIM_ABI32
+#undef _MIPS_SIM_NABI32
+#undef _MIPS_SIM_ABI64
+
+/*
+ * Definitions for the ISA level
+ */
+#define _MIPS_ISA_MIPS1 1
+#define _MIPS_ISA_MIPS2 2
+#define _MIPS_ISA_MIPS3 3
+#define _MIPS_ISA_MIPS4 4
+#define _MIPS_ISA_MIPS5 5
+#define _MIPS_ISA_MIPS32 6
+#define _MIPS_ISA_MIPS64 7
+
+/*
+ * Subprogram calling convention
+ */
+#ifndef _ABIO32
+# define _ABIO32		1
+#endif
+#define _MIPS_SIM_ABI32		_ABIO32
+
+#ifndef _ABIN32
+# define _ABIN32		2
+#endif
+#define _MIPS_SIM_NABI32	_ABIN32
+
+#ifndef _ABI64
+# define _ABI64			3
+#endif
+#define _MIPS_SIM_ABI64		_ABI64
+
+#endif /* sgidefs.h */
diff --git a/sysdeps/mips/soft-fp/Dist b/sysdeps/mips/soft-fp/Dist
new file mode 100644
index 0000000000..7e9914fe58
--- /dev/null
+++ b/sysdeps/mips/soft-fp/Dist
@@ -0,0 +1 @@
+sfp-machine.h
diff --git a/sysdeps/mips/soft-fp/sfp-machine.h b/sysdeps/mips/soft-fp/sfp-machine.h
new file mode 100644
index 0000000000..3b2a40f0e2
--- /dev/null
+++ b/sysdeps/mips/soft-fp/sfp-machine.h
@@ -0,0 +1,47 @@
+#define _FP_W_TYPE_SIZE		32
+#define _FP_W_TYPE		unsigned long
+#define _FP_WS_TYPE		signed long
+#define _FP_I_TYPE		long
+
+#define _FP_MUL_MEAT_S(R,X,Y)				\
+  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_D(R,X,Y)				\
+  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_Q(R,X,Y)				\
+  _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_S(R,X,Y)	_FP_DIV_MEAT_1_udiv_norm(S,R,X,Y)
+#define _FP_DIV_MEAT_D(R,X,Y)	_FP_DIV_MEAT_2_udiv(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y)	_FP_DIV_MEAT_4_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S		((_FP_QNANBIT_S << 1) - 1)
+#define _FP_NANFRAC_D		((_FP_QNANBIT_D << 1) - 1), -1
+#define _FP_NANFRAC_Q		((_FP_QNANBIT_Q << 1) - 1), -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/stackinfo.h b/sysdeps/mips/stackinfo.h
new file mode 100644
index 0000000000..86e3d621ba
--- /dev/null
+++ b/sysdeps/mips/stackinfo.h
@@ -0,0 +1,28 @@
+/* Copyright (C) 2000 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 file contains a bit of information about the stack allocation
+   of the processor.  */
+
+#ifndef _STACKINFO_H
+#define _STACKINFO_H	1
+
+/* On MIPS the stack grows down.  */
+#define _STACK_GROWS_DOWN	1
+
+#endif	/* stackinfo.h */
diff --git a/sysdeps/mips/sub_n.S b/sysdeps/mips/sub_n.S
new file mode 100644
index 0000000000..53fa019343
--- /dev/null
+++ b/sysdeps/mips/sub_n.S
@@ -0,0 +1,122 @@
+/* MIPS2 __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>
+
+/* INPUT PARAMETERS
+   res_ptr	$4
+   s1_ptr	$5
+   s2_ptr	$6
+   size		$7
+*/
+#ifdef __PIC__
+	.option pic2
+#endif
+ENTRY (__mpn_sub_n)
+	.set	noreorder
+#ifdef __PIC__
+	.cpload t9
+#endif
+	.set	nomacro
+
+	lw	$10,0($5)
+	lw	$11,0($6)
+
+	addiu	$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
+
+	subu	$7,$7,$9
+
+L(Loop0):	addiu	$9,$9,-1
+	lw	$12,4($5)
+	addu	$11,$11,$2
+	lw	$13,4($6)
+	sltu	$8,$11,$2
+	subu	$11,$10,$11
+	sltu	$2,$10,$11
+	sw	$11,0($4)
+	or	$2,$2,$8
+
+	addiu	$5,$5,4
+	addiu	$6,$6,4
+	move	$10,$12
+	move	$11,$13
+	bne	$9,$0,L(Loop0)
+	addiu	$4,$4,4
+
+L(L0):	beq	$7,$0,L(Lend)
+	nop
+
+L(Loop):	addiu	$7,$7,-4
+
+	lw	$12,4($5)
+	addu	$11,$11,$2
+	lw	$13,4($6)
+	sltu	$8,$11,$2
+	subu	$11,$10,$11
+	sltu	$2,$10,$11
+	sw	$11,0($4)
+	or	$2,$2,$8
+
+	lw	$10,8($5)
+	addu	$13,$13,$2
+	lw	$11,8($6)
+	sltu	$8,$13,$2
+	subu	$13,$12,$13
+	sltu	$2,$12,$13
+	sw	$13,4($4)
+	or	$2,$2,$8
+
+	lw	$12,12($5)
+	addu	$11,$11,$2
+	lw	$13,12($6)
+	sltu	$8,$11,$2
+	subu	$11,$10,$11
+	sltu	$2,$10,$11
+	sw	$11,8($4)
+	or	$2,$2,$8
+
+	lw	$10,16($5)
+	addu	$13,$13,$2
+	lw	$11,16($6)
+	sltu	$8,$13,$2
+	subu	$13,$12,$13
+	sltu	$2,$12,$13
+	sw	$13,12($4)
+	or	$2,$2,$8
+
+	addiu	$5,$5,16
+	addiu	$6,$6,16
+
+	bne	$7,$0,L(Loop)
+	addiu	$4,$4,16
+
+L(Lend):	addu	$11,$11,$2
+	sltu	$8,$11,$2
+	subu	$11,$10,$11
+	sltu	$2,$10,$11
+	sw	$11,0($4)
+	j	$31
+	or	$2,$2,$8
+	END (__mpn_sub_n)
diff --git a/sysdeps/mips/submul_1.S b/sysdeps/mips/submul_1.S
new file mode 100644
index 0000000000..4c8a612650
--- /dev/null
+++ b/sysdeps/mips/submul_1.S
@@ -0,0 +1,99 @@
+/* MIPS __mpn_submul_1 -- Multiply a limb vector with a single limb and
+subtract the product from a second 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>
+
+/* INPUT PARAMETERS
+   res_ptr	$4
+   s1_ptr	$5
+   size		$6
+   s2_limb	$7
+*/
+#ifdef __PIC__
+	.option pic2
+#endif
+ENTRY (__mpn_submul_1)
+	.set    noreorder
+#ifdef __PIC__
+	.cpload t9
+#endif
+	.set    nomacro
+
+	/* warm up phase 0 */
+	lw	$8,0($5)
+
+	/* warm up phase 1 */
+	addiu	$5,$5,4
+	multu	$8,$7
+
+	addiu	$6,$6,-1
+	beq	$6,$0,L(LC0)
+	move	$2,$0		/* zero cy2 */
+
+	addiu	$6,$6,-1
+	beq	$6,$0,L(LC1)
+	lw	$8,0($5)	/* load new s1 limb as early as possible */
+
+L(Loop):	lw	$10,0($4)
+	mflo	$3
+	mfhi	$9
+	addiu	$5,$5,4
+	addu	$3,$3,$2	/* add old carry limb to low product limb */
+	multu	$8,$7
+	lw	$8,0($5)	/* load new s1 limb as early as possible */
+	addiu	$6,$6,-1	/* decrement loop counter */
+	sltu	$2,$3,$2	/* carry from previous addition -> $2 */
+	subu	$3,$10,$3
+	sgtu	$10,$3,$10
+	addu	$2,$2,$10
+	sw	$3,0($4)
+	addiu	$4,$4,4
+	bne	$6,$0,L(Loop)	/* should be "bnel" */
+	addu	$2,$9,$2	/* add high product limb and carry from addition */
+
+	/* cool down phase 1 */
+L(LC1):	lw	$10,0($4)
+	mflo	$3
+	mfhi	$9
+	addu	$3,$3,$2
+	sltu	$2,$3,$2
+	multu	$8,$7
+	subu	$3,$10,$3
+	sgtu	$10,$3,$10
+	addu	$2,$2,$10
+	sw	$3,0($4)
+	addiu	$4,$4,4
+	addu	$2,$9,$2	/* add high product limb and carry from addition */
+
+	/* cool down phase 0 */
+L(LC0):	lw	$10,0($4)
+	mflo	$3
+	mfhi	$9
+	addu	$3,$3,$2
+	sltu	$2,$3,$2
+	subu	$3,$10,$3
+	sgtu	$10,$3,$10
+	addu	$2,$2,$10
+	sw	$3,0($4)
+	j	$31
+	addu	$2,$9,$2	/* add high product limb and carry from addition */
+	END (__mpn_submul_1)
diff --git a/sysdeps/mips/sys/asm.h b/sysdeps/mips/sys/asm.h
new file mode 100644
index 0000000000..b04c36ba5e
--- /dev/null
+++ b/sysdeps/mips/sys/asm.h
@@ -0,0 +1,473 @@
+/* Copyright (C) 1997, 1998, 2002, 2003, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ralf Baechle <ralf@gnu.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.  */
+
+#ifndef _SYS_ASM_H
+#define _SYS_ASM_H
+
+#include <sgidefs.h>
+
+#ifndef CAT
+# ifdef __STDC__
+#  define __CAT(str1,str2) str1##str2
+# else
+#  define __CAT(str1,str2) str1/**/str2
+# endif
+# define CAT(str1,str2) __CAT(str1,str2)
+#endif
+
+/*
+ * Macros to handle different pointer/register sizes for 32/64-bit code
+ *
+ * 64 bit address space isn't used yet, so we may use the R3000 32 bit
+ * defines for now.
+ */
+#if _MIPS_SIM == _ABIO32 || _MIPS_SIM == _ABIN32
+# define PTR .word
+# define PTRSIZE 4
+# define PTRLOG 2
+#elif _MIPS_SIM == _ABI64
+# define PTR .dword
+# define PTRSIZE 8
+# define PTRLOG 3
+#endif
+
+/*
+ * PIC specific declarations
+ */
+#if _MIPS_SIM == _ABIO32
+# ifdef __PIC__
+#  define CPRESTORE(register) \
+		.cprestore register
+#  define CPLOAD(register) \
+		.cpload register
+# else
+#  define CPRESTORE(register)
+#  define CPLOAD(register)
+# endif
+
+# define CPADD(register) \
+		.cpadd	register
+
+/*
+ * Set gp when at 1st instruction
+ */
+# define SETUP_GP					\
+		.set noreorder;				\
+		.cpload $25;				\
+		.set reorder
+/* Set gp when not at 1st instruction */
+# define SETUP_GPX(r)					\
+		.set noreorder;				\
+		move r, $31;	 /* Save old ra.  */	\
+		bal 10f; /* Find addr of cpload.  */	\
+		nop;					\
+10:							\
+		.cpload $31;				\
+		move $31, r;				\
+		.set reorder
+# define SETUP_GPX_L(r, l)				\
+		.set noreorder;				\
+		move r, $31;	 /* Save old ra.  */	\
+		bal l;   /* Find addr of cpload.  */	\
+		nop;					\
+l:							\
+		.cpload $31;				\
+		move $31, r;				\
+		.set reorder
+# define SAVE_GP(x) \
+		.cprestore x /* Save gp trigger t9/jalr conversion.	 */
+# define SETUP_GP64(a, b)
+# define SETUP_GPX64(a, b)
+# define SETUP_GPX64_L(cp_reg, ra_save, l)
+# define RESTORE_GP64
+# define USE_ALT_CP(a)
+#else /* _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32 */
+/*
+ * For callee-saved gp calling convention:
+ */
+# define SETUP_GP
+# define SETUP_GPX(r)
+# define SETUP_GPX_L(r, l)
+# define SAVE_GP(x)
+
+# define SETUP_GP64(gpoffset, proc) \
+		.cpsetup $25, gpoffset, proc
+# define SETUP_GPX64(cp_reg, ra_save)			\
+		move ra_save, $31; /* Save old ra.  */	\
+		.set noreorder;				\
+		bal 10f; /* Find addr of .cpsetup.  */	\
+		nop;					\
+10:							\
+		.set reorder;				\
+		.cpsetup $31, cp_reg, 10b;		\
+		move $31, ra_save
+# define SETUP_GPX64_L(cp_reg, ra_save, l)  \
+		move ra_save, $31; /* Save old ra.  */	\
+		.set noreorder;				\
+		bal l;   /* Find addr of .cpsetup.  */	\
+		nop;					\
+l:							\
+		.set reorder;				\
+		.cpsetup $31, cp_reg, l;		\
+		move $31, ra_save
+# define RESTORE_GP64 \
+		.cpreturn
+/* Use alternate register for context pointer.  */
+# define USE_ALT_CP(reg)	\
+		.cplocal reg
+#endif /* _MIPS_SIM != _ABIO32 */
+
+/*
+ * Stack Frame Definitions
+ */
+#if _MIPS_SIM == _ABIO32
+# define NARGSAVE 4 /* Space for 4 argument registers must be allocated.  */
+#endif
+#if _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32
+# define NARGSAVE 0 /* No caller responsibilities.  */
+#endif
+
+
+/*
+ * LEAF - declare leaf routine
+ */
+#define	LEAF(symbol)                                    \
+		.globl	symbol;                         \
+		.align	2;                              \
+		.type	symbol,@function;               \
+		.ent	symbol,0;                       \
+symbol:		.frame	sp,0,ra
+
+/*
+ * NESTED - declare nested routine entry point
+ */
+#define	NESTED(symbol, framesize, rpc)                  \
+		.globl	symbol;                         \
+		.align	2;                              \
+		.type	symbol,@function;               \
+		.ent	symbol,0;                       \
+symbol:		.frame	sp, framesize, rpc
+
+/*
+ * END - mark end of function
+ */
+#ifndef END
+# define END(function)                                   \
+		.end	function;		        \
+		.size	function,.-function
+#endif
+
+/*
+ * EXPORT - export definition of symbol
+ */
+#define	EXPORT(symbol)                                  \
+		.globl	symbol;                         \
+symbol:
+
+/*
+ * ABS - export absolute symbol
+ */
+#define	ABS(symbol,value)                               \
+		.globl	symbol;                         \
+symbol		=	value
+
+#define	PANIC(msg)                                      \
+		.set	push;				\
+		.set	reorder;                        \
+		la	a0,8f;                          \
+		jal	panic;                          \
+9:		b	9b;                             \
+		.set	pop;				\
+		TEXT(msg)
+
+/*
+ * Print formated string
+ */
+#define PRINT(string)                                   \
+		.set	push;				\
+		.set	reorder;                        \
+		la	a0,8f;                          \
+		jal	printk;                         \
+		.set	pop;				\
+		TEXT(string)
+
+#define	TEXT(msg)                                       \
+		.data;                                  \
+8:		.asciiz	msg;                            \
+		.previous;
+
+/*
+ * Build text tables
+ */
+#define TTABLE(string)                                  \
+		.text;                                  \
+		.word	1f;                             \
+		.previous;                              \
+		.data;                                  \
+1:		.asciz	string;                         \
+		.previous
+
+/*
+ * MIPS IV pref instruction.
+ * Use with .set noreorder only!
+ *
+ * MIPS IV implementations are free to treat this as a nop.  The R5000
+ * is one of them.  So we should have an option not to use this instruction.
+ */
+#if (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \
+    (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
+# define PREF(hint,addr)                                 \
+		pref	hint,addr
+# define PREFX(hint,addr)                                \
+		prefx	hint,addr
+#else
+# define PREF
+# define PREFX
+#endif
+
+/*
+ * MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs.
+ */
+#if _MIPS_ISA == _MIPS_ISA_MIPS1
+# define MOVN(rd,rs,rt)					\
+		.set	push;				\
+		.set	reorder;			\
+		beqz	rt,9f;				\
+		move	rd,rs;				\
+		.set	pop;				\
+9:
+# define MOVZ(rd,rs,rt)					\
+		.set	push;				\
+		.set	reorder;			\
+		bnez	rt,9f;				\
+		move	rd,rt;				\
+		.set	pop;				\
+9:
+#endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */
+#if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3)
+# define MOVN(rd,rs,rt)					\
+		.set	push;				\
+		.set	noreorder;			\
+		bnezl	rt,9f;				\
+		move	rd,rs;				\
+		.set	pop;				\
+9:
+# define MOVZ(rd,rs,rt)					\
+		.set	push;				\
+		.set	noreorder;			\
+		beqzl	rt,9f;				\
+		movz	rd,rs;				\
+		.set	pop;				\
+9:
+#endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */
+#if (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \
+    (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
+# define MOVN(rd,rs,rt)					\
+		movn	rd,rs,rt
+# define MOVZ(rd,rs,rt)					\
+		movz	rd,rs,rt
+#endif /* (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) */
+
+/*
+ * Stack alignment
+ */
+#if _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32
+# define ALSZ	15
+# define ALMASK	~15
+#else
+# define ALSZ	7
+# define ALMASK	~7
+#endif
+
+/*
+ * Size of a register
+ */
+#if _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32
+# define SZREG	8
+#else
+# define SZREG	4
+#endif
+
+/*
+ * Use the following macros in assemblercode to load/store registers,
+ * pointers etc.
+ */
+#if (SZREG == 4)
+# define REG_S sw
+# define REG_L lw
+#else
+# define REG_S sd
+# define REG_L ld
+#endif
+
+/*
+ * How to add/sub/load/store/shift C int variables.
+ */
+#if (_MIPS_SZINT == 32)
+# define INT_ADD	add
+# define INT_ADDI	addi
+# define INT_ADDU	addu
+# define INT_ADDIU	addiu
+# define INT_SUB	add
+# define INT_SUBI	subi
+# define INT_SUBU	subu
+# define INT_SUBIU	subu
+# define INT_L		lw
+# define INT_S		sw
+#endif
+
+#if (_MIPS_SZINT == 64)
+# define INT_ADD	dadd
+# define INT_ADDI	daddi
+# define INT_ADDU	daddu
+# define INT_ADDIU	daddiu
+# define INT_SUB	dadd
+# define INT_SUBI	dsubi
+# define INT_SUBU	dsubu
+# define INT_SUBIU	dsubu
+# define INT_L		ld
+# define INT_S		sd
+#endif
+
+/*
+ * How to add/sub/load/store/shift C long variables.
+ */
+#if (_MIPS_SZLONG == 32)
+# define LONG_ADD	add
+# define LONG_ADDI	addi
+# define LONG_ADDU	addu
+# define LONG_ADDIU	addiu
+# define LONG_SUB	add
+# define LONG_SUBI	subi
+# define LONG_SUBU	subu
+# define LONG_SUBIU	subu
+# define LONG_L		lw
+# define LONG_S		sw
+# define LONG_SLL	sll
+# define LONG_SLLV	sllv
+# define LONG_SRL	srl
+# define LONG_SRLV	srlv
+# define LONG_SRA	sra
+# define LONG_SRAV	srav
+#endif
+
+#if (_MIPS_SZLONG == 64)
+# define LONG_ADD	dadd
+# define LONG_ADDI	daddi
+# define LONG_ADDU	daddu
+# define LONG_ADDIU	daddiu
+# define LONG_SUB	dadd
+# define LONG_SUBI	dsubi
+# define LONG_SUBU	dsubu
+# define LONG_SUBIU	dsubu
+# define LONG_L		ld
+# define LONG_S		sd
+# define LONG_SLL	dsll
+# define LONG_SLLV	dsllv
+# define LONG_SRL	dsrl
+# define LONG_SRLV	dsrlv
+# define LONG_SRA	dsra
+# define LONG_SRAV	dsrav
+#endif
+
+/*
+ * How to add/sub/load/store/shift pointers.
+ */
+#if (_MIPS_SIM == _ABIO32 && _MIPS_SZPTR == 32)
+# define PTR_ADD	add
+# define PTR_ADDI	addi
+# define PTR_ADDU	addu
+# define PTR_ADDIU	addiu
+# define PTR_SUB	add
+# define PTR_SUBI	subi
+# define PTR_SUBU	subu
+# define PTR_SUBIU	subu
+# define PTR_L		lw
+# define PTR_LA		la
+# define PTR_S		sw
+# define PTR_SLL	sll
+# define PTR_SLLV	sllv
+# define PTR_SRL	srl
+# define PTR_SRLV	srlv
+# define PTR_SRA	sra
+# define PTR_SRAV	srav
+
+# define PTR_SCALESHIFT	2
+#endif
+
+#if _MIPS_SIM == _ABIN32
+# define PTR_ADD	add
+# define PTR_ADDI	addi
+# define PTR_ADDU	add /* no u */
+# define PTR_ADDIU	addi /* no u */
+# define PTR_SUB	add
+# define PTR_SUBI	subi
+# define PTR_SUBU	sub /* no u */
+# define PTR_SUBIU	sub /* no u */
+# define PTR_L		lw
+# define PTR_LA		la
+# define PTR_S		sw
+# define PTR_SLL	sll
+# define PTR_SLLV	sllv
+# define PTR_SRL	srl
+# define PTR_SRLV	srlv
+# define PTR_SRA	sra
+# define PTR_SRAV	srav
+
+# define PTR_SCALESHIFT	2
+#endif
+
+#if (_MIPS_SIM == _ABIO32 && _MIPS_SZPTR == 64 /* o64??? */) \
+    || _MIPS_SIM == _ABI64
+# define PTR_ADD	dadd
+# define PTR_ADDI	daddi
+# define PTR_ADDU	daddu
+# define PTR_ADDIU	daddiu
+# define PTR_SUB	dadd
+# define PTR_SUBI	dsubi
+# define PTR_SUBU	dsubu
+# define PTR_SUBIU	dsubu
+# define PTR_L		ld
+# define PTR_LA		dla
+# define PTR_S		sd
+# define PTR_SLL	dsll
+# define PTR_SLLV	dsllv
+# define PTR_SRL	dsrl
+# define PTR_SRLV	dsrlv
+# define PTR_SRA	dsra
+# define PTR_SRAV	dsrav
+
+# define PTR_SCALESHIFT	3
+#endif
+
+/*
+ * Some cp0 registers were extended to 64bit for MIPS III.
+ */
+#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) || \
+    (_MIPS_ISA == _MIPS_ISA_MIPS32)
+# define MFC0	mfc0
+# define MTC0	mtc0
+#endif
+#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \
+    (_MIPS_ISA == _MIPS_ISA_MIPS5) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
+# define MFC0	dmfc0
+# define MTC0	dmtc0
+#endif
+
+#endif /* sys/asm.h */
diff --git a/sysdeps/mips/sys/fpregdef.h b/sysdeps/mips/sys/fpregdef.h
new file mode 100644
index 0000000000..378115274f
--- /dev/null
+++ b/sysdeps/mips/sys/fpregdef.h
@@ -0,0 +1,61 @@
+/* Copyright (C) 1991, 92, 94, 95, 96, 97, 98 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.  */
+
+#ifndef _SYS_FPREGDEF_H
+#define _SYS_FPREGDEF_H
+
+/*
+ * These definitions only cover the R3000-ish 16/32 register model.
+ * But we're trying to be R3000 friendly anyway ...
+ */
+#define fv0	$f0      /* return value */
+#define fv0f	$f1
+#define fv1	$f2
+#define fv1f	$f3
+#define fa0	$f12     /* argument registers */
+#define fa0f	$f13
+#define fa1	$f14
+#define fa1f	$f15
+#define ft0	$f4      /* caller saved */
+#define ft0f	$f5
+#define ft1	$f6
+#define ft1f	$f7
+#define ft2	$f8
+#define ft2f	$f9
+#define ft3	$f10
+#define ft3f	$f11
+#define ft4	$f16
+#define ft4f	$f17
+#define ft5	$f18
+#define ft5f	$f19
+#define fs0	$f20     /* callee saved */
+#define fs0f	$f21
+#define fs1	$f22
+#define fs1f	$f23
+#define fs2	$f24
+#define fs2f	$f25
+#define fs3	$f26
+#define fs3f	$f27
+#define fs4	$f28
+#define fs4f	$f29
+#define fs5	$f30
+#define fs5f	$f31
+
+#define fcr31	$31      /* FPU status register */
+
+#endif /* sys/fpregdef.h */
diff --git a/sysdeps/mips/sys/regdef.h b/sysdeps/mips/sys/regdef.h
new file mode 100644
index 0000000000..8fb898a2d0
--- /dev/null
+++ b/sysdeps/mips/sys/regdef.h
@@ -0,0 +1,82 @@
+/* Copyright (C) 1997, 1998, 2002, 2003, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ralf Baechle <ralf@gnu.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.  */
+
+#ifndef _SYS_REGDEF_H
+#define _SYS_REGDEF_H
+
+#include <sgidefs.h>
+
+/*
+ * Symbolic register names for 32 bit ABI
+ */
+#define zero    $0      /* wired zero */
+#define AT      $1      /* assembler temp  - uppercase because of ".set at" */
+#define v0      $2      /* return value */
+#define v1      $3
+#define a0      $4      /* argument registers */
+#define a1      $5
+#define a2      $6
+#define a3      $7
+#if _MIPS_SIM != _ABIO32
+#define a4      $8
+#define a5      $9
+#define a6      $10
+#define a7      $11
+#define t0      $12
+#define t1      $13
+#define t2      $14
+#define t3      $15
+#define ta0     a4
+#define ta1     a5
+#define ta2     a6
+#define ta3     a7
+#else /* if _MIPS_SIM == _ABIO32 */
+#define t0      $8      /* caller saved */
+#define t1      $9
+#define t2      $10
+#define t3      $11
+#define t4      $12
+#define t5      $13
+#define t6      $14
+#define t7      $15
+#define ta0     t4
+#define ta1     t5
+#define ta2     t6
+#define ta3     t7
+#endif /* _MIPS_SIM == _ABIO32 */
+#define s0      $16     /* callee saved */
+#define s1      $17
+#define s2      $18
+#define s3      $19
+#define s4      $20
+#define s5      $21
+#define s6      $22
+#define s7      $23
+#define t8      $24     /* caller saved */
+#define t9      $25
+#define jp      $25     /* PIC jump register */
+#define k0      $26     /* kernel scratch */
+#define k1      $27
+#define gp      $28     /* global pointer */
+#define sp      $29     /* stack pointer */
+#define fp      $30     /* frame pointer */
+#define s8	$30	/* same like fp! */
+#define ra      $31     /* return address */
+
+#endif /* _SYS_REGDEF_H */
diff --git a/sysdeps/mips/sys/ucontext.h b/sysdeps/mips/sys/ucontext.h
new file mode 100644
index 0000000000..fe378e94cd
--- /dev/null
+++ b/sysdeps/mips/sys/ucontext.h
@@ -0,0 +1,159 @@
+/* Copyright (C) 1998, 1999, 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.  */
+
+/* System V/mips ABI compliant context switching support.  */
+
+#ifndef _SYS_UCONTEXT_H
+#define _SYS_UCONTEXT_H	1
+
+#include <features.h>
+#include <sgidefs.h>
+#include <signal.h>
+
+/* Type for general register.  */
+#if _MIPS_SIM == _ABIO32
+typedef __uint32_t greg_t;
+#else
+typedef __uint64_t greg_t;
+#endif
+
+/* Number of general registers.  */
+#define NGREG	36
+
+/* Container for all general registers.  */
+typedef greg_t gregset_t[NGREG];
+
+/* Number of each register is the `gregset_t' array.  */
+enum
+{
+  CTX_R0 = 0,
+#define CTX_R0	CTX_R0
+  CTX_AT = 1,
+#define CTX_AT	CTX_AT
+  CTX_V0 = 2,
+#define CTX_V0	CTX_V0
+  CTX_V1 = 3,
+#define CTX_V1	CTX_V1
+  CTX_A0 = 4,
+#define CTX_A0	CTX_A0
+  CTX_A1 = 5,
+#define CTX_A1	CTX_A1
+  CTX_A2 = 6,
+#define CTX_A2	CTX_A2
+  CTX_A3 = 7,
+#define CTX_A3	CTX_A3
+  CTX_T0 = 8,
+#define CTX_T0	CTX_T0
+  CTX_T1 = 9,
+#define CTX_T1	CTX_T1
+  CTX_T2 = 10,
+#define CTX_T2	CTX_T2
+  CTX_T3 = 11,
+#define CTX_T3	CTX_T3
+  CTX_T4 = 12,
+#define CTX_T4	CTX_T4
+  CTX_T5 = 13,
+#define CTX_T5	CTX_T5
+  CTX_T6 = 14,
+#define CTX_T6	CTX_T6
+  CTX_T7 = 15,
+#define CTX_T7	CTX_T7
+  CTX_S0 = 16,
+#define CTX_S0	CTX_S0
+  CTX_S1 = 17,
+#define CTX_S1	CTX_S1
+  CTX_S2 = 18,
+#define CTX_S2	CTX_S2
+  CTX_S3 = 19,
+#define CTX_S3	CTX_S3
+  CTX_S4 = 20,
+#define CTX_S4	CTX_S4
+  CTX_S5 = 21,
+#define CTX_S5	CTX_S5
+  CTX_S6 = 22,
+#define CTX_S6	CTX_S6
+  CTX_S7 = 23,
+#define CTX_S7	CTX_S7
+  CTX_T8 = 24,
+#define CTX_T8	CTX_T8
+  CTX_T9 = 25,
+#define CTX_T9	CTX_T9
+  CTX_K0 = 26,
+#define CTX_K0	CTX_K0
+  CTX_K1 = 27,
+#define CTX_K1	CTX_K1
+  CTX_GP = 28,
+#define CTX_GP	CTX_GP
+  CTX_SP = 29,
+#define CTX_SP	CTX_SP
+  CTX_S8 = 30,
+#define CTX_S8	CTX_S8
+  CTX_RA = 31,
+#define CTX_RA	CTX_RA
+  CTX_MDLO = 32,
+#define CTX_MDLO	CTX_MDLO
+  CTX_MDHI = 33,
+#define CTX_MDHI	CTX_MDHI
+  CTX_CAUSE = 34,
+#define CTX_CAUSE	CTX_CAUSE
+  CTX_EPC = 35,
+#define CTX_EPC	CTX_EPC
+};
+
+/* Structure to describe FPU registers.  */
+typedef struct fpregset
+{
+  union
+  {
+#if _MIPS_SIM == _ABIO32
+    double fp_dregs[16];
+    float fp_fregs[32];
+    unsigned int fp_regs[32];
+#else
+    double fp_dregs[32];
+    /* float fp_fregs[32]; */
+    __uint64_t fp_regs[32];
+#endif
+  } fp_r;
+  unsigned int fp_csr;
+  unsigned int fp_pad;
+} fpregset_t;
+
+/* Context to describe whole processor state.  */
+typedef struct
+{
+  gregset_t gpregs;
+  fpregset_t fpregs;
+} mcontext_t;
+
+/* Userlevel context.  */
+typedef struct ucontext
+{
+#if _MIPS_SIM == _ABIO32
+  unsigned long int uc_flags;
+#else
+  __uint64_t uc_flags;
+#endif
+  struct ucontext *uc_link;
+  __sigset_t uc_sigmask;
+  stack_t uc_stack;
+  mcontext_t uc_mcontext;
+  int uc_filler[48];
+} ucontext_t;
+
+#endif /* sys/ucontext.h */