diff -Naur glibc-2.11.orig/ports/sysdeps/mips/bits/atomic.h glibc-2.11/ports/sysdeps/mips/bits/atomic.h
--- glibc-2.11.orig/ports/sysdeps/mips/bits/atomic.h	2011-02-11 14:23:54.967412296 -0500
+++ glibc-2.11/ports/sysdeps/mips/bits/atomic.h	2011-02-11 14:25:06.186160978 -0500
@@ -154,24 +154,47 @@
 
 /* Compare and exchange with "acquire" semantics, ie barrier after.  */
 
+#if defined(_MIPS_ARCH_XLP)
+#define atomic_compare_and_exchange_bool_acq(mem, new, old)	\
+  __atomic_bool_bysize (__arch_compare_and_exchange_bool, int,	\
+		        mem, new, old, "", "")
+#else
 #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)
+#endif
 
+#if defined(_MIPS_ARCH_XLP)	
+#define atomic_compare_and_exchange_val_acq(mem, new, old)	\
+  __atomic_val_bysize (__arch_compare_and_exchange_val, int,	\
+		       mem, new, old, "", "")
+#else
 #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)
+#endif
 
 /* Compare and exchange with "release" semantics, ie barrier before.  */
 
+#if defined(_MIPS_ARCH_XLP)	
+#define atomic_compare_and_exchange_bool_rel(mem, new, old)	\
+  __atomic_bool_bysize (__arch_compare_and_exchange_bool, int,	\
+		        mem, new, old, "", "")
+#else
 #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, "")
+#endif
 
+#if defined(_MIPS_ARCH_XLP)	
+#define atomic_compare_and_exchange_val_rel(mem, new, old)	\
+  __atomic_val_bysize (__arch_compare_and_exchange_val, int,	\
+		       mem, new, old, "", "")
+#else
 #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, "")
-
+#endif
 
 
 /* Atomic exchange (without compare).  */
@@ -182,6 +205,37 @@
 #define __arch_exchange_xxx_16_int(mem, newval, rel, acq) \
   (abort (), 0)
 
+#if defined(_MIPS_ARCH_XLP)
+static int __always_inline __arch_exchange_xxx_32_int(int *mem,
+		typeof (*mem) newval, const char *rel, const char *acq) {
+
+	__asm__ __volatile__
+		(".set  push\n\t"
+		 "swapw %0,%2\n\t"
+		 ".set  pop\n"
+		 : "=&r" (newval), "=m" (*mem)
+		 : "r" (mem), "0"
+		 (newval));
+
+	return newval;
+}
+#elif defined(_MIPS_ARCH_XLR)
+static int __always_inline __arch_exchange_xxx_32_int(int *mem,
+		typeof (*mem) newval, const char *rel, const char *acq) {
+
+	__asm__ __volatile__
+		(".set  push\n\t"
+		 "sync	\n\t"
+		 "swapw %0,%2\n\t"
+		 "sync	\n\t"
+		 ".set  pop\n"
+		 : "=&r" (newval), "=m" (*mem)
+		 : "r" (mem), "0"
+		 (newval));
+
+	return newval;
+}
+#else	/* default */
 #define __arch_exchange_xxx_32_int(mem, newval, rel, acq) \
 ({ typeof (*mem) __prev; int __cmp;					      \
      __asm__ __volatile__ ("\n"						      \
@@ -200,12 +254,45 @@
 	      : "r" (newval), "m" (*mem)				      \
 	      : "memory");						      \
   __prev; })
+#endif /* default */
 
 #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 (), 0)
 #else
