about summary refs log tree commit diff
path: root/REORG.TODO/sysdeps/tile/tilegx
diff options
context:
space:
mode:
authorZack Weinberg <zackw@panix.com>2017-06-08 15:39:03 -0400
committerZack Weinberg <zackw@panix.com>2017-06-08 15:39:03 -0400
commit5046dbb4a7eba5eccfd258f92f4735c9ffc8d069 (patch)
tree4470480d904b65cf14ca524f96f79eca818c3eaf /REORG.TODO/sysdeps/tile/tilegx
parent199fc19d3aaaf57944ef036e15904febe877fc93 (diff)
downloadglibc-5046dbb4a7eba5eccfd258f92f4735c9ffc8d069.tar.gz
glibc-5046dbb4a7eba5eccfd258f92f4735c9ffc8d069.tar.xz
glibc-5046dbb4a7eba5eccfd258f92f4735c9ffc8d069.zip
Prepare for radical source tree reorganization. zack/build-layout-experiment
All top-level files and directories are moved into a temporary storage
directory, REORG.TODO, except for files that will certainly still
exist in their current form at top level when we're done (COPYING,
COPYING.LIB, LICENSES, NEWS, README), all old ChangeLog files (which
are moved to the new directory OldChangeLogs, instead), and the
generated file INSTALL (which is just deleted; in the new order, there
will be no generated files checked into version control).
Diffstat (limited to 'REORG.TODO/sysdeps/tile/tilegx')
-rw-r--r--REORG.TODO/sysdeps/tile/tilegx/Implies1
-rw-r--r--REORG.TODO/sysdeps/tile/tilegx/Makefile35
-rw-r--r--REORG.TODO/sysdeps/tile/tilegx/atomic-machine.h61
-rw-r--r--REORG.TODO/sysdeps/tile/tilegx/bits/wordsize.h11
-rw-r--r--REORG.TODO/sysdeps/tile/tilegx/memchr.c77
-rw-r--r--REORG.TODO/sysdeps/tile/tilegx/memcpy.c272
-rw-r--r--REORG.TODO/sysdeps/tile/tilegx/memset.c151
-rw-r--r--REORG.TODO/sysdeps/tile/tilegx/memusage.h31
-rw-r--r--REORG.TODO/sysdeps/tile/tilegx/rawmemchr.c45
-rw-r--r--REORG.TODO/sysdeps/tile/tilegx/strcasestr.c53
-rw-r--r--REORG.TODO/sysdeps/tile/tilegx/strchr.c67
-rw-r--r--REORG.TODO/sysdeps/tile/tilegx/strchrnul.c64
-rw-r--r--REORG.TODO/sysdeps/tile/tilegx/string-endian.h58
-rw-r--r--REORG.TODO/sysdeps/tile/tilegx/strlen.c39
-rw-r--r--REORG.TODO/sysdeps/tile/tilegx/strnlen.c57
-rw-r--r--REORG.TODO/sysdeps/tile/tilegx/strrchr.c68
-rw-r--r--REORG.TODO/sysdeps/tile/tilegx/strstr.c270
-rw-r--r--REORG.TODO/sysdeps/tile/tilegx/tilegx32/Implies3
-rw-r--r--REORG.TODO/sysdeps/tile/tilegx/tilegx64/Implies3
19 files changed, 1366 insertions, 0 deletions
diff --git a/REORG.TODO/sysdeps/tile/tilegx/Implies b/REORG.TODO/sysdeps/tile/tilegx/Implies
new file mode 100644
index 0000000000..ade71c1957
--- /dev/null
+++ b/REORG.TODO/sysdeps/tile/tilegx/Implies
@@ -0,0 +1 @@
+ieee754/dbl-64/wordsize-64
diff --git a/REORG.TODO/sysdeps/tile/tilegx/Makefile b/REORG.TODO/sysdeps/tile/tilegx/Makefile
new file mode 100644
index 0000000000..4281dd98fc
--- /dev/null
+++ b/REORG.TODO/sysdeps/tile/tilegx/Makefile
@@ -0,0 +1,35 @@
+include $(common-objpfx)cflags-mcmodel-large.mk
+
+# Check for gcc to support the command-line switch, and for
+# binutils to support the hwN_plt() assembly operators and relocations.
+$(common-objpfx)cflags-mcmodel-large.mk: $(common-objpfx)config.make
+	mcmodel=no; \
+	(echo 'int main() { return getuid(); }' | \
+	 $(CC) -o /dev/null -xc - -mcmodel=large -fpic) && mcmodel=yes; \
+	echo "cflags-mcmodel-large = $$mcmodel" > $@
+
+ifeq (yes,$(cflags-mcmodel-large))
+
+ifeq ($(subdir),csu)
+# elf-init.c is in libc_nonshared.o (the end of the shared object) but
+# must reach the _init symbol at the very start of the shared object.
+CFLAGS-elf-init.c += -mcmodel=large
+
+# __gmon_start__ is at the very start of the shared object when linked
+# with profiling, but calls to libc.so via the PLT at the very end.
+CFLAGS-gmon-start.c += -mcmodel=large
+endif
+
+else
+
+# Don't try to compile assembly code with hwN_plt() directives if the
+# toolchain doesn't support -mcmodel=large.
+ifeq ($(subdir),csu)
+CPPFLAGS-start.S += -DNO_PLT_PCREL
+CPPFLAGS-crti.S += -DNO_PLT_PCREL
+endif
+ifeq ($(subdir),nptl)
+CPPFLAGS-pt-crti.S += -DNO_PLT_PCREL
+endif
+
+endif
diff --git a/REORG.TODO/sysdeps/tile/tilegx/atomic-machine.h b/REORG.TODO/sysdeps/tile/tilegx/atomic-machine.h
new file mode 100644
index 0000000000..e77f6707b0
--- /dev/null
+++ b/REORG.TODO/sysdeps/tile/tilegx/atomic-machine.h
@@ -0,0 +1,61 @@
+/* Copyright (C) 2011-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
+
+   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 _ATOMIC_MACHINE_H
+#define _ATOMIC_MACHINE_H	1
+
+#include <arch/spr_def.h>
+
+#ifdef _LP64
+# define __HAVE_64B_ATOMICS 1
+#else
+/* tilegx32 does have 64-bit atomics, but assumptions in the semaphore
+   code mean that unaligned 64-bit atomics will be used if this symbol
+   is true, and unaligned atomics are not supported on tile.  */
+# define __HAVE_64B_ATOMICS 0
+#endif
+
+#define USE_ATOMIC_COMPILER_BUILTINS 0
+#define ATOMIC_EXCHANGE_USES_CAS 0
+
+/* Pick appropriate 8- or 4-byte instruction. */
+#define __atomic_update(mem, v, op)                                     \
+  ((__typeof (*(mem))) (__typeof (*(mem) - *(mem)))                     \
+   ((sizeof (*(mem)) == 8) ?                                            \
+    __insn_##op ((void *) (mem), (int64_t) (__typeof((v) - (v))) (v)) : \
+    (sizeof (*(mem)) == 4) ?                                            \
+    __insn_##op##4 ((void *) (mem), (int32_t) (__typeof ((v) - (v))) (v)) : \
+    __atomic_error_bad_argument_size()))
+
+#define atomic_compare_and_exchange_val_acq(mem, n, o)                  \
+  ({ __insn_mtspr (SPR_CMPEXCH_VALUE, (int64_t) (__typeof ((o) - (o))) (o)); \
+     __atomic_update (mem, n, cmpexch); })
+#define atomic_exchange_acq(mem, newvalue) \
+  __atomic_update (mem, newvalue, exch)
+#define atomic_exchange_and_add(mem, value) \
+  __atomic_update (mem, value, fetchadd)
+#define atomic_and_val(mem, mask) \
+  __atomic_update (mem, mask, fetchand)
+#define atomic_or_val(mem, mask) \
+  __atomic_update (mem, mask, fetchor)
+#define atomic_decrement_if_positive(mem) \
+  __atomic_update (mem, -1, fetchaddgez)
+
+#include <sysdeps/tile/atomic-machine.h>
+
+#endif /* atomic-machine.h */
diff --git a/REORG.TODO/sysdeps/tile/tilegx/bits/wordsize.h b/REORG.TODO/sysdeps/tile/tilegx/bits/wordsize.h
new file mode 100644
index 0000000000..9dc4da5de9
--- /dev/null
+++ b/REORG.TODO/sysdeps/tile/tilegx/bits/wordsize.h
@@ -0,0 +1,11 @@
+/* Determine the wordsize from the preprocessor defines.  */
+
+#ifdef __LP64__
+# define __WORDSIZE	64
+# define __WORDSIZE_TIME64_COMPAT32	1
+#else
+# define __WORDSIZE	32
+# define __WORDSIZE_TIME64_COMPAT32	0
+# define __WORDSIZE32_SIZE_ULONG	0
+# define __WORDSIZE32_PTRDIFF_LONG	0
+#endif
diff --git a/REORG.TODO/sysdeps/tile/tilegx/memchr.c b/REORG.TODO/sysdeps/tile/tilegx/memchr.c
new file mode 100644
index 0000000000..7da0f79da2
--- /dev/null
+++ b/REORG.TODO/sysdeps/tile/tilegx/memchr.c
@@ -0,0 +1,77 @@
+/* Copyright (C) 2011-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
+
+   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/>.  */
+
+#include <string.h>
+#include <stdint.h>
+#include "string-endian.h"
+
+void *
+__memchr (const void *s, int c, size_t n)
+{
+  const uint64_t *last_word_ptr;
+  const uint64_t *p;
+  const char *last_byte_ptr;
+  uintptr_t s_int;
+  uint64_t goal, before_mask, v, bits;
+  char *ret;
+
+  if (__builtin_expect (n == 0, 0))
+    {
+      /* Don't dereference any memory if the array is empty. */
+      return NULL;
+    }
+
+  /* Get an aligned pointer. */
+  s_int = (uintptr_t) s;
+  p = (const uint64_t *) (s_int & -8);
+
+  /* Create eight copies of the byte for which we are looking. */
+  goal = copy_byte(c);
+
+  /* Read the first word, but munge it so that bytes before the array
+     will not match goal.  */
+  before_mask = MASK (s_int);
+  v = (*p | before_mask) ^ (goal & before_mask);
+
+  /* Compute the address of the last byte. */
+  last_byte_ptr = (const char *) s + n - 1;
+
+  /* Handle possible addition overflow.  */
+  if (__glibc_unlikely ((uintptr_t) last_byte_ptr < (uintptr_t) s))
+    last_byte_ptr = (const char *) UINTPTR_MAX;
+
+  /* Compute the address of the word containing the last byte. */
+  last_word_ptr = (const uint64_t *) ((uintptr_t) last_byte_ptr & -8);
+
+  while ((bits = __insn_v1cmpeq (v, goal)) == 0)
+    {
+      if (__builtin_expect (p == last_word_ptr, 0))
+        {
+          /* We already read the last word in the array, so give up.  */
+          return NULL;
+        }
+      v = *++p;
+    }
+
+  /* We found a match, but it might be in a byte past the end
+     of the array.  */
+  ret = ((char *) p) + (CFZ (bits) >> 3);
+  return (ret <= last_byte_ptr) ? ret : NULL;
+}
+weak_alias (__memchr, memchr)
+libc_hidden_builtin_def (memchr)
diff --git a/REORG.TODO/sysdeps/tile/tilegx/memcpy.c b/REORG.TODO/sysdeps/tile/tilegx/memcpy.c
new file mode 100644
index 0000000000..c1a2a29860
--- /dev/null
+++ b/REORG.TODO/sysdeps/tile/tilegx/memcpy.c
@@ -0,0 +1,272 @@
+/* Copyright (C) 2011-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
+
+   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/>.  */
+
+#include <string.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <memcopy.h>
+#include <arch/chip.h>
+
+/* How many cache lines ahead should we prefetch? */
+#define PREFETCH_LINES_AHEAD 3
+
+void * inhibit_loop_to_libcall
+__memcpy (void *__restrict dstv, const void *__restrict srcv, size_t n)
+{
+  char *__restrict dst1 = (char *) dstv;
+  const char *__restrict src1 = (const char *) srcv;
+  const char *__restrict src1_end;
+  const char *__restrict prefetch;
+  op_t *__restrict dst8; /* 8-byte pointer to destination memory. */
+  op_t final; /* Final bytes to write to trailing word, if any */
+  long i;
+
+  if (n < 16)
+    {
+      for (; n; n--)
+        *dst1++ = *src1++;
+      return dstv;
+    }
+
+  /* Locate the end of source memory we will copy.  Don't prefetch
+     past this.  */
+  src1_end = src1 + n - 1;
+
+  /* Prefetch ahead a few cache lines, but not past the end. */
+  prefetch = src1;
+  for (i = 0; i < PREFETCH_LINES_AHEAD; i++)
+    {
+      __insn_prefetch (prefetch);
+      prefetch += CHIP_L2_LINE_SIZE ();
+      prefetch = (prefetch < src1_end) ? prefetch : src1;
+    }
+
+  /* Copy bytes until dst is word-aligned. */
+  for (; (uintptr_t) dst1 & (sizeof (op_t) - 1); n--)
+    *dst1++ = *src1++;
+
+  /* 8-byte pointer to destination memory. */
+  dst8 = (op_t *) dst1;
+
+  if (__builtin_expect ((uintptr_t) src1 & (sizeof (op_t) - 1), 0))
+    {
+      /* Misaligned copy.  Use glibc's _wordcopy_fwd_dest_aligned, but
+         inline it to avoid prologue/epilogue.  TODO: Consider
+         prefetching and using wh64 as well.  */
+      void * srci;
+      op_t a0, a1, a2, a3;
+      long int dstp = (long int) dst1;
+      long int srcp = (long int) src1;
+      long int len = n / OPSIZ;
+
+      /* Save the initial source pointer so we know the number of
+         bytes to shift for merging two unaligned results.  */
+      srci = (void *) srcp;
+
+      /* Make SRCP aligned by rounding it down to the beginning of the
+         `op_t' it points in the middle of.  */
+      srcp &= -OPSIZ;
+
+      switch (len % 4)
+	{
+	case 2:
+	  a1 = ((op_t *) srcp)[0];
+	  a2 = ((op_t *) srcp)[1];
+	  len += 2;
+	  srcp += 2 * OPSIZ;
+	  goto do1;
+	case 3:
+	  a0 = ((op_t *) srcp)[0];
+	  a1 = ((op_t *) srcp)[1];
+	  len += 1;
+	  srcp += 2 * OPSIZ;
+	  goto do2;
+	case 0:
+	  if (OP_T_THRES <= 3 * OPSIZ && len == 0)
+	    return dstv;
+	  a3 = ((op_t *) srcp)[0];
+	  a0 = ((op_t *) srcp)[1];
+	  len += 0;
+	  srcp += 2 * OPSIZ;
+	  goto do3;
+	case 1:
+	  a2 = ((op_t *) srcp)[0];
+	  a3 = ((op_t *) srcp)[1];
+	  srcp += 2 * OPSIZ;
+	  len -= 1;
+	  if (OP_T_THRES <= 3 * OPSIZ && len == 0)
+	    goto do0;
+	  goto do4;			/* No-op.  */
+	}
+
+      do
+	{
+	do4:
+	  a0 = ((op_t *) srcp)[0];
+	  a2 = __insn_dblalign (a2, a3, srci);
+	  ((op_t *) dstp)[0] = a2;
+	  srcp += OPSIZ;
+	  dstp += OPSIZ;
+	do3:
+	  a1 = ((op_t *) srcp)[0];
+	  a3 = __insn_dblalign (a3, a0, srci);
+	  ((op_t *) dstp)[0] = a3;
+	  srcp += OPSIZ;
+	  dstp += OPSIZ;
+	do2:
+	  a2 = ((op_t *) srcp)[0];
+	  a0 = __insn_dblalign (a0, a1, srci);
+	  ((op_t *) dstp)[0] = a0;
+	  srcp += OPSIZ;
+	  dstp += OPSIZ;
+	do1:
+	  a3 = ((op_t *) srcp)[0];
+	  a1 = __insn_dblalign (a1, a2, srci);
+	  ((op_t *) dstp)[0] = a1;
+	  srcp += OPSIZ;
+	  dstp += OPSIZ;
+	  len -= 4;
+	}
+      while (len != 0);
+
+      /* This is the right position for do0.  Please don't move
+         it into the loop.  */
+    do0:
+      ((op_t *) dstp)[0] = __insn_dblalign (a2, a3, srci);
+
+      n = n % OPSIZ;
+      if (n == 0)
+	return dstv;
+
+      a0 = ((const char *) srcp <= src1_end) ? ((op_t *) srcp)[0] : 0;
+
+      final = __insn_dblalign (a3, a0, srci);
+      dst8 = (op_t *)(dstp + OPSIZ);
+    }
+  else
+    {
+      /* Aligned copy. */
+
+      const op_t *__restrict src8 = (const op_t *) src1;
+
+      /* src8 and dst8 are both word-aligned. */
+      if (n >= CHIP_L2_LINE_SIZE ())
+        {
+          /* Copy until 'dst' is cache-line-aligned. */
+          for (; (uintptr_t) dst8 & (CHIP_L2_LINE_SIZE () - 1);
+               n -= sizeof (op_t))
+            *dst8++ = *src8++;
+
+          for (; n >= CHIP_L2_LINE_SIZE ();)
+	    {
+	      op_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+
+	      /* Prefetch and advance to next line to prefetch, but
+		 don't go past the end.  */
+	      __insn_prefetch (prefetch);
+	      prefetch += CHIP_L2_LINE_SIZE ();
+	      prefetch = (prefetch < src1_end) ? prefetch :
+		(const char *) src8;
+
+	      /* Do all the loads before wh64.  This is necessary if
+		 [src8, src8+7] and [dst8, dst8+7] share the same
+		 cache line and dst8 <= src8, as can be the case when
+		 called from memmove, or with code tested on x86 whose
+		 memcpy always works with forward copies.  */
+	      tmp0 = *src8++;
+	      tmp1 = *src8++;
+	      tmp2 = *src8++;
+	      tmp3 = *src8++;
+	      tmp4 = *src8++;
+	      tmp5 = *src8++;
+	      tmp6 = *src8++;
+	      tmp7 = *src8++;
+
+	      __insn_wh64 (dst8);
+
+	      *dst8++ = tmp0;
+	      *dst8++ = tmp1;
+	      *dst8++ = tmp2;
+	      *dst8++ = tmp3;
+	      *dst8++ = tmp4;
+	      *dst8++ = tmp5;
+	      *dst8++ = tmp6;
+	      *dst8++ = tmp7;
+
+	      n -= 64;
+	    }
+#if CHIP_L2_LINE_SIZE() != 64
+# error "Fix code that assumes particular L2 cache line size."
+#endif
+        }
+
+      for (; n >= sizeof (op_t); n -= sizeof (op_t))
+        *dst8++ = *src8++;
+
+      if (__builtin_expect (n == 0, 1))
+        return dstv;
+
+      final = *src8;
+    }
+
+  /* n != 0 if we get here.  Write out any trailing bytes. */
+  dst1 = (char *) dst8;
+#ifndef __BIG_ENDIAN__
+  if (n & 4)
+    {
+      *(uint32_t *) dst1 = final;
+      dst1 += 4;
+      final >>= 32;
+      n &= 3;
+    }
+  if (n & 2)
+    {
+      *(uint16_t *) dst1 = final;
+      dst1 += 2;
+      final >>= 16;
+      n &= 1;
+    }
+  if (n)
+    *(uint8_t *) dst1 = final;
+#else
+  if (n & 4)
+    {
+      *(uint32_t *) dst1 = final >> 32;
+      dst1 += 4;
+    }
+  else
+    {
+      final >>= 32;
+    }
+  if (n & 2)
+    {
+      *(uint16_t *) dst1 = final >> 16;
+      dst1 += 2;
+    }
+  else
+    {
+      final >>= 16;
+    }
+  if (n & 1)
+    *(uint8_t *) dst1 = final >> 8;
+#endif
+
+  return dstv;
+}
+weak_alias (__memcpy, memcpy)
+libc_hidden_builtin_def (memcpy)
diff --git a/REORG.TODO/sysdeps/tile/tilegx/memset.c b/REORG.TODO/sysdeps/tile/tilegx/memset.c
new file mode 100644
index 0000000000..c6804a9dc6
--- /dev/null
+++ b/REORG.TODO/sysdeps/tile/tilegx/memset.c
@@ -0,0 +1,151 @@
+/* Copyright (C) 2011-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
+
+   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/>.  */
+
+#include <arch/chip.h>
+#include <string.h>
+#include <stdint.h>
+#include "string-endian.h"
+
+void * inhibit_loop_to_libcall
+__memset (void *s, int c, size_t n)
+{
+  uint64_t *out64;
+  int n64, to_align64;
+  uint64_t v64;
+  uint8_t *out8 = s;
+
+  /* Experimentation shows that a trivial tight loop is a win up until
+     around a size of 20, where writing a word at a time starts to win.  */
+#define BYTE_CUTOFF 20
+
+#if BYTE_CUTOFF < 7
+  /* This must be at least at least this big, or some code later
+     on doesn't work.  */
+# error "BYTE_CUTOFF is too small."
+#endif
+
+  if (n < BYTE_CUTOFF)
+    {
+      /* Strangely, this turns out to be the tightest way to write
+         this loop.  */
+      if (n != 0)
+        {
+          do
+            {
+              /* Strangely, combining these into one line performs worse.  */
+              *out8 = c;
+              out8++;
+            }
+          while (--n != 0);
+        }
+
+      return s;
+    }
+
+  /* Align 'out8'. We know n >= 7 so this won't write past the end.  */
+  while (((uintptr_t) out8 & 7) != 0)
+    {
+      *out8++ = c;
+      --n;
+    }
+
+  /* Align 'n'. */
+  while (n & 7)
+    out8[--n] = c;
+
+  out64 = (uint64_t *) out8;
+  n64 = n >> 3;
+
+  /* Tile input byte out to 64 bits. */
+  v64 = copy_byte(c);
+
+  /* This must be at least 8 or the following loop doesn't work. */
+#define CACHE_LINE_SIZE_IN_DOUBLEWORDS (CHIP_L2_LINE_SIZE() / 8)
+
+  /* Determine how many words we need to emit before the 'out32'
+     pointer becomes aligned modulo the cache line size.  */
+  to_align64 = (-((uintptr_t) out64 >> 3)) &
+    (CACHE_LINE_SIZE_IN_DOUBLEWORDS - 1);
+
+  /* Only bother aligning and using wh64 if there is at least
+     one full cache line to process.  This check also prevents
+     overrunning the end of the buffer with alignment words.  */
+  if (to_align64 <= n64 - CACHE_LINE_SIZE_IN_DOUBLEWORDS)
+    {
+      int lines_left;
+
+      /* Align out64 mod the cache line size so we can use wh64. */
+      n64 -= to_align64;
+      for (; to_align64 != 0; to_align64--)
+        {
+          *out64 = v64;
+          out64++;
+        }
+
+      /* Use unsigned divide to turn this into a right shift. */
+      lines_left = (unsigned) n64 / CACHE_LINE_SIZE_IN_DOUBLEWORDS;
+
+      do
+        {
+          /* Only wh64 a few lines at a time, so we don't exceed the
+             maximum number of victim lines.  */
+          int x = ((lines_left < CHIP_MAX_OUTSTANDING_VICTIMS ()) ? lines_left
+                   : CHIP_MAX_OUTSTANDING_VICTIMS ());
+          uint64_t *wh = out64;
+          int i = x;
+          int j;
+
+          lines_left -= x;
+
+          do
+            {
+              __insn_wh64 (wh);
+              wh += CACHE_LINE_SIZE_IN_DOUBLEWORDS;
+            }
+          while (--i);
+
+          for (j = x * (CACHE_LINE_SIZE_IN_DOUBLEWORDS / 4); j != 0; j--)
+            {
+              *out64++ = v64;
+              *out64++ = v64;
+              *out64++ = v64;
+              *out64++ = v64;
+            }
+        }
+      while (lines_left != 0);
+
+      /* We processed all full lines above, so only this many
+         words remain to be processed.  */
+      n64 &= CACHE_LINE_SIZE_IN_DOUBLEWORDS - 1;
+    }
+
+  /* Now handle any leftover values. */
+  if (n64 != 0)
+    {
+      do
+        {
+          *out64 = v64;
+          out64++;
+        }
+      while (--n64 != 0);
+    }
+
+  return s;
+}
+weak_alias (__memset, memset)
+libc_hidden_builtin_def (memset)
diff --git a/REORG.TODO/sysdeps/tile/tilegx/memusage.h b/REORG.TODO/sysdeps/tile/tilegx/memusage.h
new file mode 100644
index 0000000000..c91371adcd
--- /dev/null
+++ b/REORG.TODO/sysdeps/tile/tilegx/memusage.h
@@ -0,0 +1,31 @@
+/* Copyright (C) 2011-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
+
+   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/>.  */
+
+#include <stdint.h>
+#include <arch/spr_def.h>
+
+#define GETSP() ({ register uintptr_t stack_ptr asm ("sp"); stack_ptr; })
+
+#define GETTIME(low,high)                       \
+  {                                             \
+    uint64_t cycles = __insn_mfspr (SPR_CYCLE); \
+    low = cycles & 0xffffffff;                  \
+    high = cycles >> 32;                        \
+  }
+
+#include <sysdeps/generic/memusage.h>
diff --git a/REORG.TODO/sysdeps/tile/tilegx/rawmemchr.c b/REORG.TODO/sysdeps/tile/tilegx/rawmemchr.c
new file mode 100644
index 0000000000..54b4a5c1b8
--- /dev/null
+++ b/REORG.TODO/sysdeps/tile/tilegx/rawmemchr.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 2011-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
+
+   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/>.  */
+
+#include <string.h>
+#include <stdint.h>
+#include "string-endian.h"
+
+void *
+__rawmemchr (const void *s, int c)
+{
+  /* Get an aligned pointer. */
+  const uintptr_t s_int = (uintptr_t) s;
+  const uint64_t *p = (const uint64_t *) (s_int & -8);
+
+  /* Create eight copies of the byte for which we are looking. */
+  const uint64_t goal = copy_byte(c);
+
+  /* Read the first word, but munge it so that bytes before the array
+     will not match goal.  */
+  const uint64_t before_mask = MASK (s_int);
+  uint64_t v = (*p | before_mask) ^ (goal & before_mask);
+
+  uint64_t bits;
+  while ((bits = __insn_v1cmpeq (v, goal)) == 0)
+    v = *++p;
+
+  return ((char *) p) + (CFZ (bits) >> 3);
+}
+libc_hidden_def (__rawmemchr)
+weak_alias (__rawmemchr, rawmemchr)
diff --git a/REORG.TODO/sysdeps/tile/tilegx/strcasestr.c b/REORG.TODO/sysdeps/tile/tilegx/strcasestr.c
new file mode 100644
index 0000000000..ecb3e623ca
--- /dev/null
+++ b/REORG.TODO/sysdeps/tile/tilegx/strcasestr.c
@@ -0,0 +1,53 @@
+/* Return the offset of one string within another.
+   Copyright (C) 1994-2017 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 HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+/* Specification.  */
+#include <string.h>
+
+#include <ctype.h>
+#include <stdbool.h>
+#include <strings.h>
+
+#define USE_AS_STRCASESTR
+#define STRSTR __strcasestr
+#define STRSTR2 strcasestr2
+#define STRCHR strcasechr
+#define STRSTR_SCAN strcasestr_scan
+
+#undef strcasestr
+#undef __strcasestr
+
+#ifndef STRCASESTR
+#define STRCASESTR __strcasestr
+#endif
+
+#define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch))
+
+#define CANON_ELEMENT(c) TOLOWER (c)
+#define CMP_FUNC(p1, p2, l)				\
+  __strncasecmp ((const char *) (p1), (const char *) (p2), l)
+
+#include "strstr.c"
+
+#ifndef NO_ALIAS
+weak_alias (__strcasestr, strcasestr)
+#endif
diff --git a/REORG.TODO/sysdeps/tile/tilegx/strchr.c b/REORG.TODO/sysdeps/tile/tilegx/strchr.c
new file mode 100644
index 0000000000..36dfd31391
--- /dev/null
+++ b/REORG.TODO/sysdeps/tile/tilegx/strchr.c
@@ -0,0 +1,67 @@
+/* Copyright (C) 2011-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
+
+   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/>.  */
+
+#include <string.h>
+#include <stdint.h>
+#include "string-endian.h"
+
+#undef strchr
+
+char *
+strchr (const char *s, int c)
+{
+  int z, g;
+
+  /* Get an aligned pointer. */
+  const uintptr_t s_int = (uintptr_t) s;
+  const uint64_t *p = (const uint64_t *) (s_int & -8);
+
+  /* Create eight copies of the byte for which we are looking. */
+  const uint64_t goal = copy_byte(c);
+
+  /* Read the first aligned word, but force bytes before the string to
+     match neither zero nor goal (we make sure the high bit of each byte
+     is 1, and the low 7 bits are all the opposite of the goal byte).  */
+  const uint64_t before_mask = MASK (s_int);
+  uint64_t v = (*p | before_mask) ^ (goal & __insn_v1shrui (before_mask, 1));
+
+  uint64_t zero_matches, goal_matches;
+  while (1)
+    {
+      /* Look for a terminating '\0'. */
+      zero_matches = __insn_v1cmpeqi (v, 0);
+
+      /* Look for the goal byte. */
+      goal_matches = __insn_v1cmpeq (v, goal);
+
+      if (__builtin_expect ((zero_matches | goal_matches) != 0, 0))
+        break;
+
+      v = *++p;
+    }
+
+  z = CFZ (zero_matches);
+  g = CFZ (goal_matches);
+
+  /* If we found c before '\0' we got a match. Note that if c == '\0'
+     then g == z, and we correctly return the address of the '\0'
+     rather than NULL.  */
+  return (g <= z) ? ((char *) p) + (g >> 3) : NULL;
+}
+weak_alias (strchr, index)
+libc_hidden_builtin_def (strchr)
diff --git a/REORG.TODO/sysdeps/tile/tilegx/strchrnul.c b/REORG.TODO/sysdeps/tile/tilegx/strchrnul.c
new file mode 100644
index 0000000000..e0f13b684e
--- /dev/null
+++ b/REORG.TODO/sysdeps/tile/tilegx/strchrnul.c
@@ -0,0 +1,64 @@
+/* Copyright (C) 2011-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
+
+   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/>.  */
+
+#include <string.h>
+#include <stdint.h>
+#include "string-endian.h"
+
+char *
+__strchrnul (const char *s, int c)
+{
+  int z, g;
+
+  /* Get an aligned pointer. */
+  const uintptr_t s_int = (uintptr_t) s;
+  const uint64_t *p = (const uint64_t *) (s_int & -8);
+
+  /* Create eight copies of the byte for which we are looking. */
+  const uint64_t goal = copy_byte(c);
+
+  /* Read the first aligned word, but force bytes before the string to
+     match neither zero nor goal (we make sure the high bit of each byte
+     is 1, and the low 7 bits are all the opposite of the goal byte).  */
+  const uint64_t before_mask = MASK (s_int);
+  uint64_t v = (*p | before_mask) ^ (goal & __insn_v1shrui (before_mask, 1));
+
+  uint64_t zero_matches, goal_matches;
+  while (1)
+    {
+      /* Look for a terminating '\0'. */
+      zero_matches = __insn_v1cmpeqi (v, 0);
+
+      /* Look for the goal byte. */
+      goal_matches = __insn_v1cmpeq (v, goal);
+
+      if (__builtin_expect ((zero_matches | goal_matches) != 0, 0))
+        break;
+
+      v = *++p;
+    }
+
+  z = CFZ (zero_matches);
+  g = CFZ (goal_matches);
+
+  /* Return a pointer to the NUL or goal, whichever is first. */
+  if (z < g)
+    g = z;
+  return ((char *) p) + (g >> 3);
+}
+weak_alias (__strchrnul, strchrnul)
diff --git a/REORG.TODO/sysdeps/tile/tilegx/string-endian.h b/REORG.TODO/sysdeps/tile/tilegx/string-endian.h
new file mode 100644
index 0000000000..fe9b073efb
--- /dev/null
+++ b/REORG.TODO/sysdeps/tile/tilegx/string-endian.h
@@ -0,0 +1,58 @@
+/* Copyright (C) 2011-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
+
+   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/>.  */
+
+#include <endian.h>
+#include <stdint.h>
+
+/* Provide a set of macros to help keep endianness #ifdefs out of
+   the string functions.
+
+   MASK: Provide a mask based on the pointer alignment that
+   sets up non-zero bytes before the beginning of the string.
+   The MASK expression works because shift counts are taken mod 64.
+
+   NULMASK: Clear bytes beyond a given point in the string.
+
+   CFZ: Find the first zero bit in the 8 string bytes in a long.
+
+   REVCZ: Find the last zero bit in the 8 string bytes in a long.
+
+   STRSHIFT: Shift N bits towards the start of the string.  */
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define MASK(x) (__insn_shl(1ULL, (x << 3)) - 1)
+#define NULMASK(x) ((2ULL << x) - 1)
+#define CFZ(x) __insn_ctz(x)
+#define REVCZ(x) __insn_clz(x)
+#define STRSHIFT(x,n) ((x) >> n)
+#else
+#define MASK(x) (__insn_shl(-2LL, ((-x << 3) - 1)))
+#define NULMASK(x) (-2LL << (63 - x))
+#define CFZ(x) __insn_clz(x)
+#define REVCZ(x) __insn_ctz(x)
+#define STRSHIFT(x,n) ((x) << n)
+#endif
+
+/* Create eight copies of the byte in a uint64_t.  Byte Shuffle uses
+   the bytes of srcB as the index into the dest vector to select a
+   byte.  With all indices of zero, the first byte is copied into all
+   the other bytes.  */
+static inline uint64_t copy_byte(uint8_t byte)
+{
+  return __insn_shufflebytes(byte, 0, 0);
+}
diff --git a/REORG.TODO/sysdeps/tile/tilegx/strlen.c b/REORG.TODO/sysdeps/tile/tilegx/strlen.c
new file mode 100644
index 0000000000..5cd04acc59
--- /dev/null
+++ b/REORG.TODO/sysdeps/tile/tilegx/strlen.c
@@ -0,0 +1,39 @@
+/* Copyright (C) 2011-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
+
+   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/>.  */
+
+#include <string.h>
+#include <stdint.h>
+#include "string-endian.h"
+
+size_t
+strlen (const char *s)
+{
+  /* Get an aligned pointer. */
+  const uintptr_t s_int = (uintptr_t) s;
+  const uint64_t *p = (const uint64_t *) (s_int & -8);
+
+  /* Read and MASK the first word. */
+  uint64_t v = *p | MASK (s_int);
+
+  uint64_t bits;
+  while ((bits = __insn_v1cmpeqi (v, 0)) == 0)
+    v = *++p;
+
+  return ((const char *) p) + (CFZ (bits) >> 3) - s;
+}
+libc_hidden_builtin_def (strlen)
diff --git a/REORG.TODO/sysdeps/tile/tilegx/strnlen.c b/REORG.TODO/sysdeps/tile/tilegx/strnlen.c
new file mode 100644
index 0000000000..5d73a14926
--- /dev/null
+++ b/REORG.TODO/sysdeps/tile/tilegx/strnlen.c
@@ -0,0 +1,57 @@
+/* Copyright (C) 2013-2017 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/>.  */
+
+#include <string.h>
+#include <stdint.h>
+#include "string-endian.h"
+
+/* Find the length of S, but scan at most MAXLEN characters.  If no
+   '\0' terminator is found in that many characters, return MAXLEN.  */
+size_t
+__strnlen (const char *s, size_t maxlen)
+{
+  /* When maxlen is 0, can't read any bytes or it might cause a page fault.  */
+  if (maxlen == 0)
+    return 0;
+
+  /* Get an aligned pointer. */
+  const uintptr_t s_int = (uintptr_t) s;
+  const uint64_t *p = (const uint64_t *) (s_int & -8);
+  size_t bytes_read = sizeof (*p) - (s_int & (sizeof (*p) - 1));
+
+  /* Read and MASK the first word. */
+  uint64_t v = *p | MASK (s_int);
+
+  uint64_t bits;
+  while ((bits = __insn_v1cmpeqi (v, 0)) == 0)
+    {
+      if (bytes_read >= maxlen)
+	{
+	  /* Read maxlen bytes and didn't find the terminator. */
+	  return maxlen;
+	}
+      v = *++p;
+      bytes_read += sizeof (v);
+    }
+
+  /* Found '\0', check it is not larger than maxlen */
+  size_t len = ((const char *) p) + (CFZ (bits) >> 3) - s;
+  return (len < maxlen ? len : maxlen);
+}
+libc_hidden_def (__strnlen)
+weak_alias (__strnlen, strnlen)
+libc_hidden_def (strnlen)
diff --git a/REORG.TODO/sysdeps/tile/tilegx/strrchr.c b/REORG.TODO/sysdeps/tile/tilegx/strrchr.c
new file mode 100644
index 0000000000..5a9049e1b9
--- /dev/null
+++ b/REORG.TODO/sysdeps/tile/tilegx/strrchr.c
@@ -0,0 +1,68 @@
+/* Copyright (C) 2011-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
+
+   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/>.  */
+
+#include <string.h>
+#include <stdint.h>
+#include "string-endian.h"
+
+char *
+strrchr (const char *s, int c)
+{
+  /* Get an aligned pointer. */
+  const uintptr_t s_int = (uintptr_t) s;
+  const uint64_t *p = (const uint64_t *) (s_int & -8);
+
+  /* Create eight copies of the byte for which we are looking. */
+  const uint64_t goal = copy_byte(c);
+
+  /* Read the first aligned word, but force bytes before the string to
+     match neither zero nor goal (we make sure the high bit of each byte
+     is 1, and the low 7 bits are all the opposite of the goal byte).  */
+  const uint64_t before_mask = MASK (s_int);
+  uint64_t v = (*p | before_mask) ^ (goal & __insn_v1shrui (before_mask, 1));
+  const char *found = NULL;
+  uint64_t zero_matches, goal_matches;
+  while (1)
+    {
+      /* Look for a terminating '\0'. */
+      zero_matches = __insn_v1cmpeqi (v, 0);
+
+      /* Look for the goal byte. */
+      goal_matches = __insn_v1cmpeq (v, goal);
+
+      /* If we found the goal, record the last offset. */
+      if (__builtin_expect (goal_matches != 0, 0))
+        {
+          if (__builtin_expect (zero_matches != 0, 0))
+            {
+              /* Clear any goal after the first zero. */
+              int first_nul = CFZ (zero_matches);
+              goal_matches &= NULMASK (first_nul);
+            }
+          if (__builtin_expect (goal_matches != 0, 1))
+            found = ((char *) p) + 7 - (REVCZ (goal_matches) >> 3);
+        }
+
+      if (__builtin_expect (zero_matches != 0, 0))
+        return (char *) found;
+
+      v = *++p;
+    }
+}
+weak_alias (strrchr, rindex)
+libc_hidden_builtin_def (strrchr)
diff --git a/REORG.TODO/sysdeps/tile/tilegx/strstr.c b/REORG.TODO/sysdeps/tile/tilegx/strstr.c
new file mode 100644
index 0000000000..548a92045d
--- /dev/null
+++ b/REORG.TODO/sysdeps/tile/tilegx/strstr.c
@@ -0,0 +1,270 @@
+/* Copyright (C) 2013-2017 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.  */
+
+/* Specification of strstr.  */
+#include <string.h>
+
+#include <stdbool.h>
+#include "string-endian.h"
+
+#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"
+typeof(two_way_short_needle) two_way_short_needle __attribute__((unused));
+
+#undef strstr
+
+#ifndef STRSTR
+#define STRSTR strstr
+#endif
+
+#ifndef STRSTR2
+#define STRSTR2 strstr2
+#endif
+
+#ifndef STRCHR
+#define STRCHR strchr
+#endif
+
+#ifndef STRSTR_SCAN
+#define STRSTR_SCAN strstr_scan
+#endif
+
+#ifndef TOLOWER
+# define TOLOWER(Ch) (Ch)
+#endif
+
+#ifdef USE_AS_STRCASESTR
+
+static uint64_t
+vec_tolower (uint64_t cc)
+{
+  /* For Uppercases letters, add 32 to convert to lower case.  */
+  uint64_t less_than_eq_Z = __insn_v1cmpltui (cc, 'Z' + 1);
+  uint64_t less_than_A =  __insn_v1cmpltui (cc, 'A');
+  uint64_t is_upper = __insn_v1cmpne (less_than_eq_Z, less_than_A);
+  return __insn_v1add (cc,__insn_v1shli (is_upper, 5));
+}
+
+/* There is no strcasechr() defined, but needed for 1 byte case
+   of strcasestr(), so create it here.  */
+
+static char *
+strcasechr (const char *s, int c)
+{
+  int z, g;
+
+  c = tolower (c);
+
+  /* Get an aligned pointer.  */
+  const uintptr_t s_int = (uintptr_t) s;
+  const uint64_t *p = (const uint64_t *) (s_int & -8);
+
+  /* Create eight copies of the byte for which we are looking.  */
+  const uint64_t goal = copy_byte(c);
+
+  /* Read the first aligned word, but force bytes before the string to
+     match neither zero nor goal (we make sure the high bit of each byte
+     is 1, and the low 7 bits are all the opposite of the goal byte).  */
+  const uint64_t before_mask = MASK (s_int);
+  uint64_t v =
+    (vec_tolower (*p) | before_mask) ^ (goal & __insn_v1shrui (before_mask, 1));
+
+  uint64_t zero_matches, goal_matches;
+  while (1)
+    {
+      /* Look for a terminating '\0'.  */
+      zero_matches = __insn_v1cmpeqi (v, 0);
+
+      /* Look for the goal byte.  */
+      goal_matches = __insn_v1cmpeq (v, goal);
+
+      if (__builtin_expect ((zero_matches | goal_matches) != 0, 0))
+        break;
+
+      v = vec_tolower (*++p);
+    }
+
+  z = CFZ (zero_matches);
+  g = CFZ (goal_matches);
+
+  /* If we found c before '\0' we got a match. Note that if c == '\0'
+     then g == z, and we correctly return the address of the '\0'
+     rather than NULL.  */
+  return (g <= z) ? ((char *) p) + (g >> 3) : NULL;
+}
+
+# define vec_load(p) vec_tolower (*(p))
+# define STRCHR strcasechr
+# define CMP_FUNC __strncasecmp
+
+#else
+
+# define vec_load(p) (*(p))
+# define STRCHR strchr
+# define CMP_FUNC memcmp
+
+#endif
+
+
+/* Compare 2-character needle using SIMD.  */
+static char *
+STRSTR2 (const char *haystack_start, const char *needle)
+{
+  int z, g;
+
+  __insn_prefetch (haystack_start + 64);
+
+  /* Get an aligned pointer.  */
+  const uintptr_t s_int = (uintptr_t) haystack_start;
+  const uint64_t *p = (const uint64_t *) (s_int & -8);
+
+  /* Create eight copies of the first byte for which we are looking.  */
+  const uint64_t byte1 = copy_byte (TOLOWER (*needle));
+  /* Create eight copies of the second byte for which we are looking.  */
+  const uint64_t byte2 = copy_byte (TOLOWER (*(needle + 1)));
+
+  /* Read the first aligned word, but force bytes before the string to
+     match neither zero nor goal (we make sure the high bit of each byte
+     is 1, and the low 7 bits are all the opposite of the goal byte).  */
+  const uint64_t before_mask = MASK (s_int);
+  uint64_t v =
+    (vec_load (p) | before_mask) ^ (byte1 & __insn_v1shrui (before_mask, 1));
+
+  uint64_t zero_matches, goal_matches;
+  while (1)
+    {
+      /* Look for a terminating '\0'.  */
+      zero_matches = __insn_v1cmpeqi (v, 0);
+      uint64_t byte1_matches = __insn_v1cmpeq (v, byte1);
+      if (__builtin_expect (zero_matches != 0, 0))
+	{
+	  /* This is the last vector.  Don't worry about matches
+	     crossing into the next vector.  Shift the second byte
+	     back 1 byte to align it with the first byte, then and to
+	     check for both matching.  Each vector has a 1 in the LSB
+	     of the byte if there was match.  */
+	  uint64_t byte2_matches = __insn_v1cmpeq (v, byte2);
+	  goal_matches = byte1_matches & STRSHIFT (byte2_matches, 8);
+	  break;
+	}
+      else
+	{
+	  /* This is not the last vector, so load the next vector now.
+	     And compare byte2 to the 8-bytes starting 1 byte shifted from v,
+	     which goes 1-byte into the next vector.  */
+	  uint64_t v2 = vec_load (p + 1);
+	  if (byte1_matches)
+	    {
+	      /* 8-bytes starting 1 byte into v.  */
+	      v = __insn_dblalign (v, v2, (void*)1);
+	      uint64_t byte2_matches_shifted = __insn_v1cmpeq (v, byte2);
+	      goal_matches = byte1_matches & byte2_matches_shifted;
+	      if (__builtin_expect (goal_matches != 0, 0))
+		break;
+	    }
+	  __insn_prefetch (p + 4);
+	  /* Move to next vector.  */
+	  v = v2;
+	  p++;
+	}
+    }
+
+  z = CFZ (zero_matches);
+  g = CFZ (goal_matches);
+
+  /* If we found the match before '\0' we got a true match. Note that
+     if c == '\0' then g == z, and we correctly return the address of
+     the '\0' rather than NULL.  */
+  return (g <= z) ? ((char *) p) + (g >> 3) : NULL;
+}
+
+/* Scan for NEEDLE, using the first two characters as a filter.  */
+static char *
+STRSTR_SCAN (const char *haystack, const char *needle,
+	     unsigned int needle_len)
+{
+  char *match;
+  while (1)
+    {
+      match = STRSTR2 (haystack, needle);
+      if (match == NULL)
+	return NULL;
+      /* Found first two characters of needle, check for remainder.  */
+      if (CMP_FUNC (match + 2, needle + 2, needle_len - 2) == 0)
+	return match;
+      /* Move past the previous match. Could be +2 instead of +1 if
+         first two characters are different, but that tested slower.  */
+      haystack = match + 1;
+    }
+}
+
+/* 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)
+{
+  const char *haystack = haystack_start;
+  const char *needle = needle_start;
+  __insn_prefetch (haystack);
+  size_t needle_len = strlen (needle_start); /* Length of NEEDLE.  */
+  size_t haystack_len; /* Known minimum length of HAYSTACK.  */
+
+  if (needle_len <= 2)
+    {
+      if (needle_len == 1)
+	return STRCHR (haystack_start, *needle_start);
+      if (needle_len == 0)
+	return (char *) haystack_start;
+      else
+	return STRSTR2 (haystack_start, needle_start);
+    }
+
+  /* Fail if NEEDLE is longer than HAYSTACK.  */
+  if (__strnlen (haystack, needle_len) < needle_len)
+    return NULL;
+
+  /* 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 < 40)
+    return STRSTR_SCAN (haystack_start, needle_start, needle_len);
+  else
+    {
+      /* Reduce the size of haystack using STRSTR2, since it has a smaller
+	 linear coefficient than the Two-Way algorithm.  */
+      haystack = STRSTR2 (haystack_start, needle_start);
+      if (haystack == NULL)
+	return NULL;
+      needle = needle_start;
+      haystack_len = (haystack > haystack_start + needle_len ? 1
+		      : needle_len + haystack_start - haystack);
+
+      return two_way_long_needle ((const unsigned char *) haystack,
+				  haystack_len,
+				  (const unsigned char *) needle, needle_len);
+    }
+}
+#ifndef USE_AS_STRCASESTR
+libc_hidden_builtin_def (STRSTR)
+#endif
+
+#undef LONG_NEEDLE_THRESHOLD
diff --git a/REORG.TODO/sysdeps/tile/tilegx/tilegx32/Implies b/REORG.TODO/sysdeps/tile/tilegx/tilegx32/Implies
new file mode 100644
index 0000000000..993b7f4cd1
--- /dev/null
+++ b/REORG.TODO/sysdeps/tile/tilegx/tilegx32/Implies
@@ -0,0 +1,3 @@
+tile/tilegx
+tile
+wordsize-32
diff --git a/REORG.TODO/sysdeps/tile/tilegx/tilegx64/Implies b/REORG.TODO/sysdeps/tile/tilegx/tilegx64/Implies
new file mode 100644
index 0000000000..eb0686e0e6
--- /dev/null
+++ b/REORG.TODO/sysdeps/tile/tilegx/tilegx64/Implies
@@ -0,0 +1,3 @@
+tile/tilegx
+tile
+wordsize-64