about summary refs log tree commit diff
path: root/sysdeps/mips/bits
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2014-02-10 23:30:21 +0000
committerJoseph Myers <joseph@codesourcery.com>2014-02-10 23:30:21 +0000
commit2ad7600be76ada35c6e9f0baa75bc96252785268 (patch)
tree15f3bfba2d40ea05b02fdbf584aa9f403df2cdbc /sysdeps/mips/bits
parent384b7b4309cbbbe84481973b84ead98bb4fc54be (diff)
downloadglibc-2ad7600be76ada35c6e9f0baa75bc96252785268.tar.gz
glibc-2ad7600be76ada35c6e9f0baa75bc96252785268.tar.xz
glibc-2ad7600be76ada35c6e9f0baa75bc96252785268.zip
Move mips from ports to libc.
I've moved the MIPS port from ports to the main sysdeps hierarchy.
Beyond the README update, the move of the files was simply

git mv ports/sysdeps/mips sysdeps/mips
git mv ports/sysdeps/unix/mips sysdeps/unix/mips
git mv ports/sysdeps/unix/sysv/linux/mips sysdeps/unix/sysv/linux/mips

and in addition to the ChangeLog entries here, I put a note at the top
of ports/ChangeLog.mips similar to those in other files.

Tested that disassembly of installed shared libraries for mips is the
same before and after this patch (except for ld.so where paths in
assertions are involved, as for arm).

	* sysdeps/mips: Move directory from ports/sysdeps/mips.
	* sysdeps/unix/mips: Move directory from ports/sysdeps/unix/mips.
	* sysdeps/unix/sysv/linux/mips: Move directory from
	ports/sysdeps/unix/sysv/linux/mips.
	* README: Update listing for mips-*-linux-gnu and
	mips64-*-linux-gnu.

	* sysdeps/mips: Move directory to ../sysdeps/mips.
	* sysdeps/unix/mips: Move directory to ../sysdeps/unix/mips.
	* sysdeps/unix/sysv/linux/mips: Move directory to
	../sysdeps/unix/sysv/linux/mips.