+
+#if defined(_MIPS_ARCH_XLP)
+static long __always_inline __arch_exchange_xxx_64_int(int *mem,
+		typeof (*mem) newval, const char *rel, const char *acq) {
+
+	__asm__ __volatile__
+		(".set  push\n\t"
+		 "swapd %0,%2\n\t"
+		 ".set  pop\n"
+		 : "=&r" (newval), "=m" (*mem)
+		 : "r" (mem), "0"
+		 (newval));
+
+	return newval;
+}
+#elif defined(_MIPS_ARCH_XLR) 
+static long __always_inline __arch_exchange_xxx_64_int(int *mem,
+		typeof (*mem) newval, const char *rel, const char *acq) {
+
+	__asm__ __volatile__
+		(".set  push\n\t"
+		 "sync	\n\t"
+		 "swapd %0,%2\n\t"
+		 "sync	\n\t"
+		 ".set  pop\n"
+		 : "=&r" (newval), "=m" (*mem)
+		 : "r" (mem), "0"
+		 (newval));
+
+	return newval;
+}
+#else	/* default */
 #define __arch_exchange_xxx_64_int(mem, newval, rel, acq) \
 ({ typeof (*mem) __prev; int __cmp;					      \
      __asm__ __volatile__ ("\n"						      \
@@ -224,6 +311,8 @@
 	      : "r" (newval), "m" (*mem)				      \
 	      : "memory");						      \
   __prev; })
+
+#endif /* default */
 #endif
 
 #define atomic_exchange_acq(mem, value) \
@@ -241,6 +330,33 @@
 #define __arch_exchange_and_add_16_int(mem, newval, rel, acq) \
   (abort (), (typeof(*mem)) 0)
 
+#if defined (_MIPS_ARCH_XLP)
+static int __always_inline __arch_exchange_and_add_32_int(unsigned int *mem,
+		typeof (*mem) value, const char *rel, const char *acq) {
+
+	__asm__ __volatile__ (
+			".set       push\n\t"
+			"ldaddw     %0,%2\n\t"
+			".set       pop\n"
+			: "=&r" (value), "=m" (*mem)
+			: "r"(mem), "0" (value));
+	return value;
+}
+#elif defined(_MIPS_ARCH_XLR)
+static int __always_inline __arch_exchange_and_add_32_int(unsigned int *mem,
+		typeof (*mem) value, const char *rel, const char *acq) {
+
+	__asm__ __volatile__ (
+			".set       push\n\t"
+			"sync       \n\t"
+			"ldaddw     %0,%2\n\t"
+			"sync       \n\t"
+			".set       pop\n"
+			: "=&r" (value), "=m" (*mem)
+			: "r"(mem), "0" (value));
+	return value;
+}
+#else /* default */
 #define __arch_exchange_and_add_32_int(mem, value, rel, acq) \
 ({ typeof (*mem) __prev; int __cmp;					      \
      __asm__ __volatile__ ("\n"						      \
@@ -259,12 +375,40 @@
 	      : "r" (value), "m" (*mem)					      \
 	      : "memory");						      \
   __prev; })
+#endif /* default */
 
 #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
+#if defined (_MIPS_ARCH_XLP)
+static long __always_inline __arch_exchange_and_add_64_int(unsigned int *mem,
+		typeof (*mem) value, const char *rel, const char *acq) {
+
+	__asm__ __volatile__ (
+			".set       push\n\t"
+			"ldaddd     %0,%2\n\t"
+			".set       pop\n"
+			: "=&r" (value), "=m" (*mem)
+			: "r"(mem), "0" (value));
+	return value;
+}
+#elif defined(_MIPS_ARCH_XLR)
+static long __always_inline __arch_exchange_and_add_64_int(unsigned int *mem,
+		typeof (*mem) value, const char *rel, const char *acq) {
+
+	__asm__ __volatile__ (
+			".set       push\n\t"
+			"sync       \n\t"
+			"ldaddd     %0,%2\n\t"
+			"sync       \n\t"
+			".set       pop\n"
+			: "=&r" (value), "=m" (*mem)
+			: "r"(mem), "0" (value));
+	return value;
+}
+#else /* default */
 #define __arch_exchange_and_add_64_int(mem, value, rel, acq) \
 ({ typeof (*mem) __prev; int __cmp;					      \
      __asm__ __volatile__ (						      \
@@ -283,6 +427,7 @@
 	      : "r" (value), "m" (*mem)					      \
 	      : "memory");						      \
   __prev; })
+#endif /* default */
 #endif
 
 /* ??? Barrier semantics for atomic_exchange_and_add appear to be 
diff -Naur glibc-2.11.orig/ports/sysdeps/mips/dl-lookup.c glibc-2.11/ports/sysdeps/mips/dl-lookup.c
--- glibc-2.11.orig/ports/sysdeps/mips/dl-lookup.c	2011-02-11 14:23:54.977412716 -0500
+++ glibc-2.11/ports/sysdeps/mips/dl-lookup.c	2011-02-11 14:25:06.186160978 -0500
@@ -329,16 +329,16 @@
 		 definition we have to use it.  */
 	      void enter (struct unique_sym *table, size_t size,
 			  unsigned int hash, const char *name,
-			  const ElfW(Sym) *sym, const struct link_map *map)
+			  const ElfW(Sym) *sym, struct link_map *map)
 	      {
 		size_t idx = hash % size;
 		size_t hash2 = 1 + hash % (size - 2);
 		while (1)
 		  {
-		    if (table[idx].hashval == 0)
+		    if (table[idx].name == NULL)
 		      {
 			table[idx].hashval = hash;
-			table[idx].name = strtab + sym->st_name;
+			table[idx].name = name;
 			if ((type_class & ELF_RTYPE_CLASS_COPY) != 0)
 			  {
 			    table[idx].sym = ref;
@@ -348,7 +348,13 @@
 			  {
 			    table[idx].sym = sym;
 			    table[idx].map = map;
+
+			    if (map->l_type == lt_loaded)
+			      /* Make sure we don't unload this object by
+				 setting the appropriate flag.  */
+			      map->l_flags_1 |= DF_1_NODELETE;
 			  }
+
 			return;
 		      }
 
@@ -380,8 +386,7 @@
 			  return 1;
 			}
 
-		      if (entries[idx].hashval == 0
-			  && entries[idx].name == NULL)
+		      if (entries[idx].name == NULL)
 			break;
 
 		      idx += hash2;
@@ -389,10 +394,14 @@
 			idx -= size;
 		    }
 
-		  if (size * 3 <= tab->n_elements)
+		  if (size * 3 <= tab->n_elements * 4)
 		    {
 		      /* Expand the table.  */
-		      size_t newsize = _dl_higher_prime_number (size);
+#ifdef RTLD_CHECK_FOREIGN_CALL
+		      /* This must not happen during runtime relocations.  */
+		      assert (!RTLD_CHECK_FOREIGN_CALL);
+#endif
+		      size_t newsize = _dl_higher_prime_number (size + 1);
 		      struct unique_sym *newentries
 			= calloc (sizeof (struct unique_sym), newsize);
 		      if (newentries == NULL)
@@ -403,19 +412,25 @@
 			}
 
 		      for (idx = 0; idx < size; ++idx)
-			if (entries[idx].hashval != 0)
+			if (entries[idx].name != NULL)
 			  enter (newentries, newsize, entries[idx].hashval,
 				 entries[idx].name, entries[idx].sym,
 				 entries[idx].map);
 
 		      tab->free (entries);
 		      tab->size = newsize;
+		      size = newsize;
 		      entries = tab->entries = newentries;
 		      tab->free = free;
 		    }
 		}
 	      else
 		{
+#ifdef RTLD_CHECK_FOREIGN_CALL
+		  /* This must not happen during runtime relocations.  */
+		  assert (!RTLD_CHECK_FOREIGN_CALL);
+#endif
+
 #define INITIAL_NUNIQUE_SYM_TABLE 31
 		  size = INITIAL_NUNIQUE_SYM_TABLE;
 		  entries = calloc (sizeof (struct unique_sym), size);
@@ -427,7 +442,8 @@
 		  tab->free = free;
 		}
 
-	      enter (entries, size, new_hash, strtab + sym->st_name, sym, map);
+	      enter (entries, size, new_hash, strtab + sym->st_name, sym,
+		     (struct link_map *) map);
 	      ++tab->n_elements;
 
 	      __rtld_lock_unlock_recursive (tab->lock);
@@ -610,6 +626,10 @@
 	  unsigned int max
 	    = undef_map->l_reldepsmax ? undef_map->l_reldepsmax * 2 : 10;
 