Diffstat (limited to 'sysdeps/mips/bits')
-rw-r--r--sysdeps/mips/bits/atomic.h493
-rw-r--r--sysdeps/mips/bits/dlfcn.h64
-rw-r--r--sysdeps/mips/bits/endian.h13
-rw-r--r--sysdeps/mips/bits/fenv.h85
-rw-r--r--sysdeps/mips/bits/ipctypes.h31
-rw-r--r--sysdeps/mips/bits/link.h117
-rw-r--r--sysdeps/mips/bits/linkmap.h4
-rw-r--r--sysdeps/mips/bits/mathdef.h43
-rw-r--r--sysdeps/mips/bits/nan.h67
-rw-r--r--sysdeps/mips/bits/setjmp.h73
-rw-r--r--sysdeps/mips/bits/wordsize.h21
11 files changed, 1011 insertions, 0 deletions
diff --git a/sysdeps/mips/bits/atomic.h b/sysdeps/mips/bits/atomic.h
new file mode 100644
index 0000000000..35b3786789
--- /dev/null
+++ b/sysdeps/mips/bits/atomic.h
@@ -0,0 +1,493 @@
+/* Low-level functions for atomic operations. Mips version.
+   Copyright (C) 2005-2014 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _MIPS_BITS_ATOMIC_H
+#define _MIPS_BITS_ATOMIC_H 1
+
+#include <stdint.h>
+#include <inttypes.h>
+#include <sgidefs.h>
+
+typedef int32_t atomic32_t;
+typedef uint32_t uatomic32_t;
+typedef int_fast32_t atomic_fast32_t;
+typedef uint_fast32_t uatomic_fast32_t;
+
+typedef int64_t atomic64_t;
+typedef uint64_t uatomic64_t;
+typedef int_fast64_t atomic_fast64_t;
+typedef uint_fast64_t uatomic_fast64_t;
+
+typedef intptr_t atomicptr_t;
+typedef uintptr_t uatomicptr_t;
+typedef intmax_t atomic_max_t;
+typedef uintmax_t uatomic_max_t;
+
+#if _MIPS_SIM == _ABIO32
+#define MIPS_PUSH_MIPS2 ".set	mips2\n\t"
+#else
+#define MIPS_PUSH_MIPS2
+#endif
+
+/* See the comments in <sys/asm.h> about the use of the sync instruction.  */
+#ifndef MIPS_SYNC
+# define MIPS_SYNC	sync
+#endif
+
+/* Certain revisions of the R10000 Processor need an LL/SC Workaround
+   enabled.  Revisions before 3.0 misbehave on atomic operations, and
+   Revs 2.6 and lower deadlock after several seconds due to other errata.
+
+   To quote the R10K Errata:
+      Workaround: The basic idea is to inhibit the four instructions
+      from simultaneously becoming active in R10000. Padding all
+      ll/sc sequences with nops or changing the looping branch in the
+      routines to a branch likely (which is always predicted taken
+      by R10000) will work. The nops should go after the loop, and the
+      number of them should be 28. This number could be decremented for
+      each additional instruction in the ll/sc loop such as the lock
+      modifier(s) between the ll and sc, the looping branch and its
+      delay slot. For typical short routines with one ll/sc loop, any
+      instructions after the loop could also count as a decrement. The
+      nop workaround pollutes the cache more but would be a few cycles
+      faster if all the code is in the cache and the looping branch
+      is predicted not taken.  */
+
+
+#ifdef _MIPS_ARCH_R10000
+#define R10K_BEQZ_INSN "beqzl"
+#else
+#define R10K_BEQZ_INSN "beqz"
+#endif
+
+#define MIPS_SYNC_STR_2(X) #X
+#define MIPS_SYNC_STR_1(X) MIPS_SYNC_STR_2(X)
+#define MIPS_SYNC_STR MIPS_SYNC_STR_1(MIPS_SYNC)
+
+#if __GNUC_PREREQ (4, 8) || (defined __mips16 && __GNUC_PREREQ (4, 7))
+/* The __atomic_* builtins are available in GCC 4.7 and later, but MIPS
+   support for their efficient implementation was added only in GCC 4.8.
+   We still want to use them even with GCC 4.7 for MIPS16 code where we
+   have no assembly alternative available and want to avoid the __sync_*
+   builtins if at all possible.  */
+
+/* Compare and exchange.
+   For all "bool" routines, we return FALSE if exchange succesful.  */
+
+# define __arch_compare_and_exchange_bool_8_int(mem, newval, oldval, model) \
+  (abort (), 0)
+
+# define __arch_compare_and_exchange_bool_16_int(mem, newval, oldval, model) \
+  (abort (), 0)
+
+# define __arch_compare_and_exchange_bool_32_int(mem, newval, oldval, model) \
+  ({									\
+    typeof (*mem) __oldval = (oldval);					\
+    !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0,	\
+				  model, __ATOMIC_RELAXED);		\
+  })
+
+# define __arch_compare_and_exchange_val_8_int(mem, newval, oldval, model) \
+  (abort (), (typeof(*mem)) 0)
+
+# define __arch_compare_and_exchange_val_16_int(mem, newval, oldval, model) \
+  (abort (), (typeof(*mem)) 0)
+
+# define __arch_compare_and_exchange_val_32_int(mem, newval, oldval, model) \
+  ({									\
+    typeof (*mem) __oldval = (oldval);					\
+    __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0,	\
+				 model, __ATOMIC_RELAXED);		\
+    __oldval;								\
+  })
+
+# if _MIPS_SIM == _ABIO32
+  /* We can't do an atomic 64-bit operation in O32.  */
+#  define __arch_compare_and_exchange_bool_64_int(mem, newval, oldval, model) \
+  (abort (), 0)
+#  define __arch_compare_and_exchange_val_64_int(mem, newval, oldval, model) \
+  (abort (), (typeof(*mem)) 0)
+# else
+#  define __arch_compare_and_exchange_bool_64_int(mem, newval, oldval, model) \
+  __arch_compare_and_exchange_bool_32_int (mem, newval, oldval, model)
+#  define __arch_compare_and_exchange_val_64_int(mem, newval, oldval, model) \
+  __arch_compare_and_exchange_val_32_int (mem, newval, oldval, model)
+# endif
+
+/* Compare and exchange with "acquire" semantics, ie barrier after.  */
+
+# define atomic_compare_and_exchange_bool_acq(mem, new, old)	\
+  __atomic_bool_bysize (__arch_compare_and_exchange_bool, int,	\
+			mem, new, old, __ATOMIC_ACQUIRE)
+
+# define atomic_compare_and_exchange_val_acq(mem, new, old)	\
+  __atomic_val_bysize (__arch_compare_and_exchange_val, int,	\
+		       mem, new, old, __ATOMIC_ACQUIRE)
+
+/* Compare and exchange with "release" semantics, ie barrier before.  */
+
+# define atomic_compare_and_exchange_bool_rel(mem, new, old)	\
+  __atomic_bool_bysize (__arch_compare_and_exchange_bool, int,	\
+			mem, new, old, __ATOMIC_RELEASE)
+
+# define atomic_compare_and_exchange_val_rel(mem, new, old)	 \
+  __atomic_val_bysize (__arch_compare_and_exchange_val, int,    \
+                       mem, new, old, __ATOMIC_RELEASE)
+
+
+/* Atomic exchange (without compare).  */
+
+# define __arch_exchange_8_int(mem, newval, model)	\
+  (abort (), (typeof(*mem)) 0)
+
+# define __arch_exchange_16_int(mem, newval, model)	\
+  (abort (), (typeof(*mem)) 0)
+
+# define __arch_exchange_32_int(mem, newval, model)	\
+  __atomic_exchange_n (mem, newval, model)
+
+# if _MIPS_SIM == _ABIO32
+/* We can't do an atomic 64-bit operation in O32.  */
+#  define __arch_exchange_64_int(mem, newval, model)	\
+  (abort (), (typeof(*mem)) 0)
+# else
+#  define __arch_exchange_64_int(mem, newval, model)	\
+  __atomic_exchange_n (mem, newval, model)
+# endif
+
+# define atomic_exchange_acq(mem, value)				\
+  __atomic_val_bysize (__arch_exchange, int, mem, value, __ATOMIC_ACQUIRE)
+
+# define atomic_exchange_rel(mem, value)				\
+  __atomic_val_bysize (__arch_exchange, int, mem, value, __ATOMIC_RELEASE)
+
+
+/* Atomically add value and return the previous (unincremented) value.  */
+
+# define __arch_exchange_and_add_8_int(mem, value, model)	\
+  (abort (), (typeof(*mem)) 0)
+
+# define __arch_exchange_and_add_16_int(mem, value, model)	\
+  (abort (), (typeof(*mem)) 0)
+
+# define __arch_exchange_and_add_32_int(mem, value, model)	\
+  __atomic_fetch_add (mem, value, model)
+
+# if _MIPS_SIM == _ABIO32
+/* We can't do an atomic 64-bit operation in O32.  */
+#  define __arch_exchange_and_add_64_int(mem, value, model)	\
+  (abort (), (typeof(*mem)) 0)
+# else
+#  define __arch_exchange_and_add_64_int(mem, value, model)	\
+  __atomic_fetch_add (mem, value, model)
+# endif
+
+# define atomic_exchange_and_add_acq(mem, value)			\
+  __atomic_val_bysize (__arch_exchange_and_add, int, mem, value,	\
+		       __ATOMIC_ACQUIRE)
+
+# define atomic_exchange_and_add_rel(mem, value)			\
+  __atomic_val_bysize (__arch_exchange_and_add, int, mem, value,	\
+		       __ATOMIC_RELEASE)
+
+#elif defined __mips16 /* !__GNUC_PREREQ (4, 7) */
+/* This implementation using __sync* builtins will be removed once glibc
+   requires GCC 4.7 or later to build.  */
+
+# define atomic_compare_and_exchange_val_acq(mem, newval, oldval)	\
+  __sync_val_compare_and_swap ((mem), (oldval), (newval))
+# define atomic_compare_and_exchange_bool_acq(mem, newval, oldval)	\
+  (!__sync_bool_compare_and_swap ((mem), (oldval), (newval)))
+
+# define atomic_exchange_acq(mem, newval)				\
+  __sync_lock_test_and_set ((mem), (newval))
+
+# define atomic_exchange_and_add(mem, val)				\
+  __sync_fetch_and_add ((mem), (val))
+
+# define atomic_bit_test_set(mem, bit)					\
+  ({ __typeof (bit) __bit = (bit);					\
+     (__sync_fetch_and_or ((mem), 1 << (__bit)) & (1 << (__bit))); })
+
+# define atomic_and(mem, mask) (void) __sync_fetch_and_and ((mem), (mask))
+# define atomic_and_val(mem, mask) __sync_fetch_and_and ((mem), (mask))
+
+# define atomic_or(mem, mask) (void) __sync_fetch_and_or ((mem), (mask))
+# define atomic_or_val(mem, mask) __sync_fetch_and_or ((mem), (mask))
+
+#else /* !__mips16 && !__GNUC_PREREQ (4, 8) */
+/* This implementation using inline assembly will be removed once glibc
+   requires GCC 4.8 or later to build.  */
+
+/* Compare and exchange.  For all of the "xxx" routines, we expect a
+   "__prev" and a "__cmp" variable to be provided by the enclosing scope,
+   in which values are returned.  */
+
+# define __arch_compare_and_exchange_xxx_8_int(mem, newval, oldval, rel, acq) \
+  (abort (), __prev = 0, __cmp = 0, (void) __cmp)
+
+# define __arch_compare_and_exchange_xxx_16_int(mem, newval, oldval, rel, acq) \
+  (abort (), __prev = 0, __cmp = 0, (void) __cmp)
+
+# define __arch_compare_and_exchange_xxx_32_int(mem, newval, oldval, rel, acq) \
+     __asm__ __volatile__ (						      \
+     ".set	push\n\t"						      \
+     MIPS_PUSH_MIPS2							      \
+     rel	"\n"							      \
+     "1:\t"								      \
+     "ll	%0,%5\n\t"						      \
+     "move	%1,$0\n\t"						      \
+     "bne	%0,%3,2f\n\t"						      \
+     "move	%1,%4\n\t"						      \
+     "sc	%1,%2\n\t"						      \
+     R10K_BEQZ_INSN"	%1,1b\n"					      \
+     acq	"\n\t"							      \
+     ".set	pop\n"							      \
+     "2:\n\t"								      \
+	      : "=&r" (__prev), "=&r" (__cmp), "=m" (*mem)		      \
+	      : "r" (oldval), "r" (newval), "m" (*mem)			      \
+	      : "memory")
+
+# if _MIPS_SIM == _ABIO32
+/* We can't do an atomic 64-bit operation in O32.  */
+# define __arch_compare_and_exchange_xxx_64_int(mem, newval, oldval, rel, acq) \
+  (abort (), __prev = 0, __cmp = 0, (void) __cmp)
+# else
+# define __arch_compare_and_exchange_xxx_64_int(mem, newval, oldval, rel, acq) \
+     __asm__ __volatile__ ("\n"						      \
+     ".set	push\n\t"						      \
+     MIPS_PUSH_MIPS2							      \
+     rel	"\n"							      \
+     "1:\t"								      \
+     "lld	%0,%5\n\t"						      \
+     "move	%1,$0\n\t"						      \
+     "bne	%0,%3,2f\n\t"						      \
+     "move	%1,%4\n\t"						      \
+     "scd	%1,%2\n\t"						      \
+     R10K_BEQZ_INSN"	%1,1b\n"					      \
+     acq	"\n\t"							      \
+     ".set	pop\n"							      \
+     "2:\n\t"								      \
+	      : "=&r" (__prev), "=&r" (__cmp), "=m" (*mem)		      \
+	      : "r" (oldval), "r" (newval), "m" (*mem)			      \
+	      : "memory")
+# endif
+
+/* For all "bool" routines, we return FALSE if exchange succesful.  */
+
+# define __arch_compare_and_exchange_bool_8_int(mem, new, old, rel, acq) \
+({ typeof (*mem) __prev __attribute__ ((unused)); int __cmp;		\
+   __arch_compare_and_exchange_xxx_8_int(mem, new, old, rel, acq);	\
+   !__cmp; })
+
+# define __arch_compare_and_exchange_bool_16_int(mem, new, old, rel, acq) \
+({ typeof (*mem) __prev __attribute__ ((unused)); int __cmp;		\
+   __arch_compare_and_exchange_xxx_16_int(mem, new, old, rel, acq);	\
+   !__cmp; })
+
+# define __arch_compare_and_exchange_bool_32_int(mem, new, old, rel, acq) \
+({ typeof (*mem) __prev __attribute__ ((unused)); int __cmp;		\
+   __arch_compare_and_exchange_xxx_32_int(mem, new, old, rel, acq);	\
+   !__cmp; })
+
+# define __arch_compare_and_exchange_bool_64_int(mem, new, old, rel, acq) \
+({ typeof (*mem) __prev __attribute__ ((unused)); int __cmp;		\
+   __arch_compare_and_exchange_xxx_64_int(mem, new, old, rel, acq);	\
+   !__cmp; })
+
+/* For all "val" routines, return the old value whether exchange
+   successful or not.  */
+
+# define __arch_compare_and_exchange_val_8_int(mem, new, old, rel, acq)	\
+({ typeof (*mem) __prev; int __cmp;					\
+   __arch_compare_and_exchange_xxx_8_int(mem, new, old, rel, acq);	\
+   (typeof (*mem))__prev; })
+
+# define __arch_compare_and_exchange_val_16_int(mem, new, old, rel, acq) \
+({ typeof (*mem) __prev; int __cmp;					\
+   __arch_compare_and_exchange_xxx_16_int(mem, new, old, rel, acq);	\
+   (typeof (*mem))__prev; })
+
+# define __arch_compare_and_exchange_val_32_int(mem, new, old, rel, acq) \
+({ typeof (*mem) __prev; int __cmp;					\
+   __arch_compare_and_exchange_xxx_32_int(mem, new, old, rel, acq);	\
+   (typeof (*mem))__prev; })
+
+# define __arch_compare_and_exchange_val_64_int(mem, new, old, rel, acq) \
+({ typeof (*mem) __prev; int __cmp;					\
+   __arch_compare_and_exchange_xxx_64_int(mem, new, old, rel, acq);	\
+   (typeof (*mem))__prev; })
+
+/* Compare and exchange with "acquire" semantics, ie barrier after.  */
+
+# define atomic_compare_and_exchange_bool_acq(mem, new, old)	\
+  __atomic_bool_bysize (__arch_compare_and_exchange_bool, int,	\
+		        mem, new, old, "", MIPS_SYNC_STR)
+
+# define atomic_compare_and_exchange_val_acq(mem, new, old)	\
+  __atomic_val_bysize (__arch_compare_and_exchange_val, int,	\
+		       mem, new, old, "", MIPS_SYNC_STR)
+
+/* Compare and exchange with "release" semantics, ie barrier before.  */
+
+# define atomic_compare_and_exchange_bool_rel(mem, new, old)	\
+  __atomic_bool_bysize (__arch_compare_and_exchange_bool, int,	\
+		        mem, new, old, MIPS_SYNC_STR, "")
+
+# define atomic_compare_and_exchange_val_rel(mem, new, old)	\
+  __atomic_val_bysize (__arch_compare_and_exchange_val, int,	\
+		       mem, new, old, MIPS_SYNC_STR, "")
+
+
+
+/* Atomic exchange (without compare).  */
+
+# define __arch_exchange_xxx_8_int(mem, newval, rel, acq) \
+  (abort (), (typeof(*mem)) 0)
+
+# define __arch_exchange_xxx_16_int(mem, newval, rel, acq) \
+  (abort (), (typeof(*mem)) 0)
+
+# define __arch_exchange_xxx_32_int(mem, newval, rel, acq) \
+({ typeof (*mem) __prev; int __cmp;					      \
+     __asm__ __volatile__ ("\n"						      \
+     ".set	push\n\t"						      \
+     MIPS_PUSH_MIPS2							      \
+     rel	"\n"							      \
+     "1:\t"								      \
+     "ll	%0,%4\n\t"						      \
+     "move	%1,%3\n\t"						      \
+     "sc	%1,%2\n\t"						      \
+     R10K_BEQZ_INSN"	%1,1b\n"					      \
+     acq	"\n\t"							      \
+     ".set	pop\n"							      \
+     "2:\n\t"								      \
+	      : "=&r" (__prev), "=&r" (__cmp), "=m" (*mem)		      \
+	      : "r" (newval), "m" (*mem)				      \
+	      : "memory");						      \
+  __prev; })
+
+# if _MIPS_SIM == _ABIO32
+/* We can't do an atomic 64-bit operation in O32.  */
+#  define __arch_exchange_xxx_64_int(mem, newval, rel, acq) \
+  (abort (), (typeof(*mem)) 0)
+# else
+#  define __arch_exchange_xxx_64_int(mem, newval, rel, acq) \
+({ typeof (*mem) __prev; int __cmp;					      \
+     __asm__ __volatile__ ("\n"						      \
+     ".set	push\n\t"						      \
+     MIPS_PUSH_MIPS2							      \
+     rel	"\n"							      \
+     "1:\n"								      \
+     "lld	%0,%4\n\t"						      \
+     "move	%1,%3\n\t"						      \
+     "scd	%1,%2\n\t"						      \
+     R10K_BEQZ_INSN"	%1,1b\n"					      \
+     acq	"\n\t"							      \
+     ".set	pop\n"							      \
+     "2:\n\t"								      \
+	      : "=&r" (__prev), "=&r" (__cmp), "=m" (*mem)		      \
+	      : "r" (newval), "m" (*mem)				      \
+	      : "memory");						      \
+  __prev; })
+# endif
+
+# define atomic_exchange_acq(mem, value) \
+  __atomic_val_bysize (__arch_exchange_xxx, int, mem, value, "", MIPS_SYNC_STR)
+
+# define atomic_exchange_rel(mem, value) \
+  __atomic_val_bysize (__arch_exchange_xxx, int, mem, value, MIPS_SYNC_STR, "")
+
+
+/* Atomically add value and return the previous (unincremented) value.  */
+
+# define __arch_exchange_and_add_8_int(mem, newval, rel, acq) \
+  (abort (), (typeof(*mem)) 0)
+
+# define __arch_exchange_and_add_16_int(mem, newval, rel, acq) \
+  (abort (), (typeof(*mem)) 0)
+
+# define __arch_exchange_and_add_32_int(mem, value, rel, acq) \
+({ typeof (*mem) __prev; int __cmp;					      \
+     __asm__ __volatile__ ("\n"						      \
+     ".set	push\n\t"						      \
+     MIPS_PUSH_MIPS2							      \
+     rel	"\n"							      \
+     "1:\t"								      \
+     "ll	%0,%4\n\t"						      \
+     "addu	%1,%0,%3\n\t"						      \
+     "sc	%1,%2\n\t"						      \
+     R10K_BEQZ_INSN"	%1,1b\n"					      \
+     acq	"\n\t"							      \
+     ".set	pop\n"							      \
+     "2:\n\t"								      \
+	      : "=&r" (__prev), "=&r" (__cmp), "=m" (*mem)		      \
+	      : "r" (value), "m" (*mem)					      \
+	      : "memory");						      \
+  __prev; })
+
+# if _MIPS_SIM == _ABIO32
+/* We can't do an atomic 64-bit operation in O32.  */
+#  define __arch_exchange_and_add_64_int(mem, value, rel, acq) \
+  (abort (), (typeof(*mem)) 0)
+# else
+#  define __arch_exchange_and_add_64_int(mem, value, rel, acq) \
+({ typeof (*mem) __prev; int __cmp;					      \
+     __asm__ __volatile__ (						      \
+     ".set	push\n\t"						      \
+     MIPS_PUSH_MIPS2							      \
+     rel	"\n"							      \
+     "1:\t"								      \
+     "lld	%0,%4\n\t"						      \
+     "daddu	%1,%0,%3\n\t"						      \
+     "scd	%1,%2\n\t"						      \
+     R10K_BEQZ_INSN"	%1,1b\n"					      \
+     acq	"\n\t"							      \
+     ".set	pop\n"							      \
+     "2:\n\t"								      \
+	      : "=&r" (__prev), "=&r" (__cmp), "=m" (*mem)		      \
+	      : "r" (value), "m" (*mem)					      \
+	      : "memory");						      \
+  __prev; })
+# endif
+
+# define atomic_exchange_and_add_acq(mem, value)			\
+  __atomic_val_bysize (__arch_exchange_and_add, int, mem, value,	\
+		       "", MIPS_SYNC_STR)
+
+# define atomic_exchange_and_add_rel(mem, value)			\
+  __atomic_val_bysize (__arch_exchange_and_add, int, mem, value,	\
+		       MIPS_SYNC_STR, "")
+
+#endif /* !__mips16 && !__GNUC_PREREQ (4, 8) */
+
+/* TODO: More atomic operations could be implemented efficiently; only the
+   basic requirements are done.  */
+
+#ifdef __mips16
+# define atomic_full_barrier() __sync_synchronize ()
+
+#else /* !__mips16 */
+# define atomic_full_barrier() \
+  __asm__ __volatile__ (".set push\n\t"					      \
+			MIPS_PUSH_MIPS2					      \
+			MIPS_SYNC_STR "\n\t"				      \
+			".set pop" : : : "memory")
+#endif /* !__mips16 */
+
+#endif /* bits/atomic.h */
diff --git a/sysdeps/mips/bits/dlfcn.h b/sysdeps/mips/bits/dlfcn.h
new file mode 100644
index 0000000000..405041dbc8
--- /dev/null
+++ b/sysdeps/mips/bits/dlfcn.h
@@ -0,0 +1,64 @@
+/* System dependent definitions for run-time dynamic loading.
+   Copyright (C) 1996-2014 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#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..fcc03682c2
--- /dev/null
+++ b/sysdeps/mips/bits/fenv.h
@@ -0,0 +1,85 @@
+/* Copyright (C) 1998-2014 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#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 =
+#define FE_INEXACT	0x04
+      FE_INEXACT,
+    FE_UNDERFLOW =
+#define FE_UNDERFLOW	0x08
+      FE_UNDERFLOW,
+    FE_OVERFLOW =
+#define FE_OVERFLOW	0x10
+      FE_OVERFLOW,
+    FE_DIVBYZERO =
+#define FE_DIVBYZERO	0x20
+      FE_DIVBYZERO,
+    FE_INVALID =
+#define FE_INVALID	0x40
+      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 =
+#define FE_TONEAREST	0x0
+      FE_TONEAREST,
+    FE_TOWARDZERO =
+#define FE_TOWARDZERO	0x1
+      FE_TOWARDZERO,
+    FE_UPWARD =
+#define FE_UPWARD	0x2
+      FE_UPWARD,
+    FE_DOWNWARD =
+#define FE_DOWNWARD	0x3
+      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..888e9282e8
--- /dev/null
+++ b/sysdeps/mips/bits/ipctypes.h
@@ -0,0 +1,31 @@
+/* bits/ipctypes.h -- Define some types used by SysV IPC/MSG/SHM.  MIPS version
+   Copyright (C) 2002-2014 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/*
+ * 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/link.h b/sysdeps/mips/bits/link.h
new file mode 100644
index 0000000000..4e99e8b673
--- /dev/null
+++ b/sysdeps/mips/bits/link.h
@@ -0,0 +1,117 @@
+/* Copyright (C) 2005-2014 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef	_LINK_H
+# error "Never include <bits/link.h> directly; use <link.h> instead."
+#endif
+
+#include <sgidefs.h>
+
+#if _MIPS_SIM == _ABIO32
+
+/* Registers for entry into PLT on MIPS.  */
+typedef struct La_mips_32_regs
+{
+  uint32_t lr_reg[4]; /* $a0 through $a3 */
+  double lr_fpreg[2]; /* $f12 and $f14 */
+  uint32_t lr_ra;
+  uint32_t lr_sp;
+} La_mips_32_regs;
+
+/* Return values for calls from PLT on MIPS.  */
+typedef struct La_mips_32_retval
+{
+  uint32_t lrv_v0;
+  uint32_t lrv_v1;
+  double lrv_f0;
+  double lrv_f2;
+} La_mips_32_retval;
+
+#else
+
+typedef struct La_mips_64_regs
+{
+  uint64_t lr_reg[8]; /* $a0 through $a7 */
+  double lr_fpreg[8]; /* $f12 throgh $f19 */
+  uint64_t lr_ra;
+  uint64_t lr_sp;
+} La_mips_64_regs;
+
+/* Return values for calls from PLT on MIPS.  */
+typedef struct La_mips_64_retval
+{
+  uint64_t lrv_v0;
+  uint64_t lrv_v1;
+  double lrv_f0;
+  double lrv_f2;
+} La_mips_64_retval;
+
+#endif
+
+__BEGIN_DECLS
+
+#if _MIPS_SIM == _ABIO32
+
+extern Elf32_Addr la_mips_o32_gnu_pltenter (Elf32_Sym *__sym, unsigned int __ndx,
+					    uintptr_t *__refcook,
+					    uintptr_t *__defcook,
+					    La_mips_32_regs *__regs,
+					    unsigned int *__flags,
+					    const char *__symname,
+					    long int *__framesizep);
+extern unsigned int la_mips_o32_gnu_pltexit (Elf32_Sym *__sym, unsigned int __ndx,
+					     uintptr_t *__refcook,
+					     uintptr_t *__defcook,
+					     const La_mips_32_regs *__inregs,
+					     La_mips_32_retval *__outregs,
+					     const char *__symname);
+
+#elif _MIPS_SIM == _ABIN32
+
+extern Elf32_Addr la_mips_n32_gnu_pltenter (Elf32_Sym *__sym, unsigned int __ndx,
+					    uintptr_t *__refcook,
+					    uintptr_t *__defcook,
+					    La_mips_64_regs *__regs,
+					    unsigned int *__flags,
+					    const char *__symname,
+					    long int *__framesizep);
+extern unsigned int la_mips_n32_gnu_pltexit (Elf32_Sym *__sym, unsigned int __ndx,
+					     uintptr_t *__refcook,
+					     uintptr_t *__defcook,
+					     const La_mips_64_regs *__inregs,
+					     La_mips_64_retval *__outregs,
+					     const char *__symname);
+
+#else
+
+extern Elf64_Addr la_mips_n64_gnu_pltenter (Elf64_Sym *__sym, unsigned int __ndx,
+					    uintptr_t *__refcook,
+					    uintptr_t *__defcook,
+					    La_mips_64_regs *__regs,
+					    unsigned int *__flags,
+					    const char *__symname,
+					    long int *__framesizep);
+extern unsigned int la_mips_n64_gnu_pltexit (Elf64_Sym *__sym, unsigned int __ndx,
+					     uintptr_t *__refcook,
+					     uintptr_t *__defcook,
+					     const La_mips_64_regs *__inregs,
+					     La_mips_64_retval *__outregs,
+					     const char *__symname);
+
+#endif
+
+__END_DECLS
diff --git a/sysdeps/mips/bits/linkmap.h b/sysdeps/mips/bits/linkmap.h
new file mode 100644
index 0000000000..a6df7821e6
--- /dev/null
+++ b/sysdeps/mips/bits/linkmap.h
@@ -0,0 +1,4 @@
+struct link_map_machine
+  {
+    ElfW(Addr) plt; /* Address of .plt */
+  };
diff --git a/sysdeps/mips/bits/mathdef.h b/sysdeps/mips/bits/mathdef.h
new file mode 100644
index 0000000000..0e7f56bc97
--- /dev/null
+++ b/sysdeps/mips/bits/mathdef.h
@@ -0,0 +1,43 @@
+/* Copyright (C) 1997-2014 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#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
+
+/* MIPS has `float' and `double' operations.  */
+typedef float float_t;		/* `float' expressions are evaluated as
+				   `float'.  */
+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/bits/nan.h b/sysdeps/mips/bits/nan.h
new file mode 100644
index 0000000000..80067ea145
--- /dev/null
+++ b/sysdeps/mips/bits/nan.h
@@ -0,0 +1,67 @@
+/* `NAN' constant for IEEE 754 machines.  MIPS version.
+   Copyright (C) 1992-2014 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _MATH_H
+# error "Never use <bits/nan.h> directly; include <math.h> instead."
+#endif
+
+
+/* IEEE Not A Number.  */
+/* In legacy-NaN mode MIPS has the qNaN and sNaN patterns reversed
+   compared to most other architectures.  IEEE 754-1985 left the
+   definition of this open to implementations, and for MIPS the top bit
+   of the mantissa must be SET to indicate a sNaN.  In 2008-NaN mode
+   MIPS aligned to IEEE 754-2008.  */
+
+#if __GNUC_PREREQ(3,3)
+
+# define NAN	(__builtin_nanf (""))
+
+#elif defined __GNUC__
+
+/* No 2008-NaN mode support in any GCC version before 4.9.  */
+
+# define NAN \
+  (__extension__							      \
+   ((union { unsigned __l __attribute__ ((__mode__ (__SI__))); float __d; })  \
+    { __l: 0x7fbfffffUL }).__d)
+
+#else
+
+# include <endian.h>
+
+# if __BYTE_ORDER == __BIG_ENDIAN
+#  ifdef __mips_nan2008
+#   define __qnan_bytes		{ 0x7f, 0xc0, 0, 0 }
+#  else
+#   define __qnan_bytes		{ 0x7f, 0xbf, 0xff, 0xff }
+#  endif
+# endif
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+#  ifdef __mips_nan2008
+#   define __qnan_bytes		{ 0, 0, 0xc0, 0x7f }
+#  else
+#   define __qnan_bytes		{ 0xff, 0xff, 0xbf, 0x7f }
+#  endif
+# endif
+
+static union { unsigned char __c[4]; float __d; } __qnan_union
+  __attribute__ ((__unused__)) = { __qnan_bytes };
+# define NAN	(__qnan_union.__d)
+
+#endif	/* GCC.  */
diff --git a/sysdeps/mips/bits/setjmp.h b/sysdeps/mips/bits/setjmp.h
new file mode 100644
index 0000000000..b9aaeb0f6b
--- /dev/null
+++ b/sysdeps/mips/bits/setjmp.h
@@ -0,0 +1,73 @@
+/* Define the machine-dependent type `jmp_buf'.  MIPS version.
+   Copyright (C) 1992-2014 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _MIPS_BITS_SETJMP_H
+#define _MIPS_BITS_SETJMP_H 1
+
+#if !defined(_SETJMP_H) && !defined(_PTHREAD_H)
+# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
+#endif
+
+#include <sgidefs.h>
+
+typedef struct __jmp_buf_internal_tag
+  {
+#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
+
+    /* Unused (was floating point status register).  */
+    int __glibc_reserved1;
+
+    /* Callee-saved floating point registers.  */
+#if _MIPS_SIM == _ABI64
+    double __fpregs[8];
+#else
+    double __fpregs[6];
+#endif
+  } __jmp_buf[1];
+
+#endif /* _MIPS_BITS_SETJMP_H */
diff --git a/sysdeps/mips/bits/wordsize.h b/sysdeps/mips/bits/wordsize.h
new file mode 100644
index 0000000000..3f05c7d652
--- /dev/null
+++ b/sysdeps/mips/bits/wordsize.h
@@ -0,0 +1,21 @@
+/* Copyright (C) 2002-2014 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define __WORDSIZE	_MIPS_SZPTR
+#if _MIPS_SIM == _ABI64
+# define __WORDSIZE_TIME64_COMPAT32	1
+#endif