+#ifdef RTLD_PREPARE_FOREIGN_CALL
+	  RTLD_PREPARE_FOREIGN_CALL;
+#endif
+
 	  newp = malloc (sizeof (*newp) + max * sizeof (struct link_map *));
 	  if (newp == NULL)
 	    {
@@ -774,7 +794,7 @@
   if (__builtin_expect (protected != 0, 0))
     {
       /* It is very tricky.  We need to figure out what value to
-         return for the protected symbol.  */
+	 return for the protected symbol.  */
       if (type_class == ELF_RTYPE_CLASS_PLT)
 	{
 	  if (current_value.s != NULL && current_value.m != undef_map)
@@ -819,7 +839,8 @@
 				  version, type_class, flags, skip_map);
 
   /* The object is used.  */
-  current_value.m->l_used = 1;
+  if (__builtin_expect (current_value.m->l_used == 0, 0))
+    current_value.m->l_used = 1;
 
   if (__builtin_expect (GLRO(dl_debug_mask)
 			& (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK), 0))
@@ -841,7 +862,7 @@
   Elf_Symndx nchain;
 
   if (__builtin_expect (map->l_info[DT_ADDRTAGIDX (DT_GNU_HASH) + DT_NUM
-  				    + DT_THISPROCNUM + DT_VERSIONTAGNUM
+				    + DT_THISPROCNUM + DT_VERSIONTAGNUM
 				    + DT_EXTRANUM + DT_VALNUM] != NULL, 1))
     {
       Elf32_Word *hash32
diff -Naur glibc-2.11.orig/ports/sysdeps/mips/nptl/pthread_spin_lock.S glibc-2.11/ports/sysdeps/mips/nptl/pthread_spin_lock.S
--- glibc-2.11.orig/ports/sysdeps/mips/nptl/pthread_spin_lock.S	2011-02-11 14:23:54.967412296 -0500
+++ glibc-2.11/ports/sysdeps/mips/nptl/pthread_spin_lock.S	2011-02-11 14:25:06.206161839 -0500
@@ -21,6 +21,31 @@
 #include <sgidefs.h>
 
 ENTRY (pthread_spin_lock)
+
+#if defined(_MIPS_ARCH_XLP)
+	.set    push
+	.set    noreorder
+	li      a1, 1
+1:  swapw   a1, a0
+	bnez    a1, 1b
+	li      a1, 1
+	.set    reorder
+	.set    pop
+	li      v0, 0
+	ret
+#elif defined(_MIPS_ARCH_XLR)
+	.set    push
+	.set    noreorder
+	li      a1, 1
+1:  swapw   a1, a0
+	bnez    a1, 1b
+	li      a1, 1
+	MIPS_SYNC
+	.set    reorder
+	.set    pop
+	li      v0, 0
+	ret
+#else
 	.set	push
 #if _MIPS_SIM == _ABIO32
 	.set	mips2
@@ -34,4 +59,6 @@
 	.set	pop
 	li	v0, 0
 	ret
+#endif
+
 PSEUDO_END (pthread_spin_lock)
diff -Naur glibc-2.11.orig/ports/sysdeps/mips/nptl/pthread_spin_trylock.S glibc-2.11/ports/sysdeps/mips/nptl/pthread_spin_trylock.S
--- glibc-2.11.orig/ports/sysdeps/mips/nptl/pthread_spin_trylock.S	2011-02-11 14:23:54.967412296 -0500
+++ glibc-2.11/ports/sysdeps/mips/nptl/pthread_spin_trylock.S	2011-02-11 14:25:06.206161839 -0500
@@ -23,6 +23,33 @@
 #include <sgidefs.h>
 
 ENTRY (pthread_spin_trylock)
+
+#if defined(_MIPS_ARCH_XLP)
+	.set    push
+	.set    noreorder
+	li      a1, 1
+	swapw   a1, a0
+	bnez    a1, 1f
+	.set    reorder
+	.set    pop
+	li      v0, 0
+	ret
+1:  li      v0, EBUSY
+	ret
+#elif defined(_MIPS_ARCH_XLR)
+	.set    push
+	.set    noreorder
+	li      a1, 1
+	swapw   a1, a0
+	bnez    a1, 1f
+	MIPS_SYNC
+	.set    reorder
+	.set    pop
+	li      v0, 0
+	ret
+1:  li      v0, EBUSY
+	ret
+#else
 	.set	push
 #if _MIPS_SIM == _ABIO32
 	.set	mips2
@@ -38,4 +65,6 @@
 	ret
 1:	li	v0, EBUSY
 	ret
+#endif
+
 PSEUDO_END (pthread_spin_trylock)
 /* The POSIX people had to invent similar names for the same things.  */
diff -Naur glibc-2.11.orig/ports/sysdeps/unix/sysv/linux/mips/bits/mman.h glibc-2.11/ports/sysdeps/unix/sysv/linux/mips/bits/mman.h
--- glibc-2.11.orig/ports/sysdeps/unix/sysv/linux/mips/bits/mman.h	2011-02-11 14:23:54.807412122 -0500
+++ glibc-2.11/ports/sysdeps/unix/sysv/linux/mips/bits/mman.h	2011-02-11 14:25:06.986163653 -0500
@@ -1,5 +1,5 @@
 /* Definitions for POSIX memory map interface.  Linux/MIPS version.
-   Copyright (C) 1997, 2000, 2003, 2004, 2005, 2006
+   Copyright (C) 1997, 2000, 2003, 2004, 2005, 2006, 2009
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -86,14 +86,17 @@
 
 /* Advice to `madvise'.  */
 #ifdef __USE_BSD
-# define MADV_NORMAL	 0	/* No further special treatment.  */
-# define MADV_RANDOM	 1	/* Expect random page references.  */
-# define MADV_SEQUENTIAL 2	/* Expect sequential page references.  */
-# define MADV_WILLNEED	 3	/* Will need these pages.  */
-# define MADV_DONTNEED	 4	/* Don't need these pages.  */
-# define MADV_REMOVE	 9	/* Remove these pages and resources.  */
-# define MADV_DONTFORK	 10	/* Do not inherit across fork.  */
-# define MADV_DOFORK	 11	/* Do inherit across fork.  */
+# define MADV_NORMAL	  0	/* No further special treatment.  */
+# define MADV_RANDOM	  1	/* Expect random page references.  */
+# define MADV_SEQUENTIAL  2	/* Expect sequential page references.  */
+# define MADV_WILLNEED	  3	/* Will need these pages.  */
+# define MADV_DONTNEED	  4	/* Don't need these pages.  */
+# define MADV_REMOVE	  9	/* Remove these pages and resources.  */
+# define MADV_DONTFORK	  10	/* Do not inherit across fork.  */
+# define MADV_DOFORK	  11	/* Do inherit across fork.  */
+# define MADV_MERGEABLE	  12	/* KSM may merge identical pages.  */
+# define MADV_UNMERGEABLE 13	/* KSM may not merge identical pages.  */
+# define MADV_HWPOISON	  100	/* Poison a page for testing.  */
 #endif
 
 /* The POSIX people had to invent similar names for the same things.  */
diff -Naur glibc-2.11.orig/ports/sysdeps/unix/sysv/linux/mips/mips64/configure glibc-2.11/ports/sysdeps/unix/sysv/linux/mips/mips64/configure
--- glibc-2.11.orig/ports/sysdeps/unix/sysv/linux/mips/mips64/configure	2011-02-11 14:23:54.817412912 -0500
+++ glibc-2.11/ports/sysdeps/unix/sysv/linux/mips/mips64/configure	2011-02-11 14:25:06.996162642 -0500
@@ -1,4 +1,5 @@
 # This file is generated from configure.in by Autoconf.  DO NOT EDIT!
  # Local configure fragment for sysdeps/unix/sysv/linux/mips/mips64.
 
-ldd_rewrite_script=$dest/ldd-rewrite.sed
+#ldd_rewrite_script=$dest/ldd-rewrite.sed
+ldd_rewrite_script=../ports/sysdeps/unix/sysv/linux/mips/mips64/ldd-rewrite.sed
diff -Naur glibc-2.11.orig/ports/sysdeps/unix/sysv/linux/mips/mips64/n32/posix_fadvise.c glibc-2.11/ports/sysdeps/unix/sysv/linux/mips/mips64/n32/posix_fadvise.c
--- glibc-2.11.orig/ports/sysdeps/unix/sysv/linux/mips/mips64/n32/posix_fadvise.c	1969-12-31 19:00:00.000000000 -0500
+++ glibc-2.11/ports/sysdeps/unix/sysv/linux/mips/mips64/n32/posix_fadvise.c	2011-02-11 14:25:06.996162642 -0500
@@ -0,0 +1,38 @@
+/* Copyright (C) 2003, 2004, 2009 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 <errno.h>
+#include <fcntl.h>
+#include <sysdep.h>
+
+/* Advice the system about the expected behaviour of the application with
+   respect to the file associated with FD.  */
+
+int
+posix_fadvise (int fd, off_t offset, off_t len, int advise)
+{
+#ifdef __NR_fadvise64
+  INTERNAL_SYSCALL_DECL (err);
+  int ret = INTERNAL_SYSCALL (fadvise64, err, 4, fd, offset, len, advise);
+  if (INTERNAL_SYSCALL_ERROR_P (ret, err))
+    return INTERNAL_SYSCALL_ERRNO (ret, err);
+  return 0;
+#else
+  return ENOSYS;
+#endif
+}
diff -Naur glibc-2.11.orig/ports/sysdeps/unix/sysv/linux/mips/mips64/n32/syscalls.list glibc-2.11/ports/sysdeps/unix/sysv/linux/mips/mips64/n32/syscalls.list
--- glibc-2.11.orig/ports/sysdeps/unix/sysv/linux/mips/mips64/n32/syscalls.list	2011-02-11 14:23:54.817412912 -0500
+++ glibc-2.11/ports/sysdeps/unix/sysv/linux/mips/mips64/n32/syscalls.list	2011-02-11 14:25:06.996162642 -0500
@@ -2,6 +2,5 @@
 
 readahead	-	readahead	i:iii	__readahead	readahead
 sync_file_range	-	sync_file_range	i:iiii	sync_file_range
-posix_fadvise	-	fadvise64	i:iiii	posix_fadvise
 ftruncate	-	ftruncate	i:ii	__ftruncate	ftruncate ftruncate64 __ftruncate64
 truncate	-	truncate	i:si	truncate	truncate64
diff -Naur glibc-2.11.orig/ports/sysdeps/unix/sysv/linux/mips/mips64/n64/posix_fadvise64.c glibc-2.11/ports/sysdeps/unix/sysv/linux/mips/mips64/n64/posix_fadvise64.c
--- glibc-2.11.orig/ports/sysdeps/unix/sysv/linux/mips/mips64/n64/posix_fadvise64.c	1969-12-31 19:00:00.000000000 -0500
+++ glibc-2.11/ports/sysdeps/unix/sysv/linux/mips/mips64/n64/posix_fadvise64.c	2011-02-11 14:25:07.006164245 -0500
@@ -0,0 +1 @@
+/* posix_fadvise64 is in posix_fadvise.c */
diff -Naur glibc-2.11.orig/ports/sysdeps/unix/sysv/linux/mips/mips64/n64/posix_fadvise.c glibc-2.11/ports/sysdeps/unix/sysv/linux/mips/mips64/n64/posix_fadvise.c
--- glibc-2.11.orig/ports/sysdeps/unix/sysv/linux/mips/mips64/n64/posix_fadvise.c	1969-12-31 19:00:00.000000000 -0500
+++ glibc-2.11/ports/sysdeps/unix/sysv/linux/mips/mips64/n64/posix_fadvise.c	2011-02-11 14:25:07.006164245 -0500
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/wordsize-64/posix_fadvise.c>
diff -Naur glibc-2.11.orig/ports/sysdeps/unix/sysv/linux/mips/sys/tas.h glibc-2.11/ports/sysdeps/unix/sysv/linux/mips/sys/tas.h
--- glibc-2.11.orig/ports/sysdeps/unix/sysv/linux/mips/sys/tas.h	2011-02-11 14:23:54.817412912 -0500
+++ glibc-2.11/ports/sysdeps/unix/sysv/linux/mips/sys/tas.h	2011-02-11 14:25:07.016166158 -0500
@@ -37,6 +37,30 @@
 _EXTERN_INLINE int
 __NTH (_test_and_set (int *__p, int __v))
 {
+#if defined(_MIPS_ARCH_XLP)
+	int newval = __v;
+	__asm__ __volatile__
+		("/* Inline test and set */\n"
+		 ".set  push\n\t"
+		 "swapw %0,%2\n\t"
+		 ".set  pop\n\t"
+		 : "=&r" (__v), "=m" (*__p)
+		 : "r" (__p), "0" (__v));
+	return (__v == newval);
+#elif defined (_MIPS_ARCH_XLR)
+	int newval = __v;
+	__asm__ __volatile__
+		("/* Inline test and set */\n"
+		 ".set  push\n\t"
+     	 "sync\n\t"
+		 "swapw %0,%2\n\t"
+     	 "sync\n\t"
+		 ".set  pop\n\t"
+		 : "=&r" (__v), "=m" (*__p)
+		 : "r" (__p), "0" (__v));
+	return (__v == newval);
+#else
+  /* Default scenario */
   int __r, __t;
 
   __asm__ __volatile__
@@ -61,6 +85,7 @@
      : "memory");
 
   return __r;
+#endif
 }
 
 #endif /* __USE_EXTERN_INLINES */
diff -Naur glibc-2.11.orig/scripts/config.sub glibc-2.11/scripts/config.sub
--- glibc-2.11.orig/scripts/config.sub	2011-02-11 14:23:54.687443909 -0500
+++ glibc-2.11/scripts/config.sub	2011-02-11 14:25:07.076163229 -0500
@@ -263,6 +263,7 @@
 	| mipsisa32r2 | mipsisa32r2el \
 	| mipsisa64 | mipsisa64el \
 	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64r2nlm | mipsisa64r2nlmel \
 	| mipsisa64sb1 | mipsisa64sb1el \
 	| mipsisa64sr71k | mipsisa64sr71kel \
 	| mipstx39 | mipstx39el \
@@ -346,6 +347,7 @@
 	| mipsisa32r2-* | mipsisa32r2el-* \
 	| mipsisa64-* | mipsisa64el-* \
 	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64r2nlm-* | mipsisa64r2nlmel-* \
 	| mipsisa64sb1-* | mipsisa64sb1el-* \
 	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
 	| mipstx39-* | mipstx39el-* \
diff -Naur glibc-2.11.orig/string/strstr.c glibc-2.11/string/strstr.c
--- glibc-2.11.orig/string/strstr.c	2011-02-11 14:23:54.497413354 -0500
+++ glibc-2.11/string/strstr.c	2011-02-11 14:25:07.076163229 -0500
@@ -1,6 +1,5 @@
 /* Return the offset of one string within another.
-   Copyright (C) 1994,1996,1997,2000,2001,2003,2008,2009
-   Free Software Foundation, Inc.
+   Copyright (C) 1994,1996,1997,2000,2001,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
@@ -18,75 +17,107 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-/* This particular implementation was written by Eric Blake, 2008.  */
+/*
+ * My personal strstr() implementation that beats most other algorithms.
+ * Until someone tells me otherwise, I assume that this is the
+ * fastest implementation of strstr() in C.
+ * I deliberately chose not to comment it.  You should have at least
+ * as much fun trying to understand it, as I had to write it :-).
+ *
+ * Stephen R. van den Berg, berg@pool.informatik.rwth-aachen.de	*/
 
-#ifndef _LIBC
+#if HAVE_CONFIG_H
 # include <config.h>
 #endif
 
-/* Specification of strstr.  */
-#include <string.h>
-
-#include <stdbool.h>
-
-#ifndef _LIBC
-# define __builtin_expect(expr, val)   (expr)
+#if defined _LIBC || defined HAVE_STRING_H
+# include <string.h>
 #endif
 
-#define RETURN_TYPE char *
-#define AVAILABLE(h, h_l, j, n_l)			\
-  (!memchr ((h) + (h_l), '\0', (j) + (n_l) - (h_l))	\
-   && ((h_l) = (j) + (n_l)))
-#include "str-two-way.h"
+typedef unsigned chartype;
 
 #undef strstr
 
-#ifndef STRSTR
-#define STRSTR strstr
-#endif
-
-/* Return the first occurrence of NEEDLE in HAYSTACK.  Return HAYSTACK
-   if NEEDLE is empty, otherwise NULL if NEEDLE is not found in
-   HAYSTACK.  */
 char *
-STRSTR (const char *haystack_start, const char *needle_start)
+strstr (phaystack, pneedle)
+     const char *phaystack;
+     const char *pneedle;
 {
-  const char *haystack = haystack_start;
-  const char *needle = needle_start;
-  size_t needle_len; /* Length of NEEDLE.  */
-  size_t haystack_len; /* Known minimum length of HAYSTACK.  */
-  bool ok = true; /* True if NEEDLE is prefix of HAYSTACK.  */
-
-  /* Determine length of NEEDLE, and in the process, make sure
-     HAYSTACK is at least as long (no point processing all of a long
-     NEEDLE if HAYSTACK is too short).  */
-  while (*haystack && *needle)
-    ok &= *haystack++ == *needle++;
-  if (*needle)
-    return NULL;
-  if (ok)
-    return (char *) haystack_start;
-
-  /* Reduce the size of haystack using strchr, since it has a smaller
-     linear coefficient than the Two-Way algorithm.  */
-  needle_len = needle - needle_start;
-  haystack = strchr (haystack_start + 1, *needle_start);
-  if (!haystack || __builtin_expect (needle_len == 1, 0))
-    return (char *) haystack;
-  needle -= needle_len;
-  haystack_len = (haystack > haystack_start + needle_len ? 1
-		  : needle_len + haystack_start - haystack);
-
-  /* Perform the search.  Abstract memory is considered to be an array
-     of 'unsigned char' values, not an array of 'char' values.  See
-     ISO C 99 section 6.2.6.1.  */
-  if (needle_len < LONG_NEEDLE_THRESHOLD)
-    return two_way_short_needle ((const unsigned char *) haystack,
-				 haystack_len,
-				 (const unsigned char *) needle, needle_len);
-  return two_way_long_needle ((const unsigned char *) haystack, haystack_len,
-			      (const unsigned char *) needle, needle_len);
+  const unsigned char *haystack, *needle;
+  chartype b;
+  const unsigned char *rneedle;
+
+  haystack = (const unsigned char *) phaystack;
+
+  if ((b = *(needle = (const unsigned char *) pneedle)))
+    {
+      chartype c;
+      haystack--;		/* possible ANSI violation */
+
+      {
+	chartype a;
+	do
+	  if (!(a = *++haystack))
+	    goto ret0;
+	while (a != b);
+      }
+
+      if (!(c = *++needle))
+	goto foundneedle;
+      ++needle;
+      goto jin;
+
+      for (;;)
+	{
+	  {
+	    chartype a;
+	    if (0)
+	    jin:{
+		if ((a = *++haystack) == c)
+		  goto crest;
+	      }
+	    else
+	      a = *++haystack;
+	    do
+	      {
+		for (; a != b; a = *++haystack)
+		  {
+		    if (!a)
+		      goto ret0;
+		    if ((a = *++haystack) == b)
+		      break;
+		    if (!a)
+		      goto ret0;
+		  }
+	      }
+	    while ((a = *++haystack) != c);
+	  }
+	crest:
+	  {
+	    chartype a;
+	    {
+	      const unsigned char *rhaystack;
+	      if (*(rhaystack = haystack-- + 1) == (a = *(rneedle = needle)))
+		do
+		  {
+		    if (!a)
+		      goto foundneedle;
+		    if (*++rhaystack != (a = *++needle))
+		      break;
+		    if (!a)
+		      goto foundneedle;
+		  }
+		while (*++rhaystack == (a = *++needle));
+	      needle = rneedle;	/* took the register-poor aproach */
+	    }
+	    if (!a)
+	      break;
+	  }
+	}
+    }
+foundneedle:
+  return (char *) haystack;
+ret0:
+  return 0;
 }
 libc_hidden_builtin_def (strstr)
-
-#undef LONG_NEEDLE_THRESHOLD
