Add a port to Linux/TileGx.  Zhi-Gang Liu (zliu@tilera.com)
Valgrind aspects, to match vex r3124.

See bug 339778 - Linux/TileGx platform support to Valgrind



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15080 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/Makefile.all.am b/Makefile.all.am
index 860ef90..282c791 100644
--- a/Makefile.all.am
+++ b/Makefile.all.am
@@ -234,6 +234,9 @@
 				$(AM_CFLAGS_PSO_BASE)
 AM_CCASFLAGS_MIPS64_LINUX  = @FLAG_M64@ -g @FLAG_MIPS64@
 
+AM_CFLAGS_TILEGX_LINUX     = @FLAG_M64@ $(AM_CFLAGS_BASE)
+AM_CFLAGS_PSO_TILEGX_LINUX = @FLAG_M64@ $(AM_CFLAGS_BASE) $(AM_CFLAGS_PSO_BASE)
+
 # Flags for the primary target.  These must be used to build the
 # regtests and performance tests.  In fact, these must be used to
 # build anything which is built only once on a dual-arch build.
@@ -274,4 +277,5 @@
 PRELOAD_LDFLAGS_S390X_LINUX    = $(PRELOAD_LDFLAGS_COMMON_LINUX) @FLAG_M64@
 PRELOAD_LDFLAGS_MIPS32_LINUX   = $(PRELOAD_LDFLAGS_COMMON_LINUX) @FLAG_M32@
 PRELOAD_LDFLAGS_MIPS64_LINUX   = $(PRELOAD_LDFLAGS_COMMON_LINUX) @FLAG_M64@
+PRELOAD_LDFLAGS_TILEGX_LINUX   = $(PRELOAD_LDFLAGS_COMMON_LINUX) @FLAG_M64@
 
diff --git a/Makefile.tool.am b/Makefile.tool.am
index 458d5ee..41f5c97 100644
--- a/Makefile.tool.am
+++ b/Makefile.tool.am
@@ -76,6 +76,9 @@
 	-static -nodefaultlibs -nostartfiles -u __start @FLAG_NO_BUILD_ID@ \
 	@FLAG_M64@
 
+TOOL_LDFLAGS_TILEGX_LINUX = \
+	$(TOOL_LDFLAGS_COMMON_LINUX) @FLAG_M64@
+
 # On Android we must ask for non-executable stack, not sure why.
 if VGCONF_PLATFORMS_INCLUDE_ARM_LINUX
 if VGCONF_PLATVARIANT_IS_ANDROID
@@ -132,6 +135,9 @@
 LIBREPLACEMALLOC_MIPS64_LINUX = \
 	$(top_builddir)/coregrind/libreplacemalloc_toolpreload-mips64-linux.a
 
+LIBREPLACEMALLOC_TILEGX_LINUX = \
+	$(top_builddir)/coregrind/libreplacemalloc_toolpreload-tilegx-linux.a
+
 LIBREPLACEMALLOC_LDFLAGS_X86_LINUX = \
 	-Wl,--whole-archive \
 	$(LIBREPLACEMALLOC_X86_LINUX) \
@@ -188,6 +194,11 @@
 	$(LIBREPLACEMALLOC_MIPS64_LINUX) \
 	-Wl,--no-whole-archive
 
+LIBREPLACEMALLOC_LDFLAGS_TILEGX_LINUX = \
+	-Wl,--whole-archive \
+	$(LIBREPLACEMALLOC_TILEGX_LINUX) \
+	-Wl,--no-whole-archive
+
 #----------------------------------------------------------------------------
 # General stuff
 #----------------------------------------------------------------------------
diff --git a/Makefile.vex.am b/Makefile.vex.am
index 9b9b9b5..09a8db6 100644
--- a/Makefile.vex.am
+++ b/Makefile.vex.am
@@ -26,6 +26,7 @@
 	pub/libvex_guest_s390x.h \
 	pub/libvex_guest_mips32.h \
 	pub/libvex_guest_mips64.h \
+	pub/libvex_guest_tilegx.h \
 	pub/libvex_s390x_common.h \
 	pub/libvex_ir.h \
 	pub/libvex_trc_values.h
@@ -44,6 +45,7 @@
 	priv/guest_arm64_defs.h \
 	priv/guest_s390_defs.h \
 	priv/guest_mips_defs.h \
+	priv/guest_tilegx_defs.h \
 	priv/host_generic_regs.h \
 	priv/host_generic_simd64.h \
 	priv/host_generic_simd128.h \
@@ -57,7 +59,8 @@
 	priv/host_s390_defs.h \
 	priv/s390_disasm.h \
 	priv/s390_defs.h \
-	priv/host_mips_defs.h
+	priv/host_mips_defs.h \
+	priv/tilegx_disasm.h
 
 BUILT_SOURCES = pub/libvex_guest_offsets.h
 CLEANFILES    = pub/libvex_guest_offsets.h
@@ -82,7 +85,8 @@
 			    pub/libvex_guest_arm64.h \
 			    pub/libvex_guest_s390x.h \
 			    pub/libvex_guest_mips32.h \
-			    pub/libvex_guest_mips64.h
+			    pub/libvex_guest_mips64.h \
+			    pub/libvex_guest_tilegx.h
 	rm -f auxprogs/genoffsets.s
 	$(mkdir_p) auxprogs pub
 	$(CC) $(CFLAGS_FOR_GENOFFSETS) \
@@ -137,6 +141,8 @@
 	priv/guest_s390_toIR.c \
 	priv/guest_mips_helpers.c \
 	priv/guest_mips_toIR.c \
+	priv/guest_tilegx_helpers.c \
+	priv/guest_tilegx_toIR.c \
 	priv/host_generic_regs.c \
 	priv/host_generic_simd64.c \
 	priv/host_generic_simd128.c \
@@ -157,7 +163,10 @@
 	priv/host_s390_isel.c \
 	priv/s390_disasm.c \
 	priv/host_mips_defs.c \
-	priv/host_mips_isel.c
+	priv/host_mips_isel.c \
+	priv/host_tilegx_defs.c \
+	priv/host_tilegx_isel.c \
+	priv/tilegx_disasm.c
 
 LIBVEXMULTIARCH_SOURCES = priv/multiarch_main_main.c
 
diff --git a/cachegrind/cg_arch.c b/cachegrind/cg_arch.c
index 265044e..376d79e 100644
--- a/cachegrind/cg_arch.c
+++ b/cachegrind/cg_arch.c
@@ -477,6 +477,13 @@
    *D1c = (cache_t) {  65536, 2, 64 };
    *LLc = (cache_t) { 262144, 8, 64 };
 
+#elif defined(VGA_tilegx)
+
+   // Set caches to default for Tilegx.
+   *I1c = (cache_t) { 0x8000,  2, 64 };
+   *D1c = (cache_t) { 0x8000,  2, 64 };
+   *LLc = (cache_t) { 0x40000, 8, 64 };
+
 #else
 
 #error "Unknown arch"
diff --git a/cachegrind/cg_branchpred.c b/cachegrind/cg_branchpred.c
index 9ee5c62..396bde1 100644
--- a/cachegrind/cg_branchpred.c
+++ b/cachegrind/cg_branchpred.c
@@ -51,6 +51,8 @@
 #  define N_IADDR_LO_ZERO_BITS 0
 #elif defined(VGA_s390x) || defined(VGA_arm)
 #  define N_IADDR_LO_ZERO_BITS 1
+#elif defined(VGA_tilegx)
+#  define N_IADDR_LO_ZERO_BITS 3
 #else
 #  error "Unsupported architecture"
 #endif
diff --git a/configure.ac b/configure.ac
index a9d2310..9de9217 100644
--- a/configure.ac
+++ b/configure.ac
@@ -268,6 +268,12 @@
         AC_MSG_RESULT([ok (${host_cpu})])
         ARCH_MAX="mips64"
         ;;
+
+     tilegx)
+        AC_MSG_RESULT([ok (${host_cpu})])
+        ARCH_MAX="tilegx"
+        ;;
+
      *) 
 	AC_MSG_RESULT([no (${host_cpu})])
 	AC_MSG_ERROR([Unsupported host architecture. Sorry])
@@ -690,6 +696,17 @@
         valt_load_address_sec_inner="0xUNSET"
         AC_MSG_RESULT([ok (${ARCH_MAX}-${VGCONF_OS})])
         ;;
+     tilegx-linux)
+        VGCONF_ARCH_PRI="tilegx"
+        VGCONF_ARCH_SEC=""
+        VGCONF_PLATFORM_PRI_CAPS="TILEGX_LINUX"
+        VGCONF_PLATFORM_SEC_CAPS=""
+        valt_load_address_pri_norml="0x38000000"
+        valt_load_address_pri_inner="0x28000000"
+        valt_load_address_sec_norml="0xUNSET"
+        valt_load_address_sec_inner="0xUNSET"
+        AC_MSG_RESULT([ok (${ARCH_MAX}-${VGCONF_OS})])
+        ;;
     *)
         VGCONF_ARCH_PRI="unknown"
         VGCONF_ARCH_SEC="unknown"
@@ -733,6 +750,8 @@
                test x$VGCONF_PLATFORM_PRI_CAPS = xMIPS32_LINUX )
 AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_MIPS64,
                test x$VGCONF_PLATFORM_PRI_CAPS = xMIPS64_LINUX ) 
+AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_TILEGX,
+               test x$VGCONF_PLATFORM_PRI_CAPS = xTILEGX_LINUX )
 
 # Set up VGCONF_PLATFORMS_INCLUDE_<platform>.  Either one or two of these
 # become defined.
@@ -760,6 +779,8 @@
                test x$VGCONF_PLATFORM_PRI_CAPS = xMIPS32_LINUX)
 AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_MIPS64_LINUX,
                test x$VGCONF_PLATFORM_PRI_CAPS = xMIPS64_LINUX)
+AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_TILEGX_LINUX,
+               test x$VGCONF_PLATFORM_PRI_CAPS = xTILEGX_LINUX)
 AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_X86_DARWIN,   
                test x$VGCONF_PLATFORM_PRI_CAPS = xX86_DARWIN \
                  -o x$VGCONF_PLATFORM_SEC_CAPS = xX86_DARWIN)
@@ -780,7 +801,8 @@
                  -o x$VGCONF_PLATFORM_PRI_CAPS = xARM64_LINUX \
                  -o x$VGCONF_PLATFORM_PRI_CAPS = xS390X_LINUX \
                  -o x$VGCONF_PLATFORM_PRI_CAPS = xMIPS32_LINUX \
-                 -o x$VGCONF_PLATFORM_PRI_CAPS = xMIPS64_LINUX)
+                 -o x$VGCONF_PLATFORM_PRI_CAPS = xMIPS64_LINUX \
+                 -o x$VGCONF_PLATFORM_PRI_CAPS = xTILEGX_LINUX)
 AM_CONDITIONAL(VGCONF_OS_IS_DARWIN,
                test x$VGCONF_PLATFORM_PRI_CAPS = xX86_DARWIN \
                  -o x$VGCONF_PLATFORM_PRI_CAPS = xAMD64_DARWIN)
@@ -3008,6 +3030,7 @@
    none/tests/s390x/Makefile
    none/tests/mips32/Makefile
    none/tests/mips64/Makefile
+   none/tests/tilegx/Makefile
    none/tests/linux/Makefile
    none/tests/darwin/Makefile
    none/tests/x86-linux/Makefile
diff --git a/coregrind/Makefile.am b/coregrind/Makefile.am
index 1532b53..e62d774 100644
--- a/coregrind/Makefile.am
+++ b/coregrind/Makefile.am
@@ -343,6 +343,7 @@
 	m_dispatch/dispatch-s390x-linux.S \
 	m_dispatch/dispatch-mips32-linux.S \
 	m_dispatch/dispatch-mips64-linux.S \
+	m_dispatch/dispatch-tilegx-linux.S \
 	m_dispatch/dispatch-x86-darwin.S \
 	m_dispatch/dispatch-amd64-darwin.S \
 	m_gdbserver/inferiors.c \
@@ -362,6 +363,7 @@
 	m_gdbserver/valgrind-low-s390x.c \
 	m_gdbserver/valgrind-low-mips32.c \
 	m_gdbserver/valgrind-low-mips64.c \
+	m_gdbserver/valgrind-low-tilegx.c \
 	m_gdbserver/version.c \
 	m_initimg/initimg-linux.c \
 	m_initimg/initimg-darwin.c \
@@ -384,6 +386,7 @@
 	m_sigframe/sigframe-s390x-linux.c \
 	m_sigframe/sigframe-mips32-linux.c \
 	m_sigframe/sigframe-mips64-linux.c \
+	m_sigframe/sigframe-tilegx-linux.c \
 	m_sigframe/sigframe-x86-darwin.c \
 	m_sigframe/sigframe-amd64-darwin.c \
 	m_syswrap/syscall-x86-linux.S \
@@ -396,6 +399,7 @@
 	m_syswrap/syscall-s390x-linux.S \
 	m_syswrap/syscall-mips32-linux.S \
 	m_syswrap/syscall-mips64-linux.S \
+	m_syswrap/syscall-tilegx-linux.S \
 	m_syswrap/syscall-x86-darwin.S \
 	m_syswrap/syscall-amd64-darwin.S \
 	m_syswrap/syswrap-main.c \
@@ -412,6 +416,7 @@
 	m_syswrap/syswrap-s390x-linux.c \
 	m_syswrap/syswrap-mips32-linux.c \
 	m_syswrap/syswrap-mips64-linux.c \
+	m_syswrap/syswrap-tilegx-linux.c \
 	m_syswrap/syswrap-x86-darwin.c \
 	m_syswrap/syswrap-amd64-darwin.c \
 	m_syswrap/syswrap-xen.c \
diff --git a/coregrind/launcher-linux.c b/coregrind/launcher-linux.c
index 53c8d83..08f38c1 100644
--- a/coregrind/launcher-linux.c
+++ b/coregrind/launcher-linux.c
@@ -65,6 +65,10 @@
 #define EM_PPC64 21  // ditto
 #endif
 
+#ifndef EM_TILEGX
+#define EM_TILEGX 191
+#endif
+
 /* Report fatal errors */
 __attribute__((noreturn))
 static void barf ( const char *format, ... )
@@ -243,6 +247,10 @@
                 (ehdr->e_ident[EI_OSABI] == ELFOSABI_SYSV ||
                  ehdr->e_ident[EI_OSABI] == ELFOSABI_LINUX)) {
                platform = "mips64-linux";
+            } else if (ehdr->e_machine == EM_TILEGX &&
+                (ehdr->e_ident[EI_OSABI] == ELFOSABI_SYSV ||
+                 ehdr->e_ident[EI_OSABI] == ELFOSABI_LINUX)) {
+               platform = "tilegx-linux";
             } else if (ehdr->e_machine == EM_AARCH64 &&
                 (ehdr->e_ident[EI_OSABI] == ELFOSABI_SYSV ||
                  ehdr->e_ident[EI_OSABI] == ELFOSABI_LINUX)) {
@@ -349,6 +357,7 @@
        (0==strcmp(VG_PLATFORM,"arm-linux"))    ||
        (0==strcmp(VG_PLATFORM,"arm64-linux"))  ||
        (0==strcmp(VG_PLATFORM,"s390x-linux"))  ||
+       (0==strcmp(VG_PLATFORM,"tilegx-linux")) ||
        (0==strcmp(VG_PLATFORM,"mips32-linux")) ||
        (0==strcmp(VG_PLATFORM,"mips64-linux")))
       default_platform = VG_PLATFORM;
diff --git a/coregrind/m_aspacemgr/aspacemgr-common.c b/coregrind/m_aspacemgr/aspacemgr-common.c
index 20a1783..21f1e0e 100644
--- a/coregrind/m_aspacemgr/aspacemgr-common.c
+++ b/coregrind/m_aspacemgr/aspacemgr-common.c
@@ -158,7 +158,8 @@
 #  elif defined(VGP_amd64_linux) \
         || defined(VGP_ppc64be_linux)  || defined(VGP_ppc64le_linux) \
         || defined(VGP_s390x_linux) || defined(VGP_mips32_linux) \
-        || defined(VGP_mips64_linux) || defined(VGP_arm64_linux)
+        || defined(VGP_mips64_linux) || defined(VGP_arm64_linux) \
+        || defined(VGP_tilegx_linux)
    res = VG_(do_syscall6)(__NR_mmap, (UWord)start, length, 
                          prot, flags, fd, offset);
 #  elif defined(VGP_x86_darwin)
@@ -245,6 +246,9 @@
    /* ARM64 wants to use __NR_openat rather than __NR_open. */
    SysRes res = VG_(do_syscall4)(__NR_openat,
                                  VKI_AT_FDCWD, (UWord)pathname, flags, mode);
+#  elif defined(VGP_tilegx_linux)
+   SysRes res = VG_(do_syscall4)(__NR_openat, AT_FDCWD, (UWord)pathname,
+                                 flags, mode);
 #  else
    SysRes res = VG_(do_syscall3)(__NR_open, (UWord)pathname, flags, mode);
 #  endif
@@ -268,6 +272,9 @@
 #  if defined(VGP_arm64_linux)
    res = VG_(do_syscall4)(__NR_readlinkat, VKI_AT_FDCWD,
                                            (UWord)path, (UWord)buf, bufsiz);
+#  elif defined(VGP_tilegx_linux)
+   res = VG_(do_syscall4)(__NR_readlinkat, AT_FDCWD, (UWord)path, (UWord)buf,
+                          bufsiz);
 #  else
    res = VG_(do_syscall3)(__NR_readlink, (UWord)path, (UWord)buf, bufsiz);
 #  endif
diff --git a/coregrind/m_cache.c b/coregrind/m_cache.c
index d208a53..811eb91 100644
--- a/coregrind/m_cache.c
+++ b/coregrind/m_cache.c
@@ -540,8 +540,8 @@
 
 #elif defined(VGA_arm) || defined(VGA_ppc32)    || \
    defined(VGA_ppc64be) || defined(VGA_ppc64le) || \
-   defined(VGA_mips32) || defined(VGA_mips64) || defined(VGA_arm64)
-
+   defined(VGA_mips32) || defined(VGA_mips64) || defined(VGA_arm64) || \
+   defined(VGA_tilegx)
 static Bool
 get_cache_info(VexArchInfo *vai)
 {
diff --git a/coregrind/m_coredump/coredump-elf.c b/coregrind/m_coredump/coredump-elf.c
index 2c59bba..f68cc1f 100644
--- a/coregrind/m_coredump/coredump-elf.c
+++ b/coregrind/m_coredump/coredump-elf.c
@@ -419,7 +419,17 @@
 #  undef DO
    regs->MIPS_hi   = arch->vex.guest_HI;
    regs->MIPS_lo   = arch->vex.guest_LO;
-
+#elif defined(VGP_tilegx_linux)
+#  define DO(n)  regs->regs[n] = arch->vex.guest_r##n
+   DO(0);  DO(1);  DO(2);  DO(3);  DO(4);  DO(5);  DO(6);  DO(7);
+   DO(8);  DO(9);  DO(10); DO(11); DO(12); DO(13); DO(14); DO(15);
+   DO(16); DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23);
+   DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31);
+   DO(32); DO(33); DO(34); DO(35); DO(36); DO(37); DO(38); DO(39);
+   DO(40); DO(41); DO(42); DO(43); DO(44); DO(45); DO(46); DO(47);
+   DO(48); DO(49); DO(50); DO(51); DO(52); DO(53); DO(54); DO(55);
+   regs->pc = arch->vex.guest_pc;
+   regs->orig_r0 =  arch->vex.guest_r0;
 #else
 #  error Unknown ELF platform
 #endif
@@ -492,7 +502,7 @@
    DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31);
 #  undef DO
 
-#elif defined(VGP_arm_linux)
+#elif defined(VGP_arm_linux) || defined(VGP_tilegx_linux)
    // umm ...
 
 #elif defined(VGP_arm64_linux)
diff --git a/coregrind/m_debugger.c b/coregrind/m_debugger.c
index 45f4243..fc7169a 100644
--- a/coregrind/m_debugger.c
+++ b/coregrind/m_debugger.c
@@ -386,6 +386,69 @@
    regs.MIPS_r31     = vex->guest_r31;
    return VG_(ptrace)(VKI_PTRACE_SETREGS, pid, NULL, &regs);
 
+#elif defined(VGP_tilegx_linux)
+   struct vki_user_regs_struct regs;
+   VG_(memset)(&regs, 0, sizeof(regs));
+   regs.TILEGX_r0     = vex->guest_r0;
+   regs.TILEGX_r1     = vex->guest_r1;
+   regs.TILEGX_r2     = vex->guest_r2;
+   regs.TILEGX_r3     = vex->guest_r3;
+   regs.TILEGX_r4     = vex->guest_r4;
+   regs.TILEGX_r5     = vex->guest_r5;
+   regs.TILEGX_r6     = vex->guest_r6;
+   regs.TILEGX_r7     = vex->guest_r7;
+   regs.TILEGX_r8     = vex->guest_r8;
+   regs.TILEGX_r9     = vex->guest_r9;
+   regs.TILEGX_r10     = vex->guest_r10;
+   regs.TILEGX_r11     = vex->guest_r11;
+   regs.TILEGX_r12     = vex->guest_r12;
+   regs.TILEGX_r13     = vex->guest_r13;
+   regs.TILEGX_r14     = vex->guest_r14;
+   regs.TILEGX_r15     = vex->guest_r15;
+   regs.TILEGX_r16     = vex->guest_r16;
+   regs.TILEGX_r17     = vex->guest_r17;
+   regs.TILEGX_r18     = vex->guest_r18;
+   regs.TILEGX_r19     = vex->guest_r19;
+   regs.TILEGX_r20     = vex->guest_r20;
+   regs.TILEGX_r21     = vex->guest_r21;
+   regs.TILEGX_r22     = vex->guest_r22;
+   regs.TILEGX_r23     = vex->guest_r23;
+   regs.TILEGX_r24     = vex->guest_r24;
+   regs.TILEGX_r25     = vex->guest_r25;
+   regs.TILEGX_r26     = vex->guest_r26;
+   regs.TILEGX_r27     = vex->guest_r27;
+   regs.TILEGX_r28     = vex->guest_r28;
+   regs.TILEGX_r29     = vex->guest_r29;
+   regs.TILEGX_r30     = vex->guest_r30;
+   regs.TILEGX_r31     = vex->guest_r31;
+   regs.TILEGX_r32     = vex->guest_r32;
+   regs.TILEGX_r33     = vex->guest_r33;
+   regs.TILEGX_r34     = vex->guest_r34;
+   regs.TILEGX_r35     = vex->guest_r35;
+   regs.TILEGX_r36     = vex->guest_r36;
+   regs.TILEGX_r37     = vex->guest_r37;
+   regs.TILEGX_r38     = vex->guest_r38;
+   regs.TILEGX_r39     = vex->guest_r39;
+   regs.TILEGX_r40     = vex->guest_r40;
+   regs.TILEGX_r41     = vex->guest_r41;
+   regs.TILEGX_r42     = vex->guest_r42;
+   regs.TILEGX_r43     = vex->guest_r43;
+   regs.TILEGX_r44     = vex->guest_r44;
+   regs.TILEGX_r45     = vex->guest_r45;
+   regs.TILEGX_r46     = vex->guest_r46;
+   regs.TILEGX_r47     = vex->guest_r47;
+   regs.TILEGX_r48     = vex->guest_r48;
+   regs.TILEGX_r49     = vex->guest_r49;
+   regs.TILEGX_r50     = vex->guest_r50;
+   regs.TILEGX_r51     = vex->guest_r51;
+   regs.TILEGX_r52     = vex->guest_r52;
+   regs.TILEGX_r53     = vex->guest_r53;
+   regs.TILEGX_r54     = vex->guest_r54;
+   regs.TILEGX_r55     = vex->guest_r55;
+   regs.TILEGX_pc     =  vex->guest_pc;
+
+   return VG_(ptrace)(VKI_PTRACE_SETREGS, pid, NULL, &regs);
+
 #else
 #  error Unknown arch
 #endif
diff --git a/coregrind/m_debuginfo/d3basics.c b/coregrind/m_debuginfo/d3basics.c
index 2f7f802..09d1b12 100644
--- a/coregrind/m_debuginfo/d3basics.c
+++ b/coregrind/m_debuginfo/d3basics.c
@@ -424,6 +424,9 @@
    if (regno == 30) { *a = regs->fp; return True; }
 #  elif defined(VGP_arm64_linux)
    if (regno == 31) { *a = regs->sp; return True; }
+#  elif defined(VGP_tilegx_linux)
+   if (regno == 52) { *a = regs->fp; return True; }
+   if (regno == 54) { *a = regs->sp; return True; }
 #  else
 #    error "Unknown platform"
 #  endif
diff --git a/coregrind/m_debuginfo/debuginfo.c b/coregrind/m_debuginfo/debuginfo.c
index 158daa7..1fcc612 100644
--- a/coregrind/m_debuginfo/debuginfo.c
+++ b/coregrind/m_debuginfo/debuginfo.c
@@ -955,6 +955,9 @@
 #  elif defined(VGP_s390x_linux)
    is_rx_map = seg->hasR && seg->hasX && !seg->hasW;
    is_rw_map = seg->hasR && seg->hasW;
+#  elif defined(VGA_tilegx)
+   is_rx_map = seg->hasR && seg->hasX; // && !seg->hasW;
+   is_rw_map = seg->hasR && seg->hasW; // && !seg->hasX;
 #  else
 #    error "Unknown platform"
 #  endif
@@ -2488,6 +2491,11 @@
                || defined(VGA_ppc64le)
 #           elif defined(VGP_arm64_linux)
             case Creg_ARM64_X30: return eec->uregs->x30;
+#           elif defined(VGA_tilegx)
+            case Creg_TILEGX_IP: return eec->uregs->pc;
+            case Creg_TILEGX_SP: return eec->uregs->sp;
+            case Creg_TILEGX_BP: return eec->uregs->fp;
+            case Creg_TILEGX_LR: return eec->uregs->lr;
 #           else
 #             error "Unsupported arch"
 #           endif
@@ -2743,6 +2751,16 @@
       case CFIC_ARM64_X29REL: 
          cfa = cfsi_m->cfa_off + uregs->x29;
          break;
+#     elif defined(VGA_tilegx)
+      case CFIC_IA_SPREL:
+         cfa = cfsi_m->cfa_off + uregs->sp;
+         break;
+      case CFIR_SAME:
+         cfa = uregs->fp;
+         break;
+      case CFIC_IA_BPREL:
+         cfa = cfsi_m->cfa_off + uregs->fp;
+         break;
 #     else
 #       error "Unsupported arch"
 #     endif
@@ -2797,7 +2815,7 @@
      return compute_cfa(&uregs,
                         min_accessible,  max_accessible, ce->di, ce->cfsi_m);
    }
-#elif defined(VGA_mips32) || defined(VGA_mips64)
+#elif defined(VGA_mips32) || defined(VGA_mips64) || defined(VGA_tilegx)
    { D3UnwindRegs uregs;
      uregs.pc = ip;
      uregs.sp = sp;
@@ -2846,6 +2864,8 @@
 #  elif defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le)
 #  elif defined(VGP_arm64_linux)
    ipHere = uregsHere->pc;
+#  elif defined(VGA_tilegx)
+   ipHere = uregsHere->pc;
 #  else
 #    error "Unknown arch"
 #  endif
@@ -2931,6 +2951,10 @@
    COMPUTE(uregsPrev.sp,  uregsHere->sp,  cfsi_m->sp_how,  cfsi_m->sp_off);
    COMPUTE(uregsPrev.x30, uregsHere->x30, cfsi_m->x30_how, cfsi_m->x30_off);
    COMPUTE(uregsPrev.x29, uregsHere->x29, cfsi_m->x29_how, cfsi_m->x29_off);
+#  elif defined(VGA_tilegx)
+   COMPUTE(uregsPrev.pc, uregsHere->pc, cfsi_m->ra_how, cfsi_m->ra_off);
+   COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi_m->sp_how, cfsi_m->sp_off);
+   COMPUTE(uregsPrev.fp, uregsHere->fp, cfsi_m->fp_how, cfsi_m->fp_off);
 #  else
 #    error "Unknown arch"
 #  endif
diff --git a/coregrind/m_debuginfo/priv_storage.h b/coregrind/m_debuginfo/priv_storage.h
index e64401c..c7278e2e 100644
--- a/coregrind/m_debuginfo/priv_storage.h
+++ b/coregrind/m_debuginfo/priv_storage.h
@@ -333,6 +333,19 @@
       Int   fp_off;
    }
    DiCfSI_m;
+#elif defined(VGA_tilegx)
+typedef
+   struct {
+      UChar cfa_how; /* a CFIC_IA value */
+      UChar ra_how;  /* a CFIR_ value */
+      UChar sp_how;  /* a CFIR_ value */
+      UChar fp_how;  /* a CFIR_ value */
+      Int   cfa_off;
+      Int   ra_off;
+      Int   sp_off;
+      Int   fp_off;
+   }
+   DiCfSI_m;
 #else
 #  error "Unknown arch"
 #endif
@@ -386,7 +399,11 @@
       Creg_S390_SP,
       Creg_S390_FP,
       Creg_S390_LR,
-      Creg_MIPS_RA
+      Creg_MIPS_RA,
+      Creg_TILEGX_IP,
+      Creg_TILEGX_SP,
+      Creg_TILEGX_BP,
+      Creg_TILEGX_LR
    }
    CfiReg;
 
diff --git a/coregrind/m_debuginfo/readdwarf.c b/coregrind/m_debuginfo/readdwarf.c
index f0b7ede..a038a52 100644
--- a/coregrind/m_debuginfo/readdwarf.c
+++ b/coregrind/m_debuginfo/readdwarf.c
@@ -1763,6 +1763,10 @@
 #  define FP_REG         30
 #  define SP_REG         29
 #  define RA_REG_DEFAULT 31
+#elif defined(VGP_tilegx_linux)
+#  define FP_REG         52
+#  define SP_REG         54
+#  define RA_REG_DEFAULT 55
 #else
 #  error "Unknown platform"
 #endif
@@ -1775,7 +1779,7 @@
      || defined(VGP_ppc64le_linux) || defined(VGP_mips32_linux) \
      || defined(VGP_mips64_linux)
 # define N_CFI_REGS 72
-#elif defined(VGP_arm_linux)
+#elif defined(VGP_arm_linux) || defined(VGP_tilegx_linux)
 # define N_CFI_REGS 320
 #elif defined(VGP_arm64_linux)
 # define N_CFI_REGS 128
@@ -2083,7 +2087,8 @@
    if (ctxs->cfa_is_regoff && ctxs->cfa_reg == SP_REG) {
       si_m->cfa_off = ctxs->cfa_off;
 #     if defined(VGA_x86) || defined(VGA_amd64) || defined(VGA_s390x) \
-         || defined(VGA_mips32) || defined(VGA_mips64)
+         || defined(VGA_mips32) || defined(VGA_mips64) \
+         || defined(VGA_tilegx)
       si_m->cfa_how = CFIC_IA_SPREL;
 #     elif defined(VGA_arm)
       si_m->cfa_how = CFIC_ARM_R13REL;
@@ -2097,7 +2102,8 @@
    if (ctxs->cfa_is_regoff && ctxs->cfa_reg == FP_REG) {
       si_m->cfa_off = ctxs->cfa_off;
 #     if defined(VGA_x86) || defined(VGA_amd64) || defined(VGA_s390x) \
-         || defined(VGA_mips32) || defined(VGA_mips64)
+         || defined(VGA_mips32) || defined(VGA_mips64) \
+         || defined(VGA_tilegx)
       si_m->cfa_how = CFIC_IA_BPREL;
 #     elif defined(VGA_arm)
       si_m->cfa_how = CFIC_ARM_R12REL;
@@ -2345,9 +2351,9 @@
    return True;
 
 #  elif defined(VGA_mips32) || defined(VGA_mips64)
- 
+
    /* --- entire tail of this fn specialised for mips --- */
- 
+
    SUMMARISE_HOW(si_m->ra_how, si_m->ra_off,
                                ctxs->reg[ctx->ra_reg] );
    SUMMARISE_HOW(si_m->fp_how, si_m->fp_off,
@@ -2386,7 +2392,48 @@
    *len  = (UInt)(ctx->loc - loc_start);
 
    return True;
+#  elif defined(VGA_tilegx)
 
+   /* --- entire tail of this fn specialised for tilegx --- */
+
+   SUMMARISE_HOW(si_m->ra_how, si_m->ra_off,
+                               ctxs->reg[ctx->ra_reg] );
+   SUMMARISE_HOW(si_m->fp_how, si_m->fp_off,
+                               ctxs->reg[FP_REG] );
+   SUMMARISE_HOW(si_m->sp_how, si_m->sp_off,
+                               ctxs->reg[SP_REG] );
+   si_m->sp_how = CFIR_CFAREL;
+   si_m->sp_off = 0;
+
+   if (si_m->fp_how == CFIR_UNKNOWN)
+       si_m->fp_how = CFIR_SAME;
+   if (si_m->cfa_how == CFIR_UNKNOWN) {
+      si_m->cfa_how = CFIC_IA_SPREL;
+      si_m->cfa_off = 160;
+   }
+   if (si_m->ra_how == CFIR_UNKNOWN) {
+      if (!debuginfo->cfsi_exprs)
+         debuginfo->cfsi_exprs = VG_(newXA)( ML_(dinfo_zalloc),
+                                             "di.ccCt.2a",
+                                             ML_(dinfo_free),
+                                             sizeof(CfiExpr) );
+      si_m->ra_how = CFIR_EXPR;
+      si_m->ra_off = ML_(CfiExpr_CfiReg)( debuginfo->cfsi_exprs,
+                                          Creg_TILEGX_LR);
+   }
+
+   if (si_m->ra_how == CFIR_SAME)
+      { why = 3; goto failed; }
+
+   if (loc_start >= ctx->loc) 
+      { why = 4; goto failed; }
+   if (ctx->loc - loc_start > 10000000 /* let's say */)
+      { why = 5; goto failed; }
+
+   *base = loc_start + ctx->initloc;
+   *len  = (UInt)(ctx->loc - loc_start);
+
+   return True;
 #  elif defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le)
    /* These don't use CFI based unwinding (is that really true?) */
 
@@ -2483,6 +2530,13 @@
          I_die_here;
 #        elif defined(VGA_ppc32) || defined(VGA_ppc64be) \
             || defined(VGA_ppc64le)
+#        elif defined(VGA_tilegx)
+         if (dwreg == SP_REG)
+            return ML_(CfiExpr_CfiReg)( dstxa, Creg_TILEGX_SP );
+         if (dwreg == FP_REG)
+            return ML_(CfiExpr_CfiReg)( dstxa, Creg_TILEGX_BP );
+         if (dwreg == srcuc->ra_reg)
+            return ML_(CfiExpr_CfiReg)( dstxa, Creg_TILEGX_IP );
 #        else
 #           error "Unknown arch"
 #        endif
diff --git a/coregrind/m_debuginfo/readelf.c b/coregrind/m_debuginfo/readelf.c
index f5c4674..fda4161 100644
--- a/coregrind/m_debuginfo/readelf.c
+++ b/coregrind/m_debuginfo/readelf.c
@@ -2161,7 +2161,7 @@
 #     if defined(VGP_x86_linux) || defined(VGP_amd64_linux) \
          || defined(VGP_arm_linux) || defined (VGP_s390x_linux) \
          || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
-         || defined(VGP_arm64_linux)
+         || defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
       /* Accept .plt where mapped as rx (code) */
       if (0 == VG_(strcmp)(name, ".plt")) {
          if (inrx && !di->plt_present) {
diff --git a/coregrind/m_debuginfo/storage.c b/coregrind/m_debuginfo/storage.c
index 663d5f7..926a13f 100644
--- a/coregrind/m_debuginfo/storage.c
+++ b/coregrind/m_debuginfo/storage.c
@@ -212,6 +212,11 @@
    SHOW_HOW(si_m->x30_how, si_m->x30_off);
    VG_(printf)(" X29=");
    SHOW_HOW(si_m->x29_how, si_m->x29_off);
+#  elif defined(VGA_tilegx)
+   VG_(printf)(" SP=");
+   SHOW_HOW(si_m->sp_how, si_m->sp_off);
+   VG_(printf)(" FP=");
+   SHOW_HOW(si_m->fp_how, si_m->fp_off);
 #  else
 #    error "Unknown arch"
 #  endif
@@ -920,6 +925,10 @@
       case Creg_S390_SP:   VG_(printf)("SP"); break;
       case Creg_S390_FP:   VG_(printf)("FP"); break;
       case Creg_S390_LR:   VG_(printf)("LR"); break;
+      case Creg_TILEGX_IP: VG_(printf)("PC");  break;
+      case Creg_TILEGX_SP: VG_(printf)("SP");  break;
+      case Creg_TILEGX_BP: VG_(printf)("BP");  break;
+      case Creg_TILEGX_LR: VG_(printf)("R55"); break;
       default: vg_assert(0);
    }
 }
diff --git a/coregrind/m_debuglog.c b/coregrind/m_debuglog.c
index 22941f2..76adccc 100644
--- a/coregrind/m_debuglog.c
+++ b/coregrind/m_debuglog.c
@@ -508,6 +508,51 @@
       : "$2" );
    return (UInt)(__res);
 }
+#elif defined(VGP_tilegx_linux)
+static UInt local_sys_write_stderr ( const HChar* buf, Int n )
+{
+   volatile Long block[2];
+   block[0] = (Long)buf;
+   block[1] = n;
+   ULong __res = 0;
+   __asm__ volatile (
+      "movei  r0,  2    \n\t"    /* stderr */
+      "move   r1,  %1   \n\t"    /* buf */
+      "move   r2,  %2   \n\t"    /* n */
+      "move   r3,  zero \n\t"
+      "moveli r10, %3   \n\t"    /* set r10 = __NR_write */
+      "swint1           \n\t"    /* write() */
+      "nop              \n\t"
+      "move   %0, r0    \n\t"    /* save return into block[0] */
+      : "=r"(__res)
+      : "r" (block[0]), "r"(block[1]), "n" (__NR_write)
+      : "r0", "r1", "r2", "r3", "r4", "r5");
+   if (__res < 0)
+      __res = -1;
+   return (UInt)__res;
+}
+
+static UInt local_sys_getpid ( void )
+{
+   UInt __res, __err;
+   __res = 0;
+   __err = 0;
+   __asm__ volatile (
+      "moveli r10, %2\n\t"    /* set r10 = __NR_getpid */
+      "swint1\n\t"            /* getpid() */
+      "nop\n\t"
+      "move  %0, r0\n"
+      "move  %1, r1\n"
+      : "=r" (__res), "=r"(__err)
+      : "n" (__NR_getpid)
+      : "r0", "r1", "r2", "r3", "r4",
+        "r5", "r6", "r7", "r8", "r9",
+        "r10", "r11", "r12", "r13", "r14",
+        "r15", "r16", "r17", "r18", "r19",
+        "r20", "r21", "r22", "r23", "r24",
+        "r25", "r26", "r27", "r28", "r29");
+  return __res;
+}
 
 #else
 # error Unknown platform
diff --git a/coregrind/m_dispatch/dispatch-tilegx-linux.S b/coregrind/m_dispatch/dispatch-tilegx-linux.S
new file mode 100644
index 0000000..3451fe5
--- /dev/null
+++ b/coregrind/m_dispatch/dispatch-tilegx-linux.S
@@ -0,0 +1,308 @@
+
+/*--------------------------------------------------------------------*/
+/*--- begin                                dispatch-tilegx-linux.S ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+  This file is part of Valgrind, a dynamic binary instrumentation
+  framework.
+
+  Copyright (C) 2010-2013  Tilera Corp.
+
+  This program is free software; you can redistribute it and/or
+  modify it under the terms of the GNU General Public License as
+  published by the Free Software Foundation; either version 2 of the
+  License, or (at your option) any later version.
+
+  This program 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
+  General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+  02111-1307, USA.
+
+  The GNU General Public License is contained in the file COPYING.
+*/
+
+/* Contributed by Zhi-Gang Liu <zliu at tilera dot com> */
+
+#if defined(VGP_tilegx_linux)
+#include "pub_core_basics_asm.h"
+#include "pub_core_dispatch_asm.h"
+#include "pub_core_transtab_asm.h"
+#include "libvex_guest_offsets.h"       /* for OFFSET_tilegx_PC */
+
+        /*------------------------------------------------------------*/
+        /*---                                                      ---*/
+        /*--- The dispatch loop.  VG_(run_innerloop) is used to    ---*/
+        /*--- run all translations except no-redir ones.           ---*/
+        /*---                                                      ---*/
+        /*------------------------------------------------------------*/
+
+        /*----------------------------------------------------*/
+        /*--- Preamble (set everything up)                 ---*/
+        /*----------------------------------------------------*/
+
+        /* signature:
+        void VG_(disp_run_translations)(UWord* two_words,
+        void*  guest_state,
+        Addr   host_addr );
+        UWord VG_(run_innerloop) ( void* guest_state, UWord do_profiling );
+        */
+
+        .text
+        .globl  VG_(disp_run_translations)
+        VG_(disp_run_translations):
+
+        /* r0 holds two_words
+           r1 holds guest_state
+           r2 holds host_addr */
+
+        /* New stack frame */
+        addli sp, sp, -256
+        addi  r29, sp, 8
+        /*
+        high memory of stack
+        216  lr
+        208  r53
+        200  r52
+        192  r51
+        ...
+        48   r33
+        40   r32
+        32   r31
+        24   r30
+        16   r1 <---
+        8    r0
+        0       <-sp
+        */
+        st_add r29, r0, 8
+        st_add r29, r1, 8
+
+        /* ... and r30 - r53 */
+        st_add  r29, r30, 8
+        st_add  r29, r31, 8
+        st_add  r29, r32, 8
+        st_add  r29, r33, 8
+        st_add  r29, r34, 8
+        st_add  r29, r35, 8
+        st_add  r29, r36, 8
+        st_add  r29, r37, 8
+        st_add  r29, r38, 8
+        st_add  r29, r39, 8
+        st_add  r29, r40, 8
+        st_add  r29, r41, 8
+        st_add  r29, r42, 8
+        st_add  r29, r43, 8
+        st_add  r29, r44, 8
+        st_add  r29, r45, 8
+        st_add  r29, r46, 8
+        st_add  r29, r47, 8
+        st_add  r29, r48, 8
+        st_add  r29, r49, 8
+        st_add  r29, r50, 8
+        st_add  r29, r51, 8
+        st_add  r29, r52, 8
+        st_add  r29, r53, 8
+        st      r29, lr
+
+        /* Load the address of guest state into guest state register r50. */
+        move r50, r1
+
+        //j postamble
+
+        /* jump to the code cache. */
+        jr  r2
+        /*NOTREACHED*/
+
+
+       /*----------------------------------------------------*/
+       /*--- Postamble and exit.                          ---*/
+       /*----------------------------------------------------*/
+
+postamble:
+        /* At this point, r12 and r13 contain two
+        words to be returned to the caller.  r12
+        holds a TRC value, and r13 optionally may
+        hold another word (for CHAIN_ME exits, the
+        address of the place to patch.) */
+
+        /* run_innerloop_exit_REALLY:
+        r50 holds VG_TRC_* value to return
+        Return to parent stack
+        addli  sp, sp, 256 */
+
+        addi r29, sp, 8
+
+        /* Restore r0 from stack; holding address of twp words */
+        ld_add  r0, r29, 16
+        /* store r12 in two_words[0] */
+        st_add  r0, r12, 8
+        /* store r13 in two_words[1] */
+        st  r0, r13
+
+        /* Restore callee-saved registers... */
+        ld_add  r30, r29, 8
+        ld_add  r31, r29, 8
+        ld_add  r32, r29, 8
+        ld_add  r33, r29, 8
+        ld_add  r34, r29, 8
+        ld_add  r35, r29, 8
+        ld_add  r36, r29, 8
+        ld_add  r37, r29, 8
+        ld_add  r38, r29, 8
+        ld_add  r39, r29, 8
+        ld_add  r40, r29, 8
+        ld_add  r41, r29, 8
+        ld_add  r42, r29, 8
+        ld_add  r43, r29, 8
+        ld_add  r44, r29, 8
+        ld_add  r45, r29, 8
+        ld_add  r46, r29, 8
+        ld_add  r47, r29, 8
+        ld_add  r48, r29, 8
+        ld_add  r49, r29, 8
+        ld_add  r50, r29, 8
+        ld_add  r51, r29, 8
+        ld_add  r52, r29, 8
+        ld_add  r53, r29, 8
+        ld      lr, r29
+        addli   sp, sp, 256   /* stack_size */
+        jr      lr
+        nop
+
+
+       /*----------------------------------------------------*/
+       /*---           Continuation points                ---*/
+       /*----------------------------------------------------*/
+
+       /* ------ Chain me to slow entry point ------ */
+       .global VG_(disp_cp_chain_me_to_slowEP)
+       VG_(disp_cp_chain_me_to_slowEP):
+        /* We got called.  The return address indicates
+        where the patching needs to happen.  Collect
+        the return address and, exit back to C land,
+        handing the caller the pair (Chain_me_S, RA) */
+        # if (VG_TRC_CHAIN_ME_TO_SLOW_EP > 128)
+        # error ("VG_TRC_CHAIN_ME_TO_SLOW_EP is > 128");
+        # endif
+        moveli r12, VG_TRC_CHAIN_ME_TO_SLOW_EP
+        move   r13, lr
+        /* 32 = mkLoadImm_EXACTLY4
+        8 = jalr r9
+        8 = nop */
+        addi   r13, r13, -40
+        j      postamble
+
+        /* ------ Chain me to slow entry point ------ */
+        .global VG_(disp_cp_chain_me_to_fastEP)
+        VG_(disp_cp_chain_me_to_fastEP):
+        /* We got called.  The return address indicates
+        where the patching needs to happen.  Collect
+        the return address and, exit back to C land,
+        handing the caller the pair (Chain_me_S, RA) */
+        # if (VG_TRC_CHAIN_ME_TO_FAST_EP > 128)
+        # error ("VG_TRC_CHAIN_ME_TO_FAST_EP is > 128");
+        # endif
+        moveli r12, VG_TRC_CHAIN_ME_TO_FAST_EP
+        move   r13, lr
+        /* 32 = mkLoadImm_EXACTLY4
+        8 = jalr r9
+        8 = nop */
+        addi   r13, r13, -40
+        j      postamble
+
+        /* ------ Indirect but boring jump ------ */
+        .global VG_(disp_cp_xindir)
+        VG_(disp_cp_xindir):
+        /* Where are we going? */
+        addli    r11, r50, OFFSET_tilegx_pc
+        ld       r11, r11
+
+        moveli      r7, hw2_last(VG_(stats__n_xindirs_32))
+        shl16insli  r7, r7, hw1(VG_(stats__n_xindirs_32))
+        shl16insli  r7, r7, hw0(VG_(stats__n_xindirs_32))
+        ld4u   r6, r7
+        addi   r6, r6, 1
+        st4    r7, r6
+
+        /* try a fast lookup in the translation cache */
+        /* r14 = VG_TT_FAST_HASH(addr) * sizeof(ULong*)
+        = (t8 >> 3 & VG_TT_FAST_MASK)  << 3 */
+
+        move    r14, r11
+        /* Assume VG_TT_FAST_MASK < 4G */
+        moveli  r12, hw1(VG_TT_FAST_MASK)
+        shl16insli r12, r12, hw0(VG_TT_FAST_MASK)
+        shrui   r14, r14, 3
+        and     r14, r14, r12
+        shli    r14, r14, 4
+        /* Note, each tt_fast hash entry has two pointers i.e. 16 Bytes. */
+
+        /* r13 = (addr of VG_(tt_fast)) + r14 */
+        moveli  r13, hw2_last(VG_(tt_fast))
+        shl16insli   r13, r13, hw1(VG_(tt_fast))
+        shl16insli   r13, r13, hw0(VG_(tt_fast))
+
+        add     r13, r13, r14
+
+        /* r12 = VG_(tt_fast)[hash] :: ULong* */
+        ld_add  r12, r13, 8
+
+        {
+        ld      r25, r13
+        sub     r7, r12, r11
+        }
+
+        bnez     r7, fast_lookup_failed
+
+        /* Run the translation */
+        jr      r25
+
+        .quad   0x0
+
+fast_lookup_failed:
+        /* %PC is up to date */
+        /* back out decrement of the dispatch counter */
+        /* hold dispatch_ctr in t0 (r8) */
+
+        moveli      r7, hw2_last(VG_(stats__n_xindir_misses_32))
+        shl16insli  r7, r7, hw1(VG_(stats__n_xindir_misses_32))
+        shl16insli  r7, r7, hw0(VG_(stats__n_xindir_misses_32))
+        ld4u  r6, r7
+        addi  r6, r6, 1
+        st4   r7, r6
+        moveli  r12, VG_TRC_INNER_FASTMISS
+        movei   r13, 0
+        j       postamble
+
+        /* ------ Assisted jump ------ */
+        .global VG_(disp_cp_xassisted)
+        VG_(disp_cp_xassisted):
+        /* guest-state-pointer contains the TRC. Put the value into the
+        return register */
+        move    r12, r50
+        movei   r13, 0
+        j       postamble
+
+        /* ------ Event check failed ------ */
+        .global VG_(disp_cp_evcheck_fail)
+        VG_(disp_cp_evcheck_fail):
+        moveli  r12, VG_TRC_INNER_COUNTERZERO
+        movei   r13, 0
+        j       postamble
+
+        .size VG_(disp_run_translations), .-VG_(disp_run_translations)
+
+
+        /* Let the linker know we do not need an executable stack */
+        .section .note.GNU-stack,"",@progbits
+
+#endif /* defined(VGP_tilegx_linux) */
+/*--------------------------------------------------------------------*/
+/*--- end                                                          ---*/
+/*--------------------------------------------------------------------*/
+
diff --git a/coregrind/m_gdbserver/target.c b/coregrind/m_gdbserver/target.c
index c23581a..1dc6e41 100644
--- a/coregrind/m_gdbserver/target.c
+++ b/coregrind/m_gdbserver/target.c
@@ -804,6 +804,8 @@
    mips32_init_architecture(&the_low_target);
 #elif defined(VGA_mips64)
    mips64_init_architecture(&the_low_target);
+#elif defined(VGA_tilegx)
+   tilegx_init_architecture(&the_low_target);
 #else
    #error "architecture missing in target.c valgrind_initialize_target"
 #endif
diff --git a/coregrind/m_gdbserver/valgrind-low-tilegx.c b/coregrind/m_gdbserver/valgrind-low-tilegx.c
new file mode 100644
index 0000000..81ccafe
--- /dev/null
+++ b/coregrind/m_gdbserver/valgrind-low-tilegx.c
@@ -0,0 +1,260 @@
+/* Low level interface to valgrind, for the remote server for GDB integrated
+   in valgrind.
+   Copyright (C) 2012
+   Free Software Foundation, Inc.
+
+   This file is part of VALGRIND.
+   It has been inspired from a file from gdbserver in gdb 6.6.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA. */
+
+#include "server.h"
+#include "target.h"
+#include "regdef.h"
+#include "regcache.h"
+
+#include "pub_core_aspacemgr.h"
+#include "pub_core_threadstate.h"
+#include "pub_core_transtab.h"
+#include "pub_core_gdbserver.h"
+
+#include "valgrind_low.h"
+
+#include "libvex_guest_tilegx.h"
+#define  REG_ONE(_n)  { "r"#_n, 64 * (_n), 64 }
+#define  REG_ONE_NAME(_n, _name) { _name, 64 * (_n), 64 }
+
+static struct reg regs[] = {
+  REG_ONE(0),
+  REG_ONE(1),
+  REG_ONE(2),
+  REG_ONE(3),
+  REG_ONE(4),
+  REG_ONE(5),
+  REG_ONE(6),
+  REG_ONE(7),
+  REG_ONE(8),
+  REG_ONE(9),
+
+  REG_ONE(10),
+  REG_ONE(11),
+  REG_ONE(12),
+  REG_ONE(13),
+  REG_ONE(14),
+  REG_ONE(15),
+  REG_ONE(16),
+  REG_ONE(17),
+  REG_ONE(18),
+  REG_ONE(19),
+
+  REG_ONE(20),
+  REG_ONE(21),
+  REG_ONE(22),
+  REG_ONE(23),
+  REG_ONE(24),
+  REG_ONE(25),
+  REG_ONE(26),
+  REG_ONE(27),
+  REG_ONE(28),
+  REG_ONE(29),
+
+  REG_ONE(30),
+  REG_ONE(31),
+  REG_ONE(32),
+  REG_ONE(33),
+  REG_ONE(34),
+  REG_ONE(35),
+  REG_ONE(36),
+  REG_ONE(37),
+  REG_ONE(38),
+  REG_ONE(39),
+
+  REG_ONE(40),
+  REG_ONE(41),
+  REG_ONE(42),
+  REG_ONE(43),
+  REG_ONE(44),
+  REG_ONE(45),
+  REG_ONE(46),
+  REG_ONE(47),
+  REG_ONE(48),
+  REG_ONE(49),
+
+  REG_ONE(50),
+  REG_ONE(51),
+  REG_ONE(52),
+  REG_ONE(53),
+
+  REG_ONE_NAME(54, "sp"),
+  REG_ONE_NAME(55, "lr"),
+  REG_ONE(56),
+  REG_ONE(57),
+  REG_ONE(58),
+  REG_ONE(59),
+
+  REG_ONE(60),
+  REG_ONE(61),
+  REG_ONE(62),
+  REG_ONE_NAME(63, "zero"),
+  REG_ONE_NAME(64, "pc"),
+};
+
+#define num_regs (sizeof (regs) / sizeof (regs[0]))
+
+static const char *expedite_regs[] = { "sp", "pc", 0 };
+
+static
+CORE_ADDR get_pc (void)
+{
+  unsigned long pc;
+
+  collect_register_by_name ("pc", &pc);
+
+  dlog(1, "stop pc is %p\n", (void *) pc);
+  return pc;
+}
+
+static
+void set_pc ( CORE_ADDR newpc )
+{
+  Bool mod;
+  supply_register_by_name ("pc", &newpc, &mod);
+  if (mod)
+    dlog(1, "set pc to %p\n", C2v (newpc));
+  else
+    dlog(1, "set pc not changed %p\n", C2v (newpc));
+}
+
+/* store registers in the guest state (gdbserver_to_valgrind)
+   or fetch register from the guest state (valgrind_to_gdbserver). */
+static
+void transfer_register ( ThreadId tid, int abs_regno, void * buf,
+                         transfer_direction dir, int size, Bool *mod )
+{
+  ThreadState* tst = VG_(get_ThreadState)(tid);
+  int set = abs_regno / num_regs;
+  int regno = abs_regno % num_regs;
+  *mod = False;
+
+  VexGuestTILEGXState* tilegx = (VexGuestTILEGXState*) get_arch (set, tst);
+
+  switch (regno) {
+  case 0: VG_(transfer) (&tilegx->guest_r0, buf, dir, size, mod); break;
+  case 1: VG_(transfer) (&tilegx->guest_r1, buf, dir, size, mod); break;
+  case 2: VG_(transfer) (&tilegx->guest_r2, buf, dir, size, mod); break;
+  case 3: VG_(transfer) (&tilegx->guest_r3, buf, dir, size, mod); break;
+  case 4: VG_(transfer) (&tilegx->guest_r4, buf, dir, size, mod); break;
+  case 5: VG_(transfer) (&tilegx->guest_r5, buf, dir, size, mod); break;
+  case 6: VG_(transfer) (&tilegx->guest_r6, buf, dir, size, mod); break;
+  case 7: VG_(transfer) (&tilegx->guest_r7, buf, dir, size, mod); break;
+  case 8: VG_(transfer) (&tilegx->guest_r8, buf, dir, size, mod); break;
+  case 9: VG_(transfer) (&tilegx->guest_r9, buf, dir, size, mod); break;
+  case 10: VG_(transfer) (&tilegx->guest_r10, buf, dir, size, mod); break;
+  case 11: VG_(transfer) (&tilegx->guest_r11, buf, dir, size, mod); break;
+  case 12: VG_(transfer) (&tilegx->guest_r12, buf, dir, size, mod); break;
+  case 13: VG_(transfer) (&tilegx->guest_r13, buf, dir, size, mod); break;
+  case 14: VG_(transfer) (&tilegx->guest_r14, buf, dir, size, mod); break;
+  case 15: VG_(transfer) (&tilegx->guest_r15, buf, dir, size, mod); break;
+  case 16: VG_(transfer) (&tilegx->guest_r16, buf, dir, size, mod); break;
+  case 17: VG_(transfer) (&tilegx->guest_r17, buf, dir, size, mod); break;
+  case 18: VG_(transfer) (&tilegx->guest_r18, buf, dir, size, mod); break;
+  case 19: VG_(transfer) (&tilegx->guest_r19, buf, dir, size, mod); break;
+  case 20: VG_(transfer) (&tilegx->guest_r20, buf, dir, size, mod); break;
+  case 21: VG_(transfer) (&tilegx->guest_r21, buf, dir, size, mod); break;
+  case 22: VG_(transfer) (&tilegx->guest_r22, buf, dir, size, mod); break;
+  case 23: VG_(transfer) (&tilegx->guest_r23, buf, dir, size, mod); break;
+  case 24: VG_(transfer) (&tilegx->guest_r24, buf, dir, size, mod); break;
+  case 25: VG_(transfer) (&tilegx->guest_r25, buf, dir, size, mod); break;
+  case 26: VG_(transfer) (&tilegx->guest_r26, buf, dir, size, mod); break;
+  case 27: VG_(transfer) (&tilegx->guest_r27, buf, dir, size, mod); break;
+  case 28: VG_(transfer) (&tilegx->guest_r28, buf, dir, size, mod); break;
+  case 29: VG_(transfer) (&tilegx->guest_r29, buf, dir, size, mod); break;
+  case 30: VG_(transfer) (&tilegx->guest_r30, buf, dir, size, mod); break;
+  case 31: VG_(transfer) (&tilegx->guest_r31, buf, dir, size, mod); break;
+  case 32: VG_(transfer) (&tilegx->guest_r32, buf, dir, size, mod); break;
+  case 33: VG_(transfer) (&tilegx->guest_r33, buf, dir, size, mod); break;
+  case 34: VG_(transfer) (&tilegx->guest_r34, buf, dir, size, mod); break;
+  case 35: VG_(transfer) (&tilegx->guest_r35, buf, dir, size, mod); break;
+  case 36: VG_(transfer) (&tilegx->guest_r36, buf, dir, size, mod); break;
+  case 37: VG_(transfer) (&tilegx->guest_r37, buf, dir, size, mod); break;
+  case 38: VG_(transfer) (&tilegx->guest_r38, buf, dir, size, mod); break;
+  case 39: VG_(transfer) (&tilegx->guest_r39, buf, dir, size, mod); break;
+  case 40: VG_(transfer) (&tilegx->guest_r40, buf, dir, size, mod); break;
+  case 41: VG_(transfer) (&tilegx->guest_r41, buf, dir, size, mod); break;
+  case 42: VG_(transfer) (&tilegx->guest_r42, buf, dir, size, mod); break;
+  case 43: VG_(transfer) (&tilegx->guest_r43, buf, dir, size, mod); break;
+  case 44: VG_(transfer) (&tilegx->guest_r44, buf, dir, size, mod); break;
+  case 45: VG_(transfer) (&tilegx->guest_r45, buf, dir, size, mod); break;
+  case 46: VG_(transfer) (&tilegx->guest_r46, buf, dir, size, mod); break;
+  case 47: VG_(transfer) (&tilegx->guest_r47, buf, dir, size, mod); break;
+  case 48: VG_(transfer) (&tilegx->guest_r48, buf, dir, size, mod); break;
+  case 49: VG_(transfer) (&tilegx->guest_r49, buf, dir, size, mod); break;
+  case 50: VG_(transfer) (&tilegx->guest_r50, buf, dir, size, mod); break;
+  case 51: VG_(transfer) (&tilegx->guest_r51, buf, dir, size, mod); break;
+  case 52: VG_(transfer) (&tilegx->guest_r52, buf, dir, size, mod); break;
+  case 53: VG_(transfer) (&tilegx->guest_r53, buf, dir, size, mod); break;
+  case 54: VG_(transfer) (&tilegx->guest_r54, buf, dir, size, mod); break;
+  case 55: VG_(transfer) (&tilegx->guest_r55, buf, dir, size, mod); break;
+  case 56: VG_(transfer) (&tilegx->guest_r56, buf, dir, size, mod); break;
+  case 57: VG_(transfer) (&tilegx->guest_r57, buf, dir, size, mod); break;
+  case 58: VG_(transfer) (&tilegx->guest_r58, buf, dir, size, mod); break;
+  case 59: VG_(transfer) (&tilegx->guest_r59, buf, dir, size, mod); break;
+  case 60: VG_(transfer) (&tilegx->guest_r60, buf, dir, size, mod); break;
+  case 61: VG_(transfer) (&tilegx->guest_r61, buf, dir, size, mod); break;
+  case 62: VG_(transfer) (&tilegx->guest_r62, buf, dir, size, mod); break;
+  case 63: VG_(transfer) (&tilegx->guest_r63, buf, dir, size, mod); break;
+  case 64: VG_(transfer) (&tilegx->guest_pc,  buf, dir, size, mod); break;
+
+  default: VG_(printf)("regno: %d\n", regno); vg_assert(0);
+  }
+}
+
+static
+const char* target_xml ( Bool shadow_mode )
+{
+  if (shadow_mode) {
+    return "tilegx-linux-valgrind.xml";
+  } else {
+    return "tilegx-linux.xml";
+  }
+}
+
+static CORE_ADDR** target_get_dtv (ThreadState *tst)
+{
+  VexGuestTILEGXState* tilegx = (VexGuestTILEGXState*)&tst->arch.vex;
+  // tilegx dtv location similar to mips
+  return (CORE_ADDR**)((CORE_ADDR)tilegx->guest_r53
+                        - 0x7000 - sizeof(CORE_ADDR));
+}
+
+static struct valgrind_target_ops low_target = {
+  num_regs,
+  regs,
+  54, //sp = r54, which is register offset 54 in regs
+  transfer_register,
+  get_pc,
+  set_pc,
+  "tilegx",
+  target_xml,
+  target_get_dtv
+};
+
+void tilegx_init_architecture ( struct valgrind_target_ops *target )
+{
+  *target = low_target;
+  set_register_cache (regs, num_regs);
+  gdbserver_expedite_regs = expedite_regs;
+}
diff --git a/coregrind/m_gdbserver/valgrind_low.h b/coregrind/m_gdbserver/valgrind_low.h
index 7b87856..3a3228f 100644
--- a/coregrind/m_gdbserver/valgrind_low.h
+++ b/coregrind/m_gdbserver/valgrind_low.h
@@ -107,5 +107,6 @@
 extern void s390x_init_architecture (struct valgrind_target_ops *target);
 extern void mips32_init_architecture (struct valgrind_target_ops *target);
 extern void mips64_init_architecture (struct valgrind_target_ops *target);
+extern void tilegx_init_architecture (struct valgrind_target_ops *target);
 
 #endif
diff --git a/coregrind/m_initimg/initimg-linux.c b/coregrind/m_initimg/initimg-linux.c
index b198dbf..868325b 100644
--- a/coregrind/m_initimg/initimg-linux.c
+++ b/coregrind/m_initimg/initimg-linux.c
@@ -1173,6 +1173,21 @@
    arch->vex.guest_PC = iifii.initial_client_IP;
    arch->vex.guest_r31 = iifii.initial_client_SP;
 
+#  elif defined(VGP_tilegx_linux)
+   vg_assert(0 == sizeof(VexGuestTILEGXState) % 8);
+   vg_assert(0 == sizeof(VexGuestTILEGXState) % VexGuestTILEGXStateAlignment);
+
+   /* Zero out the initial state. */
+   LibVEX_GuestTILEGX_initialise(&arch->vex);
+
+   /* Zero out the shadow areas. */
+   VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestTILEGXState));
+   VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestTILEGXState));
+
+   /* Put essential stuff into the new state. */
+   arch->vex.guest_r54 = iifii.initial_client_SP;
+   arch->vex.guest_pc  = iifii.initial_client_IP;
+
 #  else
 #    error Unknown platform
 #  endif
diff --git a/coregrind/m_libcassert.c b/coregrind/m_libcassert.c
index 80d372d..365b503 100644
--- a/coregrind/m_libcassert.c
+++ b/coregrind/m_libcassert.c
@@ -225,6 +225,29 @@
         (srP)->misc.MIPS64.r31 = (ULong)ra;               \
         (srP)->misc.MIPS64.r28 = (ULong)gp;               \
       }
+#elif defined(VGP_tilegx_linux)
+#  define GET_STARTREGS(srP)                              \
+      { UInt pc, sp, fp, ra;                              \
+        __asm__ __volatile__(                             \
+          "move r8, lr \n"                                \
+          "jal 0f \n"                                     \
+          "0:\n"                                          \
+          "move %0, lr \n"                                \
+          "move lr, r8 \n"      /* put old lr back*/      \
+          "move %1, sp \n"                                \
+          "move %2, r52 \n"                               \
+          "move %3, lr \n"                                \
+          : "=r" (pc),                                    \
+            "=r" (sp),                                    \
+            "=r" (fp),                                    \
+            "=r" (ra)                                     \
+          : /* reads none */                              \
+          : "%r8" /* trashed */ );                        \
+        (srP)->r_pc = (ULong)pc - 8;                      \
+        (srP)->r_sp = (ULong)sp;                          \
+        (srP)->misc.TILEGX.r52 = (ULong)fp;               \
+        (srP)->misc.TILEGX.r55 = (ULong)ra;               \
+      }
 #else
 #  error Unknown platform
 #endif
diff --git a/coregrind/m_libcfile.c b/coregrind/m_libcfile.c
index 55d33f7..8506f5d 100644
--- a/coregrind/m_libcfile.c
+++ b/coregrind/m_libcfile.c
@@ -131,8 +131,8 @@
 }
 
 SysRes VG_(mknod) ( const HChar* pathname, Int mode, UWord dev )
-{  
-#  if defined(VGP_arm64_linux)
+{
+#  if defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
    /* ARM64 wants to use __NR_mknodat rather than __NR_mknod. */
    SysRes res = VG_(do_syscall4)(__NR_mknodat,
                                  VKI_AT_FDCWD, (UWord)pathname, mode, dev);
@@ -147,7 +147,7 @@
 
 SysRes VG_(open) ( const HChar* pathname, Int flags, Int mode )
 {
-#  if defined(VGP_arm64_linux)
+#  if defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
    /* ARM64 wants to use __NR_openat rather than __NR_open. */
    SysRes res = VG_(do_syscall4)(__NR_openat,
                                  VKI_AT_FDCWD, (UWord)pathname, flags, mode);
@@ -238,7 +238,7 @@
    } else {
       return -1;
    }
-#  elif defined(VGP_arm64_linux)
+#  elif defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
    SysRes res = VG_(do_syscall2)(__NR_pipe2, (UWord)fd, 0);
    return sr_isError(res) ? -1 : 0;
 #  elif defined(VGO_linux)
@@ -328,7 +328,7 @@
 #  endif /* defined(__NR_stat64) */
    /* This is the fallback ("vanilla version"). */
    { struct vki_stat buf;
-#    if defined(VGP_arm64_linux)
+#    if defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
      res = VG_(do_syscall3)(__NR3264_fstatat, VKI_AT_FDCWD,
                                               (UWord)file_name, (UWord)&buf);
 #    else
@@ -434,13 +434,18 @@
 
 Int VG_(rename) ( const HChar* old_name, const HChar* new_name )
 {
+#  if defined(VGP_tilegx_linux)
+   SysRes res = VG_(do_syscall3)(__NR_renameat, AT_FDCWD,
+                                 (UWord)old_name, (UWord)new_name);
+#  else
    SysRes res = VG_(do_syscall2)(__NR_rename, (UWord)old_name, (UWord)new_name);
+#  endif
    return sr_isError(res) ? (-1) : 0;
 }
 
 Int VG_(unlink) ( const HChar* file_name )
 {
-#  if defined(VGP_arm64_linux)
+#  if defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
    SysRes res = VG_(do_syscall2)(__NR_unlinkat, VKI_AT_FDCWD,
                                                 (UWord)file_name);
 #  else
@@ -515,7 +520,7 @@
 SysRes VG_(poll) (struct vki_pollfd *fds, Int nfds, Int timeout)
 {
    SysRes res;
-#  if defined(VGP_arm64_linux)
+#  if defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
    /* ARM64 wants to use __NR_ppoll rather than __NR_poll. */
    struct vki_timespec timeout_ts;
    if (timeout >= 0) {
@@ -545,7 +550,7 @@
 {
    SysRes res;
    /* res = readlink( path, buf, bufsiz ); */
-#  if defined(VGP_arm64_linux)
+#  if defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
    res = VG_(do_syscall4)(__NR_readlinkat, VKI_AT_FDCWD,
                                            (UWord)path, (UWord)buf, bufsiz);
 #  else
@@ -581,7 +586,7 @@
    UWord w = (irusr ? VKI_R_OK : 0)
              | (iwusr ? VKI_W_OK : 0)
              | (ixusr ? VKI_X_OK : 0);
-#  if defined(VGP_arm64_linux)
+#  if defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
    SysRes res = VG_(do_syscall3)(__NR_faccessat, VKI_AT_FDCWD, (UWord)path, w);
 #  else
    SysRes res = VG_(do_syscall2)(__NR_access, (UWord)path, w);
@@ -721,7 +726,7 @@
 #  elif defined(VGP_amd64_linux) || defined(VGP_s390x_linux) \
       || defined(VGP_ppc64be_linux)  || defined(VGP_ppc64le_linux) \
       || defined(VGP_mips64_linux) \
-      || defined(VGP_arm64_linux)
+  || defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
    res = VG_(do_syscall4)(__NR_pread64, fd, (UWord)buf, count, offset);
    return res;
 #  elif defined(VGP_amd64_darwin)
@@ -968,7 +973,7 @@
 
 #  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
         || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
-        || defined(VGP_arm64_linux)
+        || defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
    SysRes res;
    res = VG_(do_syscall3)(__NR_socket, domain, type, protocol );
    return sr_isError(res) ? -1 : sr_Res(res);
@@ -1009,7 +1014,7 @@
 
 #  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
         || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
-        || defined(VGP_arm64_linux)
+        || defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
    SysRes res;
    res = VG_(do_syscall3)(__NR_connect, sockfd, (UWord)serv_addr, addrlen);
    return sr_isError(res) ? -1 : sr_Res(res);
@@ -1050,7 +1055,7 @@
 
 #  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
         || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
-        || defined(VGP_arm64_linux)
+        || defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
    SysRes res;
    res = VG_(do_syscall6)(__NR_sendto, sd, (UWord)msg, 
                                        count, VKI_MSG_NOSIGNAL, 0,0);
@@ -1081,7 +1086,8 @@
    return sr_isError(res) ? -1 : sr_Res(res);
 
 #  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
-        || defined(VGP_mips64_linux) || defined(VGP_arm64_linux)
+        || defined(VGP_mips64_linux) || defined(VGP_arm64_linux) \
+        || defined(VGP_tilegx_linux)
    SysRes res;
    res = VG_(do_syscall3)( __NR_getsockname,
                            (UWord)sd, (UWord)name, (UWord)namelen );
@@ -1113,7 +1119,8 @@
    return sr_isError(res) ? -1 : sr_Res(res);
 
 #  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
-        || defined(VGP_mips64_linux) || defined(VGP_arm64_linux)
+        || defined(VGP_mips64_linux) || defined(VGP_arm64_linux) \
+        || defined(VGP_tilegx_linux)
    SysRes res;
    res = VG_(do_syscall3)( __NR_getpeername,
                            (UWord)sd, (UWord)name, (UWord)namelen );
@@ -1148,7 +1155,7 @@
 
 #  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
         || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
-        || defined(VGP_arm64_linux)
+        || defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
    SysRes res;
    res = VG_(do_syscall5)( __NR_getsockopt,
                            (UWord)sd, (UWord)level, (UWord)optname, 
@@ -1186,7 +1193,7 @@
 
 #  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
         || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
-        || defined(VGP_arm64_linux)
+        || defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
    SysRes res;
    res = VG_(do_syscall5)( __NR_setsockopt,
                            (UWord)sd, (UWord)level, (UWord)optname, 
diff --git a/coregrind/m_libcproc.c b/coregrind/m_libcproc.c
index f3f4070..f25320a 100644
--- a/coregrind/m_libcproc.c
+++ b/coregrind/m_libcproc.c
@@ -466,7 +466,7 @@
        * the /proc/self link is pointing...
        */
 
-#     if defined(VGP_arm64_linux)
+#     if defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
       res = VG_(do_syscall4)(__NR_readlinkat, VKI_AT_FDCWD,
                              (UWord)"/proc/self",
                              (UWord)pid, sizeof(pid));
@@ -552,7 +552,7 @@
    if (size < 0) return -1;
 
 #  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
-      || defined(VGP_mips64_linux)
+      || defined(VGP_mips64_linux) || defined(VGP_tilegx_linux)
    Int    i;
    SysRes sres;
    UShort list16[size];
@@ -599,7 +599,7 @@
 
 Int VG_(fork) ( void )
 {
-#  if defined(VGP_arm64_linux)
+#  if defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
    SysRes res;
    res = VG_(do_syscall5)(__NR_clone, VKI_SIGCHLD,
                           (UWord)NULL, (UWord)NULL, (UWord)NULL, (UWord)NULL);
@@ -920,6 +920,25 @@
                                  (UWord) nbytes, (UWord) 3);
    vg_assert( sres._isError == 0 );
 
+#  elif defined(VGA_tilegx)
+   const HChar *start, *end;
+
+   /* L1 ICache is 32KB. cacheline size is 64 bytes. */
+   if (nbytes > 0x8000) nbytes = 0x8000;
+
+   start = (const HChar *)((unsigned long)ptr & -64ULL);
+   end = (const HChar*)ptr + nbytes - 1;
+
+   __insn_mf();
+
+   do {
+     const HChar* p;
+     for (p = start; p <= end; p += 64)
+       __insn_icoh(p);
+   } while (0);
+
+   __insn_drain();
+
 #  endif
 }
 
diff --git a/coregrind/m_machine.c b/coregrind/m_machine.c
index 3fa403b..2551b10 100644
--- a/coregrind/m_machine.c
+++ b/coregrind/m_machine.c
@@ -127,6 +127,13 @@
       = VG_(threads)[tid].arch.vex.guest_r31;
    regs->misc.MIPS64.r28
       = VG_(threads)[tid].arch.vex.guest_r28;
+#  elif defined(VGA_tilegx)
+   regs->r_pc = VG_(threads)[tid].arch.vex.guest_pc;
+   regs->r_sp = VG_(threads)[tid].arch.vex.guest_r54;
+   regs->misc.TILEGX.r52
+      = VG_(threads)[tid].arch.vex.guest_r52;
+   regs->misc.TILEGX.r55
+      = VG_(threads)[tid].arch.vex.guest_r55;
 #  else
 #    error "Unknown arch"
 #  endif
@@ -344,6 +351,63 @@
    (*f)(tid, "x28", vex->guest_X28);
    (*f)(tid, "x29", vex->guest_X29);
    (*f)(tid, "x30", vex->guest_X30);
+#elif defined(VGA_tilegx)
+   (*f)(tid, "r0",  vex->guest_r0 );
+   (*f)(tid, "r1",  vex->guest_r1 );
+   (*f)(tid, "r2",  vex->guest_r2 );
+   (*f)(tid, "r3",  vex->guest_r3 );
+   (*f)(tid, "r4",  vex->guest_r4 );
+   (*f)(tid, "r5",  vex->guest_r5 );
+   (*f)(tid, "r6",  vex->guest_r6 );
+   (*f)(tid, "r7",  vex->guest_r7 );
+   (*f)(tid, "r8",  vex->guest_r8 );
+   (*f)(tid, "r9",  vex->guest_r9 );
+   (*f)(tid, "r10", vex->guest_r10);
+   (*f)(tid, "r11", vex->guest_r11);
+   (*f)(tid, "r12", vex->guest_r12);
+   (*f)(tid, "r13", vex->guest_r13);
+   (*f)(tid, "r14", vex->guest_r14);
+   (*f)(tid, "r15", vex->guest_r15);
+   (*f)(tid, "r16", vex->guest_r16);
+   (*f)(tid, "r17", vex->guest_r17);
+   (*f)(tid, "r18", vex->guest_r18);
+   (*f)(tid, "r19", vex->guest_r19);
+   (*f)(tid, "r20", vex->guest_r20);
+   (*f)(tid, "r21", vex->guest_r21);
+   (*f)(tid, "r22", vex->guest_r22);
+   (*f)(tid, "r23", vex->guest_r23);
+   (*f)(tid, "r24", vex->guest_r24);
+   (*f)(tid, "r25", vex->guest_r25);
+   (*f)(tid, "r26", vex->guest_r26);
+   (*f)(tid, "r27", vex->guest_r27);
+   (*f)(tid, "r28", vex->guest_r28);
+   (*f)(tid, "r29", vex->guest_r29);
+   (*f)(tid, "r30", vex->guest_r30);
+   (*f)(tid, "r31", vex->guest_r31);
+   (*f)(tid, "r32", vex->guest_r32);
+   (*f)(tid, "r33", vex->guest_r33);
+   (*f)(tid, "r34", vex->guest_r34);
+   (*f)(tid, "r35", vex->guest_r35);
+   (*f)(tid, "r36", vex->guest_r36);
+   (*f)(tid, "r37", vex->guest_r37);
+   (*f)(tid, "r38", vex->guest_r38);
+   (*f)(tid, "r39", vex->guest_r39);
+   (*f)(tid, "r40", vex->guest_r40);
+   (*f)(tid, "r41", vex->guest_r41);
+   (*f)(tid, "r42", vex->guest_r42);
+   (*f)(tid, "r43", vex->guest_r43);
+   (*f)(tid, "r44", vex->guest_r44);
+   (*f)(tid, "r45", vex->guest_r45);
+   (*f)(tid, "r46", vex->guest_r46);
+   (*f)(tid, "r47", vex->guest_r47);
+   (*f)(tid, "r48", vex->guest_r48);
+   (*f)(tid, "r49", vex->guest_r49);
+   (*f)(tid, "r50", vex->guest_r50);
+   (*f)(tid, "r51", vex->guest_r51);
+   (*f)(tid, "r52", vex->guest_r52);
+   (*f)(tid, "r53", vex->guest_r53);
+   (*f)(tid, "r54", vex->guest_r54);
+   (*f)(tid, "r55", vex->guest_r55);
 #else
 #  error Unknown arch
 #endif
@@ -1615,6 +1679,17 @@
      return True;
    }
 
+#elif defined(VGA_tilegx)
+   {
+     va = VexArchTILEGX;
+     vai.hwcaps = VEX_HWCAPS_TILEGX_BASE;
+     vai.endness = VexEndnessLE;
+
+     VG_(machine_get_cache_info)(&vai);
+
+     return True;
+   }
+
 #else
 #  error "Unknown arch"
 #endif
@@ -1748,6 +1823,9 @@
 #  elif defined(VGA_mips64)
    return 8;
 
+#  elif defined(VGA_tilegx)
+   return 8;
+
 #  else
 #    error "Unknown arch"
 #  endif
@@ -1762,7 +1840,8 @@
       || defined(VGP_arm_linux) || defined(VGO_darwin)          \
       || defined(VGP_ppc32_linux) || defined(VGP_ppc64le_linux) \
       || defined(VGP_s390x_linux) || defined(VGP_mips32_linux) \
-      || defined(VGP_mips64_linux) || defined(VGP_arm64_linux)
+      || defined(VGP_mips64_linux) || defined(VGP_arm64_linux) \
+      || defined(VGP_tilegx_linux)
    return f;
 #  elif defined(VGP_ppc64be_linux)
    /* ppc64-linux uses the AIX scheme, in which f is a pointer to a
diff --git a/coregrind/m_main.c b/coregrind/m_main.c
index 05ddc35..52f9f9f 100644
--- a/coregrind/m_main.c
+++ b/coregrind/m_main.c
@@ -2152,7 +2152,7 @@
 #     if defined(VGP_x86_linux)
       iters = 10;
 #     elif defined(VGP_amd64_linux) || defined(VGP_ppc64be_linux) \
-         || defined(VGP_ppc64le_linux)
+         || defined(VGP_ppc64le_linux) || defined(VGP_tilegx_linux)
       iters = 10;
 #     elif defined(VGP_ppc32_linux)
       iters = 5;
@@ -3206,6 +3206,45 @@
     "\tnop\n"
 ".previous\n"
 );
+#elif defined(VGP_tilegx_linux)
+asm("\n"
+    ".text\n"
+    "\t.align 8\n"
+    "\t.globl _start\n"
+    "\t.type _start,@function\n"
+    "_start:\n"
+
+    "\tjal 1f\n"
+    "1:\n"
+
+    /* --FIXME, bundle them :) */
+    /* r19 <- Addr(interim_stack) */
+    "\tmoveli r19, hw2_last(vgPlain_interim_stack)\n"
+    "\tshl16insli r19, r19, hw1(vgPlain_interim_stack)\n"
+    "\tshl16insli r19, r19, hw0(vgPlain_interim_stack)\n"
+
+    "\tmoveli r20, hw1("VG_STRINGIFY(VG_STACK_GUARD_SZB)")\n"
+    "\tshl16insli r20, r20, hw0("VG_STRINGIFY(VG_STACK_GUARD_SZB)")\n"
+    "\tmoveli r21, hw1("VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB)")\n"
+    "\tshl16insli r21, r21, hw0("VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB)")\n"
+    "\tadd     r19, r19, r20\n"
+    "\tadd     r19, r19, r21\n"
+
+    "\tmovei    r12, 0x0F\n"
+    "\tnor      r12, zero, r12\n"
+
+    "\tand      r19, r19, r12\n"
+
+    /* now r19 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
+       VG_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
+       boundary.  And $54 is the original SP.  Set the SP to r0 and
+       call _start_in_C, passing it the initial SP. */
+
+    "\tmove    r0,  r54\n"    // r0  <- $sp (_start_in_C first arg)
+    "\tmove    r54, r19\n"    // $sp <- r19 (new sp)
+
+    "\tjal  _start_in_C_linux\n"
+);
 #else
 #  error "Unknown linux platform"
 #endif
diff --git a/coregrind/m_redir.c b/coregrind/m_redir.c
index d87110b..2465582 100644
--- a/coregrind/m_redir.c
+++ b/coregrind/m_redir.c
@@ -1491,6 +1491,15 @@
       );
    }
 
+#  elif defined(VGP_tilegx_linux)
+   if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {
+
+      add_hardwired_spec(
+         "ld.so.1", "strlen",
+         (Addr)&VG_(tilegx_linux_REDIR_FOR_strlen), NULL
+      );
+   }
+
 #  else
 #    error Unknown platform
 #  endif
diff --git a/coregrind/m_scheduler/scheduler.c b/coregrind/m_scheduler/scheduler.c
index 0207f5b..5d3b175 100644
--- a/coregrind/m_scheduler/scheduler.c
+++ b/coregrind/m_scheduler/scheduler.c
@@ -1684,6 +1684,9 @@
 #elif defined(VGA_mips32) || defined(VGA_mips64)
 #  define VG_CLREQ_ARGS       guest_r12
 #  define VG_CLREQ_RET        guest_r11
+#elif defined(VGA_tilegx)
+#  define VG_CLREQ_ARGS       guest_r12
+#  define VG_CLREQ_RET        guest_r11
 #else
 #  error Unknown arch
 #endif
diff --git a/coregrind/m_sigframe/sigframe-tilegx-linux.c b/coregrind/m_sigframe/sigframe-tilegx-linux.c
new file mode 100644
index 0000000..e6cf4ef
--- /dev/null
+++ b/coregrind/m_sigframe/sigframe-tilegx-linux.c
@@ -0,0 +1,391 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Create/destroy signal delivery frames.                       ---*/
+/*---                                  sigframe-tilegx-linux.c     ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+  This file is part of Valgrind, a dynamic binary instrumentation
+  framework.
+
+  Copyright (C) 2010-2013 Tilera Corp.
+
+  This program is free software; you can redistribute it and/or
+  modify it under the terms of the GNU General Public License as
+  published by the Free Software Foundation; either version 2 of the
+  License, or (at your option) any later version.
+
+  This program 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
+  General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+  02111-1307, USA.
+
+  The GNU General Public License is contained in the file COPYING.
+*/
+
+/* Contributed by Zhi-Gang Liu <zliu at tilera dot com> */
+
+#if defined(VGP_tilegx_linux)
+
+#include "pub_core_basics.h"
+#include "pub_core_vki.h"
+#include "pub_core_vkiscnums.h"
+#include "pub_core_libcsetjmp.h"    // to keep _threadstate.h happy
+#include "pub_core_threadstate.h"
+#include "pub_core_aspacemgr.h"
+#include "pub_core_libcbase.h"
+#include "pub_core_libcassert.h"
+#include "pub_core_libcprint.h"
+#include "pub_core_machine.h"
+#include "pub_core_options.h"
+#include "pub_core_sigframe.h"
+#include "pub_core_signals.h"
+#include "pub_core_tooliface.h"
+#include "pub_core_trampoline.h"
+#include "pub_core_transtab.h"      // VG_(discard_translations)
+
+struct vg_sig_private
+{
+  UInt magicPI;
+  UInt sigNo_private;
+  VexGuestTILEGXState vex_shadow1;
+  VexGuestTILEGXState vex_shadow2;
+};
+
+#ifndef C_ABI_SAVE_AREA_SIZE
+#define C_ABI_SAVE_AREA_SIZE  16
+#endif
+struct rt_sigframe {
+  unsigned char save_area[C_ABI_SAVE_AREA_SIZE]; /* caller save area */
+  vki_siginfo_t rs_info;
+  struct vki_ucontext rs_uc;
+  struct vg_sig_private priv;
+};
+
+/* Extend the stack segment downwards if needed so as to ensure the
+   new signal frames are mapped to something.  Return a Bool
+   indicating whether or not the operation was successful.
+*/
+static Bool extend ( ThreadState *tst, Addr addr, SizeT size )
+{
+  ThreadId        tid = tst->tid;
+  NSegment const* stackseg = NULL;
+
+  if (VG_(extend_stack)(addr, addr))
+    stackseg = VG_(am_find_nsegment)(addr);
+
+  if (stackseg == NULL || !stackseg->hasR || !stackseg->hasW)
+  {
+    VG_(message)(Vg_UserMsg,
+                 "Can't extend stack to %#lx during signal delivery for thread %d:\n",
+                 addr, tid );
+    if (stackseg == NULL)
+      VG_(message)( Vg_UserMsg, "  no stack segment\n" );
+    else
+      VG_(message)( Vg_UserMsg, "  too small or bad protection modes\n" );
+
+    /* set SIGSEGV to default handler */
+    VG_(set_default_handler)( VKI_SIGSEGV );
+    VG_(synth_fault_mapping)( tid, addr );
+
+    /* The whole process should be about to die, since the default
+       action of SIGSEGV to kill the whole process. */
+    return False;
+  }
+
+  /* For tracking memory events, indicate the entire frame has been
+     allocated. */
+  VG_TRACK( new_mem_stack_signal, addr - VG_STACK_REDZONE_SZB,
+            size + VG_STACK_REDZONE_SZB, tid );
+
+  return True;
+}
+
+static
+void setup_sigcontext2 ( ThreadState* tst, struct vki_sigcontext **sc1,
+                         const vki_siginfo_t *si )
+{
+
+  struct vki_sigcontext *sc = *sc1;
+
+  VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal frame mcontext",
+            (Addr)sc, sizeof(unsigned long long)*34 );
+  sc->gregs[0] = tst->arch.vex.guest_r0;
+  sc->gregs[1] = tst->arch.vex.guest_r1;
+  sc->gregs[2] = tst->arch.vex.guest_r2;
+  sc->gregs[3] = tst->arch.vex.guest_r3;
+  sc->gregs[4] = tst->arch.vex.guest_r4;
+  sc->gregs[5] = tst->arch.vex.guest_r5;
+  sc->gregs[6] = tst->arch.vex.guest_r6;
+  sc->gregs[7] = tst->arch.vex.guest_r7;
+  sc->gregs[8] = tst->arch.vex.guest_r8;
+  sc->gregs[9] = tst->arch.vex.guest_r9;
+  sc->gregs[10] = tst->arch.vex.guest_r10;
+  sc->gregs[11] = tst->arch.vex.guest_r11;
+  sc->gregs[12] = tst->arch.vex.guest_r12;
+  sc->gregs[13] = tst->arch.vex.guest_r13;
+  sc->gregs[14] = tst->arch.vex.guest_r14;
+  sc->gregs[15] = tst->arch.vex.guest_r15;
+  sc->gregs[16] = tst->arch.vex.guest_r16;
+  sc->gregs[17] = tst->arch.vex.guest_r17;
+  sc->gregs[18] = tst->arch.vex.guest_r18;
+  sc->gregs[19] = tst->arch.vex.guest_r19;
+  sc->gregs[20] = tst->arch.vex.guest_r20;
+  sc->gregs[21] = tst->arch.vex.guest_r21;
+  sc->gregs[22] = tst->arch.vex.guest_r22;
+  sc->gregs[23] = tst->arch.vex.guest_r23;
+  sc->gregs[24] = tst->arch.vex.guest_r24;
+  sc->gregs[25] = tst->arch.vex.guest_r25;
+  sc->gregs[26] = tst->arch.vex.guest_r26;
+  sc->gregs[27] = tst->arch.vex.guest_r27;
+  sc->gregs[28] = tst->arch.vex.guest_r28;
+  sc->gregs[29] = tst->arch.vex.guest_r29;
+  sc->gregs[30] = tst->arch.vex.guest_r30;
+  sc->gregs[31] = tst->arch.vex.guest_r31;
+  sc->gregs[32] = tst->arch.vex.guest_r32;
+  sc->gregs[33] = tst->arch.vex.guest_r33;
+  sc->gregs[34] = tst->arch.vex.guest_r34;
+  sc->gregs[35] = tst->arch.vex.guest_r35;
+  sc->gregs[36] = tst->arch.vex.guest_r36;
+  sc->gregs[37] = tst->arch.vex.guest_r37;
+  sc->gregs[38] = tst->arch.vex.guest_r38;
+  sc->gregs[39] = tst->arch.vex.guest_r39;
+  sc->gregs[40] = tst->arch.vex.guest_r40;
+  sc->gregs[41] = tst->arch.vex.guest_r41;
+  sc->gregs[42] = tst->arch.vex.guest_r42;
+  sc->gregs[43] = tst->arch.vex.guest_r43;
+  sc->gregs[44] = tst->arch.vex.guest_r44;
+  sc->gregs[45] = tst->arch.vex.guest_r45;
+  sc->gregs[46] = tst->arch.vex.guest_r46;
+  sc->gregs[47] = tst->arch.vex.guest_r47;
+  sc->gregs[48] = tst->arch.vex.guest_r48;
+  sc->gregs[49] = tst->arch.vex.guest_r49;
+  sc->gregs[50] = tst->arch.vex.guest_r50;
+  sc->gregs[51] = tst->arch.vex.guest_r51;
+  sc->gregs[52] = tst->arch.vex.guest_r52;
+  sc->tp        = tst->arch.vex.guest_r53;
+  sc->sp        = tst->arch.vex.guest_r54;
+  sc->lr        = tst->arch.vex.guest_r55;
+  sc->pc        = tst->arch.vex.guest_pc;
+}
+
+/* EXPORTED */
+void VG_(sigframe_create)( ThreadId tid,
+                           Addr sp_top_of_frame,
+                           const vki_siginfo_t *siginfo,
+                           const struct vki_ucontext *siguc,
+                           void *handler,
+                           UInt flags,
+                           const vki_sigset_t *mask,
+                           void *restorer )
+{
+  Addr sp;
+  ThreadState* tst;
+  Addr faultaddr;
+  Int sigNo = siginfo->si_signo;
+  struct vg_sig_private *priv;
+
+  /* Stack must be 8-byte aligned */
+  sp_top_of_frame &= ~0x7ULL;
+
+  sp = sp_top_of_frame - sizeof(struct rt_sigframe);
+
+  tst = VG_(get_ThreadState)(tid);
+  if (!extend(tst, sp, sizeof(struct rt_sigframe)))
+    return;
+
+  vg_assert(VG_IS_8_ALIGNED(sp));
+
+  /* SIGILL defines addr to be the faulting address */
+
+  faultaddr = (Addr)siginfo->_sifields._sigfault._addr;
+  if (sigNo == VKI_SIGILL && siginfo->si_code > 0)
+    faultaddr = tst->arch.vex.guest_pc;
+
+
+  struct rt_sigframe *frame = (struct rt_sigframe *) sp;
+  struct vki_ucontext *ucp = &frame->rs_uc;
+  if (VG_(clo_trace_signals))
+    VG_(printf)("rt_sigframe\n");
+  /* Create siginfo.  */
+  VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame siginfo",
+            (Addr)&frame->rs_info, sizeof(frame->rs_info) );
+
+  VG_(memcpy)(&frame->rs_info, siginfo, sizeof(*siginfo));
+
+  VG_TRACK( post_mem_write, Vg_CoreSignal, tid,
+            (Addr)&frame->rs_info, sizeof(frame->rs_info) );
+
+  /* Create the ucontext.  */
+  VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame ucontext",
+            (Addr)ucp, offsetof(struct vki_ucontext, uc_mcontext) );
+
+  ucp->uc_flags = 0;
+  ucp->uc_link = 0;
+  ucp->uc_stack = tst->altstack;
+
+  VG_TRACK( post_mem_write, Vg_CoreSignal, tid, (Addr)ucp,
+            offsetof(struct vki_ucontext, uc_mcontext) );
+
+  struct vki_sigcontext *scp = &(frame->rs_uc.uc_mcontext);
+  setup_sigcontext2(tst, &(scp), siginfo);
+
+  ucp->uc_sigmask = tst->sig_mask;
+
+  priv = &frame->priv;
+
+  /*
+   * Arguments to signal handler:
+   *
+   *   r0 = signal number
+   *   r1 = 0 (should be cause)
+   *   r2 = pointer to ucontext
+   *
+   * r54 points to the struct rt_sigframe.
+   */
+
+  tst->arch.vex.guest_r0 = siginfo->si_signo;
+  tst->arch.vex.guest_r1 = (Addr) &frame->rs_info;
+  tst->arch.vex.guest_r2 = (Addr) &frame->rs_uc;
+  tst->arch.vex.guest_r54 = (Addr) frame;
+
+  if (flags & VKI_SA_RESTORER)
+  {
+    tst->arch.vex.guest_r55 = (Addr) restorer;
+  }
+  else
+  {
+    tst->arch.vex.guest_r55 = (Addr)&VG_(tilegx_linux_SUBST_FOR_rt_sigreturn);
+  }
+
+  priv->magicPI       = 0x31415927;
+  priv->sigNo_private = sigNo;
+  priv->vex_shadow1   = tst->arch.vex_shadow1;
+  priv->vex_shadow2   = tst->arch.vex_shadow2;
+  /* Set the thread so it will next run the handler. */
+  /* tst->m_sp  = sp;  also notify the tool we've updated SP */
+  VG_TRACK( post_reg_write, Vg_CoreSignal, tid, VG_O_STACK_PTR, sizeof(Addr));
+  if (VG_(clo_trace_signals))
+    VG_(printf)("handler = %p\n", handler);
+  tst->arch.vex.guest_pc = (Addr) handler;
+  /* This thread needs to be marked runnable, but we leave that the
+     caller to do. */
+  if (0)
+    VG_(printf)("pushed signal frame; sp now = %lx, "
+                "next %pc = %lx, status=%d\n",
+                (Addr)frame, tst->arch.vex.guest_pc, tst->status);
+}
+
+/* EXPORTED */
+void VG_(sigframe_destroy)( ThreadId tid, Bool isRT )
+{
+  ThreadState *tst;
+  struct vg_sig_private *priv1;
+  Addr sp;
+  UInt frame_size;
+  struct vki_sigcontext *mc;
+  Int sigNo;
+  Bool has_siginfo = isRT;
+
+  vg_assert(VG_(is_valid_tid)(tid));
+  tst = VG_(get_ThreadState)(tid);
+  sp   = tst->arch.vex.guest_r54 + 8;
+  if (has_siginfo)
+  {
+    struct rt_sigframe *frame = (struct rt_sigframe *)sp;
+    struct vki_ucontext *ucp = &frame->rs_uc;
+
+    if (0)
+      VG_(printf)("destory signal frame; sp = %lx, "
+                  " %pc = %lx, status=%d\n",
+                  (Addr)frame, tst->arch.vex.guest_pc, tst->status);
+
+    frame_size = sizeof(*frame);
+    mc = &ucp->uc_mcontext;
+    priv1 = &frame->priv;
+    vg_assert(priv1->magicPI == 0x31415927);
+    sigNo = priv1->sigNo_private;
+  }
+  else
+  {
+    vg_assert(0);
+  }
+
+  //restore regs
+  tst->arch.vex.guest_r0  = mc->gregs[0];
+  tst->arch.vex.guest_r1  = mc->gregs[1];
+  tst->arch.vex.guest_r2  = mc->gregs[2];
+  tst->arch.vex.guest_r3  = mc->gregs[3];
+  tst->arch.vex.guest_r4  = mc->gregs[4];
+  tst->arch.vex.guest_r5  = mc->gregs[5];
+  tst->arch.vex.guest_r6  = mc->gregs[6];
+  tst->arch.vex.guest_r7  = mc->gregs[7];
+  tst->arch.vex.guest_r8  = mc->gregs[8];
+  tst->arch.vex.guest_r9  = mc->gregs[9];
+  tst->arch.vex.guest_r10 = mc->gregs[10];
+  tst->arch.vex.guest_r11 = mc->gregs[11];
+  tst->arch.vex.guest_r12 = mc->gregs[12];
+  tst->arch.vex.guest_r13 = mc->gregs[13];
+  tst->arch.vex.guest_r14 = mc->gregs[14];
+  tst->arch.vex.guest_r15 = mc->gregs[15];
+  tst->arch.vex.guest_r16 = mc->gregs[16];
+  tst->arch.vex.guest_r17 = mc->gregs[17];
+  tst->arch.vex.guest_r18 = mc->gregs[18];
+  tst->arch.vex.guest_r19 = mc->gregs[19];
+  tst->arch.vex.guest_r20 = mc->gregs[20];
+  tst->arch.vex.guest_r21 = mc->gregs[21];
+  tst->arch.vex.guest_r22 = mc->gregs[22];
+  tst->arch.vex.guest_r23 = mc->gregs[23];
+  tst->arch.vex.guest_r24 = mc->gregs[24];
+  tst->arch.vex.guest_r25 = mc->gregs[25];
+  tst->arch.vex.guest_r26 = mc->gregs[26];
+  tst->arch.vex.guest_r27 = mc->gregs[27];
+  tst->arch.vex.guest_r28 = mc->gregs[28];
+  tst->arch.vex.guest_r29 = mc->gregs[29];
+  tst->arch.vex.guest_r30 = mc->gregs[30];
+  tst->arch.vex.guest_r31 = mc->gregs[31];
+  tst->arch.vex.guest_r32 = mc->gregs[32];
+  tst->arch.vex.guest_r33 = mc->gregs[33];
+  tst->arch.vex.guest_r34 = mc->gregs[34];
+  tst->arch.vex.guest_r35 = mc->gregs[35];
+  tst->arch.vex.guest_r36 = mc->gregs[36];
+  tst->arch.vex.guest_r37 = mc->gregs[37];
+  tst->arch.vex.guest_r38 = mc->gregs[38];
+  tst->arch.vex.guest_r39 = mc->gregs[39];
+  tst->arch.vex.guest_r40 = mc->gregs[40];
+  tst->arch.vex.guest_r41 = mc->gregs[41];
+  tst->arch.vex.guest_r42 = mc->gregs[42];
+  tst->arch.vex.guest_r43 = mc->gregs[43];
+  tst->arch.vex.guest_r44 = mc->gregs[44];
+  tst->arch.vex.guest_r45 = mc->gregs[45];
+  tst->arch.vex.guest_r46 = mc->gregs[46];
+  tst->arch.vex.guest_r47 = mc->gregs[47];
+  tst->arch.vex.guest_r48 = mc->gregs[48];
+  tst->arch.vex.guest_r49 = mc->gregs[49];
+  tst->arch.vex.guest_r50 = mc->gregs[50];
+  tst->arch.vex.guest_r51 = mc->gregs[51];
+  tst->arch.vex.guest_r52 = mc->gregs[52];
+  tst->arch.vex.guest_r53 = mc->tp;
+  tst->arch.vex.guest_r54 = mc->sp;
+  tst->arch.vex.guest_r55 = mc->lr;
+  tst->arch.vex.guest_pc  = mc->pc;
+
+  VG_TRACK(die_mem_stack_signal, sp, frame_size);
+  if (VG_(clo_trace_signals))
+    VG_(message)( Vg_DebugMsg,
+                  "VG_(signal_return) (thread %d): isRT=%d valid magic; EIP=%#x\n",
+                  tid, isRT, tst->arch.vex.guest_pc);
+  /* tell the tools */
+  VG_TRACK( post_deliver_signal, tid, sigNo );
+}
+
+#endif // defined(VGP_tilegx_linux)
+
+/*--------------------------------------------------------------------*/
+/*--- end                                  sigframe-tilegx-linux.c ---*/
+/*--------------------------------------------------------------------*/
diff --git a/coregrind/m_signals.c b/coregrind/m_signals.c
index 4c34c05..e27a61b 100644
--- a/coregrind/m_signals.c
+++ b/coregrind/m_signals.c
@@ -567,8 +567,21 @@
         (srP)->misc.MIPS64.r31 = (uc)->uc_mcontext.sc_regs[31]; \
         (srP)->misc.MIPS64.r28 = (uc)->uc_mcontext.sc_regs[28]; \
       }
-
-#else 
+#elif defined(VGP_tilegx_linux)
+#  define VG_UCONTEXT_INSTR_PTR(uc)       ((uc)->uc_mcontext.pc)
+#  define VG_UCONTEXT_STACK_PTR(uc)       ((uc)->uc_mcontext.sp)
+#  define VG_UCONTEXT_FRAME_PTR(uc)       ((uc)->uc_mcontext.gregs[52])
+#  define VG_UCONTEXT_SYSCALL_NUM(uc)     ((uc)->uc_mcontext.gregs[10])
+#  define VG_UCONTEXT_SYSCALL_SYSRES(uc)                            \
+      /* Convert the value in uc_mcontext.rax into a SysRes. */     \
+      VG_(mk_SysRes_amd64_linux)((uc)->uc_mcontext.gregs[0])
+#  define VG_UCONTEXT_TO_UnwindStartRegs(srP, uc)              \
+      { (srP)->r_pc = (uc)->uc_mcontext.pc;                    \
+        (srP)->r_sp = (uc)->uc_mcontext.sp;                    \
+        (srP)->misc.TILEGX.r52 = (uc)->uc_mcontext.gregs[52];  \
+        (srP)->misc.TILEGX.r55 = (uc)->uc_mcontext.lr;         \
+      }
+#else
 #  error Unknown platform
 #endif
 
@@ -942,6 +955,14 @@
    "   syscall\n" \
    ".previous\n"
 
+#elif defined(VGP_tilegx_linux)
+#  define _MY_SIGRETURN(name) \
+   ".text\n" \
+   "my_sigreturn:\n" \
+   " moveli r10 ," #name "\n" \
+   " swint1\n" \
+   ".previous\n"
+
 #else
 #  error Unknown platform
 #endif
diff --git a/coregrind/m_stacktrace.c b/coregrind/m_stacktrace.c
index 617f26c..c4672e6 100644
--- a/coregrind/m_stacktrace.c
+++ b/coregrind/m_stacktrace.c
@@ -1392,6 +1392,213 @@
 
 #endif
 
+/* ------------------------ tilegx ------------------------- */
+#if defined(VGP_tilegx_linux)
+UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
+                               /*OUT*/Addr* ips, UInt max_n_ips,
+                               /*OUT*/Addr* sps, /*OUT*/Addr* fps,
+                               const UnwindStartRegs* startRegs,
+                               Addr fp_max_orig )
+{
+   Bool  debug = False;
+   Int   i;
+   Addr  fp_max;
+   UInt  n_found = 0;
+   const Int cmrf = VG_(clo_merge_recursive_frames);
+
+   vg_assert(sizeof(Addr) == sizeof(UWord));
+   vg_assert(sizeof(Addr) == sizeof(void*));
+
+   D3UnwindRegs uregs;
+   uregs.pc = startRegs->r_pc;
+   uregs.sp = startRegs->r_sp;
+   Addr fp_min = uregs.sp;
+
+   uregs.fp = startRegs->misc.TILEGX.r52;
+   uregs.lr = startRegs->misc.TILEGX.r55;
+
+   fp_max = VG_PGROUNDUP(fp_max_orig);
+   if (fp_max >= sizeof(Addr))
+      fp_max -= sizeof(Addr);
+
+   if (debug)
+      VG_(printf)("max_n_ips=%d fp_min=0x%lx fp_max_orig=0x%lx, "
+                  "fp_max=0x%lx pc=0x%lx sp=0x%lx fp=0x%lx\n",
+                  max_n_ips, fp_min, fp_max_orig, fp_max,
+                  uregs.pc, uregs.sp, uregs.fp);
+
+   if (sps) sps[0] = uregs.sp;
+   if (fps) fps[0] = uregs.fp;
+   ips[0] = uregs.pc;
+   i = 1;
+
+   /* Loop unwinding the stack. */
+   while (True) {
+      if (debug) {
+         VG_(printf)("i: %d, pc: 0x%lx, sp: 0x%lx, lr: 0x%lx\n",
+                     i, uregs.pc, uregs.sp, uregs.lr);
+     }
+     if (i >= max_n_ips)
+        break;
+
+     D3UnwindRegs uregs_copy = uregs;
+     if (VG_(use_CF_info)( &uregs, fp_min, fp_max )) {
+        if (debug)
+           VG_(printf)("USING CFI: pc: 0x%lx, sp: 0x%lx, fp: 0x%lx, lr: 0x%lx\n",
+                       uregs.pc, uregs.sp, uregs.fp, uregs.lr);
+        if (0 != uregs.pc && 1 != uregs.pc &&
+            (uregs.pc < fp_min || uregs.pc > fp_max)) {
+           if (sps) sps[i] = uregs.sp;
+           if (fps) fps[i] = uregs.fp;
+           if (uregs.pc != uregs_copy.pc && uregs.sp != uregs_copy.sp)
+              ips[i++] = uregs.pc - 8;
+           uregs.pc = uregs.pc - 8;
+           if (UNLIKELY(cmrf > 0)) { RECURSIVE_MERGE(cmrf,ips,i); };
+           continue;
+        } else
+           uregs = uregs_copy;
+     }
+
+     Long frame_offset = 0;
+     PtrdiffT offset;
+     if (VG_(get_inst_offset_in_function)(uregs.pc, &offset)) {
+        Addr start_pc = uregs.pc;
+        Addr limit_pc = uregs.pc - offset;
+        Addr cur_pc;
+        /* Try to find any stack adjustment from current instruction
+           bundles downward. */
+        for (cur_pc = start_pc; cur_pc > limit_pc; cur_pc -= 8) {
+           ULong inst;
+           Long off = 0;
+           ULong* cur_inst;
+           /* Fetch the instruction.   */
+           cur_inst = (ULong *)cur_pc;
+           inst = *cur_inst;
+           if(debug)
+              VG_(printf)("cur_pc: 0x%lx, inst: 0x%lx\n", cur_pc, inst);
+
+           if ((inst & 0xC000000000000000ULL) == 0) {
+              /* Bundle is X type. */
+             if ((inst & 0xC000000070000fffULL) ==
+                 (0x0000000010000db6ULL)) {
+                /* addli at X0 */
+                off = (short)(0xFFFF & (inst >> 12));
+             } else if ((inst & 0xF80007ff80000000ULL) ==
+                        (0x000006db00000000ULL)) {
+                /* addli at X1 addli*/
+                off = (short)(0xFFFF & (inst >> 43));
+             } else if ((inst & 0xC00000007FF00FFFULL) ==
+                        (0x0000000040100db6ULL)) {
+                /* addi at X0 */
+                off = (char)(0xFF & (inst >> 12));
+             } else if ((inst & 0xFFF807ff80000000ULL) ==
+                        (0x180806db00000000ULL)) {
+                /* addi at X1 */
+                off = (char)(0xFF & (inst >> 43));
+             }
+           } else {
+              /* Bundle is Y type. */
+              if ((inst & 0x0000000078000FFFULL) ==
+                  (0x0000000000000db6ULL)) {
+                 /* addi at Y0 */
+                 off = (char)(0xFF & (inst >> 12));
+              } else if ((inst & 0x3C0007FF80000000ULL) ==
+                         (0x040006db00000000ULL)) {
+                 /* addi at Y1 */
+                 off = (char)(0xFF & (inst >> 43));
+              }
+           }
+
+           if(debug && off)
+              VG_(printf)("offset: -0x%lx\n", -off);
+
+           if (off < 0) {
+              /* frame offset should be modular of 8 */
+              vg_assert((off & 7) == 0);
+              frame_offset += off;
+           } else if (off > 0)
+              /* Exit loop if a positive stack adjustment is found, which
+                 usually means that the stack cleanup code in the function
+                 epilogue is reached.  */
+             break;
+        }
+     }
+
+     if (frame_offset < 0) {
+        if (0 == uregs.pc || 1 == uregs.pc) break;
+
+        /* Subtract the offset from the current stack. */
+        uregs.sp = uregs.sp + (ULong)(-frame_offset);
+
+        if (debug)
+           VG_(printf)("offset: i: %d, pc: 0x%lx, sp: 0x%lx, lr: 0x%lx\n",
+                       i, uregs.pc, uregs.sp, uregs.lr);
+
+        if (uregs.pc == uregs.lr - 8 ||
+            uregs.lr - 8 >= fp_min && uregs.lr - 8 <= fp_max) {
+           if (debug)
+              VG_(printf)("new lr = 0x%lx\n", *(ULong*)uregs.sp);
+           uregs.lr = *(ULong*)uregs.sp;
+        }
+
+        uregs.pc = uregs.lr - 8;
+
+        if (uregs.lr != 0) {
+           /* Avoid the invalid pc = 0xffff...ff8 */
+           if (sps)
+              sps[i] = uregs.sp;
+
+           if (fps)
+              fps[i] = fps[0];
+
+           ips[i++] = uregs.pc;
+
+           if (UNLIKELY(cmrf > 0)) { RECURSIVE_MERGE(cmrf,ips,i); };
+        }
+        continue;
+     }
+
+     /* A special case for the 1st frame. Assume it was a bad jump.
+        Use the link register "lr" and current stack and frame to
+        try again. */
+     if (i == 1) {
+        if (sps) {
+           sps[1] = sps[0];
+           uregs.sp = sps[0];
+        }
+        if (fps) {
+           fps[1] = fps[0];
+           uregs.fp = fps[0];
+        }
+        if (0 == uregs.lr || 1 == uregs.lr)
+           break;
+
+        uregs.pc = uregs.lr - 8;
+        ips[i++] = uregs.lr - 8;
+        if (UNLIKELY(cmrf > 0)) { RECURSIVE_MERGE(cmrf,ips,i); };
+        continue;
+     }
+     /* No luck.  We have to give up. */
+     break;
+   }
+
+   if (debug) {
+      /* Display the back trace. */
+      Int ii ;
+      for ( ii = 0; ii < i; ii++) {
+         if (sps) {
+            VG_(printf)("%d: pc=%lx  ", ii, ips[ii]);
+            VG_(printf)("sp=%lx\n", sps[ii]);
+         } else {
+            VG_(printf)("%d: pc=%lx\n", ii, ips[ii]);
+         }
+      }
+   }
+
+   n_found = i;
+   return n_found;
+}
+#endif
 
 /*------------------------------------------------------------*/
 /*---                                                      ---*/
diff --git a/coregrind/m_syscall.c b/coregrind/m_syscall.c
index cd33958..0d7e1f0 100644
--- a/coregrind/m_syscall.c
+++ b/coregrind/m_syscall.c
@@ -85,6 +85,18 @@
    return res;
 }
 
+SysRes VG_(mk_SysRes_tilegx_linux) ( Long val ) {
+  SysRes res;
+  res._valEx   = 0; /* unused except on mips-linux */
+  res._isError = val >= -4095 && val <= -1;
+  if (res._isError) {
+    res._val = (ULong)(-val);
+  } else {
+    res._val = (ULong)val;
+  }
+  return res;
+}
+
 /* PPC uses the CR7.SO bit to flag an error (CR0 in IBM-speak) */
 /* Note this must be in the bottom bit of the second arg */
 SysRes VG_(mk_SysRes_ppc32_linux) ( UInt val, UInt cr0so ) {
@@ -733,6 +745,27 @@
 ".previous\n"
 );
 
+#elif defined(VGP_tilegx_linux)
+extern UWord do_syscall_WRK (
+          UWord syscall_no, 
+          UWord a1, UWord a2, UWord a3,
+          UWord a4, UWord a5, UWord a6
+       );
+asm(
+    ".text\n"
+    "do_syscall_WRK:\n"
+    "move  r10, r0\n"
+    "move  r0,  r1\n"
+    "move  r1,  r2\n"
+    "move  r2,  r3\n"
+    "move  r3,  r4\n"
+    "move  r4,  r5\n"
+    "move  r5,  r6\n"
+    "swint1\n"
+    "jrp   lr\n"
+    ".previous\n"
+    );
+
 #else
 #  error Unknown platform
 #endif
@@ -861,6 +894,11 @@
    ULong A3 = (ULong)v1_a3[1];
    return VG_(mk_SysRes_mips64_linux)( V0, V1, A3 );
 
+#  elif defined(VGP_tilegx_linux)
+   UWord val = do_syscall_WRK(sysno,a1,a2,a3,a4,a5,a6);
+
+   return VG_(mk_SysRes_tilegx_linux)( val );
+
 #else
 #  error Unknown platform
 #endif
diff --git a/coregrind/m_syswrap/priv_types_n_macros.h b/coregrind/m_syswrap/priv_types_n_macros.h
index 62ce783..14f1780 100644
--- a/coregrind/m_syswrap/priv_types_n_macros.h
+++ b/coregrind/m_syswrap/priv_types_n_macros.h
@@ -93,7 +93,8 @@
          || defined(VGP_ppc32_linux) \
          || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
          || defined(VGP_arm_linux) || defined(VGP_s390x_linux) \
-         || defined(VGP_mips64_linux) || defined(VGP_arm64_linux)
+         || defined(VGP_mips64_linux) || defined(VGP_arm64_linux) \
+         || defined(VGP_tilegx_linux)
       Int o_arg1;
       Int o_arg2;
       Int o_arg3;
diff --git a/coregrind/m_syswrap/syscall-tilegx-linux.S b/coregrind/m_syswrap/syscall-tilegx-linux.S
new file mode 100644
index 0000000..0bd3756
--- /dev/null
+++ b/coregrind/m_syswrap/syscall-tilegx-linux.S
@@ -0,0 +1,191 @@
+/*--------------------------------------------------------------------*/
+/*--- Support for doing system calls.      syscall-tilegx-linux.S  ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+   This file is part of Valgrind, a dynamic binary instrumentation
+   framework.
+
+   Copyright (C) 2010-2012 Tilera Corp.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   This program 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
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307, USA.
+
+   The GNU General Public License is contained in the file COPYING.
+*/
+
+/* Contributed by Zhi-Gang Liu <zliu at tilera dot com> */
+
+#if defined(VGP_tilegx_linux)
+
+#include "pub_core_basics_asm.h"
+#include "pub_core_vkiscnums_asm.h"
+#include "libvex_guest_offsets.h"
+
+
+/*----------------------------------------------------------------*/
+/*
+   Perform a syscall for the client.  This will run a syscall
+   with the client's specific per-thread signal mask.
+
+   The structure of this function is such that, if the syscall is
+   interrupted by a signal, we can determine exactly what
+   execution state we were in with respect to the execution of
+   the syscall by examining the value of IP in the signal
+   handler.  This means that we can always do the appropriate
+   thing to precisely emulate the kernel's signal/syscall
+   interactions.
+
+   The syscall number is taken from the argument, even though it
+   should also be in regs->v0.  The syscall result is written
+   back to regs->v0 on completion.
+
+   Returns 0 if the syscall was successfully called (even if the
+   syscall itself failed), or a nonzero error code in the lowest
+   8 bits if one of the sigprocmasks failed (there's no way to
+   determine which one failed).  And there's no obvious way to
+   recover from that either, but nevertheless we want to know.
+
+   VG_(fixup_guest_state_after_syscall_interrupted) does the
+   thread state fixup in the case where we were interrupted by a
+   signal.
+
+   Prototype:
+
+   UWord ML_(do_syscall_for_client_WRK)(
+        Int syscallno,                 // r0
+        void* guest_state,             // r1
+        const vki_sigset_t *sysmask,   // r2
+        const vki_sigset_t *postmask,  // r3
+        Int nsigwords)                 // r4
+*/
+/* from vki_arch.h */
+#define VKI_SIG_SETMASK 2
+
+.globl ML_(do_syscall_for_client_WRK)
+ML_(do_syscall_for_client_WRK):
+
+    addli  sp,  sp, -64   // alloc 64B new stack space
+    addli  r29, sp, 56    // r29 points to offset 56 above sp
+    st_add r29, r0, -8    // save r0
+                          // offset 48
+    st_add r29, r1, -8    // save r1
+                          // offset 40
+    st_add r29, r2, -8    // save r2
+                          // offset 32
+    st_add r29, r3, -8    // save r3
+                          // offset 24
+    st_add r29, r4, -8    // save r4
+                          // offset 16
+    st     r29, lr        // save lr
+1:
+    {
+     moveli r10, __NR_rt_sigprocmask
+     moveli r0, VKI_SIG_SETMASK
+    }
+    {
+     move   r1, r2
+     move   r2, r3
+    }
+    move   r3, r4
+    swint1
+
+    // error, go 7f
+    bnez  r1, 7f
+
+    /* Get registers from guest_state. */
+    addli  r29, sp, 56    // get syscallno
+    ld     r10, r29
+    addli  r29, sp, 48
+    ld     r29, r29       // r29 points to guest_state
+    ld_add r0, r29, 8     // read r0
+    ld_add r1, r29, 8     // read r1
+    ld_add r2, r29, 8     // read r2
+    ld_add r3, r29, 8     // read r3
+    ld_add r4, r29, 8     // read r4
+    ld_add r5, r29, 8     // read r5
+
+2:  swint1                // syscall
+3:
+    // Write register into guest_state
+    addli  r29, sp, 48
+    ld     r29, r29
+    st_add r29, r0, 8
+    st_add r29, r1, 8
+    st_add r29, r2, 8
+    st_add r29, r3, 8
+    st_add r29, r4, 8
+    st_add r29, r5, 8
+    nop
+4:
+    {
+     moveli r10, __NR_rt_sigprocmask
+     moveli r0, VKI_SIG_SETMASK
+    }
+    addli  r29, sp, 32
+    {
+     ld     r1, r29
+     movei  r2, 0
+    }
+    addli  r29, sp, 24
+    ld     r3, r29
+
+    swint1
+    // error, go 7f
+    bnez  r1, 7f
+    nop
+5:  addli  r29, sp, 16
+    {
+     ld     lr, r29       // restore lr
+     addli  sp, sp,  64
+    }
+    jr lr
+
+7:  addi   r29, sp, 16
+    {
+     ld     lr, r29       // restore lr
+     addi   sp, sp, 64
+    }
+    {
+     // r0 = 0x8000
+     shl16insli r0, zero, -0x8000
+     jr lr
+    }
+
+    .section .rodata
+    /* export the ranges so that
+       VG_(fixup_guest_state_after_syscall_interrupted) can do the
+       right thing */
+
+    .globl ML_(blksys_setup)
+    .globl ML_(blksys_restart)
+    .globl ML_(blksys_complete)
+    .globl ML_(blksys_committed)
+    .globl ML_(blksys_finished)
+    ML_(blksys_setup):      .quad 1b
+    ML_(blksys_restart):    .quad 2b
+    ML_(blksys_complete):   .quad 3b
+    ML_(blksys_committed):  .quad 4b
+    ML_(blksys_finished):   .quad 5b
+    .previous
+    /* Let the linker know we don't need an executable stack */
+    .section .note.GNU-stack,"",%progbits
+
+#endif /* defined(VGP_tilegx_linux) */
+
+/*--------------------------------------------------------------------*/
+/*--- end                                                          ---*/
+/*--------------------------------------------------------------------*/
+
diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c
index f0c9793..a98d10a 100644
--- a/coregrind/m_syswrap/syswrap-linux.c
+++ b/coregrind/m_syswrap/syswrap-linux.c
@@ -297,6 +297,15 @@
          : "r" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
          : "cc", "memory" , "v0", "a0"
       );
+#elif defined(VGP_tilegx_linux)
+      asm volatile (
+         "st4    %0,  %1\n"      /* set tst->status = VgTs_Empty */
+         "moveli r10, %2\n"      /* set r10 = __NR_exit */
+         "move   r0,  %3\n"      /* set  r0 = tst->os_state.exitcode */
+         "swint1\n"              /* exit(tst->os_state.exitcode) */
+         : "=m" (tst->status)
+         : "r" (VgTs_Empty), "n" (__NR_exit), "r" (tst->os_state.exitcode)
+         : "r0", "r1", "r2", "r3", "r4", "r5");
 #else
 # error Unknown platform
 #endif
@@ -446,7 +455,7 @@
    res = VG_(do_syscall5)( __NR_clone, flags, 
                            (UWord)NULL, (UWord)parent_tidptr, 
                            (UWord)NULL, (UWord)child_tidptr );
-#elif defined(VGP_amd64_linux)
+#elif defined(VGP_amd64_linux) || defined(VGP_tilegx_linux)
    /* note that the last two arguments are the opposite way round to x86 and
       ppc32 as the amd64 kernel expects the arguments in a different order */
    res = VG_(do_syscall5)( __NR_clone, flags, 
@@ -5223,7 +5232,8 @@
 }
 #endif
 
-#if defined(VGP_amd64_linux) || defined(VGP_s390x_linux)
+#if defined(VGP_amd64_linux) || defined(VGP_s390x_linux)        \
+      || defined(VGP_tilegx_linux)
 PRE(sys_lookup_dcookie)
 {
    *flags |= SfMayBlock;
diff --git a/coregrind/m_syswrap/syswrap-main.c b/coregrind/m_syswrap/syswrap-main.c
index d9c24a5..cf45638 100644
--- a/coregrind/m_syswrap/syswrap-main.c
+++ b/coregrind/m_syswrap/syswrap-main.c
@@ -650,6 +650,19 @@
    canonical->arg6  = gst->guest_r7;
    canonical->arg7  = 0;
    canonical->arg8  = 0;
+
+#elif defined(VGP_tilegx_linux)
+   VexGuestTILEGXState* gst = (VexGuestTILEGXState*)gst_vanilla;
+   canonical->sysno = gst->guest_r10;
+   canonical->arg1  = gst->guest_r0;
+   canonical->arg2  = gst->guest_r1;
+   canonical->arg3  = gst->guest_r2;
+   canonical->arg4  = gst->guest_r3;
+   canonical->arg5  = gst->guest_r4;
+   canonical->arg6  = gst->guest_r5;
+   canonical->arg7  = 0;
+   canonical->arg8  = 0;
+
 #else
 #  error "getSyscallArgsFromGuestState: unknown arch"
 #endif
@@ -794,6 +807,17 @@
    gst->guest_r7 = canonical->arg4;
    gst->guest_r8 = canonical->arg5;
    gst->guest_r9 = canonical->arg6;
+
+#elif defined(VGP_tilegx_linux)
+   VexGuestTILEGXState* gst = (VexGuestTILEGXState*)gst_vanilla;
+   gst->guest_r10 = canonical->sysno;
+   gst->guest_r0 = canonical->arg1;
+   gst->guest_r1 = canonical->arg2;
+   gst->guest_r2 = canonical->arg3;
+   gst->guest_r3 = canonical->arg4;
+   gst->guest_r4 = canonical->arg5;
+   gst->guest_r5 = canonical->arg6;
+
 #else
 #  error "putSyscallArgsIntoGuestState: unknown arch"
 #endif
@@ -922,6 +946,11 @@
    canonical->sres = VG_(mk_SysRes_s390x_linux)( gst->guest_r2 );
    canonical->what = SsComplete;
 
+#  elif defined(VGP_tilegx_linux)
+   VexGuestTILEGXState* gst = (VexGuestTILEGXState*)gst_vanilla;
+   canonical->sres = VG_(mk_SysRes_tilegx_linux)( gst->guest_r0 );
+   canonical->what = SsComplete;
+
 #  else
 #    error "getSyscallStatusFromGuestState: unknown arch"
 #  endif
@@ -1135,6 +1164,18 @@
    VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
              OFFSET_mips64_r7, sizeof(UWord) );
 
+#  elif defined(VGP_tilegx_linux)
+   VexGuestTILEGXState* gst = (VexGuestTILEGXState*)gst_vanilla;
+   vg_assert(canonical->what == SsComplete);
+   if (sr_isError(canonical->sres)) {
+      gst->guest_r0 = - (Long)sr_Err(canonical->sres);
+      // r1 hold errno
+      gst->guest_r1 = (Long)sr_Err(canonical->sres);
+   } else {
+      gst->guest_r0 = sr_Res(canonical->sres);
+      gst->guest_r1 = 0;
+   }
+
 #  else
 #    error "putSyscallStatusIntoGuestState: unknown arch"
 #  endif
@@ -1271,6 +1312,17 @@
    layout->o_arg6   = OFFSET_s390x_r7;
    layout->uu_arg7  = -1; /* impossible value */
    layout->uu_arg8  = -1; /* impossible value */
+#elif defined(VGP_tilegx_linux)
+   layout->o_sysno  = OFFSET_tilegx_r(10);
+   layout->o_arg1   = OFFSET_tilegx_r(0);
+   layout->o_arg2   = OFFSET_tilegx_r(1);
+   layout->o_arg3   = OFFSET_tilegx_r(2);
+   layout->o_arg4   = OFFSET_tilegx_r(3);
+   layout->o_arg5   = OFFSET_tilegx_r(4);
+   layout->o_arg6   = OFFSET_tilegx_r(5);
+   layout->uu_arg7  = -1; /* impossible value */
+   layout->uu_arg8  = -1; /* impossible value */
+
 #else
 #  error "getSyscallLayout: unknown arch"
 #endif
@@ -2175,6 +2227,21 @@
 #        error "Unknown endianness"
 #     endif
    }
+#elif defined(VGP_tilegx_linux)
+   arch->vex.guest_pc -= 8;             // sizeof({ swint1 })
+
+   /* Make sure our caller is actually sane, and we're really backing
+      back over a syscall. no other instruction in same bundle.
+   */
+   {
+      unsigned long *p = (unsigned long *)arch->vex.guest_pc;
+
+      if (p[0] != 0x286b180051485000ULL )  // "swint1", little enidan only
+         VG_(message)(Vg_DebugMsg,
+                      "?! restarting over syscall at 0x%lx %lx\n",
+                      arch->vex.guest_pc, p[0]);
+      vg_assert(p[0] == 0x286b180051485000ULL);
+   }
 
 #else
 #  error "ML_(fixup_guest_state_to_restart_syscall): unknown plat"
diff --git a/coregrind/m_syswrap/syswrap-tilegx-linux.c b/coregrind/m_syswrap/syswrap-tilegx-linux.c
new file mode 100644
index 0000000..28ee5df
--- /dev/null
+++ b/coregrind/m_syswrap/syswrap-tilegx-linux.c
@@ -0,0 +1,1399 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Platform-specific syscalls stuff.    syswrap-tilegx-linux.c ----*/
+/*--------------------------------------------------------------------*/
+
+/*
+  This file is part of Valgrind, a dynamic binary instrumentation
+  framework.
+
+  Copyright (C) 2010-2013 Tilera Corp.
+
+  This program is free software; you can redistribute it and/or
+  modify it under the terms of the GNU General Public License as
+  published by the Free Software Foundation; either version 2 of the
+  License, or (at your option) any later version.
+
+  This program 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
+  General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+  02111-1307, USA.
+
+  The GNU General Public License is contained in the file COPYING.
+*/
+
+/* Contributed by Zhi-Gang Liu */
+
+#if defined(VGP_tilegx_linux)
+#include "pub_core_basics.h"
+#include "pub_core_vki.h"
+#include "pub_core_vkiscnums.h"
+#include "pub_core_libcsetjmp.h"    // to keep _threadstate.h happy
+#include "pub_core_threadstate.h"
+#include "pub_core_aspacemgr.h"
+#include "pub_core_debuglog.h"
+#include "pub_core_libcbase.h"
+#include "pub_core_libcassert.h"
+#include "pub_core_libcprint.h"
+#include "pub_core_libcproc.h"
+#include "pub_core_libcsignal.h"
+#include "pub_core_options.h"
+#include "pub_core_scheduler.h"
+#include "pub_core_sigframe.h"     // For VG_(sigframe_destroy)()
+#include "pub_core_signals.h"
+#include "pub_core_syscall.h"
+#include "pub_core_syswrap.h"
+#include "pub_core_tooliface.h"
+#include "pub_core_stacks.h"        // VG_(register_stack)
+#include "pub_core_transtab.h"      // VG_(discard_translations)
+#include "priv_types_n_macros.h"
+#include "priv_syswrap-generic.h"   /* for decls of generic wrappers */
+#include "priv_syswrap-linux.h"     /* for decls of linux wrappers */
+#include "priv_syswrap-main.h"
+
+#include "pub_core_debuginfo.h"     // VG_(di_notify_*)
+#include "pub_core_xarray.h"
+#include "pub_core_clientstate.h"   // VG_(brk_base), VG_(brk_limit)
+#include "pub_core_errormgr.h"
+#include "pub_core_libcfile.h"
+#include "pub_core_machine.h"       // VG_(get_SP)
+#include "pub_core_mallocfree.h"
+#include "pub_core_stacktrace.h"    // For VG_(get_and_pp_StackTrace)()
+#include "pub_core_ume.h"
+
+#include "config.h"
+
+/* ---------------------------------------------------------------------
+   clone() handling
+   ------------------------------------------------------------------ */
+/* Call f(arg1), but first switch stacks, using 'stack' as the new
+   stack, and use 'retaddr' as f's return-to address.  Also, clear all
+   the integer registers before entering f.*/
+
+__attribute__ ((noreturn))
+void ML_(call_on_new_stack_0_1) (Addr stack, Addr retaddr,
+                                 void (*f) (Word), Word arg1);
+                                //    r0 = stack
+                                //    r1 = retaddr
+                                //    r2 = f
+                                //    r3 = arg1
+     asm (
+       ".text\n"
+       ".globl vgModuleLocal_call_on_new_stack_0_1\n"
+       "vgModuleLocal_call_on_new_stack_0_1:\n"
+       "  {\n"
+       "   move sp, r0\n\t"
+       "   move r51, r2\n\t"
+       "  }\n"
+       "  {\n"
+       "   move r0, r3\n\t"
+       "   move r1, zero\n\t"
+       "  }\n"
+       "  {\n"
+       "   move r2, zero\n\t"
+       "   move r3, zero\n\t"
+       "  }\n"
+       "  {\n"
+       "   move r4, zero\n\t"
+       "   move r5, zero\n\t"
+       "  }\n"
+       "  {\n"
+       "   move r6, zero\n\t"
+       "   move r7, zero\n\t"
+       "  }\n"
+       "  {\n"
+       "   move r8, zero\n\t"
+       "   move r9, zero\n\t"
+       "  }\n"
+       "  {\n"
+       "   move r10, zero\n\t"
+       "   move r11, zero\n\t"
+       "  }\n"
+       "  {\n"
+       "   move r12, zero\n\t"
+       "   move r13, zero\n\t"
+       "  }\n"
+       "  {\n"
+       "   move r14, zero\n\t"
+       "   move r15, zero\n\t"
+       "  }\n"
+       "  {\n"
+       "   move r16, zero\n\t"
+       "   move r17, zero\n\t"
+       "  }\n"
+       "  {\n"
+       "   move r18, zero\n\t"
+       "   move r19, zero\n\t"
+       "  }\n"
+       "  {\n"
+       "   move r20, zero\n\t"
+       "   move r21, zero\n\t"
+       "  }\n"
+       "  {\n"
+       "   move r22, zero\n\t"
+       "   move r23, zero\n\t"
+       "  }\n"
+       "  {\n"
+       "   move r24, zero\n\t"
+       "   move r25, zero\n\t"
+       "  }\n"
+       "  {\n"
+       "   move r26, zero\n\t"
+       "   move r27, zero\n\t"
+       "  }\n"
+       "  {\n"
+       "   move r28, zero\n\t"
+       "   move r29, zero\n\t"
+       "  }\n"
+       "  {\n"
+       "   move r30, zero\n\t"
+       "   move r31, zero\n\t"
+       "  }\n"
+       "  {\n"
+       "   move r32, zero\n\t"
+       "   move r33, zero\n\t"
+       "  }\n"
+       "  {\n"
+       "   move r34, zero\n\t"
+       "   move r35, zero\n\t"
+       "  }\n"
+       "  {\n"
+       "   move r36, zero\n\t"
+       "   move r37, zero\n\t"
+       "  }\n"
+       "  {\n"
+       "   move r38, zero\n\t"
+       "   move r39, zero\n\t"
+       "  }\n"
+       "  {\n"
+       "   move r40, zero\n\t"
+       "   move r41, zero\n\t"
+       "  }\n"
+       "  {\n"
+       "   move r42, zero\n\t"
+       "   move r43, zero\n\t"
+       "  }\n"
+       "  {\n"
+       "   move r44, zero\n\t"
+       "   move r45, zero\n\t"
+       "  }\n"
+       "  {\n"
+       "   move r46, zero\n\t"
+       "   move r47, zero\n\t"
+       "  }\n"
+       "  {\n"
+       "   move r48, zero\n\t"
+       "   move r49, zero\n\t"
+       "  }\n"
+       "  {\n"
+       "   move r50, zero\n\t"
+       "   jr      r51\n\t"
+       "  }\n"
+       "   ill \n"    // should never get here
+          );
+/*
+  Perform a clone system call.  clone is strange because it has
+  fork()-like return-twice semantics, so it needs special
+  handling here.
+  Upon entry, we have:
+  int (fn)(void*)     in  r0
+  void* child_stack   in  r1
+  int flags           in  r2
+  void* arg           in  r3
+  pid_t* child_tid    in  r4
+  pid_t* parent_tid   in  r5
+  void* tls_ptr       in  r6
+
+  System call requires:
+  int    $__NR_clone  in r10
+  int    flags        in r0
+  void*  child_stack  in r1
+  pid_t* parent_tid   in r2
+  void*  tls_ptr      in $r3
+  pid_t* child_tid    in sr4
+
+  int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
+  void *parent_tidptr, void *tls, void *child_tidptr)
+
+  Returns an Int encoded in the linux-tilegx way, not a SysRes.
+*/
+#define __NR_CLONE        VG_STRINGIFY(__NR_clone)
+#define __NR_EXIT         VG_STRINGIFY(__NR_exit)
+
+Long do_syscall_clone_tilegx_linux ( Word (*fn) (void *),  //r0
+                                     void *stack,          //r1
+                                     Long flags,           //r2
+                                     void *arg,            //r3
+                                     Long * child_tid,     //r4
+                                     Long * parent_tid,    //r5
+                                     Long   tls );         //r6
+    /*
+      stack
+      high -> 4  r29
+      3
+      2
+      1  r10
+      low  -> 0  lr    <- sp
+    */
+     asm (
+       ".text\n"
+       "   .globl   do_syscall_clone_tilegx_linux\n"
+       "   do_syscall_clone_tilegx_linux:\n"
+       "   beqz  r0, .Linvalid\n"
+       "   beqz  r1, .Linvalid\n"
+       "   {\n"
+       "    st    sp, r29; "       // save r29 at top
+       "    addli sp, sp, -32\n"   // open new stack space
+       "   }\n"
+
+       "    move  r29, sp; "       // r29 <- sp
+       "    st    r29, lr\n"       // save lr at 0(sp)
+
+       "    addi  r29, r29, 8\n"
+       "   {\n"
+       "    st    r29, r10\n"      // save r10 at 8(sp)
+       /*  setup child stack */
+       "    addi  r1, r1, -32\n"   // new stack frame for child
+       "   }\n"
+       /*  save fn */
+       "   { st  r1, r0; addi r1, r1, 8 }\n"
+       /*  save args */
+       "   { st  r1, r3; addi r1, r1, 8 }\n"
+       /*  save flags */
+       "   { st  r1, r2; addi r1, r1, -16 }\n"
+
+       /*  Child stack layout
+
+           flags
+           args
+           r1->  fn
+       */
+       "   {\n"
+       /*   prepare args for clone. */
+       "    move r0,  r2\n"   // arg0 = flags
+       /*   arg1=r1 child stack */
+       "    move r2,  r5\n"   // arg2 = parent tid
+       "   }\n"
+       "   {\n"
+       "    move r3,  r4\n"   // arg3 = child tid
+       "    move r4,  r6\n"   // arg4 = tls
+       "   }\n"
+       "   moveli r10, " __NR_CLONE "\n"
+       "   swint1\n"
+
+       "   beqz  r0, .Lchild\n"
+       "   move r29, sp\n"
+       "   ld   lr, r29\n"        // Restore lr
+       "   addi r29, r29, 8\n"
+       "   {\n"
+       "    ld   r10,  r29\n"      // resotre r10
+       "    addi sp, sp, 32\n"
+       "   }\n"
+       "   ld   r29, sp\n"
+       "   jrp  lr\n"
+
+       ".Lchild:"
+       "   move r2, sp\n"
+       "   {\n"
+       "    ld   r3, r2\n"
+       "    addi r2, r2, 8\n"
+       "   }\n"
+       "   ld   r0, r2\n"
+       "   jalr r3\n"
+       "   moveli r10, " __NR_EXIT "\n"
+       "   swint1\n"
+
+       ".Linvalid:"
+       "  { movei r1, 22; jrp lr }\n"
+          );
+
+#undef __NR_CLONE
+#undef __NR_EXIT
+
+// forward declarations
+static void setup_child ( ThreadArchState *, ThreadArchState * );
+static SysRes sys_set_tls ( ThreadId tid, Addr tlsptr );
+ /*
+   When a client clones, we need to keep track of the new thread.  This means:
+   1. allocate a ThreadId+ThreadState+stack for the the thread
+   2. initialize the thread's new VCPU state
+   3. create the thread using the same args as the client requested,
+   but using the scheduler entrypoint for IP, and a separate stack
+   for SP.
+ */
+static SysRes do_clone ( ThreadId ptid,
+                         Long flags, Addr sp,
+                         Long * parent_tidptr,
+                         Long * child_tidptr,
+                         Addr child_tls )
+{
+  const Bool debug = False;
+  ThreadId ctid = VG_ (alloc_ThreadState) ();
+  ThreadState * ptst = VG_ (get_ThreadState) (ptid);
+  ThreadState * ctst = VG_ (get_ThreadState) (ctid);
+  Long ret = 0;
+  Long * stack;
+  NSegment const *seg;
+  SysRes res;
+  vki_sigset_t blockall, savedmask;
+
+  VG_ (sigfillset) (&blockall);
+  vg_assert (VG_ (is_running_thread) (ptid));
+  vg_assert (VG_ (is_valid_tid) (ctid));
+  stack = (Long *) ML_ (allocstack) (ctid);
+  if (stack == NULL) {
+    res = VG_ (mk_SysRes_Error) (VKI_ENOMEM);
+    goto out;
+  }
+  setup_child (&ctst->arch, &ptst->arch);
+
+  /* On TILEGX we need to set r0 and r3 to zero */
+  ctst->arch.vex.guest_r0 = 0;
+  ctst->arch.vex.guest_r3 = 0;
+  if (sp != 0)
+    ctst->arch.vex.guest_r54 = sp;
+
+  ctst->os_state.parent = ptid;
+  ctst->sig_mask = ptst->sig_mask;
+  ctst->tmp_sig_mask = ptst->sig_mask;
+
+  /* Start the child with its threadgroup being the same as the
+     parent's.  This is so that any exit_group calls that happen
+     after the child is created but before it sets its
+     os_state.threadgroup field for real (in thread_wrapper in
+     syswrap-linux.c), really kill the new thread.  a.k.a this avoids
+     a race condition in which the thread is unkillable (via
+     exit_group) because its threadgroup is not set.  The race window
+     is probably only a few hundred or a few thousand cycles long.
+     See #226116. */
+
+  ctst->os_state.threadgroup = ptst->os_state.threadgroup;
+  seg = VG_ (am_find_nsegment) ((Addr) sp);
+
+  if (seg && seg->kind != SkResvn) {
+    ctst->client_stack_highest_byte = (Addr) VG_PGROUNDUP (sp);
+    ctst->client_stack_szB = ctst->client_stack_highest_byte - seg->start;
+    VG_ (register_stack) (seg->start, ctst->client_stack_highest_byte);
+    if (debug)
+      VG_ (printf) ("tid %d: guessed client stack range %#lx-%#lx\n",
+
+                    ctid, seg->start, VG_PGROUNDUP (sp));
+  } else {
+    VG_ (message) (Vg_UserMsg,
+                   "!? New thread %d starts with sp+%#lx) unmapped\n",
+                   ctid, sp);
+    ctst->client_stack_szB = 0;
+  }
+
+  VG_TRACK (pre_thread_ll_create, ptid, ctid);
+  if (flags & VKI_CLONE_SETTLS) {
+    if (debug)
+      VG_(printf)("clone child has SETTLS: tls at %#lx\n", child_tls);
+    ctst->arch.vex.guest_r53 = child_tls;
+    res = sys_set_tls(ctid, child_tls);
+    if (sr_isError(res))
+      goto out;
+  }
+
+  flags &= ~VKI_CLONE_SETTLS;
+  VG_ (sigprocmask) (VKI_SIG_SETMASK, &blockall, &savedmask);
+  /* Create the new thread */
+  ret = do_syscall_clone_tilegx_linux (ML_ (start_thread_NORETURN),
+                                       stack, flags, &VG_ (threads)[ctid],
+                                       child_tidptr, parent_tidptr,
+                                       (Long)NULL /*child_tls*/);
+
+  /* High half word64 is syscall return value. */
+  if (debug)
+    VG_(printf)("ret: 0x%lx\n", ret);
+
+  res = VG_(mk_SysRes_tilegx_linux) (/*val */ ret);
+
+  VG_ (sigprocmask) (VKI_SIG_SETMASK, &savedmask, NULL);
+
+ out:
+  if (sr_isError (res)) {
+    VG_(cleanup_thread) (&ctst->arch);
+    ctst->status = VgTs_Empty;
+    VG_TRACK (pre_thread_ll_exit, ctid);
+  }
+  ptst->arch.vex.guest_r0 = 0;
+
+  return res;
+}
+
+extern Addr do_brk ( Addr newbrk );
+
+extern
+SysRes do_mremap( Addr old_addr, SizeT old_len,
+                  Addr new_addr, SizeT new_len,
+                  UWord flags, ThreadId tid );
+
+extern Bool linux_kernel_2_6_22(void);
+
+/* ---------------------------------------------------------------------
+   More thread stuff
+   ------------------------------------------------------------------ */
+
+// TILEGX doesn't have any architecture specific thread stuff that
+// needs to be cleaned up.
+void
+VG_ (cleanup_thread) ( ThreadArchState * arch ) { }
+
+void
+setup_child ( /*OUT*/ ThreadArchState * child,
+              /*IN*/ ThreadArchState * parent )
+{
+  /* We inherit our parent's guest state. */
+  child->vex = parent->vex;
+  child->vex_shadow1 = parent->vex_shadow1;
+  child->vex_shadow2 = parent->vex_shadow2;
+}
+
+SysRes sys_set_tls ( ThreadId tid, Addr tlsptr )
+{
+  VG_(threads)[tid].arch.vex.guest_r53 = tlsptr;
+  return VG_(mk_SysRes_Success)( 0 );
+}
+
+
+/* ---------------------------------------------------------------------
+   PRE/POST wrappers for tilegx/Linux-specific syscalls
+   ------------------------------------------------------------------ */
+#define PRE(name)       DEFN_PRE_TEMPLATE(tilegx_linux, name)
+#define POST(name)      DEFN_POST_TEMPLATE(tilegx_linux, name)
+
+/* Add prototypes for the wrappers declared here, so that gcc doesn't
+   harass us for not having prototypes.  Really this is a kludge --
+   the right thing to do is to make these wrappers 'static' since they
+   aren't visible outside this file, but that requires even more macro
+   magic. */
+
+DECL_TEMPLATE(tilegx_linux, sys_clone);
+DECL_TEMPLATE(tilegx_linux, sys_rt_sigreturn);
+DECL_TEMPLATE(tilegx_linux, sys_socket);
+DECL_TEMPLATE(tilegx_linux, sys_setsockopt);
+DECL_TEMPLATE(tilegx_linux, sys_getsockopt);
+DECL_TEMPLATE(tilegx_linux, sys_connect);
+DECL_TEMPLATE(tilegx_linux, sys_accept);
+DECL_TEMPLATE(tilegx_linux, sys_accept4);
+DECL_TEMPLATE(tilegx_linux, sys_sendto);
+DECL_TEMPLATE(tilegx_linux, sys_recvfrom);
+DECL_TEMPLATE(tilegx_linux, sys_sendmsg);
+DECL_TEMPLATE(tilegx_linux, sys_recvmsg);
+DECL_TEMPLATE(tilegx_linux, sys_shutdown);
+DECL_TEMPLATE(tilegx_linux, sys_bind);
+DECL_TEMPLATE(tilegx_linux, sys_listen);
+DECL_TEMPLATE(tilegx_linux, sys_getsockname);
+DECL_TEMPLATE(tilegx_linux, sys_getpeername);
+DECL_TEMPLATE(tilegx_linux, sys_socketpair);
+DECL_TEMPLATE(tilegx_linux, sys_semget);
+DECL_TEMPLATE(tilegx_linux, sys_semop);
+DECL_TEMPLATE(tilegx_linux, sys_semtimedop);
+DECL_TEMPLATE(tilegx_linux, sys_semctl);
+DECL_TEMPLATE(tilegx_linux, sys_msgget);
+DECL_TEMPLATE(tilegx_linux, sys_msgrcv);
+DECL_TEMPLATE(tilegx_linux, sys_msgsnd);
+DECL_TEMPLATE(tilegx_linux, sys_msgctl);
+DECL_TEMPLATE(tilegx_linux, sys_shmget);
+DECL_TEMPLATE(tilegx_linux, wrap_sys_shmat);
+DECL_TEMPLATE(tilegx_linux, sys_shmdt);
+DECL_TEMPLATE(tilegx_linux, sys_shmdt);
+DECL_TEMPLATE(tilegx_linux, sys_shmctl);
+DECL_TEMPLATE(tilegx_linux, sys_arch_prctl);
+DECL_TEMPLATE(tilegx_linux, sys_ptrace);
+DECL_TEMPLATE(tilegx_linux, sys_fadvise64);
+DECL_TEMPLATE(tilegx_linux, sys_mmap);
+DECL_TEMPLATE(tilegx_linux, sys_syscall184);
+DECL_TEMPLATE(tilegx_linux, sys_set_dataplane);
+
+PRE(sys_clone)
+{
+  ULong cloneflags;
+
+  PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
+  PRE_REG_READ5(int, "clone",
+                unsigned long, flags,
+                void *, child_stack,
+                int *, parent_tidptr,
+                int *, child_tidptr,
+                void *, tlsaddr);
+
+  if (ARG1 & VKI_CLONE_PARENT_SETTID) {
+    PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
+    if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int), VKI_PROT_WRITE)) {
+      SET_STATUS_Failure( VKI_EFAULT );
+      return;
+    }
+  }
+  if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
+    PRE_MEM_WRITE("clone(child_tidptr)", ARG4, sizeof(Int));
+    if (!VG_(am_is_valid_for_client)(ARG4, sizeof(Int), VKI_PROT_WRITE)) {
+      SET_STATUS_Failure( VKI_EFAULT );
+      return;
+    }
+  }
+
+  cloneflags = ARG1;
+
+  if (!ML_(client_signal_OK)(ARG1 & VKI_CSIGNAL)) {
+    SET_STATUS_Failure( VKI_EINVAL );
+    return;
+  }
+
+  /* Only look at the flags we really care about */
+  switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
+                        | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
+  case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
+    /* thread creation */
+    SET_STATUS_from_SysRes(
+      do_clone(tid,
+               ARG1,          /* flags */
+               (Addr)ARG2,    /* child ESP */
+               (Long *)ARG3,  /* parent_tidptr */
+               (Long *)ARG4,  /* child_tidptr */
+               (Addr)ARG5));  /* set_tls */
+    break;
+
+  case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
+    /* FALLTHROUGH - assume vfork == fork */
+    cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
+
+  case 0: /* plain fork */
+    SET_STATUS_from_SysRes(
+      ML_(do_fork_clone)(tid,
+                         cloneflags,      /* flags */
+                         (Int *)ARG3,     /* parent_tidptr */
+                         (Int *)ARG4));   /* child_tidptr */
+    break;
+
+  default:
+    /* should we just ENOSYS? */
+    VG_(message)(Vg_UserMsg,
+                 "Unsupported clone() flags: 0x%lx\n", ARG1);
+    VG_(message)(Vg_UserMsg,
+                 "\n");
+    VG_(message)(Vg_UserMsg,
+                 "The only supported clone() uses are:\n");
+    VG_(message)(Vg_UserMsg,
+                 " - via a threads library (LinuxThreads or NPTL)\n");
+    VG_(message)(Vg_UserMsg,
+                 " - via the implementation of fork or vfork\n");
+    VG_(unimplemented)
+      ("Valgrind does not support general clone().");
+  }
+
+  if (SUCCESS) {
+    if (ARG1 & VKI_CLONE_PARENT_SETTID)
+      POST_MEM_WRITE(ARG3, sizeof(Int));
+    if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
+      POST_MEM_WRITE(ARG4, sizeof(Int));
+
+    /* Thread creation was successful; let the child have the chance
+       to run */
+    *flags |= SfYieldAfter;
+  }
+}
+
+PRE(sys_rt_sigreturn)
+{
+  /* This isn't really a syscall at all - it's a misuse of the
+     syscall mechanism by m_sigframe.  VG_(sigframe_create) sets the
+     return address of the signal frames it creates to be a short
+     piece of code which does this "syscall".  The only purpose of
+     the syscall is to call VG_(sigframe_destroy), which restores the
+     thread's registers from the frame and then removes it.
+     Consequently we must ask the syswrap driver logic not to write
+     back the syscall "result" as that would overwrite the
+     just-restored register state. */
+
+  ThreadState* tst;
+  PRINT("sys_rt_sigreturn ( )");
+
+  vg_assert(VG_(is_valid_tid)(tid));
+  vg_assert(tid >= 1 && tid < VG_N_THREADS);
+  vg_assert(VG_(is_running_thread)(tid));
+
+  /* Adjust RSP to point to start of frame; skip back up over handler
+     ret addr */
+  tst = VG_(get_ThreadState)(tid);
+  tst->arch.vex.guest_r54 -= sizeof(Addr);
+
+  /* This is only so that the RIP is (might be) useful to report if
+     something goes wrong in the sigreturn.  JRS 20070318: no idea
+     what this is for */
+  ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
+
+  /* Restore register state from frame and remove it, as
+     described above */
+  VG_(sigframe_destroy)(tid, True);
+
+  /* Tell the driver not to update the guest state with the "result",
+     and set a bogus result to keep it happy. */
+  *flags |= SfNoWriteResult;
+  SET_STATUS_Success(0);
+
+  /* Check to see if any signals arose as a result of this. */
+  *flags |= SfPollAfter;
+}
+
+PRE(sys_arch_prctl)
+{
+  PRINT( "arch_prctl ( %ld, %lx )", ARG1, ARG2 );
+
+  vg_assert(VG_(is_valid_tid)(tid));
+  vg_assert(tid >= 1 && tid < VG_N_THREADS);
+  vg_assert(VG_(is_running_thread)(tid));
+
+  I_die_here;
+}
+
+// Parts of this are tilegx-specific, but the *PEEK* cases are generic.
+//
+// ARG3 is only used for pointers into the traced process's address
+// space and for offsets into the traced process's struct
+// user_regs_struct. It is never a pointer into this process's memory
+// space, and we should therefore not check anything it points to.
+PRE(sys_ptrace)
+{
+  PRINT("sys_ptrace ( %ld, %ld, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4);
+  PRE_REG_READ4(int, "ptrace",
+                long, request, long, pid, long, addr, long, data);
+  switch (ARG1) {
+  case VKI_PTRACE_PEEKTEXT:
+  case VKI_PTRACE_PEEKDATA:
+  case VKI_PTRACE_PEEKUSR:
+    PRE_MEM_WRITE( "ptrace(peek)", ARG4,
+                   sizeof (long));
+    break;
+  case VKI_PTRACE_GETREGS:
+    PRE_MEM_WRITE( "ptrace(getregs)", ARG4,
+                   sizeof (struct vki_user_regs_struct));
+    break;
+#if 0 // FIXME
+  case VKI_PTRACE_GETFPREGS:
+    PRE_MEM_WRITE( "ptrace(getfpregs)", ARG4,
+                   sizeof (struct vki_user_i387_struct));
+    break;
+#endif
+  case VKI_PTRACE_SETREGS:
+    PRE_MEM_READ( "ptrace(setregs)", ARG4,
+                  sizeof (struct vki_user_regs_struct));
+    break;
+#if 0 // FIXME
+  case VKI_PTRACE_SETFPREGS:
+    PRE_MEM_READ( "ptrace(setfpregs)", ARG4,
+                  sizeof (struct vki_user_i387_struct));
+    break;
+#endif
+  case VKI_PTRACE_GETEVENTMSG:
+    PRE_MEM_WRITE( "ptrace(geteventmsg)", ARG4, sizeof(unsigned long));
+    break;
+  case VKI_PTRACE_GETSIGINFO:
+    PRE_MEM_WRITE( "ptrace(getsiginfo)", ARG4, sizeof(vki_siginfo_t));
+    break;
+  case VKI_PTRACE_SETSIGINFO:
+    PRE_MEM_READ( "ptrace(setsiginfo)", ARG4, sizeof(vki_siginfo_t));
+    break;
+  default:
+    break;
+  }
+}
+
+POST(sys_ptrace)
+{
+  switch (ARG1) {
+  case VKI_PTRACE_PEEKTEXT:
+  case VKI_PTRACE_PEEKDATA:
+  case VKI_PTRACE_PEEKUSR:
+    POST_MEM_WRITE( ARG4, sizeof (long));
+    break;
+  case VKI_PTRACE_GETREGS:
+    POST_MEM_WRITE( ARG4, sizeof (struct vki_user_regs_struct));
+    break;
+#if 0 // FIXME
+  case VKI_PTRACE_GETFPREGS:
+    POST_MEM_WRITE( ARG4, sizeof (struct vki_user_i387_struct));
+    break;
+#endif
+  case VKI_PTRACE_GETEVENTMSG:
+    POST_MEM_WRITE( ARG4, sizeof(unsigned long));
+    break;
+  case VKI_PTRACE_GETSIGINFO:
+    /* XXX: This is a simplification. Different parts of the
+     * siginfo_t are valid depending on the type of signal.
+     */
+    POST_MEM_WRITE( ARG4, sizeof(vki_siginfo_t));
+    break;
+  default:
+    break;
+  }
+}
+
+PRE(sys_socket)
+{
+  PRINT("sys_socket ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
+  PRE_REG_READ3(long, "socket", int, domain, int, type, int, protocol);
+}
+POST(sys_socket)
+{
+  SysRes r;
+  vg_assert(SUCCESS);
+  r = ML_(generic_POST_sys_socket)(tid, VG_(mk_SysRes_Success)(RES));
+  SET_STATUS_from_SysRes(r);
+}
+
+PRE(sys_setsockopt)
+{
+  PRINT("sys_setsockopt ( %ld, %ld, %ld, %#lx, %ld )",ARG1,ARG2,ARG3,ARG4,ARG5);
+  PRE_REG_READ5(long, "setsockopt",
+                int, s, int, level, int, optname,
+                const void *, optval, int, optlen);
+  ML_(generic_PRE_sys_setsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
+}
+
+PRE(sys_getsockopt)
+{
+  PRINT("sys_getsockopt ( %ld, %ld, %ld, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
+  PRE_REG_READ5(long, "getsockopt",
+                int, s, int, level, int, optname,
+                void *, optval, int, *optlen);
+  ML_(linux_PRE_sys_getsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
+}
+POST(sys_getsockopt)
+{
+  vg_assert(SUCCESS);
+  ML_(linux_POST_sys_getsockopt)(tid, VG_(mk_SysRes_Success)(RES),
+                                 ARG1,ARG2,ARG3,ARG4,ARG5);
+}
+
+PRE(sys_connect)
+{
+  *flags |= SfMayBlock;
+  PRINT("sys_connect ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
+  PRE_REG_READ3(long, "connect",
+                int, sockfd, struct sockaddr *, serv_addr, int, addrlen);
+  ML_(generic_PRE_sys_connect)(tid, ARG1,ARG2,ARG3);
+}
+
+PRE(sys_accept)
+{
+  *flags |= SfMayBlock;
+  PRINT("sys_accept ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
+  PRE_REG_READ3(long, "accept",
+                int, s, struct sockaddr *, addr, int, *addrlen);
+  ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
+}
+POST(sys_accept)
+{
+  SysRes r;
+  vg_assert(SUCCESS);
+  r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
+                                   ARG1,ARG2,ARG3);
+  SET_STATUS_from_SysRes(r);
+}
+
+PRE(sys_accept4)
+{
+  *flags |= SfMayBlock;
+  PRINT("sys_accept4 ( %ld, %#lx, %ld, %ld )",ARG1,ARG2,ARG3,ARG4);
+  PRE_REG_READ4(long, "accept4",
+                int, s, struct sockaddr *, addr, int, *addrlen, int, flags);
+  ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
+}
+POST(sys_accept4)
+{
+  SysRes r;
+  vg_assert(SUCCESS);
+  r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
+                                   ARG1,ARG2,ARG3);
+  SET_STATUS_from_SysRes(r);
+}
+
+PRE(sys_sendto)
+{
+  *flags |= SfMayBlock;
+  PRINT("sys_sendto ( %ld, %#lx, %ld, %lu, %#lx, %ld )",ARG1,ARG2,ARG3,
+        ARG4,ARG5,ARG6);
+  PRE_REG_READ6(long, "sendto",
+                int, s, const void *, msg, int, len,
+                unsigned int, flags,
+                const struct sockaddr *, to, int, tolen);
+  ML_(generic_PRE_sys_sendto)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
+}
+
+PRE(sys_recvfrom)
+{
+  *flags |= SfMayBlock;
+  PRINT("sys_recvfrom ( %ld, %#lx, %ld, %lu, %#lx, %#lx )",ARG1,ARG2,ARG3,
+        ARG4,ARG5,ARG6);
+  PRE_REG_READ6(long, "recvfrom",
+                int, s, void *, buf, int, len, unsigned int, flags,
+                struct sockaddr *, from, int *, fromlen);
+  ML_(generic_PRE_sys_recvfrom)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
+}
+POST(sys_recvfrom)
+{
+  vg_assert(SUCCESS);
+  ML_(generic_POST_sys_recvfrom)(tid, VG_(mk_SysRes_Success)(RES),
+                                 ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
+}
+
+PRE(sys_sendmsg)
+{
+  *flags |= SfMayBlock;
+  PRINT("sys_sendmsg ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
+  PRE_REG_READ3(long, "sendmsg",
+                int, s, const struct msghdr *, msg, int, flags);
+  ML_(generic_PRE_sys_sendmsg)(tid, "msg", ARG2);
+}
+
+PRE(sys_recvmsg)
+{
+  *flags |= SfMayBlock;
+  PRINT("sys_recvmsg ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
+  PRE_REG_READ3(long, "recvmsg", int, s, struct msghdr *, msg, int, flags);
+  ML_(generic_PRE_sys_recvmsg)(tid, "msg", (struct vki_msghdr *) ARG2);
+}
+
+POST(sys_recvmsg)
+{
+  ML_(generic_POST_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)ARG2, RES);
+}
+
+PRE(sys_shutdown)
+{
+  *flags |= SfMayBlock;
+  PRINT("sys_shutdown ( %ld, %ld )",ARG1,ARG2);
+  PRE_REG_READ2(int, "shutdown", int, s, int, how);
+}
+
+PRE(sys_bind)
+{
+  PRINT("sys_bind ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
+  PRE_REG_READ3(long, "bind",
+                int, sockfd, struct sockaddr *, my_addr, int, addrlen);
+  ML_(generic_PRE_sys_bind)(tid, ARG1,ARG2,ARG3);
+}
+
+PRE(sys_listen)
+{
+  PRINT("sys_listen ( %ld, %ld )",ARG1,ARG2);
+  PRE_REG_READ2(long, "listen", int, s, int, backlog);
+}
+
+PRE(sys_getsockname)
+{
+  PRINT("sys_getsockname ( %ld, %#lx, %#lx )",ARG1,ARG2,ARG3);
+  PRE_REG_READ3(long, "getsockname",
+                int, s, struct sockaddr *, name, int *, namelen);
+  ML_(generic_PRE_sys_getsockname)(tid, ARG1,ARG2,ARG3);
+}
+POST(sys_getsockname)
+{
+  vg_assert(SUCCESS);
+  ML_(generic_POST_sys_getsockname)(tid, VG_(mk_SysRes_Success)(RES),
+                                    ARG1,ARG2,ARG3);
+}
+
+PRE(sys_getpeername)
+{
+  PRINT("sys_getpeername ( %ld, %#lx, %#lx )",ARG1,ARG2,ARG3);
+  PRE_REG_READ3(long, "getpeername",
+                int, s, struct sockaddr *, name, int *, namelen);
+  ML_(generic_PRE_sys_getpeername)(tid, ARG1,ARG2,ARG3);
+}
+POST(sys_getpeername)
+{
+  vg_assert(SUCCESS);
+  ML_(generic_POST_sys_getpeername)(tid, VG_(mk_SysRes_Success)(RES),
+                                    ARG1,ARG2,ARG3);
+}
+
+PRE(sys_socketpair)
+{
+  PRINT("sys_socketpair ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
+  PRE_REG_READ4(long, "socketpair",
+                int, d, int, type, int, protocol, int*, sv);
+  ML_(generic_PRE_sys_socketpair)(tid, ARG1,ARG2,ARG3,ARG4);
+}
+POST(sys_socketpair)
+{
+  vg_assert(SUCCESS);
+  ML_(generic_POST_sys_socketpair)(tid, VG_(mk_SysRes_Success)(RES),
+                                   ARG1,ARG2,ARG3,ARG4);
+}
+
+PRE(sys_semget)
+{
+  PRINT("sys_semget ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
+  PRE_REG_READ3(long, "semget", vki_key_t, key, int, nsems, int, semflg);
+}
+
+PRE(sys_semop)
+{
+  *flags |= SfMayBlock;
+  PRINT("sys_semop ( %ld, %#lx, %lu )",ARG1,ARG2,ARG3);
+  PRE_REG_READ3(long, "semop",
+                int, semid, struct sembuf *, sops, unsigned, nsoops);
+  ML_(generic_PRE_sys_semop)(tid, ARG1,ARG2,ARG3);
+}
+
+PRE(sys_semtimedop)
+{
+  *flags |= SfMayBlock;
+  PRINT("sys_semtimedop ( %ld, %#lx, %lu, %#lx )",ARG1,ARG2,ARG3,ARG4);
+  PRE_REG_READ4(long, "semtimedop",
+                int, semid, struct sembuf *, sops, unsigned, nsoops,
+                struct timespec *, timeout);
+  ML_(generic_PRE_sys_semtimedop)(tid, ARG1,ARG2,ARG3,ARG4);
+}
+
+PRE(sys_semctl)
+{
+  switch (ARG3 & ~VKI_IPC_64) {
+  case VKI_IPC_INFO:
+  case VKI_SEM_INFO:
+    PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
+    PRE_REG_READ4(long, "semctl",
+                  int, semid, int, semnum, int, cmd, struct seminfo *, arg);
+    break;
+  case VKI_IPC_STAT:
+  case VKI_SEM_STAT:
+  case VKI_IPC_SET:
+    PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
+    PRE_REG_READ4(long, "semctl",
+                  int, semid, int, semnum, int, cmd, struct semid_ds *, arg);
+    break;
+  case VKI_GETALL:
+  case VKI_SETALL:
+    PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
+    PRE_REG_READ4(long, "semctl",
+                  int, semid, int, semnum, int, cmd, unsigned short *, arg);
+    break;
+  default:
+    PRINT("sys_semctl ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
+    PRE_REG_READ3(long, "semctl",
+                  int, semid, int, semnum, int, cmd);
+    break;
+  }
+  ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
+}
+POST(sys_semctl)
+{
+  ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
+}
+
+PRE(sys_msgget)
+{
+  PRINT("sys_msgget ( %ld, %ld )",ARG1,ARG2);
+  PRE_REG_READ2(long, "msgget", vki_key_t, key, int, msgflg);
+}
+
+PRE(sys_msgsnd)
+{
+  PRINT("sys_msgsnd ( %ld, %#lx, %ld, %ld )",ARG1,ARG2,ARG3,ARG4);
+  PRE_REG_READ4(long, "msgsnd",
+                int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz,
+                int, msgflg);
+  ML_(linux_PRE_sys_msgsnd)(tid, ARG1,ARG2,ARG3,ARG4);
+  if ((ARG4 & VKI_IPC_NOWAIT) == 0)
+    *flags |= SfMayBlock;
+}
+
+PRE(sys_msgrcv)
+{
+  PRINT("sys_msgrcv ( %ld, %#lx, %ld, %ld, %ld )",ARG1,ARG2,ARG3,ARG4,ARG5);
+  PRE_REG_READ5(long, "msgrcv",
+                int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz,
+                long, msgytp, int, msgflg);
+  ML_(linux_PRE_sys_msgrcv)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
+  if ((ARG4 & VKI_IPC_NOWAIT) == 0)
+    *flags |= SfMayBlock;
+}
+POST(sys_msgrcv)
+{
+  ML_(linux_POST_sys_msgrcv)(tid, RES,ARG1,ARG2,ARG3,ARG4,ARG5);
+}
+
+PRE(sys_msgctl)
+{
+  PRINT("sys_msgctl ( %ld, %ld, %#lx )",ARG1,ARG2,ARG3);
+  PRE_REG_READ3(long, "msgctl",
+                int, msqid, int, cmd, struct msqid_ds *, buf);
+  ML_(linux_PRE_sys_msgctl)(tid, ARG1,ARG2,ARG3);
+}
+POST(sys_msgctl)
+{
+  ML_(linux_POST_sys_msgctl)(tid, RES,ARG1,ARG2,ARG3);
+}
+
+PRE(sys_shmget)
+{
+  PRINT("sys_shmget ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
+  PRE_REG_READ3(long, "shmget", vki_key_t, key, vki_size_t, size, int, shmflg);
+}
+
+PRE(wrap_sys_shmat)
+{
+  UWord arg2tmp;
+  PRINT("wrap_sys_shmat ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
+  PRE_REG_READ3(long, "shmat",
+                int, shmid, const void *, shmaddr, int, shmflg);
+  arg2tmp = ML_(generic_PRE_sys_shmat)(tid, ARG1,ARG2,ARG3);
+  if (arg2tmp == 0)
+    SET_STATUS_Failure( VKI_EINVAL );
+  else
+    ARG2 = arg2tmp;  // used in POST
+}
+POST(wrap_sys_shmat)
+{
+  ML_(generic_POST_sys_shmat)(tid, RES,ARG1,ARG2,ARG3);
+}
+
+PRE(sys_shmdt)
+{
+  PRINT("sys_shmdt ( %#lx )",ARG1);
+  PRE_REG_READ1(long, "shmdt", const void *, shmaddr);
+  if (!ML_(generic_PRE_sys_shmdt)(tid, ARG1))
+    SET_STATUS_Failure( VKI_EINVAL );
+}
+POST(sys_shmdt)
+{
+  ML_(generic_POST_sys_shmdt)(tid, RES,ARG1);
+}
+
+PRE(sys_shmctl)
+{
+  PRINT("sys_shmctl ( %ld, %ld, %#lx )",ARG1,ARG2,ARG3);
+  PRE_REG_READ3(long, "shmctl",
+                int, shmid, int, cmd, struct shmid_ds *, buf);
+  ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2|VKI_IPC_64,ARG3);
+}
+POST(sys_shmctl)
+{
+  ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2|VKI_IPC_64,ARG3);
+}
+
+PRE(sys_fadvise64)
+{
+  PRINT("sys_fadvise64 ( %ld, %ld, %lu, %ld )", ARG1,ARG2,ARG3,ARG4);
+  PRE_REG_READ4(long, "fadvise64",
+                int, fd, vki_loff_t, offset, vki_size_t, len, int, advice);
+}
+
+PRE(sys_mmap)
+{
+  SysRes r;
+
+  PRINT("sys_mmap ( %#lx, %llu, %ld, %ld, %d, %ld )",
+        ARG1, (ULong)ARG2, ARG3, ARG4, (Int)ARG5, ARG6 );
+  PRE_REG_READ6(long, "mmap",
+                unsigned long, start, unsigned long, length,
+                unsigned long, prot,  unsigned long, flags,
+                unsigned long, fd,    unsigned long, offset);
+
+  r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6 );
+  SET_STATUS_from_SysRes(r);
+}
+
+
+/* ---------------------------------------------------------------
+   PRE/POST wrappers for TILEGX/Linux-variant specific syscalls
+   ------------------------------------------------------------ */
+
+PRE(sys_set_dataplane)
+{
+  *flags |= SfMayBlock;
+  PRINT("sys_set_dataplane ( %ld )", ARG1);
+  PRE_REG_READ1(long, "set_dataplane", unsigned long, flag);
+}
+
+#undef PRE
+#undef POST
+
+
+/* ---------------------------------------------------------------------
+   The TILEGX/Linux syscall table
+   ------------------------------------------------------------------ */
+
+/* Add an tilegx-linux specific wrapper to a syscall table. */
+#define PLAX_(const, name)    WRAPPER_ENTRY_X_(tilegx_linux, const, name)
+#define PLAXY(const, name)    WRAPPER_ENTRY_XY(tilegx_linux, const, name)
+
+// This table maps from __NR_xxx syscall numbers (from
+// linux/include/asm/unistd.h) to the appropriate PRE/POST sys_foo()
+//
+// When implementing these wrappers, you need to work out if the wrapper is
+// generic, Linux-only (but arch-independent), or TILEGX/Linux only.
+
+static SyscallTableEntry syscall_table[] = {
+
+  LINXY(__NR_io_setup,          sys_io_setup),             // 0
+  LINX_(__NR_io_destroy,        sys_io_destroy),           // 1
+  LINX_(__NR_io_submit,         sys_io_submit),            // 2
+  LINXY(__NR_io_cancel,         sys_io_cancel),            // 3
+  LINXY(__NR_io_getevents,      sys_io_getevents),         // 4
+  LINX_(__NR_setxattr,          sys_setxattr),             // 5
+  LINX_(__NR_lsetxattr,         sys_lsetxattr),            // 6
+  LINX_(__NR_fsetxattr,         sys_fsetxattr),            // 7
+  LINXY(__NR_getxattr,          sys_getxattr),             // 8
+  LINXY(__NR_lgetxattr,         sys_lgetxattr),            // 9
+  LINXY(__NR_fgetxattr,         sys_fgetxattr),            // 10
+  LINXY(__NR_listxattr,         sys_listxattr),            // 11
+  LINXY(__NR_llistxattr,        sys_llistxattr),           // 12
+  LINXY(__NR_flistxattr,        sys_flistxattr),           // 13
+  LINX_(__NR_removexattr,       sys_removexattr),          // 14
+  LINX_(__NR_lremovexattr,      sys_lremovexattr),         // 15
+  LINX_(__NR_fremovexattr,      sys_fremovexattr),         // 16
+  GENXY(__NR_getcwd,            sys_getcwd),               // 17
+  LINXY(__NR_lookup_dcookie,    sys_lookup_dcookie),       // 18
+  LINX_(__NR_eventfd2,          sys_eventfd2),             // 19
+  LINXY(__NR_epoll_create1,     sys_epoll_create1),        // 20
+  LINX_(__NR_epoll_ctl,         sys_epoll_ctl),            // 21
+  LINXY(__NR_epoll_pwait,       sys_epoll_pwait),          // 22
+  GENXY(__NR_dup,               sys_dup),                  // 23
+  GENXY(__NR_dup2,              sys_dup2),                 // 23
+  LINXY(__NR_dup3,              sys_dup3),                 // 24
+  LINXY(__NR_fcntl,             sys_fcntl),                // 25
+  LINXY(__NR_inotify_init1,     sys_inotify_init1),        // 26
+  LINX_(__NR_inotify_add_watch, sys_inotify_add_watch),    // 27
+  LINX_(__NR_inotify_rm_watch,  sys_inotify_rm_watch),     // 28
+  LINXY(__NR_ioctl,             sys_ioctl),                // 29
+  LINX_(__NR_ioprio_set,        sys_ioprio_set),           // 30
+  LINX_(__NR_ioprio_get,        sys_ioprio_get),           // 31
+  GENX_(__NR_flock,             sys_flock),                // 32
+  LINX_(__NR_mknodat,           sys_mknodat),              // 33
+  LINX_(__NR_mkdirat,           sys_mkdirat),              // 34
+  LINX_(__NR_unlinkat,          sys_unlinkat),             // 35
+  LINX_(__NR_symlinkat,         sys_symlinkat),            // 36
+  LINX_(__NR_linkat,            sys_linkat),               // 37
+  LINX_(__NR_renameat,          sys_renameat),             // 38
+  LINX_(__NR_umount2,           sys_umount),               // 39
+  LINX_(__NR_mount,             sys_mount),                // 40
+
+  GENXY(__NR_statfs,            sys_statfs),               // 43
+  GENXY(__NR_fstatfs,           sys_fstatfs),              // 44
+  GENX_(__NR_truncate,          sys_truncate),             // 45
+  GENX_(__NR_ftruncate,         sys_ftruncate),            // 46
+  LINX_(__NR_fallocate,         sys_fallocate),            // 47
+  LINX_(__NR_faccessat,         sys_faccessat),            // 48
+  GENX_(__NR_chdir,             sys_chdir),                // 49
+  GENX_(__NR_fchdir,            sys_fchdir),               // 50
+  GENX_(__NR_chroot,            sys_chroot),               // 51
+  GENX_(__NR_fchmod,            sys_fchmod),               // 52
+  LINX_(__NR_fchmodat,          sys_fchmodat),             // 53
+  LINX_(__NR_fchownat,          sys_fchownat),             // 54
+  GENX_(__NR_fchown,            sys_fchown),               // 55
+  LINXY(__NR_openat,            sys_openat),               // 56
+  GENXY(__NR_close,             sys_close),                // 57
+  LINX_(__NR_vhangup,           sys_vhangup),              // 58
+  LINXY(__NR_pipe2,             sys_pipe2),                // 59
+  LINX_(__NR_quotactl,          sys_quotactl),             // 60
+  GENXY(__NR_getdents64,        sys_getdents64),           // 61
+  LINX_(__NR_lseek,             sys_lseek),                // 62
+  GENXY(__NR_read,              sys_read),                 // 63
+  GENX_(__NR_write,             sys_write),                // 64
+  GENXY(__NR_readv,             sys_readv),                // 65
+  GENX_(__NR_writev,            sys_writev),               // 66
+  GENXY(__NR_pread64,           sys_pread64),              // 67
+  GENX_(__NR_pwrite64,          sys_pwrite64),             // 68
+  LINXY(__NR_preadv,            sys_preadv),               // 69
+  LINX_(__NR_pwritev,           sys_pwritev),              // 70
+  LINXY(__NR_sendfile,          sys_sendfile),             // 71
+  LINX_(__NR_pselect6,          sys_pselect6),             // 72
+  LINXY(__NR_ppoll,             sys_ppoll),                // 73
+  LINXY(__NR_signalfd4,         sys_signalfd4),            // 74
+  LINX_(__NR_splice,            sys_splice),               // 75
+  LINX_(__NR_readlinkat,        sys_readlinkat),           // 78
+  LINXY(__NR3264_fstatat,       sys_newfstatat),           // 79
+  GENXY(__NR_fstat,             sys_newfstat),             // 80
+  GENX_(__NR_sync,              sys_sync),                 // 81
+  GENX_(__NR_fsync,             sys_fsync),                // 82
+  GENX_(__NR_fdatasync,         sys_fdatasync),            // 83
+  LINX_(__NR_sync_file_range,   sys_sync_file_range),      // 84
+  LINXY(__NR_timerfd_create,    sys_timerfd_create),       // 85
+  LINXY(__NR_timerfd_settime,   sys_timerfd_settime),      // 86
+  LINXY(__NR_timerfd_gettime,   sys_timerfd_gettime),      // 87
+  LINX_(__NR_utimensat,         sys_utimensat),            // 88
+
+  LINXY(__NR_capget,            sys_capget),               // 90
+  LINX_(__NR_capset,            sys_capset),               // 91
+  LINX_(__NR_personality,       sys_personality),          // 92
+  GENX_(__NR_exit,              sys_exit),                 // 93
+  LINX_(__NR_exit_group,        sys_exit_group),           // 94
+  LINXY(__NR_waitid,            sys_waitid),               // 95
+  LINX_(__NR_set_tid_address,   sys_set_tid_address),      // 96
+  LINXY(__NR_futex,             sys_futex),                // 98
+  LINX_(__NR_set_robust_list,   sys_set_robust_list),      // 99
+  LINXY(__NR_get_robust_list,   sys_get_robust_list),      // 100
+  GENXY(__NR_nanosleep,         sys_nanosleep),            // 101
+  GENXY(__NR_getitimer,         sys_getitimer),            // 102
+  GENXY(__NR_setitimer,         sys_setitimer),            // 103
+  LINX_(__NR_init_module,       sys_init_module),          // 105
+  LINX_(__NR_delete_module,     sys_delete_module),        // 106
+  LINXY(__NR_timer_create,      sys_timer_create),         // 107
+  LINXY(__NR_timer_gettime,     sys_timer_gettime),        // 108
+  LINX_(__NR_timer_getoverrun,  sys_timer_getoverrun),     // 109
+  LINXY(__NR_timer_settime,     sys_timer_settime),        // 110
+  LINX_(__NR_timer_delete,      sys_timer_delete),         // 111
+  LINX_(__NR_clock_settime,     sys_clock_settime),        // 112
+  LINXY(__NR_clock_gettime,     sys_clock_gettime),        // 113
+  LINXY(__NR_clock_getres,      sys_clock_getres),         // 114
+  LINXY(__NR_clock_nanosleep,   sys_clock_nanosleep),      // 115
+  LINXY(__NR_syslog,            sys_syslog),               // 116
+  PLAXY(__NR_ptrace,            sys_ptrace),               // 117
+  LINXY(__NR_sched_setparam,          sys_sched_setparam), // 118
+  LINX_(__NR_sched_setscheduler,      sys_sched_setscheduler),     // 119
+  LINX_(__NR_sched_getscheduler,      sys_sched_getscheduler),     // 120
+  LINXY(__NR_sched_getparam,          sys_sched_getparam), // 121
+  LINX_(__NR_sched_setaffinity, sys_sched_setaffinity),    // 122
+  LINXY(__NR_sched_getaffinity, sys_sched_getaffinity),    // 123
+  LINX_(__NR_sched_yield,       sys_sched_yield),          // 124
+  LINX_(__NR_sched_get_priority_max,  sys_sched_get_priority_max), // 125
+  LINX_(__NR_sched_get_priority_min,  sys_sched_get_priority_min), // 126
+  LINXY(__NR_sched_rr_get_interval,   sys_sched_rr_get_interval),  // 127
+
+  GENX_(__NR_kill,              sys_kill),                 // 129
+  LINXY(__NR_tkill,             sys_tkill),                // 130
+  LINXY(__NR_tgkill,            sys_tgkill),               // 131
+  GENXY(__NR_sigaltstack,       sys_sigaltstack),          // 132
+  LINX_(__NR_rt_sigsuspend,     sys_rt_sigsuspend),        // 133
+  LINXY(__NR_rt_sigaction,      sys_rt_sigaction),         // 134
+  LINXY(__NR_rt_sigprocmask,    sys_rt_sigprocmask),       // 135
+  LINXY(__NR_rt_sigpending,     sys_rt_sigpending),        // 136
+  LINXY(__NR_rt_sigtimedwait,   sys_rt_sigtimedwait),      // 137
+  LINXY(__NR_rt_sigqueueinfo,   sys_rt_sigqueueinfo),      // 138
+  PLAX_(__NR_rt_sigreturn,      sys_rt_sigreturn),         // 139
+  GENX_(__NR_setpriority,             sys_setpriority),    // 140
+  GENX_(__NR_getpriority,             sys_getpriority),    // 141
+
+  GENX_(__NR_setregid,          sys_setregid),             // 143
+  GENX_(__NR_setgid,            sys_setgid),               // 144
+  GENX_(__NR_setreuid,          sys_setreuid),             // 145
+  GENX_(__NR_setuid,            sys_setuid),               // 146
+  LINX_(__NR_setresuid,         sys_setresuid),            // 147
+  LINXY(__NR_getresuid,         sys_getresuid),            // 148
+  LINX_(__NR_setresgid,         sys_setresgid),            // 149
+  LINXY(__NR_getresgid,         sys_getresgid),            // 150
+  LINX_(__NR_setfsuid,          sys_setfsuid),             // 151
+  LINX_(__NR_setfsgid,          sys_setfsgid),             // 152
+  GENXY(__NR_times,             sys_times),                // 153
+  GENX_(__NR_setpgid,           sys_setpgid),              // 154
+  GENX_(__NR_getpgid,           sys_getpgid),              // 155
+  GENX_(__NR_getsid,            sys_getsid),               // 156
+  GENX_(__NR_setsid,            sys_setsid),               // 157
+  GENXY(__NR_getgroups,         sys_getgroups),            // 158
+  GENX_(__NR_setgroups,         sys_setgroups),            // 159
+  GENXY(__NR_uname,             sys_newuname),             // 160
+  GENXY(__NR_getrlimit,         sys_getrlimit),            // 163
+  GENX_(__NR_setrlimit,         sys_setrlimit),            // 164
+  GENXY(__NR_getrusage,         sys_getrusage),            // 165
+  GENX_(__NR_umask,             sys_umask),                // 166
+  LINXY(__NR_prctl,             sys_prctl),                // 167
+
+  GENXY(__NR_gettimeofday,      sys_gettimeofday),         // 169
+  GENX_(__NR_settimeofday,      sys_settimeofday),         // 170
+  LINXY(__NR_adjtimex,          sys_adjtimex),             // 171
+  GENX_(__NR_getpid,            sys_getpid),               // 172
+  GENX_(__NR_getppid,           sys_getppid),              // 173
+  GENX_(__NR_getuid,            sys_getuid),               // 174
+  GENX_(__NR_geteuid,           sys_geteuid),              // 175
+  GENX_(__NR_getgid,            sys_getgid),               // 176
+  GENX_(__NR_getegid,           sys_getegid),              // 177
+  LINX_(__NR_gettid,            sys_gettid),               // 178
+  LINXY(__NR_sysinfo,           sys_sysinfo),              // 179
+  LINXY(__NR_mq_open,           sys_mq_open),              // 180
+  LINX_(__NR_mq_unlink,         sys_mq_unlink),            // 181
+  LINX_(__NR_mq_timedsend,      sys_mq_timedsend),         // 182
+  LINXY(__NR_mq_timedreceive,   sys_mq_timedreceive),      // 183
+  LINX_(__NR_mq_notify,         sys_mq_notify),            // 184
+  LINXY(__NR_mq_getsetattr,     sys_mq_getsetattr),        // 185
+  PLAX_(__NR_msgget,            sys_msgget),               // 186
+  PLAXY(__NR_msgctl,            sys_msgctl),               // 187
+  PLAXY(__NR_msgrcv,            sys_msgrcv),               // 188
+  PLAX_(__NR_msgsnd,            sys_msgsnd),               // 189
+  PLAX_(__NR_semget,            sys_semget),               // 190
+  PLAXY(__NR_semctl,            sys_semctl),               // 191
+  PLAX_(__NR_semtimedop,        sys_semtimedop),           // 192
+  PLAX_(__NR_semop,             sys_semop),                // 193
+  PLAX_(__NR_shmget,            sys_shmget),               // 194
+  PLAXY(__NR_shmat,             wrap_sys_shmat),           // 196
+  PLAXY(__NR_shmctl,            sys_shmctl),               // 195
+  PLAXY(__NR_shmdt,             sys_shmdt),                // 197
+  PLAXY(__NR_socket,            sys_socket),               // 198
+  PLAXY(__NR_socketpair,        sys_socketpair),           // 199
+  PLAX_(__NR_bind,              sys_bind),                 // 200
+  PLAX_(__NR_listen,            sys_listen),               // 201
+  PLAXY(__NR_accept,            sys_accept),               // 202
+  PLAX_(__NR_connect,           sys_connect),              // 203
+  PLAXY(__NR_getsockname,       sys_getsockname),          // 204
+  PLAXY(__NR_getpeername,       sys_getpeername),          // 205
+  PLAX_(__NR_sendto,            sys_sendto),               // 206
+  PLAXY(__NR_recvfrom,          sys_recvfrom),             // 207
+  PLAX_(__NR_setsockopt,        sys_setsockopt),           // 208
+  PLAXY(__NR_getsockopt,        sys_getsockopt),           // 209
+  PLAX_(__NR_shutdown,          sys_shutdown),             // 210
+  PLAX_(__NR_sendmsg,           sys_sendmsg),              // 211
+  PLAXY(__NR_recvmsg,           sys_recvmsg),              // 212
+  LINX_(__NR_readahead,         sys_readahead),            // 213
+  GENX_(__NR_brk,               sys_brk),                  // 214
+  GENXY(__NR_munmap,            sys_munmap),               // 215
+  GENX_(__NR_mremap,            sys_mremap),               // 216
+  LINX_(__NR_add_key,           sys_add_key),              // 217
+  LINX_(__NR_request_key,       sys_request_key),          // 218
+  LINXY(__NR_keyctl,            sys_keyctl),               // 219
+  PLAX_(__NR_clone,             sys_clone),                // 220
+  GENX_(__NR_execve,            sys_execve),               // 221
+  PLAX_(__NR_mmap,              sys_mmap),                 // 222
+  GENXY(__NR_mprotect,          sys_mprotect),             // 226
+  GENX_(__NR_msync,             sys_msync),                // 227
+  GENX_(__NR_mlock,                   sys_mlock),          // 228
+  GENX_(__NR_munlock,           sys_munlock),              // 229
+  GENX_(__NR_mlockall,          sys_mlockall),             // 230
+  LINX_(__NR_munlockall,        sys_munlockall),           // 231
+  GENX_(__NR_mincore,           sys_mincore),              // 232
+  GENX_(__NR_madvise,           sys_madvise),              // 233
+
+  LINX_(__NR_mbind,             sys_mbind),                // 235
+  LINXY(__NR_get_mempolicy,     sys_get_mempolicy),        // 236
+  LINX_(__NR_set_mempolicy,     sys_set_mempolicy),        // 237
+
+  LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo),    // 240
+
+  PLAXY(__NR_accept4,           sys_accept4),              // 242
+
+  PLAX_(__NR_set_dataplane,     sys_set_dataplane),        // 246
+
+  GENXY(__NR_wait4,             sys_wait4),                // 260
+};
+
+SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
+{
+  const UInt syscall_table_size
+    = sizeof(syscall_table) / sizeof(syscall_table[0]);
+
+  /* Is it in the contiguous initial section of the table? */
+  if (sysno < syscall_table_size) {
+    SyscallTableEntry* sys = &syscall_table[sysno];
+    if (sys->before == NULL)
+      return NULL; /* no entry */
+    else
+      return sys;
+  }
+  //vex_printf("sysno: %d\n", sysno);
+
+  /* Can't find a wrapper */
+  return NULL;
+}
+
+#endif // defined(VGP_tilegx_linux)
+
+/*--------------------------------------------------------------------*/
+/*--- end                                   syswrap-tilegx-linux.c ---*/
+/*--------------------------------------------------------------------*/
diff --git a/coregrind/m_trampoline.S b/coregrind/m_trampoline.S
index 3d2be09..027f9f6 100644
--- a/coregrind/m_trampoline.S
+++ b/coregrind/m_trampoline.S
@@ -1329,6 +1329,76 @@
 #	undef UD2_1024
 #	undef UD2_PAGE
 
+#else
+#if defined(VGP_tilegx_linux)
+
+#	define UD2_16     ill ; ill
+#	define UD2_64     UD2_16   ; UD2_16   ; UD2_16   ; UD2_16
+#	define UD2_256    UD2_64   ; UD2_64   ; UD2_64   ; UD2_64
+#	define UD2_1024   UD2_256  ; UD2_256  ; UD2_256  ; UD2_256
+#	define UD2_4K     UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024
+#	define UD2_16K    UD2_4K   ; UD2_4K   ; UD2_4K   ; UD2_4K
+#	define UD2_PAGE   UD2_16K  ; UD2_16K  ; UD2_16K  ; UD2_16K
+	/* a leading page of unexecutable code */
+	UD2_PAGE
+
+.global VG_(trampoline_stuff_start)
+VG_(trampoline_stuff_start):
+
+.global VG_(tilegx_linux_SUBST_FOR_rt_sigreturn)
+VG_(tilegx_linux_SUBST_FOR_rt_sigreturn):
+        /* This is a very specific sequence which GDB uses to
+           recognize signal handler frames. */
+        moveli  r10, __NR_rt_sigreturn
+        swint1
+        ill
+
+.global VG_(tilegx_linux_REDIR_FOR_vgettimeofday)
+.type   VG_(tilegx_linux_REDIR_FOR_vgettimeofday), @function
+VG_(tilegx_linux_REDIR_FOR_vgettimeofday):
+        moveli  r10, __NR_gettimeofday
+        swint1
+        jrp lr
+.size VG_(tilegx_linux_REDIR_FOR_vgettimeofday), .-VG_(tilegx_linux_REDIR_FOR_vgettimeofday)
+	
+.global VG_(tilegx_linux_REDIR_FOR_vtime)
+.type   VG_(tilegx_linux_REDIR_FOR_vtime), @function
+VG_(tilegx_linux_REDIR_FOR_vtime):
+        moveli  r10, __NR_gettimeofday
+        swint1
+        jrp lr
+.size VG_(tilegx_linux_REDIR_FOR_vtime), .-VG_(tilegx_linux_REDIR_FOR_vtime)
+
+.global VG_(tilegx_linux_REDIR_FOR_strlen)
+.type   VG_(tilegx_linux_REDIR_FOR_strlen), @function
+VG_(tilegx_linux_REDIR_FOR_strlen):
+        {
+         movei   r1, 0
+         beqz    r0, 2f
+        }
+1:      {
+         addi     r1, r1, 1
+         ld1s_add r2, r0, 1
+        }
+        bnezt   r2, 1b
+        addi    r1, r1, -1
+2:      move    r0, r1
+        jrp     lr
+.size VG_(tilegx_linux_REDIR_FOR_strlen), .-VG_(tilegx_linux_REDIR_FOR_strlen)
+
+.global VG_(trampoline_stuff_end)
+VG_(trampoline_stuff_end):
+
+	/* and a trailing page of unexecutable code */
+	UD2_PAGE
+
+#	undef UD2_16
+#	undef UD2_64
+#	undef UD2_256
+#	undef UD2_1024
+#	undef UD2_4K
+#	undef UD2_16K
+#	undef UD2_PAGE
 /*---------------- unknown ----------------*/
 #else
 #  error Unknown platform
@@ -1344,6 +1414,7 @@
 #endif
 #endif
 #endif
+#endif
 
 #if defined(VGO_linux)
 /* Let the linker know we don't need an executable stack */
diff --git a/coregrind/m_translate.c b/coregrind/m_translate.c
index a5da1c9..28ac906 100644
--- a/coregrind/m_translate.c
+++ b/coregrind/m_translate.c
@@ -760,8 +760,8 @@
 
 static Bool translations_allowable_from_seg ( NSegment const* seg, Addr addr )
 {
-#  if defined(VGA_x86) || defined(VGA_s390x) || defined(VGA_mips32) \
-      || defined(VGA_mips64)
+#  if defined(VGA_x86) || defined(VGA_s390x) || defined(VGA_mips32)     \
+     || defined(VGA_mips64) || defined(VGA_tilegx)
    Bool allowR = True;
 #  else
    Bool allowR = False;
diff --git a/coregrind/pub_core_aspacemgr.h b/coregrind/pub_core_aspacemgr.h
index 531a720..767b878 100644
--- a/coregrind/pub_core_aspacemgr.h
+++ b/coregrind/pub_core_aspacemgr.h
@@ -321,7 +321,7 @@
 #if defined(VGP_ppc32_linux) \
     || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)	\
     || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
-    || defined(VGP_arm64_linux)
+    || defined(VGP_arm64_linux) || defined(VGP_tilegx_linux)
 # define VG_STACK_GUARD_SZB  65536  // 1 or 16 pages
 #else
 # define VG_STACK_GUARD_SZB  8192   // 2 pages
diff --git a/coregrind/pub_core_basics.h b/coregrind/pub_core_basics.h
index 7ac5a72..9d7e6b4 100644
--- a/coregrind/pub_core_basics.h
+++ b/coregrind/pub_core_basics.h
@@ -96,6 +96,10 @@
             ULong r31;  /* Return address of the last subroutine call */
             ULong r28;
          } MIPS64;
+         struct {
+            ULong r52;
+            ULong r55;
+         } TILEGX;
       } misc;
    }
    UnwindStartRegs;
diff --git a/coregrind/pub_core_debuginfo.h b/coregrind/pub_core_debuginfo.h
index 7618191..ce1b199 100644
--- a/coregrind/pub_core_debuginfo.h
+++ b/coregrind/pub_core_debuginfo.h
@@ -130,6 +130,10 @@
 typedef
    struct { Addr pc; Addr sp; Addr fp; Addr ra; }
    D3UnwindRegs;
+#elif defined(VGA_tilegx)
+typedef
+   struct { Addr pc; Addr sp; Addr fp; Addr lr; }
+   D3UnwindRegs;
 #else
 #  error "Unsupported arch"
 #endif
diff --git a/coregrind/pub_core_machine.h b/coregrind/pub_core_machine.h
index 14ea354..7fb7afe 100644
--- a/coregrind/pub_core_machine.h
+++ b/coregrind/pub_core_machine.h
@@ -108,6 +108,14 @@
 #  define VG_ELF_MACHINE      EM_MIPS
 #  define VG_ELF_CLASS        ELFCLASS64
 #  undef  VG_PLAT_USES_PPCTOC
+#elif defined(VGP_tilegx_linux)
+#  define VG_ELF_DATA2XXX     ELFDATA2LSB
+   #ifndef EM_TILEGX
+   #define EM_TILEGX 191
+   #endif
+#  define VG_ELF_MACHINE      EM_TILEGX
+#  define VG_ELF_CLASS        ELFCLASS64
+#  undef  VG_PLAT_USES_PPCTOC
 #else
 #  error Unknown platform
 #endif
@@ -149,6 +157,10 @@
 #  define VG_INSTR_PTR        guest_PC
 #  define VG_STACK_PTR        guest_r29
 #  define VG_FRAME_PTR        guest_r30
+#elif defined(VGA_tilegx)
+#  define VG_INSTR_PTR        guest_pc
+#  define VG_STACK_PTR        guest_r54
+#  define VG_FRAME_PTR        guest_r52
 #else
 #  error Unknown arch
 #endif
diff --git a/coregrind/pub_core_mallocfree.h b/coregrind/pub_core_mallocfree.h
index fafe707..eeb4aa1 100644
--- a/coregrind/pub_core_mallocfree.h
+++ b/coregrind/pub_core_mallocfree.h
@@ -79,7 +79,8 @@
       defined(VGP_mips64_linux)   || \
       defined(VGP_x86_darwin)     || \
       defined(VGP_amd64_darwin)   || \
-      defined(VGP_arm64_linux)
+      defined(VGP_arm64_linux)    || \
+      defined(VGP_tilegx_linux)
 #  define VG_MIN_MALLOC_SZB       16
 #else
 #  error Unknown platform
diff --git a/coregrind/pub_core_syscall.h b/coregrind/pub_core_syscall.h
index e35ff44..8c7bdba 100644
--- a/coregrind/pub_core_syscall.h
+++ b/coregrind/pub_core_syscall.h
@@ -86,6 +86,7 @@
                                            UWord a3 );
 extern SysRes VG_(mk_SysRes_mips64_linux)( ULong v0, ULong v1,
                                            ULong a3 );
+extern SysRes VG_(mk_SysRes_tilegx_linux)( Long val );
 extern SysRes VG_(mk_SysRes_Error)       ( UWord val );
 extern SysRes VG_(mk_SysRes_Success)     ( UWord val );
 
diff --git a/coregrind/pub_core_trampoline.h b/coregrind/pub_core_trampoline.h
index 411a23c..7630729 100644
--- a/coregrind/pub_core_trampoline.h
+++ b/coregrind/pub_core_trampoline.h
@@ -104,6 +104,11 @@
 extern void* VG_(arm_linux_REDIR_FOR_strcmp)( void*, void* );
 #endif
 
+#if defined(VGP_tilegx_linux)
+extern Addr  VG_(tilegx_linux_SUBST_FOR_rt_sigreturn);
+extern UInt  VG_(tilegx_linux_REDIR_FOR_strlen)( void* );
+#endif
+
 #if defined(VGP_arm64_linux)
 extern Addr  VG_(arm64_linux_SUBST_FOR_rt_sigreturn);
 extern ULong VG_(arm64_linux_REDIR_FOR_strlen)( void* );
diff --git a/coregrind/pub_core_transtab_asm.h b/coregrind/pub_core_transtab_asm.h
index b063d54..224a9cc 100644
--- a/coregrind/pub_core_transtab_asm.h
+++ b/coregrind/pub_core_transtab_asm.h
@@ -66,6 +66,9 @@
       || defined(VGA_mips32) || defined(VGA_mips64) || defined(VGA_arm64)
 #  define VG_TT_FAST_HASH(_addr)  ((((UWord)(_addr)) >> 2) & VG_TT_FAST_MASK)
 
+#elif defined(VGA_tilegx)
+#  define VG_TT_FAST_HASH(_addr)  ((((UWord)(_addr)) >> 3) & VG_TT_FAST_MASK)
+
 #else
 #  error "VG_TT_FAST_HASH: unknown platform"
 #endif
diff --git a/coregrind/vgdb-invoker-ptrace.c b/coregrind/vgdb-invoker-ptrace.c
index df9e232..8e7e42e 100644
--- a/coregrind/vgdb-invoker-ptrace.c
+++ b/coregrind/vgdb-invoker-ptrace.c
@@ -518,7 +518,7 @@
    }
 }
 
-#  if defined(VGA_arm64)
+#  if defined(VGA_arm64) || defined(VGA_tilegx)
 /* arm64 is extra special, old glibc defined kernel user_pt_regs, but
    newer glibc instead define user_regs_struct. */
 #    ifdef HAVE_SYS_USER_REGS
@@ -794,7 +794,7 @@
 {
    long res;
    Bool stopped;
-#  if defined(VGA_arm64)
+#  if defined(VGA_arm64) || defined(VGA_tilegx)
 /* arm64 is extra special, old glibc defined kernel user_pt_regs, but
    newer glibc instead define user_regs_struct. */
 #    ifdef HAVE_SYS_USER_REGS
@@ -871,6 +871,8 @@
    sp = p[29];
 #elif defined(VGA_mips64)
    sp = user_mod.regs[29];
+#elif defined(VGA_tilegx)
+   sp = user_mod.sp;
 #else
    I_die_here : (sp) architecture missing in vgdb-invoker-ptrace.c
 #endif
@@ -956,7 +958,7 @@
       /* make stack space for args */
       p[29] = sp - 32;
 
-#elif defined(VGA_mips64)
+#elif defined(VGA_mips64) || defined(VGA_tilegx)
       assert(0); // cannot vgdb a 32 bits executable with a 64 bits exe
 #else
       I_die_here : architecture missing in vgdb-invoker-ptrace.c
@@ -1063,6 +1065,12 @@
       user_mod.regs[31] = bad_return;
       user_mod.regs[34] = shared64->invoke_gdbserver;
       user_mod.regs[25] = shared64->invoke_gdbserver;
+#elif defined(VGA_tilegx)
+      /* put check arg in register r0 */
+      user_mod.regs[0] = check;
+      /* put NULL return address in lr */
+      user_mod.lr = bad_return;
+      user_mod.pc = shared64->invoke_gdbserver;
 #else
       I_die_here: architecture missing in vgdb-invoker-ptrace.c
 #endif
diff --git a/docs/internals/register-uses.txt b/docs/internals/register-uses.txt
index a57192a..f26ccca 100644
--- a/docs/internals/register-uses.txt
+++ b/docs/internals/register-uses.txt
@@ -8,7 +8,7 @@
 x86-linux
 ~~~~~~~~~
 
-Reg        Callee      Arg   
+Reg        Callee      Arg
 Name       Saves?      Reg?     Comment              Vex-uses?
 --------------------------------------------------------------
 eax        n           n        int[31:0] retreg     y
@@ -31,7 +31,7 @@
 amd64-linux
 ~~~~~~~~~~~
 
-Reg        Callee      Arg    
+Reg        Callee      Arg
 Name       Saves?      Reg?     Comment              Vex-uses?
 -------------------------------------------------------------------
 rax        n           n        int[63:0] retreg
@@ -58,7 +58,7 @@
 ppc32-linux
 ~~~~~~~~~~~
 
-Reg        Callee      Arg    
+Reg        Callee      Arg
 Name       Saves?      Reg?     Comment              Vex-uses?
 -------------------------------------------------------------------
 r0         n           n        sometimes RAZ
@@ -95,7 +95,7 @@
 
 ppc64-linux
 ~~~~~~~~~~~
-Reg        Callee      Arg    
+Reg        Callee      Arg
 Name       Saves?      Reg?     Comment              Vex-uses?
 -------------------------------------------------------------------
 r13        n           n        thread ptr
@@ -142,7 +142,7 @@
 ---------------------------------------------------------------
 r0                    int#0      ret#0 (??)
 r1                    int#1      ret#1 (??)
-r2-7                  int#2..7 
+r2-7                  int#2..7
 r8                              "Indirect res loc reg" ProfInc scratch
 r9                              "Temporary regs"      chaining scratch
 r10-15                          "Temporary regs"      avail
@@ -214,7 +214,7 @@
 ppc32-aix5
 ~~~~~~~~~~
 
-Reg        Callee      Arg    
+Reg        Callee      Arg
 Name       Saves?      Reg?     Comment              Vex-uses?
 -------------------------------------------------------------------
 r0         n           n        sometimes RAZ
@@ -237,7 +237,7 @@
 r31        y                                         & guest state
 f0         n
 f1         n           fp#1     fp retreg
-f2-13      n           fp#2-13  
+f2-13      n           fp#2-13
 f14-31     y                                         y (14-21)
 v0-v19     ?
 v20-31     y                                         y (20-27,29)
@@ -246,3 +246,68 @@
 ctr        n
 xer        n
 fpscr
+
+
+TileGx-linux
+~~~~~~~~~~~~
+
+Reg       Callee     Arg
+Name      Saves?     Reg?        Comment             Vex-uses?
+---------------------------------------------------------------------
+r0        n          int#1
+r1        n          int#2
+r2        n          int#3
+r3        n          int#4
+r4        n          int#5
+r5        n          int#6
+r6        n          int#7
+r7        n          int#8
+r8        n          int#9
+r9        n          int#10
+r10       n                      syscall#            y
+r11       n                                          Next Guest State
+r12       n                                          y
+r13       n                                          y
+r14       n                                          y
+r15       n                                          y
+r16       n                                          y
+r17       n                                          y
+r18       n                                          y
+r19       n                                          y
+r20       n                                          y
+r21       n                                          y
+r22       n                                          y
+r23       n                                          y
+r24       n                                          y
+r25       n                                          y
+r26       n                                          y
+r27       n                                          y
+r28       n                                          y
+r29       n                                          y
+r30       y                                          y
+r31       y                                          y
+r32       y                                          y
+r33       y                                          y
+r34       y                                          y
+r35       y                                          y
+r36       y                                          y
+r37       y                                          y
+r38       y                                          y
+r39       y                                          y
+r40       y                                          y
+r41       y                                          y
+r42       y                                          y
+r43       y                                          y
+r44       y                                          y
+r45       y                                          y
+r46       y                                          y
+r47       y                                          y
+r48       y                                          y
+r49       y                                          y
+r50       y                                          Guest State
+r51       y                                          used for memory Load/Store
+r52       y                      frame
+r53       y                      tls
+r54       y                      stock
+r55       y                      return address
+r63       n                      zero
diff --git a/drd/drd_bitmap.h b/drd/drd_bitmap.h
index 86d53f3..0b47157 100644
--- a/drd/drd_bitmap.h
+++ b/drd/drd_bitmap.h
@@ -140,7 +140,8 @@
     || defined(VGA_mips32)
 #define BITS_PER_BITS_PER_UWORD 5
 #elif defined(VGA_amd64) || defined(VGA_ppc64be) || defined(VGA_ppc64le) \
-      || defined(VGA_s390x) || defined(VGA_mips64) || defined(VGA_arm64)
+      || defined(VGA_s390x) || defined(VGA_mips64) || defined(VGA_arm64) \
+      || defined(VGA_tilegx)
 #define BITS_PER_BITS_PER_UWORD 6
 #else
 #error Unknown platform.
diff --git a/drd/drd_clientreq.c b/drd/drd_clientreq.c
index 413ed3b..bed68aa 100644
--- a/drd/drd_clientreq.c
+++ b/drd/drd_clientreq.c
@@ -68,7 +68,8 @@
  * DRD's handler for Valgrind client requests. The code below handles both
  * DRD's public and tool-internal client requests.
  */
-#if defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
+#if defined(VGP_mips32_linux) || defined(VGP_mips64_linux) || \
+    defined(VGP_tilegx_linux)
  /* There is a cse related issue in gcc for MIPS. Optimization level
     has to be lowered, so cse related optimizations are not
     included. */
diff --git a/drd/drd_load_store.c b/drd/drd_load_store.c
index 95e9f42..88e4d44 100644
--- a/drd/drd_load_store.c
+++ b/drd/drd_load_store.c
@@ -55,6 +55,8 @@
 #define STACK_POINTER_OFFSET OFFSET_mips32_r29
 #elif defined(VGA_mips64)
 #define STACK_POINTER_OFFSET OFFSET_mips64_r29
+#elif defined(VGA_tilegx)
+#define STACK_POINTER_OFFSET OFFSET_tilegx_r54
 #else
 #error Unknown architecture.
 #endif
diff --git a/exp-sgcheck/pc_main.c b/exp-sgcheck/pc_main.c
index 50dd402..19d78d4 100644
--- a/exp-sgcheck/pc_main.c
+++ b/exp-sgcheck/pc_main.c
@@ -77,6 +77,10 @@
    VG_(printf)("SGCheck doesn't work on MIPS yet, sorry.\n");
    VG_(exit)(1);
 #endif
+#if defined(VGA_tilegx)
+   VG_(printf)("SGCheck doesn't work on TileGx yet, sorry.\n");
+   VG_(exit)(1);
+#endif
 
    // Can't change the name until we change the names in suppressions
    // too.
diff --git a/exp-sgcheck/tests/is_arch_supported b/exp-sgcheck/tests/is_arch_supported
index 818cc61..328b9b6 100755
--- a/exp-sgcheck/tests/is_arch_supported
+++ b/exp-sgcheck/tests/is_arch_supported
@@ -10,6 +10,6 @@
 # architectures.
 
 case `uname -m` in
-  ppc*|arm*|s390x|mips*) exit 1;;
+  ppc*|arm*|s390x|mips*|tilegx) exit 1;;
   *)         exit 0;;
 esac
diff --git a/gdbserver_tests/mcblocklistsearch.vgtest b/gdbserver_tests/mcblocklistsearch.vgtest
index bced1cd..eb597e8 100644
--- a/gdbserver_tests/mcblocklistsearch.vgtest
+++ b/gdbserver_tests/mcblocklistsearch.vgtest
@@ -1,7 +1,7 @@
 # test the memcheck block_list and search monitor commands.
 prog: ../memcheck/tests/leak-tree
 vgopts: --tool=memcheck --vgdb=yes --vgdb-error=0 --vgdb-prefix=./vgdb-prefix-mcblocklistsearch -q 
-prereq: test -e gdb.eval
+prereq: test -e gdb.eval && ! ../tests/arch_test tilegx
 stdout_filter: filter_make_empty
 stderr_filter: filter_make_empty
 progB: gdb
diff --git a/gdbserver_tests/nlcontrolc.vgtest b/gdbserver_tests/nlcontrolc.vgtest
index 7cb9c2f..e18c468 100644
--- a/gdbserver_tests/nlcontrolc.vgtest
+++ b/gdbserver_tests/nlcontrolc.vgtest
@@ -11,7 +11,7 @@
 vgopts: --tool=none --vgdb=yes --vgdb-error=0 --vgdb-prefix=./vgdb-prefix-nlcontrolc
 stderr_filter: filter_stderr
 # Bug 338633 nlcontrol hangs on arm64 currently.
-prereq: test -e gdb -a -f vgdb.invoker && ! ../tests/arch_test arm64
+prereq: test -e gdb -a -f vgdb.invoker && ! ../tests/arch_test arm64 && ! ../tests/arch_test tilegx
 progB: gdb
 argsB: --quiet -l 60 --nx ./sleepers
 stdinB: nlcontrolc.stdinB.gdb
diff --git a/gdbserver_tests/nlgone_return.vgtest b/gdbserver_tests/nlgone_return.vgtest
index 996f01c..f6f869c 100644
--- a/gdbserver_tests/nlgone_return.vgtest
+++ b/gdbserver_tests/nlgone_return.vgtest
@@ -4,7 +4,7 @@
 args: return
 vgopts: --tool=none --vgdb=yes --vgdb-error=0 --vgdb-prefix=./vgdb-prefix-nlgone-return
 stderr_filter: filter_stderr
-prereq: test -e gdb
+prereq: test -e gdb && ! ../tests/arch_test tilegx
 progB: gdb
 argsB: --quiet -l 60 --nx ./gone
 stdinB: nlgone_return.stdinB.gdb
diff --git a/helgrind/tests/annotate_hbefore.c b/helgrind/tests/annotate_hbefore.c
index 74cf9d8..9f3636c 100644
--- a/helgrind/tests/annotate_hbefore.c
+++ b/helgrind/tests/annotate_hbefore.c
@@ -285,6 +285,16 @@
    return success;
 }
 
+#elif defined(VGA_tilegx)
+
+/* return 1 if success, 0 if failure */
+UWord do_acasW(UWord* addr, UWord expected, UWord nyu )
+{
+  /* Load the compare value into special register 0x2780 */
+  __insn_mtspr(0x2780, expected);
+  return __insn_cmpexch(addr, nyu);
+}
+
 #endif
 
 void atomic_incW ( UWord* w )
diff --git a/helgrind/tests/tc07_hbl1.c b/helgrind/tests/tc07_hbl1.c
index be62337..c66b8ec 100644
--- a/helgrind/tests/tc07_hbl1.c
+++ b/helgrind/tests/tc07_hbl1.c
@@ -16,6 +16,7 @@
 #undef PLAT_arm64_linux
 #undef PLAT_s390x_linux
 #undef PLAT_mips32_linux
+#undef PLAT_tilegx_linux
 
 #if defined(__APPLE__) && defined(__i386__)
 #  define PLAT_x86_darwin 1
@@ -37,6 +38,8 @@
 #  define PLAT_s390x_linux 1
 #elif defined(__linux__) && defined(__mips__)
 #  define PLAT_mips32_linux 1
+#elif defined(__linux__) && defined(__tilegx__)
+#  define PLAT_tilegx_linux 1
 #endif
 
 #if defined(PLAT_amd64_linux) || defined(PLAT_x86_linux) \
@@ -103,6 +106,12 @@
       : /*out*/ : /*in*/ "r"(&(_lval))              \
       : /*trash*/ "$8", "$9", "$10", "cc", "memory" \
    )
+#elif defined(PLAT_tilegx_linux)
+#  define INC(_lval,_lqual)                        \
+   if (sizeof(_lval) == 4)                         \
+      __insn_fetchadd(&(_lval), 1);                \
+   else if(sizeof(_lval) == 8)                     \
+      __insn_fetchadd(&(_lval), 1)
 #else
 #  error "Fix Me for this platform"
 #endif
diff --git a/helgrind/tests/tc08_hbl2.c b/helgrind/tests/tc08_hbl2.c
index 2b720a8..dde93e8 100644
--- a/helgrind/tests/tc08_hbl2.c
+++ b/helgrind/tests/tc08_hbl2.c
@@ -33,6 +33,7 @@
 #undef PLAT_s390x_linux
 #undef PLAT_mips32_linux
 #undef PLAT_mips64_linux
+#undef PLAT_tilegx_linux
 
 #if defined(__APPLE__) && defined(__i386__)
 #  define PLAT_x86_darwin 1
@@ -58,6 +59,8 @@
 #else
 #  define PLAT_mips32_linux 1
 #endif
+#elif defined(__linux__) && defined(__tilegx__)
+#  define PLAT_tilegx_linux 1
 #endif
 
 
@@ -123,6 +126,12 @@
       : /*out*/ : /*in*/ "r"(&(_lval))              \
       : /*trash*/ "t0", "t1", "memory"              \
         )
+#elif defined(PLAT_tilegx_linux)
+#  define INC(_lval,_lqual)                     \
+  if (sizeof(_lval) == 4)                       \
+    __insn_fetchadd(&(_lval), 1);               \
+  else if(sizeof(_lval) == 8)                   \
+    __insn_fetchadd(&(_lval), 1)
 #else
 #  error "Fix Me for this platform"
 #endif
diff --git a/helgrind/tests/tc11_XCHG.c b/helgrind/tests/tc11_XCHG.c
index 50e2853..481f916 100644
--- a/helgrind/tests/tc11_XCHG.c
+++ b/helgrind/tests/tc11_XCHG.c
@@ -18,6 +18,7 @@
 #undef PLAT_arm_linux
 #undef PLAT_s390x_linux
 #undef PLAT_mips32_linux
+#undef PLAT_tilegx_linux
 
 #if defined(__APPLE__) && defined(__i386__)
 #  define PLAT_x86_darwin 1
@@ -39,6 +40,8 @@
 #  define PLAT_s390x_linux 1
 #elif defined(__linux__) && defined(__mips__)
 #  define PLAT_mips32_linux 1
+#elif defined(__linux__) && defined(__tilegx__)
+#  define PLAT_tilegx_linux 1
 #endif
 
 
@@ -115,6 +118,12 @@
 #  define XCHG_M_R_with_redundant_LOCK(_addr,_lval) \
       XCHG_M_R(_addr,_lval)
 
+#elif defined(PLAT_tilegx_linux)
+#  define XCHG_M_R(_addr,_lval) \
+  _lval = __insn_exch4(&_addr, _lval)
+
+#  define XCHG_M_R_with_redundant_LOCK(_addr,_lval) \
+  XCHG_M_R(_addr, _lval)
 #else
 #  error "Unsupported architecture"
 
diff --git a/include/pub_tool_basics.h b/include/pub_tool_basics.h
index f6f192c..949459e 100644
--- a/include/pub_tool_basics.h
+++ b/include/pub_tool_basics.h
@@ -282,7 +282,7 @@
 
 #if defined(VGA_x86) || defined(VGA_amd64) || defined (VGA_arm) \
     || ((defined(VGA_mips32) || defined(VGA_mips64)) && defined (_MIPSEL)) \
-    || defined(VGA_arm64)  || defined(VGA_ppc64le)
+    || defined(VGA_arm64)  || defined(VGA_ppc64le) || defined(VGA_tilegx)
 #  define VG_LITTLEENDIAN 1
 #elif defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_s390x) \
       || ((defined(VGA_mips32) || defined(VGA_mips64)) && defined (_MIPSEB))
@@ -325,7 +325,7 @@
       || defined(VGA_ppc64be) || defined(VGA_ppc64le) \
       || defined(VGA_arm) || defined(VGA_s390x) \
       || defined(VGA_mips32) || defined(VGA_mips64) \
-      || defined(VGA_arm64)
+      || defined(VGA_arm64) || defined(VGA_tilegx)
 #  define VG_REGPARM(n)            /* */
 #else
 #  error Unknown arch
diff --git a/include/pub_tool_guest.h b/include/pub_tool_guest.h
index 436afe0..8b38283 100644
--- a/include/pub_tool_guest.h
+++ b/include/pub_tool_guest.h
@@ -64,6 +64,9 @@
 #elif defined(VGA_mips64)
 #  include "libvex_guest_mips64.h"
    typedef VexGuestMIPS64State VexGuestArchState;
+#elif defined(VGA_tilegx)
+#  include "libvex_guest_tilegx.h"
+   typedef VexGuestTILEGXState VexGuestArchState;
 #else
 #  error Unknown arch
 #endif
diff --git a/include/pub_tool_machine.h b/include/pub_tool_machine.h
index c80d49b..1e31179 100644
--- a/include/pub_tool_machine.h
+++ b/include/pub_tool_machine.h
@@ -104,6 +104,12 @@
 #  define VG_CLREQ_SZB             20
 #  define VG_STACK_REDZONE_SZB      0
 
+#elif defined(VGP_tilegx_linux)
+#  define VG_MIN_INSTR_SZB          8
+#  define VG_MAX_INSTR_SZB          8
+#  define VG_CLREQ_SZB             24
+#  define VG_STACK_REDZONE_SZB      0
+
 #else
 #  error Unknown platform
 #endif
diff --git a/include/pub_tool_vkiscnums_asm.h b/include/pub_tool_vkiscnums_asm.h
index 7f7f03e..860e8d0 100644
--- a/include/pub_tool_vkiscnums_asm.h
+++ b/include/pub_tool_vkiscnums_asm.h
@@ -63,6 +63,9 @@
 #elif defined(VGP_x86_darwin) || defined(VGP_amd64_darwin)
 #  include "vki/vki-scnums-darwin.h"
 
+#elif defined(VGP_tilegx_linux)
+#  include "vki/vki-scnums-tilegx-linux.h"
+
 #else
 #  error Unknown platform
 #endif
diff --git a/include/valgrind.h b/include/valgrind.h
index 7689a9f..4baf855 100644
--- a/include/valgrind.h
+++ b/include/valgrind.h
@@ -122,6 +122,7 @@
 #undef PLAT_s390x_linux
 #undef PLAT_mips32_linux
 #undef PLAT_mips64_linux
+#undef PLAT_tilegx_linux
 
 
 #if defined(__APPLE__) && defined(__i386__)
@@ -157,6 +158,8 @@
 #  define PLAT_mips64_linux 1
 #elif defined(__linux__) && defined(__mips__) && (__mips!=64)
 #  define PLAT_mips32_linux 1
+#elif defined(__linux__) && defined(__tilegx__)
+#  define PLAT_tilegx_linux 1
 #else
 /* If we're not compiling for our target platform, don't generate
    any inline asms.  */
@@ -1035,6 +1038,73 @@
 
 #endif /* PLAT_mips64_linux */
 
+/* ------------------------ tilegx-linux --------------- */
+#if defined(PLAT_tilegx_linux)
+
+typedef
+   struct {
+      unsigned long long int nraddr; /* where's the code? */
+   }
+   OrigFn;
+/*** special instruction sequence.
+     0:02b3c7ff91234fff { moveli zero, 4660 ; moveli zero, 22136 }
+     8:0091a7ff95678fff { moveli zero, 22136 ; moveli zero, 4660 }
+****/
+
+#define __SPECIAL_INSTRUCTION_PREAMBLE                             \
+   ".quad  0x02b3c7ff91234fff\n"                                   \
+   ".quad  0x0091a7ff95678fff\n"
+
+#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                           \
+   _zzq_default, _zzq_request,                                      \
+   _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)          \
+   ({ volatile unsigned long long int _zzq_args[6];                \
+      volatile unsigned long long int _zzq_result;                 \
+      _zzq_args[0] = (unsigned long long int)(_zzq_request);       \
+      _zzq_args[1] = (unsigned long long int)(_zzq_arg1);          \
+      _zzq_args[2] = (unsigned long long int)(_zzq_arg2);          \
+      _zzq_args[3] = (unsigned long long int)(_zzq_arg3);          \
+      _zzq_args[4] = (unsigned long long int)(_zzq_arg4);          \
+      _zzq_args[5] = (unsigned long long int)(_zzq_arg5);          \
+      __asm__ volatile("move r11, %1\n\t" /*default*/              \
+                       "move r12, %2\n\t" /*ptr*/                  \
+                       __SPECIAL_INSTRUCTION_PREAMBLE              \
+                       /* r11 = client_request */                  \
+                       "or r13, r13, r13\n\t"                      \
+                       "move %0, r11\n\t"     /*result*/           \
+                       : "=r" (_zzq_result)                        \
+                       : "r" (_zzq_default), "r" (&_zzq_args[0])   \
+                       : "memory", "r11", "r12");                  \
+      _zzq_result;                                                 \
+   })
+
+#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                        \
+   {  volatile OrigFn* _zzq_orig = &(_zzq_rlval);                  \
+      volatile unsigned long long int __addr;                      \
+      __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE              \
+                       /* r11 = guest_NRADDR */                    \
+                       "or r14, r14, r14\n"                        \
+                       "move %0, r11\n"                            \
+                       : "=r" (__addr)                             \
+                       :                                           \
+                       : "memory", "r11"                           \
+                       );                                          \
+      _zzq_orig->nraddr = __addr;                                  \
+   }
+
+#define VALGRIND_CALL_NOREDIR_R12                                  \
+   __SPECIAL_INSTRUCTION_PREAMBLE                                  \
+   "or r15, r15, r15\n\t"
+
+#define VALGRIND_VEX_INJECT_IR()                                   \
+   do {                                                            \
+      __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE              \
+                       "or r11, r11, r11\n\t"                      \
+                       );                                          \
+   } while (0)
+
+#endif /* PLAT_tilegx_linux */
+
 /* Insert assembly code for other platforms here... */
 
 #endif /* NVALGRIND */
@@ -6083,6 +6153,460 @@
 
 #endif /* PLAT_mips64_linux */
 
+/* ------------------------ tilegx-linux ------------------------- */
+
+#if defined(PLAT_tilegx_linux)
+
+/* These regs are trashed by the hidden call. */
+#define __CALLER_SAVED_REGS "r0", "r1", "r2", "r3", "r4", "r5", \
+    "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14",  \
+    "r15", "r16", "r17", "r18", "r19", "r20", "r21", "r22",     \
+    "r23", "r24", "r25", "r26", "r27", "r28", "r29", "lr"
+
+/* These CALL_FN_ macros assume that on tilegx-linux, sizeof(unsigned
+   long) == 8. */
+
+#define CALL_FN_W_v(lval, orig)                          \
+   do {                                                  \
+      volatile OrigFn        _orig = (orig);             \
+      volatile unsigned long _argvec[1];                 \
+      volatile unsigned long _res;                       \
+      _argvec[0] = (unsigned long)_orig.nraddr;          \
+      __asm__ volatile(                                  \
+         "addi sp, sp, -8 \n\t"                          \
+         "st_add sp, lr, -8 \n\t"                        \
+         "ld r12, %1 \n\t"  /* target->r11 */            \
+         VALGRIND_CALL_NOREDIR_R12                       \
+         "addi   sp, sp, 8\n\t"                          \
+         "ld_add lr, sp, 8 \n\t"                         \
+         "move  %0, r0 \n"                               \
+         : /*out*/   "=r" (_res)                         \
+         : /*in*/    "r" (&_argvec[0])                   \
+         : /*trash*/  "memory", __CALLER_SAVED_REGS);    \
+                                                         \
+      lval = (__typeof__(lval)) _res;                    \
+   } while (0)
+
+#define CALL_FN_W_W(lval, orig, arg1)                   \
+   do {                                                 \
+      volatile OrigFn        _orig = (orig);            \
+      volatile unsigned long _argvec[2];                \
+      volatile unsigned long _res;                      \
+      _argvec[0] = (unsigned long)_orig.nraddr;         \
+      _argvec[1] = (unsigned long)(arg1);               \
+      __asm__ volatile(                                 \
+         "addi sp, sp, -8 \n\t"                         \
+         "st_add sp, lr, -8 \n\t"                       \
+         "move r29, %1 \n\t"                            \
+         "ld_add r12, r29, 8 \n\t"  /* target->r11 */   \
+         "ld_add r0, r29, 8 \n\t" /*arg1 -> r0 */       \
+         VALGRIND_CALL_NOREDIR_R12                      \
+         "addi   sp, sp, 8\n\t"                         \
+         "ld_add lr, sp, 8 \n\t"                        \
+         "move  %0, r0\n"                               \
+         : /*out*/   "=r" (_res)                        \
+         : /*in*/    "r" (&_argvec[0])                  \
+         : /*trash*/  "memory", __CALLER_SAVED_REGS);   \
+      lval = (__typeof__(lval)) _res;                   \
+   } while (0)
+
+#define CALL_FN_W_WW(lval, orig, arg1,arg2)             \
+   do {                                                 \
+      volatile OrigFn        _orig = (orig);            \
+      volatile unsigned long _argvec[3];                \
+      volatile unsigned long _res;                      \
+      _argvec[0] = (unsigned long)_orig.nraddr;         \
+      _argvec[1] = (unsigned long)(arg1);               \
+      _argvec[2] = (unsigned long)(arg2);               \
+      __asm__ volatile(                                 \
+         "addi sp, sp, -8 \n\t"                         \
+         "st_add sp, lr, -8 \n\t"                       \
+         "move r29, %1 \n\t"                            \
+         "ld_add r12, r29, 8 \n\t"  /* target->r11 */   \
+         "ld_add r0, r29, 8 \n\t" /*arg1 -> r0 */       \
+         "ld_add r1, r29, 8 \n\t" /*arg2 -> r1 */       \
+         VALGRIND_CALL_NOREDIR_R12                      \
+         "addi   sp, sp, 8\n\t"                         \
+         "ld_add lr, sp, 8 \n\t"                        \
+         "move  %0, r0\n"                               \
+         : /*out*/   "=r" (_res)                        \
+         : /*in*/    "r" (&_argvec[0])                  \
+         : /*trash*/  "memory", __CALLER_SAVED_REGS);   \
+      lval = (__typeof__(lval)) _res;                   \
+   } while (0)
+
+#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)       \
+   do {                                                 \
+     volatile OrigFn        _orig = (orig);             \
+     volatile unsigned long _argvec[4];                 \
+     volatile unsigned long _res;                       \
+     _argvec[0] = (unsigned long)_orig.nraddr;          \
+     _argvec[1] = (unsigned long)(arg1);                \
+     _argvec[2] = (unsigned long)(arg2);                \
+     _argvec[3] = (unsigned long)(arg3);                \
+     __asm__ volatile(                                  \
+        "addi sp, sp, -8 \n\t"                          \
+        "st_add sp, lr, -8 \n\t"                        \
+        "move r29, %1 \n\t"                             \
+        "ld_add r12, r29, 8 \n\t"  /* target->r11 */    \
+        "ld_add r0, r29, 8 \n\t" /*arg1 -> r0 */        \
+        "ld_add r1, r29, 8 \n\t" /*arg2 -> r1 */        \
+        "ld_add r2, r29, 8 \n\t" /*arg3 -> r2 */        \
+        VALGRIND_CALL_NOREDIR_R12                       \
+        "addi   sp, sp, 8 \n\t"                         \
+        "ld_add lr, sp, 8 \n\t"                         \
+        "move  %0, r0\n"                                \
+        : /*out*/   "=r" (_res)                         \
+        : /*in*/    "r" (&_argvec[0])                   \
+        : /*trash*/  "memory", __CALLER_SAVED_REGS);    \
+     lval = (__typeof__(lval)) _res;                    \
+   } while (0)
+
+#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
+   do {                                                 \
+      volatile OrigFn        _orig = (orig);            \
+      volatile unsigned long _argvec[5];                \
+      volatile unsigned long _res;                      \
+      _argvec[0] = (unsigned long)_orig.nraddr;         \
+      _argvec[1] = (unsigned long)(arg1);               \
+      _argvec[2] = (unsigned long)(arg2);               \
+      _argvec[3] = (unsigned long)(arg3);               \
+      _argvec[4] = (unsigned long)(arg4);               \
+      __asm__ volatile(                                 \
+         "addi sp, sp, -8 \n\t"                         \
+         "st_add sp, lr, -8 \n\t"                       \
+         "move r29, %1 \n\t"                            \
+         "ld_add r12, r29, 8 \n\t"  /* target->r11 */   \
+         "ld_add r0, r29, 8 \n\t" /*arg1 -> r0 */       \
+         "ld_add r1, r29, 8 \n\t" /*arg2 -> r1 */       \
+         "ld_add r2, r29, 8 \n\t" /*arg3 -> r2 */       \
+         "ld_add r3, r29, 8 \n\t" /*arg4 -> r3 */       \
+         VALGRIND_CALL_NOREDIR_R12                      \
+         "addi   sp, sp, 8\n\t"                         \
+         "ld_add lr, sp, 8 \n\t"                        \
+         "move  %0, r0\n"                               \
+         : /*out*/   "=r" (_res)                        \
+         : /*in*/    "r" (&_argvec[0])                  \
+         : /*trash*/  "memory", __CALLER_SAVED_REGS);   \
+      lval = (__typeof__(lval)) _res;                   \
+   } while (0)
+
+#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)      \
+   do {                                                         \
+      volatile OrigFn        _orig = (orig);                    \
+      volatile unsigned long _argvec[6];                        \
+      volatile unsigned long _res;                              \
+      _argvec[0] = (unsigned long)_orig.nraddr;                 \
+      _argvec[1] = (unsigned long)(arg1);                       \
+      _argvec[2] = (unsigned long)(arg2);                       \
+      _argvec[3] = (unsigned long)(arg3);                       \
+      _argvec[4] = (unsigned long)(arg4);                       \
+      _argvec[5] = (unsigned long)(arg5);                       \
+      __asm__ volatile(                                         \
+         "addi sp, sp, -8 \n\t"                                 \
+         "st_add sp, lr, -8 \n\t"                               \
+         "move r29, %1 \n\t"                                    \
+         "ld_add r12, r29, 8 \n\t"  /* target->r11 */           \
+         "ld_add r0, r29, 8 \n\t" /*arg1 -> r0 */               \
+         "ld_add r1, r29, 8 \n\t" /*arg2 -> r1 */               \
+         "ld_add r2, r29, 8 \n\t" /*arg3 -> r2 */               \
+         "ld_add r3, r29, 8 \n\t" /*arg4 -> r3 */               \
+         "ld_add r4, r29, 8 \n\t" /*arg5 -> r4 */               \
+         VALGRIND_CALL_NOREDIR_R12                              \
+         "addi   sp, sp, 8\n\t"                                 \
+         "ld_add lr, sp, 8 \n\t"                                \
+         "move  %0, r0\n"                                       \
+         : /*out*/   "=r" (_res)                                \
+         : /*in*/    "r" (&_argvec[0])                          \
+         : /*trash*/  "memory", __CALLER_SAVED_REGS);           \
+      lval = (__typeof__(lval)) _res;                           \
+   } while (0)
+#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
+   do {                                                         \
+      volatile OrigFn        _orig = (orig);                    \
+      volatile unsigned long _argvec[7];                        \
+      volatile unsigned long _res;                              \
+      _argvec[0] = (unsigned long)_orig.nraddr;                 \
+      _argvec[1] = (unsigned long)(arg1);                       \
+      _argvec[2] = (unsigned long)(arg2);                       \
+      _argvec[3] = (unsigned long)(arg3);                       \
+      _argvec[4] = (unsigned long)(arg4);                       \
+      _argvec[5] = (unsigned long)(arg5);                       \
+      _argvec[6] = (unsigned long)(arg6);                       \
+      __asm__ volatile(                                         \
+        "addi sp, sp, -8 \n\t"                                  \
+        "st_add sp, lr, -8 \n\t"                                \
+        "move r29, %1 \n\t"                                     \
+        "ld_add r12, r29, 8 \n\t"  /* target->r11 */            \
+        "ld_add r0, r29, 8 \n\t" /*arg1 -> r0 */                \
+        "ld_add r1, r29, 8 \n\t" /*arg2 -> r1 */                \
+        "ld_add r2, r29, 8 \n\t" /*arg3 -> r2 */                \
+        "ld_add r3, r29, 8 \n\t" /*arg4 -> r3 */                \
+        "ld_add r4, r29, 8 \n\t" /*arg5 -> r4 */                \
+        "ld_add r5, r29, 8 \n\t" /*arg6 -> r5 */                \
+        VALGRIND_CALL_NOREDIR_R12                               \
+        "addi   sp, sp, 8\n\t"                                  \
+        "ld_add lr, sp, 8 \n\t"                                 \
+        "move  %0, r0\n"                                        \
+        : /*out*/   "=r" (_res)                                 \
+        : /*in*/    "r" (&_argvec[0])                           \
+        : /*trash*/  "memory", __CALLER_SAVED_REGS);            \
+      lval = (__typeof__(lval)) _res;                           \
+   } while (0)
+
+#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+                     arg7)                                      \
+   do {                                                         \
+      volatile OrigFn        _orig = (orig);                    \
+      volatile unsigned long _argvec[8];                        \
+      volatile unsigned long _res;                              \
+      _argvec[0] = (unsigned long)_orig.nraddr;                 \
+      _argvec[1] = (unsigned long)(arg1);                       \
+      _argvec[2] = (unsigned long)(arg2);                       \
+      _argvec[3] = (unsigned long)(arg3);                       \
+      _argvec[4] = (unsigned long)(arg4);                       \
+      _argvec[5] = (unsigned long)(arg5);                       \
+      _argvec[6] = (unsigned long)(arg6);                       \
+      _argvec[7] = (unsigned long)(arg7);                       \
+      __asm__ volatile(                                         \
+        "addi sp, sp, -8 \n\t"                                  \
+        "st_add sp, lr, -8 \n\t"                                \
+        "move r29, %1 \n\t"                                     \
+        "ld_add r12, r29, 8 \n\t"  /* target->r11 */            \
+        "ld_add r0, r29, 8 \n\t" /*arg1 -> r0 */                \
+        "ld_add r1, r29, 8 \n\t" /*arg2 -> r1 */                \
+        "ld_add r2, r29, 8 \n\t" /*arg3 -> r2 */                \
+        "ld_add r3, r29, 8 \n\t" /*arg4 -> r3 */                \
+        "ld_add r4, r29, 8 \n\t" /*arg5 -> r4 */                \
+        "ld_add r5, r29, 8 \n\t" /*arg6 -> r5 */                \
+        "ld_add r6, r29, 8 \n\t" /*arg7 -> r6 */                \
+        VALGRIND_CALL_NOREDIR_R12                               \
+        "addi   sp, sp, 8\n\t"                                  \
+        "ld_add lr, sp, 8 \n\t"                                 \
+        "move  %0, r0\n"                                        \
+        : /*out*/   "=r" (_res)                                 \
+        : /*in*/    "r" (&_argvec[0])                           \
+        : /*trash*/  "memory", __CALLER_SAVED_REGS);            \
+      lval = (__typeof__(lval)) _res;                           \
+   } while (0)
+
+#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+                     arg7,arg8)                                 \
+   do {                                                         \
+      volatile OrigFn        _orig = (orig);                    \
+      volatile unsigned long _argvec[9];                        \
+      volatile unsigned long _res;                              \
+      _argvec[0] = (unsigned long)_orig.nraddr;                 \
+      _argvec[1] = (unsigned long)(arg1);                       \
+      _argvec[2] = (unsigned long)(arg2);                       \
+      _argvec[3] = (unsigned long)(arg3);                       \
+      _argvec[4] = (unsigned long)(arg4);                       \
+      _argvec[5] = (unsigned long)(arg5);                       \
+      _argvec[6] = (unsigned long)(arg6);                       \
+      _argvec[7] = (unsigned long)(arg7);                       \
+      _argvec[8] = (unsigned long)(arg8);                       \
+      __asm__ volatile(                                         \
+        "addi sp, sp, -8 \n\t"                                  \
+        "st_add sp, lr, -8 \n\t"                                \
+        "move r29, %1 \n\t"                                     \
+        "ld_add r12, r29, 8 \n\t"  /* target->r11 */            \
+        "ld_add r0, r29, 8 \n\t" /*arg1 -> r0 */                \
+        "ld_add r1, r29, 8 \n\t" /*arg2 -> r1 */                \
+        "ld_add r2, r29, 8 \n\t" /*arg3 -> r2 */                \
+        "ld_add r3, r29, 8 \n\t" /*arg4 -> r3 */                \
+        "ld_add r4, r29, 8 \n\t" /*arg5 -> r4 */                \
+        "ld_add r5, r29, 8 \n\t" /*arg6 -> r5 */                \
+        "ld_add r6, r29, 8 \n\t" /*arg7 -> r6 */                \
+        "ld_add r7, r29, 8 \n\t" /*arg8 -> r7 */                \
+        VALGRIND_CALL_NOREDIR_R12                               \
+        "addi   sp, sp, 8\n\t"                                  \
+        "ld_add lr, sp, 8 \n\t"                                 \
+        "move  %0, r0\n"                                        \
+        : /*out*/   "=r" (_res)                                 \
+        : /*in*/    "r" (&_argvec[0])                           \
+        : /*trash*/  "memory", __CALLER_SAVED_REGS);            \
+      lval = (__typeof__(lval)) _res;                           \
+   } while (0)
+
+#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+                     arg7,arg8,arg9)                            \
+   do {                                                         \
+      volatile OrigFn        _orig = (orig);                    \
+      volatile unsigned long _argvec[10];                       \
+      volatile unsigned long _res;                              \
+      _argvec[0] = (unsigned long)_orig.nraddr;                 \
+      _argvec[1] = (unsigned long)(arg1);                       \
+      _argvec[2] = (unsigned long)(arg2);                       \
+      _argvec[3] = (unsigned long)(arg3);                       \
+      _argvec[4] = (unsigned long)(arg4);                       \
+      _argvec[5] = (unsigned long)(arg5);                       \
+      _argvec[6] = (unsigned long)(arg6);                       \
+      _argvec[7] = (unsigned long)(arg7);                       \
+      _argvec[8] = (unsigned long)(arg8);                       \
+      _argvec[9] = (unsigned long)(arg9);                       \
+      __asm__ volatile(                                         \
+        "addi sp, sp, -8 \n\t"                                  \
+        "st_add sp, lr, -8 \n\t"                                \
+        "move r29, %1 \n\t"                                     \
+        "ld_add r12, r29, 8 \n\t"  /* target->r11 */            \
+        "ld_add r0, r29, 8 \n\t" /*arg1 -> r0 */                \
+        "ld_add r1, r29, 8 \n\t" /*arg2 -> r1 */                \
+        "ld_add r2, r29, 8 \n\t" /*arg3 -> r2 */                \
+        "ld_add r3, r29, 8 \n\t" /*arg4 -> r3 */                \
+        "ld_add r4, r29, 8 \n\t" /*arg5 -> r4 */                \
+        "ld_add r5, r29, 8 \n\t" /*arg6 -> r5 */                \
+        "ld_add r6, r29, 8 \n\t" /*arg7 -> r6 */                \
+        "ld_add r7, r29, 8 \n\t" /*arg8 -> r7 */                \
+        "ld_add r8, r29, 8 \n\t" /*arg9 -> r8 */                \
+        VALGRIND_CALL_NOREDIR_R12                               \
+        "addi   sp, sp, 8\n\t"                                  \
+        "ld_add lr, sp, 8 \n\t"                                 \
+        "move  %0, r0\n"                                        \
+        : /*out*/   "=r" (_res)                                 \
+        : /*in*/    "r" (&_argvec[0])                           \
+        : /*trash*/  "memory", __CALLER_SAVED_REGS);            \
+      lval = (__typeof__(lval)) _res;                           \
+   } while (0)
+
+#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,        \
+                      arg7,arg8,arg9,arg10)                             \
+   do {                                                                 \
+      volatile OrigFn        _orig = (orig);                            \
+      volatile unsigned long _argvec[11];                               \
+      volatile unsigned long _res;                                      \
+      _argvec[0] = (unsigned long)_orig.nraddr;                         \
+      _argvec[1] = (unsigned long)(arg1);                               \
+      _argvec[2] = (unsigned long)(arg2);                               \
+      _argvec[3] = (unsigned long)(arg3);                               \
+      _argvec[4] = (unsigned long)(arg4);                               \
+      _argvec[5] = (unsigned long)(arg5);                               \
+      _argvec[6] = (unsigned long)(arg6);                               \
+      _argvec[7] = (unsigned long)(arg7);                               \
+      _argvec[8] = (unsigned long)(arg8);                               \
+      _argvec[9] = (unsigned long)(arg9);                               \
+      _argvec[10] = (unsigned long)(arg10);                             \
+      __asm__ volatile(                                                 \
+        "addi sp, sp, -8 \n\t"                                          \
+        "st_add sp, lr, -8 \n\t"                                        \
+        "move r29, %1 \n\t"                                             \
+        "ld_add r12, r29, 8 \n\t"  /* target->r11 */                    \
+        "ld_add r0, r29, 8 \n\t" /*arg1 -> r0 */                        \
+        "ld_add r1, r29, 8 \n\t" /*arg2 -> r1 */                        \
+        "ld_add r2, r29, 8 \n\t" /*arg3 -> r2 */                        \
+        "ld_add r3, r29, 8 \n\t" /*arg4 -> r3 */                        \
+        "ld_add r4, r29, 8 \n\t" /*arg5 -> r4 */                        \
+        "ld_add r5, r29, 8 \n\t" /*arg6 -> r5 */                        \
+        "ld_add r6, r29, 8 \n\t" /*arg7 -> r6 */                        \
+        "ld_add r7, r29, 8 \n\t" /*arg8 -> r7 */                        \
+        "ld_add r8, r29, 8 \n\t" /*arg9 -> r8 */                        \
+        "ld_add r9, r29, 8 \n\t" /*arg10 -> r9 */                       \
+        VALGRIND_CALL_NOREDIR_R12                                       \
+        "addi   sp, sp, 8\n\t"                                          \
+        "ld_add lr, sp, 8 \n\t"                                         \
+        "move  %0, r0\n"                                                \
+        : /*out*/   "=r" (_res)                                         \
+        : /*in*/    "r" (&_argvec[0])                                   \
+        : /*trash*/  "memory", __CALLER_SAVED_REGS);                    \
+      lval = (__typeof__(lval)) _res;                                   \
+   } while (0)
+
+#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,     \
+                      arg6,arg7,arg8,arg9,arg10,                \
+                      arg11)                                    \
+   do {                                                         \
+      volatile OrigFn        _orig = (orig);                    \
+      volatile unsigned long _argvec[12];                       \
+      volatile unsigned long _res;                              \
+      _argvec[0] = (unsigned long)_orig.nraddr;                 \
+      _argvec[1] = (unsigned long)(arg1);                       \
+      _argvec[2] = (unsigned long)(arg2);                       \
+      _argvec[3] = (unsigned long)(arg3);                       \
+      _argvec[4] = (unsigned long)(arg4);                       \
+      _argvec[5] = (unsigned long)(arg5);                       \
+      _argvec[6] = (unsigned long)(arg6);                       \
+      _argvec[7] = (unsigned long)(arg7);                       \
+      _argvec[8] = (unsigned long)(arg8);                       \
+      _argvec[9] = (unsigned long)(arg9);                       \
+      _argvec[10] = (unsigned long)(arg10);                     \
+      _argvec[11] = (unsigned long)(arg11);                     \
+      __asm__ volatile(                                         \
+        "addi sp, sp, -8 \n\t"                                  \
+        "st_add sp, lr, -8 \n\t"                                \
+        "move r29, %1 \n\t"                                     \
+        "ld_add r12, r29, 8 \n\t"  /* target->r11 */            \
+        "ld_add r0, r29, 8 \n\t" /*arg1 -> r0 */                \
+        "ld_add r1, r29, 8 \n\t" /*arg2 -> r1 */                \
+        "ld_add r2, r29, 8 \n\t" /*arg3 -> r2 */                \
+        "ld_add r3, r29, 8 \n\t" /*arg4 -> r3 */                \
+        "ld_add r4, r29, 8 \n\t" /*arg5 -> r4 */                \
+        "ld_add r5, r29, 8 \n\t" /*arg6 -> r5 */                \
+        "ld_add r6, r29, 8 \n\t" /*arg7 -> r6 */                \
+        "ld_add r7, r29, 8 \n\t" /*arg8 -> r7 */                \
+        "ld_add r8, r29, 8 \n\t" /*arg9 -> r8 */                \
+        "ld_add r9, r29, 8 \n\t" /*arg10 -> r9 */               \
+        "ld     r10, r29 \n\t"                                  \
+        "st_add sp, r10, -16 \n\t"                              \
+        VALGRIND_CALL_NOREDIR_R12                               \
+        "addi   sp, sp, 24 \n\t"                                \
+        "ld_add lr, sp, 8 \n\t"                                 \
+        "move  %0, r0\n"                                        \
+        : /*out*/   "=r" (_res)                                 \
+        : /*in*/    "r" (&_argvec[0])                           \
+        : /*trash*/  "memory", __CALLER_SAVED_REGS);            \
+      lval = (__typeof__(lval)) _res;                           \
+   } while (0)
+
+#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,     \
+                      arg6,arg7,arg8,arg9,arg10,                \
+                      arg11,arg12)                              \
+   do {                                                         \
+      volatile OrigFn        _orig = (orig);                    \
+      volatile unsigned long _argvec[13];                       \
+      volatile unsigned long _res;                              \
+      _argvec[0] = (unsigned long)_orig.nraddr;                 \
+      _argvec[1] = (unsigned long)(arg1);                       \
+      _argvec[2] = (unsigned long)(arg2);                       \
+      _argvec[3] = (unsigned long)(arg3);                       \
+      _argvec[4] = (unsigned long)(arg4);                       \
+      _argvec[5] = (unsigned long)(arg5);                       \
+      _argvec[6] = (unsigned long)(arg6);                       \
+      _argvec[7] = (unsigned long)(arg7);                       \
+      _argvec[8] = (unsigned long)(arg8);                       \
+      _argvec[9] = (unsigned long)(arg9);                       \
+      _argvec[10] = (unsigned long)(arg10);                     \
+      _argvec[11] = (unsigned long)(arg11);                     \
+      _argvec[12] = (unsigned long)(arg12);                     \
+      __asm__ volatile(                                         \
+        "addi sp, sp, -8 \n\t"                                  \
+        "st_add sp, lr, -8 \n\t"                                \
+        "move r29, %1 \n\t"                                     \
+        "ld_add r12, r29, 8 \n\t"  /* target->r11 */            \
+        "ld_add r0, r29, 8 \n\t" /*arg1 -> r0 */                \
+        "ld_add r1, r29, 8 \n\t" /*arg2 -> r1 */                \
+        "ld_add r2, r29, 8 \n\t" /*arg3 -> r2 */                \
+        "ld_add r3, r29, 8 \n\t" /*arg4 -> r3 */                \
+        "ld_add r4, r29, 8 \n\t" /*arg5 -> r4 */                \
+        "ld_add r5, r29, 8 \n\t" /*arg6 -> r5 */                \
+        "ld_add r6, r29, 8 \n\t" /*arg7 -> r6 */                \
+        "ld_add r7, r29, 8 \n\t" /*arg8 -> r7 */                \
+        "ld_add r8, r29, 8 \n\t" /*arg9 -> r8 */                \
+        "ld_add r9, r29, 8 \n\t" /*arg10 -> r9 */               \
+        "addi r28, sp, -8 \n\t"                                 \
+        "addi sp,  sp, -24 \n\t"                                \
+        "ld_add r10, r29, 8 \n\t"                               \
+        "ld     r11, r29 \n\t"                                  \
+        "st_add r28, r10, 8 \n\t"                               \
+        "st     r28, r11 \n\t"                                  \
+        VALGRIND_CALL_NOREDIR_R12                               \
+        "addi   sp, sp, 32 \n\t"                                \
+        "ld_add lr, sp, 8 \n\t"                                 \
+        "move  %0, r0\n"                                        \
+        : /*out*/   "=r" (_res)                                 \
+        : /*in*/    "r" (&_argvec[0])                           \
+        : /*trash*/  "memory", __CALLER_SAVED_REGS);            \
+      lval = (__typeof__(lval)) _res;                           \
+   } while (0)
+#endif  /* PLAT_tilegx_linux */
 
 /* ------------------------------------------------------------------ */
 /* ARCHITECTURE INDEPENDENT MACROS for CLIENT REQUESTS.               */
@@ -6583,5 +7107,6 @@
 #undef PLAT_s390x_linux
 #undef PLAT_mips32_linux
 #undef PLAT_mips64_linux
+#undef PLAT_tilegx_linux
 
 #endif   /* __VALGRIND_H */
diff --git a/include/vki/vki-linux.h b/include/vki/vki-linux.h
index 42b24fe..808c1d8 100644
--- a/include/vki/vki-linux.h
+++ b/include/vki/vki-linux.h
@@ -97,6 +97,8 @@
 #  include "vki-posixtypes-mips32-linux.h"
 #elif defined(VGA_mips64)
 #  include "vki-posixtypes-mips64-linux.h"
+#elif defined(VGA_tilegx)
+#  include "vki-posixtypes-tilegx-linux.h"
 #else
 #  error Unknown platform
 #endif
@@ -223,6 +225,8 @@
 #  include "vki-mips32-linux.h"
 #elif defined(VGA_mips64)
 #  include "vki-mips64-linux.h"
+#elif defined(VGA_tilegx)
+#  include "vki-tilegx-linux.h"
 #else
 #  error Unknown platform
 #endif
diff --git a/include/vki/vki-posixtypes-tilegx-linux.h b/include/vki/vki-posixtypes-tilegx-linux.h
new file mode 100644
index 0000000..c95e768
--- /dev/null
+++ b/include/vki/vki-posixtypes-tilegx-linux.h
@@ -0,0 +1,68 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Tilegx/Linux-specific kernel interface: posix types.         ---*/
+/*---                                vki-posixtypes-tilegx-linux.h ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+   This file is part of Valgrind, a dynamic binary instrumentation
+   framework.
+
+   Copyright (C) 2010-2013 Tilera Corp.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   This program 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
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307, USA.
+
+   The GNU General Public License is contained in the file COPYING.
+*/
+
+/* Contributed by Zhi-Gang Liu <zliu at tilera dot com> */
+
+#ifndef __VKI_POSIXTYPES_TILEGX_LINUX_H
+#define __VKI_POSIXTYPES_TILEGX_LINUX_H
+
+//----------------------------------------------------------------------
+// From tilegx linux/include/asm-generic/posix_types.h
+//----------------------------------------------------------------------
+
+typedef unsigned int   __vki_kernel_mode_t;
+typedef long           __vki_kernel_off_t;
+typedef int            __vki_kernel_pid_t;
+typedef int            __vki_kernel_ipc_pid_t;
+typedef unsigned int   __vki_kernel_uid_t;
+typedef unsigned int   __vki_kernel_gid_t;
+typedef unsigned long  __vki_kernel_size_t;
+typedef long           __vki_kernel_time_t;
+typedef long           __vki_kernel_suseconds_t;
+typedef long           __vki_kernel_clock_t;
+typedef int            __vki_kernel_timer_t;
+typedef int            __vki_kernel_clockid_t;
+typedef char *         __vki_kernel_caddr_t;
+typedef long long      __vki_kernel_loff_t;
+
+typedef struct {
+    int    val[2];
+} __vki_kernel_fsid_t;
+
+typedef __vki_kernel_uid_t  __vki_kernel_old_uid_t;
+typedef __vki_kernel_gid_t  __vki_kernel_old_gid_t;
+typedef __vki_kernel_uid_t  __vki_kernel_uid32_t;
+typedef __vki_kernel_gid_t  __vki_kernel_gid32_t;
+
+#endif // __VKI_POSIXTYPES_TILEGX_LINUX_H
+
+/*--------------------------------------------------------------------*/
+/*--- end                                                          ---*/
+/*--------------------------------------------------------------------*/
diff --git a/include/vki/vki-scnums-tilegx-linux.h b/include/vki/vki-scnums-tilegx-linux.h
new file mode 100644
index 0000000..08137d8
--- /dev/null
+++ b/include/vki/vki-scnums-tilegx-linux.h
@@ -0,0 +1,420 @@
+
+/*--------------------------------------------------------------------*/
+/*--- System call numbers for tilegx-linux.                         ---*/
+/*---                                     vki-scnums-tilegx-linux.h ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+   This file is part of Valgrind, a dynamic binary instrumentation
+   framework.
+
+   Copyright (C) 2010-2013 Tilera Corp.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   This program 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
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307, USA.
+
+   The GNU General Public License is contained in the file COPYING.
+*/
+
+/* Contributed by Zhi-Gang Liu <zliu at tilera dot com> */
+
+#ifndef __VKI_SCNUMS_TILEGX_LINUX_H
+#define __VKI_SCNUMS_TILEGX_LINUX_H
+
+#define AT_FDCWD    -100
+
+/* From tilegx linux/include/asm-generic/unistd.h */
+
+#define __NR_io_setup 0
+#define __NR_io_destroy 1
+#define __NR_io_submit 2
+#define __NR_io_cancel 3
+#define __NR_io_getevents 4
+
+/* fs/xattr.c */
+#define __NR_setxattr 5
+#define __NR_lsetxattr 6
+#define __NR_fsetxattr 7
+#define __NR_getxattr 8
+#define __NR_lgetxattr 9
+#define __NR_fgetxattr 10
+#define __NR_listxattr 11
+#define __NR_llistxattr 12
+#define __NR_flistxattr 13
+#define __NR_removexattr 14
+#define __NR_lremovexattr 15
+#define __NR_fremovexattr 16
+
+/* fs/dcache.c */
+#define __NR_getcwd 17
+
+/* fs/cookies.c */
+#define __NR_lookup_dcookie 18
+
+/* fs/eventfd.c */
+#define __NR_eventfd2 19
+
+/* fs/eventpoll.c */
+#define __NR_epoll_create1 20
+#define __NR_epoll_ctl 21
+#define __NR_epoll_pwait 22
+
+/* fs/fcntl.c */
+#define __NR_dup 23
+#define __NR_dup2 23
+#define __NR_dup3 24
+#define __NR_fcntl 25
+
+/* fs/inotify_user.c */
+#define __NR_inotify_init1 26
+#define __NR_inotify_add_watch 27
+#define __NR_inotify_rm_watch 28
+
+/* fs/ioctl.c */
+#define __NR_ioctl 29
+
+/* fs/ioprio.c */
+#define __NR_ioprio_set 30
+#define __NR_ioprio_get 31
+
+/* fs/locks.c */
+#define __NR_flock 32
+
+/* fs/namei.c */
+#define __NR_mknodat 33
+#define __NR_mkdirat 34
+#define __NR_unlinkat 35
+#define __NR_symlinkat 36
+#define __NR_linkat 37
+#define __NR_renameat 38
+
+/* fs/namespace.c */
+#define __NR_umount2 39
+
+#define __NR_mount 40
+#define __NR_pivot_root 41
+
+/* fs/nfsctl.c */
+#define __NR_nfsservctl 42
+
+/* fs/open.c */
+#define __NR_statfs 43
+#define __NR_fstatfs 44
+#define __NR_truncate 45
+#define __NR_ftruncate 46
+#define __NR_fallocate 47
+#define __NR_faccessat 48
+#define __NR_chdir 49
+#define __NR_fchdir 50
+#define __NR_chroot 51
+#define __NR_fchmod 52
+#define __NR_fchmodat 53
+#define __NR_fchownat 54
+#define __NR_fchown 55
+#define __NR_openat 56
+#define __NR_close 57
+#define __NR_vhangup 58
+
+/* fs/pipe.c */
+#define __NR_pipe2 59
+
+/* fs/quota.c */
+#define __NR_quotactl 60
+
+/* fs/readdir.c */
+#define __NR_getdents64 61
+
+/* fs/read_write.c */
+#define __NR_lseek 62
+#define __NR_read 63
+#define __NR_write 64
+#define __NR_readv 65
+#define __NR_writev 66
+#define __NR_pread64 67
+#define __NR_pwrite64 68
+#define __NR_preadv 69
+#define __NR_pwritev 70
+
+/* fs/sendfile.c */
+#define __NR_sendfile 71
+
+/* fs/select.c */
+#define __NR_pselect6 72
+#define __NR_ppoll 73
+
+/* fs/signalfd.c */
+#define __NR_signalfd4 74
+
+/* fs/splice.c */
+#define __NR_vmsplice 75
+#define __NR_splice 76
+#define __NR_tee 77
+
+/* fs/stat.c */
+#define __NR_readlinkat 78
+#define __NR3264_fstatat 79
+#define __NR_stat     -10000
+#define __NR_fstat   80
+
+/* fs/sync.c */
+#define __NR_sync 81
+#define __NR_fsync 82
+#define __NR_fdatasync 83
+#define __NR_sync_file_range2 84
+#define __NR_sync_file_range 84
+
+/* fs/timerfd.c */
+#define __NR_timerfd_create 85
+#define __NR_timerfd_settime 86
+#define __NR_timerfd_gettime 87
+
+/* fs/utimes.c */
+#define __NR_utimensat 88
+
+/* kernel/acct.c */
+#define __NR_acct 89
+
+/* kernel/capability.c */
+#define __NR_capget 90
+#define __NR_capset 91
+
+/* kernel/exec_domain.c */
+#define __NR_personality 92
+
+/* kernel/exit.c */
+#define __NR_exit 93
+
+#define __NR_exit_group 94
+#define __NR_waitid 95
+
+/* kernel/fork.c */
+#define __NR_set_tid_address 96
+#define __NR_unshare 97
+
+/* kernel/futex.c */
+#define __NR_futex 98
+#define __NR_set_robust_list 99
+#define __NR_get_robust_list 100
+
+/* kernel/hrtimer.c */
+#define __NR_nanosleep 101
+
+/* kernel/itimer.c */
+#define __NR_getitimer 102
+#define __NR_setitimer 103
+
+/* kernel/kexec.c */
+#define __NR_kexec_load 104
+
+/* kernel/module.c */
+#define __NR_init_module 105
+#define __NR_delete_module 106
+
+/* kernel/posix-timers.c */
+#define __NR_timer_create 107
+#define __NR_timer_gettime 108
+#define __NR_timer_getoverrun 109
+#define __NR_timer_settime 110
+#define __NR_timer_delete 111
+#define __NR_clock_settime 112
+#define __NR_clock_gettime 113
+#define __NR_clock_getres 114
+#define __NR_clock_nanosleep 115
+
+/* kernel/printk.c */
+#define __NR_syslog 116
+
+/* kernel/ptrace.c */
+#define __NR_ptrace 117
+
+/* kernel/sched.c */
+#define __NR_sched_setparam 118
+#define __NR_sched_setscheduler 119
+#define __NR_sched_getscheduler 120
+#define __NR_sched_getparam 121
+#define __NR_sched_setaffinity 122
+#define __NR_sched_getaffinity 123
+#define __NR_sched_yield 124
+#define __NR_sched_get_priority_max 125
+#define __NR_sched_get_priority_min 126
+#define __NR_sched_rr_get_interval 127
+
+/* kernel/signal.c */
+#define __NR_restart_syscall 128
+#define __NR_kill 129
+#define __NR_tkill 130
+#define __NR_tgkill 131
+#define __NR_sigaltstack 132
+#define __NR_rt_sigsuspend 133
+#define __NR_rt_sigaction 134
+#define __NR_rt_sigprocmask 135
+#define __NR_rt_sigpending 136
+#define __NR_rt_sigtimedwait 137
+#define __NR_rt_sigqueueinfo 138
+#define __NR_rt_sigreturn 139
+
+/* kernel/sys.c */
+#define __NR_setpriority 140
+#define __NR_getpriority 141
+#define __NR_reboot 142
+#define __NR_setregid 143
+#define __NR_setgid 144
+#define __NR_setreuid 145
+#define __NR_setuid 146
+#define __NR_setresuid 147
+#define __NR_getresuid 148
+#define __NR_setresgid 149
+#define __NR_getresgid 150
+#define __NR_setfsuid 151
+#define __NR_setfsgid 152
+#define __NR_times 153
+#define __NR_setpgid 154
+#define __NR_getpgid 155
+#define __NR_getsid 156
+#define __NR_setsid 157
+#define __NR_getgroups 158
+#define __NR_setgroups 159
+#define __NR_uname 160
+#define __NR_sethostname 161
+#define __NR_setdomainname 162
+#define __NR_getrlimit 163
+#define __NR_setrlimit 164
+#define __NR_getrusage 165
+#define __NR_umask 166
+#define __NR_prctl 167
+#define __NR_getcpu 168
+
+/* kernel/time.c */
+#define __NR_gettimeofday 169
+
+#define __NR_settimeofday 170
+#define __NR_adjtimex 171
+
+/* kernel/timer.c */
+#define __NR_getpid 172
+#define __NR_getppid 173
+#define __NR_getuid 174
+#define __NR_geteuid 175
+#define __NR_getgid 176
+#define __NR_getpgrp __NR_getgid
+#define __NR_getegid 177
+#define __NR_gettid 178
+#define __NR_sysinfo 179
+
+/* ipc/mqueue.c */
+#define __NR_mq_open 180
+#define __NR_mq_unlink 181
+#define __NR_mq_timedsend 182
+#define __NR_mq_timedreceive 183
+#define __NR_mq_notify 184
+#define __NR_mq_getsetattr 185
+
+/* ipc/msg.c */
+#define __NR_msgget 186
+#define __NR_msgctl 187
+#define __NR_msgrcv 188
+#define __NR_msgsnd 189
+
+/* ipc/sem.c */
+#define __NR_semget 190
+#define __NR_semctl 191
+#define __NR_semtimedop 192
+#define __NR_semop 193
+
+/* ipc/shm.c */
+#define __NR_shmget 194
+#define __NR_shmctl 195
+#define __NR_shmat 196
+#define __NR_shmdt 197
+
+/* net/socket.c */
+#define __NR_socket 198
+#define __NR_socketpair 199
+#define __NR_bind 200
+#define __NR_listen 201
+#define __NR_accept 202
+#define __NR_connect 203
+#define __NR_getsockname 204
+#define __NR_getpeername 205
+#define __NR_sendto 206
+#define __NR_recvfrom 207
+#define __NR_setsockopt 208
+#define __NR_getsockopt 209
+#define __NR_shutdown 210
+#define __NR_sendmsg 211
+#define __NR_recvmsg 212
+
+/* mm/filemap.c */
+#define __NR_readahead 213
+
+/* mm/nommu.c, also with MMU */
+#define __NR_brk 214
+#define __NR_munmap 215
+#define __NR_mremap 216
+
+/* security/keys/keyctl.c */
+#define __NR_add_key 217
+#define __NR_request_key 218
+#define __NR_keyctl 219
+
+/* arch/example/kernel/sys_example.c */
+#define __NR_clone 220
+#define __NR_fork  __NR_clone
+#define __NR_execve 221
+#define __NR_mmap  222
+
+/* mm/fadvise.c */
+#define __NR3264_fadvise64 223
+
+/* mm/, CONFIG_MMU only */
+
+#define __NR_swapon 224
+#define __NR_swapoff 225
+#define __NR_mprotect 226
+#define __NR_msync 227
+#define __NR_mlock 228
+#define __NR_munlock 229
+#define __NR_mlockall 230
+#define __NR_munlockall 231
+#define __NR_mincore 232
+#define __NR_madvise 233
+#define __NR_remap_file_pages 234
+#define __NR_mbind 235
+#define __NR_get_mempolicy 236
+#define __NR_set_mempolicy 237
+#define __NR_migrate_pages 238
+#define __NR_move_pages 239
+#define __NR_rt_tgsigqueueinfo 240
+#define __NR_perf_event_open 241
+#define __NR_accept4 242
+#define __NR_recvmmsg 243
+
+/*
+ * Architectures may provide up to 16 syscalls of their own
+ * starting with this value.
+ */
+#define __NR_arch_specific_syscall 244
+#define __NR_set_dataplane 246 
+#define __NR_wait4 260
+#define __NR_prlimit64 261
+#define __NR_fanotify_init 262
+#define __NR_fanotify_mark 263
+#define __NR_syscalls 264
+
+#endif /* __VKI_SCNUMS_TILEGX_LINUX_H */
+
+/*--------------------------------------------------------------------*/
+/*--- end                                                          ---*/
+/*--------------------------------------------------------------------*/
diff --git a/include/vki/vki-tilegx-linux.h b/include/vki/vki-tilegx-linux.h
new file mode 100644
index 0000000..9b0b99b
--- /dev/null
+++ b/include/vki/vki-tilegx-linux.h
@@ -0,0 +1,746 @@
+
+/*--------------------------------------------------------------------*/
+/*--- TILEGX/Linux-specific kernel interface.   vki-tilegx-linux.h ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+  This file is part of Valgrind, a dynamic binary instrumentation
+  framework.
+
+  Copyright (C) 2010-2013 Tilera Corp.
+
+  This program is free software; you can redistribute it and/or
+  modify it under the terms of the GNU General Public License as
+  published by the Free Software Foundation; either version 2 of the
+  License, or (at your option) any later version.
+
+  This program 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
+  General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+  02111-1307, USA.
+
+  The GNU General Public License is contained in the file COPYING.
+*/
+
+/* Contributed by Zhi-Gang Liu <zliu at tilera dot com> */
+
+#ifndef __VKI_TILEGX_LINUX_H
+#define __VKI_TILEGX_LINUX_H
+
+// TILEGX is little-endian.
+#define VKI_LITTLE_ENDIAN  1
+
+//----------------------------------------------------------------------
+// From tilegx linux/include/asm-generic/types.h
+//----------------------------------------------------------------------
+
+typedef unsigned char __vki_u8;
+
+typedef __signed__ short __vki_s16;
+typedef unsigned short __vki_u16;
+
+typedef __signed__ int __vki_s32;
+typedef unsigned int __vki_u32;
+
+typedef __signed__ long long __vki_s64;
+typedef unsigned long long __vki_u64;
+
+typedef unsigned short vki_u16;
+
+typedef unsigned int vki_u32;
+
+//----------------------------------------------------------------------
+// From tilegx linux/include/asm_generic/page.h
+//----------------------------------------------------------------------
+
+#define VKI_PAGE_SHIFT       16
+#define VKI_PAGE_SIZE       (1UL << VKI_PAGE_SHIFT)
+#define VKI_MAX_PAGE_SHIFT       VKI_PAGE_SHIFT
+#define VKI_MAX_PAGE_SIZE       VKI_PAGE_SIZE
+
+//----------------------------------------------------------------------
+// From linux/include/asm/shmparam.h
+//----------------------------------------------------------------------
+
+#define VKI_SHMLBA  VKI_PAGE_SIZE
+
+//----------------------------------------------------------------------
+// From tilegx linux/include/asm_generic/signal.h
+//----------------------------------------------------------------------
+
+#define _VKI_NSIG       64
+#define _VKI_NSIG_BPW       64
+#define _VKI_NSIG_WORDS       (_VKI_NSIG / _VKI_NSIG_BPW)
+
+typedef unsigned long vki_old_sigset_t;
+
+typedef struct {
+  unsigned long sig[_VKI_NSIG_WORDS];
+} vki_sigset_t;
+
+#define VKI_SIGHUP               1
+#define VKI_SIGINT               2
+#define VKI_SIGQUIT              3
+#define VKI_SIGILL               4
+#define VKI_SIGTRAP              5
+#define VKI_SIGABRT              6
+#define VKI_SIGIOT               6
+#define VKI_SIGBUS               7
+#define VKI_SIGFPE               8
+#define VKI_SIGKILL              9
+#define VKI_SIGUSR1              10
+#define VKI_SIGSEGV              11
+#define VKI_SIGUSR2              12
+#define VKI_SIGPIPE              13
+#define VKI_SIGALRM              14
+#define VKI_SIGTERM              15
+#define VKI_SIGSTKFLT            16
+#define VKI_SIGCHLD              17
+#define VKI_SIGCONT              18
+#define VKI_SIGSTOP              19
+#define VKI_SIGTSTP              20
+#define VKI_SIGTTIN              21
+#define VKI_SIGTTOU              22
+#define VKI_SIGURG               23
+#define VKI_SIGXCPU              24
+#define VKI_SIGXFSZ              25
+#define VKI_SIGVTALRM            26
+#define VKI_SIGPROF              27
+#define VKI_SIGWINCH             28
+#define VKI_SIGIO                29
+#define VKI_SIGPOLL              29
+#define VKI_SIGPWR               30
+#define VKI_SIGSYS               31
+#define VKI_SIGUNUSED            31
+
+#define VKI_SIGRTMIN             32
+#define VKI_SIGRTMAX            _VKI_NSIG
+
+#define VKI_SA_NOCLDSTOP        0x00000001
+#define VKI_SA_NOCLDWAIT        0x00000002
+#define VKI_SA_SIGINFO          0x00000004
+#define VKI_SA_ONSTACK          0x08000000
+#define VKI_SA_RESTART          0x10000000
+#define VKI_SA_NODEFER          0x40000000
+#define VKI_SA_RESETHAND        0x80000000
+
+#define VKI_SA_NOMASK           VKI_SA_NODEFER
+#define VKI_SA_ONESHOT          VKI_SA_RESETHAND
+
+#define VKI_SA_RESTORER         0x04000000
+
+#define VKI_SS_ONSTACK          1
+#define VKI_SS_DISABLE          2
+
+#define VKI_MINSIGSTKSZ         2048
+
+#define VKI_SIG_BLOCK           0       /* for blocking signals */
+#define VKI_SIG_UNBLOCK         1       /* for unblocking signals */
+#define VKI_SIG_SETMASK         2       /* for setting the signal mask */
+
+typedef void __vki_signalfn_t(int);
+typedef __vki_signalfn_t __user *__vki_sighandler_t;
+
+typedef void __vki_restorefn_t(void);
+typedef __vki_restorefn_t __user *__vki_sigrestore_t;
+
+#define VKI_SIG_DFL       ((__vki_sighandler_t)0)       /* default signal handling */
+#define VKI_SIG_IGN       ((__vki_sighandler_t)1)       /* ignore signal */
+
+struct vki_sigaction_base {
+  // [[Nb: a 'k' prefix is added to "sa_handler" because
+  // bits/sigaction.h (which gets dragged in somehow via signal.h)
+  // #defines it as something else.  Since that is done for glibc's
+  // purposes, which we don't care about here, we use our own name.]]
+  __vki_sighandler_t ksa_handler;
+  unsigned long sa_flags;
+  __vki_sigrestore_t sa_restorer;
+  vki_sigset_t sa_mask;              /* mask last for extensibility */
+};
+
+/* On Linux we use the same type for passing sigactions to
+   and from the kernel.  Hence: */
+typedef  struct vki_sigaction_base  vki_sigaction_toK_t;
+typedef  struct vki_sigaction_base  vki_sigaction_fromK_t;
+
+
+typedef struct vki_sigaltstack {
+  void __user *ss_sp;
+  int ss_flags;
+  vki_size_t ss_size;
+} vki_stack_t;
+
+//----------------------------------------------------------------------
+// From tilegx linux/include/asm_generic/sigcontext.h
+//----------------------------------------------------------------------
+
+// Tilegx has no FP registers.
+struct _vki_fpstate {
+
+};
+
+struct vki_sigcontext {
+  unsigned long gregs[53];
+  unsigned long tp;
+  unsigned long sp;
+  unsigned long lr;
+  unsigned long pc;
+  unsigned long ics;
+  unsigned long faultnum;
+  unsigned long pad[5];
+};
+
+//----------------------------------------------------------------------
+// From tilegx linux/include/asm_generic/mman.h
+//----------------------------------------------------------------------
+
+#define VKI_PROT_READ       0x1              /* page can be read */
+#define VKI_PROT_WRITE      0x2              /* page can be written */
+#define VKI_PROT_EXEC       0x4              /* page can be executed */
+#define VKI_PROT_NONE       0x0              /* page can not be accessed */
+#define VKI_PROT_GROWSDOWN  0x01000000       /* mprotect flag: extend change to start of growsdown vma */
+#define VKI_PROT_GROWSUP    0x02000000       /* mprotect flag: extend change to end of growsup vma */
+
+#define VKI_MAP_SHARED      0x01              /* Share changes */
+#define VKI_MAP_PRIVATE     0x02              /* Changes are private */
+#define VKI_MAP_FIXED       0x10              /* Interpret addr exactly */
+#define VKI_MAP_ANONYMOUS   0x20              /* don't use a file */
+#define VKI_MAP_HUGETLB     0x4000            /* Use HUGETLB */
+
+//----------------------------------------------------------------------
+// From tilegx linux/include/asm_generic/fcntl.h
+//----------------------------------------------------------------------
+
+#define VKI_O_RDONLY          00
+#define VKI_O_WRONLY          01
+#define VKI_O_RDWR            02
+#define VKI_O_ACCMODE         03
+#define VKI_O_CREAT           0100       /* not fcntl */
+#define VKI_O_EXCL            0200       /* not fcntl */
+#define VKI_O_TRUNC           01000      /* not fcntl */
+#define VKI_O_APPEND          02000
+#define VKI_O_NONBLOCK        04000
+#define VKI_O_LARGEFILE       0100000
+
+#define VKI_AT_FDCWD            -100
+
+#define VKI_F_DUPFD              0       /* dup */
+#define VKI_F_GETFD              1       /* get close_on_exec */
+#define VKI_F_SETFD              2       /* set/clear close_on_exec */
+#define VKI_F_GETFL              3       /* get file->f_flags */
+#define VKI_F_SETFL              4       /* set file->f_flags */
+#define VKI_F_GETLK              5
+#define VKI_F_SETLK              6
+#define VKI_F_SETLKW             7
+
+#define VKI_F_SETOWN             8       /*  for sockets. */
+#define VKI_F_GETOWN             9       /*  for sockets. */
+#define VKI_F_SETSIG             10       /*  for sockets. */
+#define VKI_F_GETSIG             11       /*  for sockets. */
+
+#define VKI_F_SETOWN_EX          15
+#define VKI_F_GETOWN_EX          16
+#define VKI_F_GETLK64            12
+#define VKI_F_SETLK64            13
+#define VKI_F_SETLKW64           14
+
+#define VKI_F_OFD_GETLK          -1
+#define VKI_F_OFD_SETLK          -2
+#define VKI_F_OFD_SETLKW         -3
+
+#define VKI_FD_CLOEXEC      1       /* actually anything with low bit set goes */
+
+#define VKI_F_LINUX_SPECIFIC_BASE       1024
+
+struct vki_f_owner_ex {
+  int type;
+  __vki_kernel_pid_t pid;
+};
+
+//----------------------------------------------------------------------
+// From tilegx linux/include/asm_generic/resource.h
+//----------------------------------------------------------------------
+
+#define VKI_RLIMIT_DATA        2       /* max data size */
+#define VKI_RLIMIT_STACK       3       /* max stack size */
+#define VKI_RLIMIT_CORE        4       /* max core file size */
+#define VKI_RLIMIT_NOFILE      7       /* max number of open files */
+
+//----------------------------------------------------------------------
+// From tilegx linux/include/asm_generic/socket.h
+//----------------------------------------------------------------------
+
+#define VKI_SOL_SOCKET         1
+#define VKI_SO_TYPE            3
+#define VKI_SO_ATTACH_FILTER   26
+
+//----------------------------------------------------------------------
+// From tilegx linux/include/asm_generic/sockios.h
+//----------------------------------------------------------------------
+
+#define VKI_SIOCSPGRP          0x8902
+#define VKI_SIOCGPGRP          0x8904
+#define VKI_SIOCATMARK         0x8905
+#define VKI_SIOCGSTAMP         0x8906              /* Get stamp (timeval) */
+#define VKI_SIOCGSTAMPNS       0x8907              /* Get stamp (timespec) */
+
+//----------------------------------------------------------------------
+// From tilegx linux/include/asm_generic/stat.h
+//----------------------------------------------------------------------
+
+struct vki_stat {
+  unsigned long      st_dev;        /* Device.  */
+  unsigned long      st_ino;        /* File serial number.  */
+  unsigned int       st_mode;       /* File mode.  */
+  unsigned int       st_nlink;      /* Link count.  */
+  unsigned int       st_uid;        /* User ID of the file's owner.  */
+  unsigned int       st_gid;        /* Group ID of the file's group. */
+  unsigned long      st_rdev;       /* Device number, if device.  */
+  unsigned long      __pad1;
+  long               st_size;       /* Size of file, in bytes.  */
+  int                st_blksize;    /* Optimal block size for I/O.  */
+  int                __pad2;
+  long               st_blocks;     /* Number 512-byte blocks allocated. */
+  long               st_atime;      /* Time of last access.  */
+  unsigned long      st_atime_nsec;
+  long               st_mtime;      /* Time of last modification.  */
+  unsigned long      st_mtime_nsec;
+  long               st_ctime;      /* Time of last status change.  */
+  unsigned long      st_ctime_nsec;
+  unsigned int       __unused4;
+  unsigned int       __unused5;
+};
+
+struct vki_stat64 {
+  unsigned long      st_dev;        /* Device.  */
+  unsigned long      st_ino;        /* File serial number.  */
+  unsigned int       st_mode;       /* File mode.  */
+  unsigned int       st_nlink;      /* Link count.  */
+  unsigned int       st_uid;        /* User ID of the file's owner.  */
+  unsigned int       st_gid;        /* Group ID of the file's group. */
+  unsigned long      st_rdev;       /* Device number, if device.  */
+  unsigned long      __pad1;
+  long               st_size;       /* Size of file, in bytes.  */
+  int                st_blksize;    /* Optimal block size for I/O.  */
+  int                __pad2;
+  long               st_blocks;     /* Number 512-byte blocks allocated. */
+  long               st_atime;      /* Time of last access.  */
+  unsigned long      st_atime_nsec;
+  long               st_mtime;      /* Time of last modification.  */
+  unsigned long      st_mtime_nsec;
+  long               st_ctime;      /* Time of last status change.  */
+  unsigned long      st_ctime_nsec;
+  unsigned int       __unused4;
+  unsigned int       __unused5;
+};
+
+//----------------------------------------------------------------------
+// From tilegx linux/include/asm_generic/statfs.h
+//----------------------------------------------------------------------
+
+struct vki_statfs {
+  long f_type;
+  long f_bsize;
+  long f_blocks;
+  long f_bfree;
+  long f_bavail;
+  long f_files;
+  long f_ffree;
+  __vki_kernel_fsid_t f_fsid;
+  long f_namelen;
+  long f_frsize;
+  long f_flags;
+  long f_spare[4];
+};
+
+//----------------------------------------------------------------------
+// From tilegx linux/include/asm_generic/termios.h
+//----------------------------------------------------------------------
+
+struct vki_winsize {
+  unsigned short ws_row;
+  unsigned short ws_col;
+  unsigned short ws_xpixel;
+  unsigned short ws_ypixel;
+};
+
+#define VKI_NCC 8
+struct vki_termio {
+  unsigned short c_iflag;            /* input mode flags */
+  unsigned short c_oflag;            /* output mode flags */
+  unsigned short c_cflag;            /* control mode flags */
+  unsigned short c_lflag;            /* local mode flags */
+  unsigned char c_line;              /* line discipline */
+  unsigned char c_cc[VKI_NCC];       /* control characters */
+};
+
+//----------------------------------------------------------------------
+// From tilegx linux/include/asm_generic/termbits.h
+//----------------------------------------------------------------------
+
+typedef unsigned char       vki_cc_t;
+typedef unsigned int        vki_tcflag_t;
+
+#define VKI_NCCS 19
+struct vki_termios {
+  vki_tcflag_t c_iflag;              /* input mode flags */
+  vki_tcflag_t c_oflag;              /* output mode flags */
+  vki_tcflag_t c_cflag;              /* control mode flags */
+  vki_tcflag_t c_lflag;              /* local mode flags */
+  vki_cc_t c_line;                   /* line discipline */
+  vki_cc_t c_cc[VKI_NCCS];           /* control characters */
+};
+
+
+//----------------------------------------------------------------------
+// From tilegx linux/include/asm_generic/ioctl.h
+//----------------------------------------------------------------------
+
+#define _VKI_IOC_NRBITS              8
+#define _VKI_IOC_TYPEBITS            8
+#define _VKI_IOC_SIZEBITS           14
+#define _VKI_IOC_DIRBITS             2
+
+#define _VKI_IOC_SIZEMASK      ((1 << _VKI_IOC_SIZEBITS)-1)
+#define _VKI_IOC_DIRMASK       ((1 << _VKI_IOC_DIRBITS)-1)
+
+#define _VKI_IOC_NRSHIFT         0
+#define _VKI_IOC_TYPESHIFT       (_VKI_IOC_NRSHIFT+_VKI_IOC_NRBITS)
+#define _VKI_IOC_SIZESHIFT       (_VKI_IOC_TYPESHIFT+_VKI_IOC_TYPEBITS)
+#define _VKI_IOC_DIRSHIFT        (_VKI_IOC_SIZESHIFT+_VKI_IOC_SIZEBITS)
+
+#define _VKI_IOC_NONE            0U
+#define _VKI_IOC_WRITE           1U
+#define _VKI_IOC_READ            2U
+
+#define _VKI_IOC(dir,type,nr,size)              \
+  (((dir)  << _VKI_IOC_DIRSHIFT) |              \
+   ((type) << _VKI_IOC_TYPESHIFT) |             \
+   ((nr)   << _VKI_IOC_NRSHIFT) |               \
+   ((size) << _VKI_IOC_SIZESHIFT))
+
+#define _VKI_IO(type,nr)        _VKI_IOC(_VKI_IOC_NONE,(type),(nr),0)
+#define _VKI_IOR(type,nr,size)  _VKI_IOC(_VKI_IOC_READ,(type),(nr),sizeof(size))
+#define _VKI_IOW(type,nr,size)  _VKI_IOC(_VKI_IOC_WRITE,(type),(nr),sizeof(size))
+#define _VKI_IOWR(type,nr,size) _VKI_IOC(_VKI_IOC_READ|_VKI_IOC_WRITE,(type),(nr),sizeof(size))
+
+#define _VKI_IOC_DIR(nr)     (((nr) >> _VKI_IOC_DIRSHIFT) & _VKI_IOC_DIRMASK)
+#define _VKI_IOC_SIZE(nr)    (((nr) >> _VKI_IOC_SIZESHIFT) & _VKI_IOC_SIZEMASK)
+
+//----------------------------------------------------------------------
+// From tilegx linux/include/asm_generic/ioctls.h
+//----------------------------------------------------------------------
+
+#define VKI_TCGETS         0x5401
+#define VKI_TCSETS         0x5402
+#define VKI_TCSETSW        0x5403
+#define VKI_TCSETSF        0x5404
+#define VKI_TCGETA         0x5405
+#define VKI_TCSETA         0x5406
+#define VKI_TCSETAW        0x5407
+#define VKI_TCSETAF        0x5408
+#define VKI_TCSBRK         0x5409
+#define VKI_TCXONC         0x540A
+#define VKI_TCFLSH         0x540B
+#define VKI_TIOCEXCL       0x540C
+#define VKI_TIOCNXCL       0x540D
+#define VKI_TIOCSCTTY      0x540E
+#define VKI_TIOCGPGRP      0x540F
+#define VKI_TIOCSPGRP      0x5410
+#define VKI_TIOCOUTQ       0x5411
+#define VKI_TIOCSTI        0x5412
+#define VKI_TIOCGWINSZ     0x5413
+#define VKI_TIOCSWINSZ     0x5414
+#define VKI_TIOCMGET       0x5415
+#define VKI_TIOCMBIS       0x5416
+#define VKI_TIOCMBIC       0x5417
+#define VKI_TIOCMSET       0x5418
+#define VKI_TIOCGSOFTCAR   0x5419
+#define VKI_TIOCSSOFTCAR   0x541A
+#define VKI_FIONREAD       0x541B
+#define VKI_TIOCINQ        VKI_FIONREAD
+#define VKI_TIOCLINUX      0x541C
+#define VKI_TIOCCONS       0x541D
+#define VKI_TIOCGSERIAL    0x541E
+#define VKI_TIOCSSERIAL    0x541F
+#define VKI_TIOCPKT        0x5420
+#define VKI_FIONBIO        0x5421
+#define VKI_TIOCNOTTY      0x5422
+#define VKI_TIOCSETD       0x5423
+#define VKI_TIOCGETD       0x5424
+#define VKI_TCSBRKP        0x5425
+#define VKI_TIOCGPTN       _VKI_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
+#define VKI_TIOCSPTLCK     _VKI_IOW('T',0x31, int)  /* Lock/unlock Pty */
+
+#define VKI_FIONCLEX       0x5450
+#define VKI_FIOCLEX        0x5451
+#define VKI_FIOASYNC       0x5452
+#define VKI_TIOCSERGETLSR  0x5459 /* Get line status register */
+#define VKI_TIOCGICOUNT    0x545D /* read serial port inline interrupt counts */
+
+// X86_64 define above, assume tilegx need no more than that. --FIXME
+
+#define VKI_TIOCGPTN       _VKI_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
+#define VKI_TIOCSPTLCK     _VKI_IOW('T',0x31, int)  /* Lock/unlock Pty */
+
+#define VKI_FIOASYNC       0x5452
+#define VKI_TIOCSERGETLSR  0x5459 /* Get line status register */
+#define VKI_TIOCGICOUNT    0x545D       /* read serial port inline interrupt counts */
+
+//----------------------------------------------------------------------
+// From tilegx linux/include/asm_generic/poll.h
+//----------------------------------------------------------------------
+
+#define VKI_POLLIN              0x0001
+
+struct vki_pollfd {
+  int fd;
+  short events;
+  short revents;
+};
+
+//----------------------------------------------------------------------
+// From tilegx linux/include/asm_generic/user.h
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+// From tilegx linux/include/asm_generic/ucontext.h
+//----------------------------------------------------------------------
+
+struct vki_ucontext {
+  unsigned long            uc_flags;
+  struct vki_ucontext      *uc_link;
+  vki_stack_t              uc_stack;
+  struct vki_sigcontext    uc_mcontext;
+  vki_sigset_t             uc_sigmask;       /* mask last for extensibility */
+};
+
+//----------------------------------------------------------------------
+// From tilegx linux/include/asm_generic/segment.h
+//----------------------------------------------------------------------
+// NA
+//----------------------------------------------------------------------
+// From tilegx linux/include/asm-generic/prctl.h
+//----------------------------------------------------------------------
+// NA
+//----------------------------------------------------------------------
+// From tilegx linux/include/asm_generic/ldt.h
+//----------------------------------------------------------------------
+
+// NA
+
+//----------------------------------------------------------------------
+// From linux-2.6.11.2/include/asm-x86_64/ipcbuf.h
+//----------------------------------------------------------------------
+
+struct vki_ipc64_perm
+{
+  __vki_kernel_key_t         key;
+  __vki_kernel_uid32_t       uid;
+  __vki_kernel_gid32_t       gid;
+  __vki_kernel_uid32_t       cuid;
+  __vki_kernel_gid32_t       cgid;
+  __vki_kernel_mode_t        mode;
+  unsigned char              __pad1[4 - sizeof(__vki_kernel_mode_t)];
+  unsigned short             seq;
+  unsigned short             __pad2;
+  unsigned long              __unused1;
+  unsigned long              __unused2;
+};
+
+//----------------------------------------------------------------------
+// From linux-2.6.11.2/include/asm-x86_64/sembuf.h
+//----------------------------------------------------------------------
+
+struct vki_semid64_ds {
+  struct vki_ipc64_perm    sem_perm;              /* permissions .. see ipc.h */
+  __vki_kernel_time_t      sem_otime;              /* last semop time */
+  __vki_kernel_time_t      sem_ctime;              /* last change time */
+  unsigned long            sem_nsems;              /* no. of semaphores in array */
+  unsigned long            __unused3;
+  unsigned long            __unused4;
+};
+
+//----------------------------------------------------------------------
+// From linux-2.6.11.2/include/asm-x86_64/msgbuf.h
+//----------------------------------------------------------------------
+
+struct vki_msqid64_ds {
+  struct vki_ipc64_perm msg_perm;
+  __vki_kernel_time_t   msg_stime;       /* last msgsnd time */
+  __vki_kernel_time_t   msg_rtime;       /* last msgrcv time */
+  __vki_kernel_time_t   msg_ctime;       /* last change time */
+  unsigned long         msg_cbytes;      /* current number of bytes on queue */
+  unsigned long         msg_qnum;        /* number of messages in queue */
+  unsigned long         msg_qbytes;      /* max number of bytes on queue */
+  __vki_kernel_pid_t    msg_lspid;       /* pid of last msgsnd */
+  __vki_kernel_pid_t    msg_lrpid;       /* last receive pid */
+  unsigned long         __unused4;
+  unsigned long         __unused5;
+};
+
+//----------------------------------------------------------------------
+// From linux-2.6.11.2/include/asm-x86_64/shmbuf.h
+//----------------------------------------------------------------------
+
+struct vki_shmid64_ds {
+  struct vki_ipc64_perm   shm_perm;        /* operation perms */
+  vki_size_t              shm_segsz;       /* size of segment (bytes) */
+  __vki_kernel_time_t     shm_atime;       /* last attach time */
+  __vki_kernel_time_t     shm_dtime;       /* last detach time */
+  __vki_kernel_time_t     shm_ctime;       /* last change time */
+  __vki_kernel_pid_t      shm_cpid;        /* pid of creator */
+  __vki_kernel_pid_t      shm_lpid;        /* pid of last operator */
+  unsigned long           shm_nattch;      /* no. of current attaches */
+  unsigned long           __unused4;
+  unsigned long           __unused5;
+};
+
+struct vki_shminfo64 {
+  unsigned long       shmmax;
+  unsigned long       shmmin;
+  unsigned long       shmmni;
+  unsigned long       shmseg;
+  unsigned long       shmall;
+  unsigned long       __unused1;
+  unsigned long       __unused2;
+  unsigned long       __unused3;
+  unsigned long       __unused4;
+};
+
+//----------------------------------------------------------------------
+// From tilegx linux/include/asm-tile/ptrace.h
+//----------------------------------------------------------------------
+
+struct vki_pt_regs {
+
+  unsigned long regs[53];
+  unsigned long tp;
+  unsigned long sp;
+  unsigned long lr;
+  unsigned long pc;
+  unsigned long ex1;
+  unsigned long faultnum;
+  unsigned long orig_r0;
+  unsigned long flags;
+  unsigned long pad[3];
+};
+
+#ifndef user_pt_regs
+#define user_pt_regs  vki_pt_regs
+#endif
+
+// Tile has no fp registers. Just make gcc happy.
+struct  tilegx_elf_fpregset {};
+typedef struct tilegx_elf_fpregset vki_elf_fpregset_t;
+
+#define vki_user_regs_struct vki_pt_regs
+
+#define TILEGX_r56       regs[56]
+#define TILEGX_r55       regs[55]
+#define TILEGX_r54       regs[54]
+#define TILEGX_r53       regs[53]
+#define TILEGX_r52       regs[52]
+#define TILEGX_r51       regs[51]
+#define TILEGX_r50       regs[50]
+#define TILEGX_r49       regs[49]
+#define TILEGX_r48       regs[48]
+#define TILEGX_r47       regs[47]
+#define TILEGX_r46       regs[46]
+#define TILEGX_r45       regs[45]
+#define TILEGX_r44       regs[44]
+#define TILEGX_r43       regs[43]
+#define TILEGX_r42       regs[42]
+#define TILEGX_r41       regs[41]
+#define TILEGX_r40       regs[40]
+#define TILEGX_r39       regs[39]
+#define TILEGX_r38       regs[38]
+#define TILEGX_r37       regs[37]
+#define TILEGX_r36       regs[36]
+#define TILEGX_r35       regs[35]
+#define TILEGX_r34       regs[34]
+#define TILEGX_r33       regs[33]
+#define TILEGX_r32       regs[32]
+#define TILEGX_r31       regs[31]
+#define TILEGX_r30       regs[30]
+#define TILEGX_r29       regs[29]
+#define TILEGX_r28       regs[28]
+#define TILEGX_r27       regs[27]
+#define TILEGX_r26       regs[26]
+#define TILEGX_r25       regs[25]
+#define TILEGX_r24       regs[24]
+#define TILEGX_r23       regs[23]
+#define TILEGX_r22       regs[22]
+#define TILEGX_r21       regs[21]
+#define TILEGX_r20       regs[20]
+#define TILEGX_r19       regs[19]
+#define TILEGX_r18       regs[18]
+#define TILEGX_r17       regs[17]
+#define TILEGX_r16       regs[16]
+#define TILEGX_r15       regs[15]
+#define TILEGX_r14       regs[14]
+#define TILEGX_r13       regs[13]
+#define TILEGX_r12       regs[12]
+#define TILEGX_r11       regs[11]
+#define TILEGX_r10       regs[10]
+#define TILEGX_r9        regs[9]
+#define TILEGX_r8        regs[8]
+#define TILEGX_r7        regs[7]
+#define TILEGX_r6        regs[6]
+#define TILEGX_r5        regs[5]
+#define TILEGX_r4        regs[4]
+#define TILEGX_r3        regs[3]
+#define TILEGX_r2        regs[2]
+#define TILEGX_r1        regs[1]
+#define TILEGX_r0        regs[0]
+
+#define TILEGX_lr        TILEGX_r55
+#define TILEGX_sp        TILEGX_r54
+#define TILEGX_tp        TILEGX_r53
+#define TILEGX_pc        TILEGX_r56
+
+#define VKI_PTRACE_GETREGS            12
+#define VKI_PTRACE_SETREGS            13
+#define VKI_PTRACE_GETFPREGS          14
+#define VKI_PTRACE_SETFPREGS          15
+
+
+//----------------------------------------------------------------------
+// From tilegx linux/include/asm_generic/elf.h
+//----------------------------------------------------------------------
+
+typedef unsigned long vki_elf_greg_t;
+
+#define VKI_ELF_NGREG (sizeof (struct vki_user_regs_struct) / sizeof(vki_elf_greg_t))
+typedef vki_elf_greg_t vki_elf_gregset_t[VKI_ELF_NGREG];
+
+
+struct tilegx_dirent64 {
+  long              d_ino;
+  long              d_off;
+  unsigned short    d_reclen;
+  unsigned char     d_type;
+  char              d_name[256];
+};
+
+//----------------------------------------------------------------------
+// From tilegx linux/include/asm-generic/errno.h
+//----------------------------------------------------------------------
+
+#define       VKI_ENOSYS       38  /* Function not implemented */
+#define       VKI_EOVERFLOW    75  /* Value too large for defined data type */
+
+//----------------------------------------------------------------------
+// And that's it!
+//----------------------------------------------------------------------
+
+#endif // __VKI_TILEGX_LINUX_H
+
+/*--------------------------------------------------------------------*/
+/*--- end                                                          ---*/
+/*--------------------------------------------------------------------*/
diff --git a/massif/tests/Makefile.am b/massif/tests/Makefile.am
index 04f06af..5017543 100644
--- a/massif/tests/Makefile.am
+++ b/massif/tests/Makefile.am
@@ -33,12 +33,18 @@
 	peak.post.exp peak.stderr.exp peak.vgtest \
 	peak2.post.exp peak2.stderr.exp peak2.vgtest \
 	realloc.post.exp realloc.stderr.exp realloc.vgtest \
-	thresholds_0_0.post.exp   thresholds_0_0.stderr.exp   thresholds_0_0.vgtest \
-	thresholds_0_10.post.exp  thresholds_0_10.stderr.exp  thresholds_0_10.vgtest \
-	thresholds_10_0.post.exp  thresholds_10_0.stderr.exp  thresholds_10_0.vgtest \
-	thresholds_5_0.post.exp   thresholds_5_0.stderr.exp   thresholds_5_0.vgtest \
-	thresholds_5_10.post.exp  thresholds_5_10.stderr.exp  thresholds_5_10.vgtest \
-	thresholds_10_10.post.exp thresholds_10_10.stderr.exp thresholds_10_10.vgtest \
+	thresholds_0_0.post.exp \
+	thresholds_0_0.stderr.exp   thresholds_0_0.vgtest \
+	thresholds_0_10.post.exp    thresholds_0_10.stderr.exp \
+	thresholds_0_10.vgtest \
+	thresholds_10_0.post.exp \
+	thresholds_10_0.stderr.exp  thresholds_10_0.vgtest \
+	thresholds_5_0.post.exp  \
+	thresholds_5_0.stderr.exp   thresholds_5_0.vgtest \
+	thresholds_5_10.post.exp \
+	thresholds_5_10.stderr.exp  thresholds_5_10.vgtest \
+	thresholds_10_10.post.exp \
+	thresholds_10_10.stderr.exp thresholds_10_10.vgtest \
 	zero1.post.exp zero1.stderr.exp zero1.vgtest \
 	zero2.post.exp zero2.stderr.exp zero2.vgtest
 
diff --git a/memcheck/mc_machine.c b/memcheck/mc_machine.c
index e4ad60c..60d5079 100644
--- a/memcheck/mc_machine.c
+++ b/memcheck/mc_machine.c
@@ -48,6 +48,11 @@
 #define MC_SIZEOF_GUEST_STATE  sizeof(VexGuestArchState)
 
 __attribute__((unused))
+#if defined(VGA_tilegx)
+# include "libvex_guest_tilegx.h"
+# define MC_SIZEOF_GUEST_STATE sizeof(VexGuestTILEGXState)
+#endif
+
 static inline Bool host_is_big_endian ( void ) {
    UInt x = 0x11223344;
    return 0x1122 == *(UShort*)(&x);
@@ -1229,6 +1234,38 @@
 #  undef GOF
 #  undef SZB
 
+   /* --------------------- tilegx --------------------- */
+#  elif defined(VGA_tilegx)
+
+#  define GOF(_fieldname) \
+      (offsetof(VexGuestTILEGXState,guest_##_fieldname))
+#  define SZB(_fieldname) \
+      (sizeof(((VexGuestTILEGXState*)0)->guest_##_fieldname))
+
+   Int  o     = offset;
+   Int  sz    = szB;
+   Bool is1248 = sz == 8 || sz == 4 || sz == 2 || sz == 1;
+
+   tl_assert(sz > 0);
+   tl_assert(host_is_little_endian());
+
+   if (o >= GOF(r0) && is1248 && o <= (GOF(r63) + 8 - sz))
+      return GOF(r0) + ((o-GOF(r0)) & -8) ;
+
+   if (o == GOF(pc)  && sz == 8) return o;
+   if (o == GOF(EMNOTE)  && sz == 8) return o;
+   if (o == GOF(CMSTART)  && sz == 8) return o;
+   if (o == GOF(CMLEN)  && sz == 8) return o;
+   if (o == GOF(NRADDR)  && sz == 8) return o;
+   if (o == GOF(cmpexch) && sz == 8) return o;
+   if (o == GOF(zero)  && sz == 8) return o;
+
+   VG_(printf)("MC_(get_otrack_shadow_offset)(tilegx)(off=%d,sz=%d)\n",
+               offset,szB);
+   tl_assert(0);
+#  undef GOF
+#  undef SZB
+
 #  else
 #    error "FIXME: not implemented for this architecture"
 #  endif
@@ -1343,6 +1380,14 @@
    ppIRRegArray(arr);
    VG_(printf)("\n");
    tl_assert(0);
+
+   /* --------------------- tilegx --------------------- */
+#  elif defined(VGA_tilegx)
+   VG_(printf)("get_reg_array_equiv_int_type(tilegx): unhandled: ");
+   ppIRRegArray(arr);
+   VG_(printf)("\n");
+   tl_assert(0);
+
 #  else
 #    error "FIXME: not implemented for this architecture"
 #  endif
diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am
index 6d6b3eb..f177167 100644
--- a/memcheck/tests/Makefile.am
+++ b/memcheck/tests/Makefile.am
@@ -187,9 +187,11 @@
 	origin5-bz2.stderr.exp-glibc212-s390x \
 	origin5-bz2.stderr.exp-glibc234-s390x \
 	origin5-bz2.stderr.exp-glibc218-mips32 \
+	origin5-bz2.stderr.exp-glibc212-tilegx \
 	origin6-fp.vgtest origin6-fp.stdout.exp \
 	origin6-fp.stderr.exp-glibc25-amd64 \
 	origin6-fp.stderr.exp-glibc27-ppc64 \
+	origin6-fp.stderr.exp-glibc212-tilegx \
 	overlap.stderr.exp overlap.stdout.exp overlap.vgtest \
 	partiallydefinedeq.vgtest partiallydefinedeq.stderr.exp \
 	partiallydefinedeq.stderr.exp4 \
diff --git a/memcheck/tests/atomic_incs.c b/memcheck/tests/atomic_incs.c
index 1fede8c..8f2c464 100644
--- a/memcheck/tests/atomic_incs.c
+++ b/memcheck/tests/atomic_incs.c
@@ -233,6 +233,20 @@
       );
    } while (block[2] != 1);
 #endif
+#elif defined(VGA_tilegx)
+   int i;
+   unsigned int *p4 = (unsigned int *)(((unsigned long long)p + 3) & (~3ULL));
+   unsigned int  mask = (0xff) << ((int)p & 3);
+   unsigned int  add = (n & 0xff) << ((int)p & 3);
+   unsigned int x, new;
+
+   while(1) {
+      x = *p4;
+      new = (x & (~mask)) | ((x + add) & mask);
+      __insn_mtspr(0x2780, x);
+      if ( __insn_cmpexch4(p4, new) == x)
+         break;
+   }
 #else
 # error "Unsupported arch"
 #endif
@@ -449,6 +463,20 @@
       );
    } while (block[2] != 1);
 #endif
+#elif defined(VGA_tilegx)
+   int i;
+   unsigned int *p4 = (unsigned int *)(((unsigned long long)p + 3) & (~3ULL));
+   unsigned int  mask = (0xffff) << ((int)p & 3);
+   unsigned int  add = (n & 0xffff) << ((int)p & 3);
+   unsigned int x, new;
+
+   while(1) {
+      x = *p4;
+      new = (x & (~mask)) | ((x + add) & mask);
+      __insn_mtspr(0x2780, x);
+      if ( __insn_cmpexch4(p4, new) == x)
+         break;
+   }
 #else
 # error "Unsupported arch"
 #endif
@@ -604,6 +632,8 @@
          : /*trash*/ "memory", "t0", "t1", "t2", "t3"
       );
    } while (block[2] != 1);
+#elif defined(VGA_tilegx)
+    __insn_fetchadd4(p, n);
 #else
 # error "Unsupported arch"
 #endif
@@ -705,6 +735,8 @@
          : /*trash*/ "memory", "t0", "t1", "t2", "t3"
       );
    } while (block[2] != 1);
+#elif defined(VGA_tilegx)
+    __insn_fetchadd(p, n);
 #else
 # error "Unsupported arch"
 #endif
diff --git a/memcheck/tests/leak-segv-jmp.c b/memcheck/tests/leak-segv-jmp.c
index 3937e3e..428ea05 100644
--- a/memcheck/tests/leak-segv-jmp.c
+++ b/memcheck/tests/leak-segv-jmp.c
@@ -159,6 +159,30 @@
                  : "v0", "v1", "a0", "a1", "a2", "a3", "$8", "$9");
    return out;
 }
+#elif defined(VGP_tilegx_linux)
+extern UWord do_syscall_WRK (
+          UWord syscall_no,
+          UWord a1, UWord a2, UWord a3,
+          UWord a4, UWord a5, UWord a6
+       )
+{
+   UWord out;
+   __asm__ __volatile__ (
+                 "move r10, r0\n\t"
+                 "move r0,  r1\n\t"
+                 "move r1,  r2\n\t"
+                 "move r2,  r3\n\t"
+                 "move r3,  r4\n\t"
+                 "move r4,  r5\n\t"
+                 "move r5,  r6\n\t"
+                 "swint1      \n\t"
+                 "move %0,  r0\n\t"
+                 : /*out*/ "=r" (out)
+                 : "r"(syscall_no), "r"(a1), "r"(a2), "r"(a3),
+                   "r"(a4), "r"(a5), "r"(a6)
+                 : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r10");
+   return out;
+}
 
 #else
 // Ensure the file compiles even if the syscall nr is not defined.
diff --git a/memcheck/tests/origin5-bz2.stderr.exp-glibc212-tilegx b/memcheck/tests/origin5-bz2.stderr.exp-glibc212-tilegx
new file mode 100644
index 0000000..cca6411
--- /dev/null
+++ b/memcheck/tests/origin5-bz2.stderr.exp-glibc212-tilegx
@@ -0,0 +1,28 @@
+Conditional jump or move depends on uninitialised value(s)
+   at 0x........: main (origin5-bz2.c:6481)
+ Uninitialised value was created by a client request
+   at 0x........: main (origin5-bz2.c:6479)
+
+Conditional jump or move depends on uninitialised value(s)
+   at 0x........: copy_input_until_stop (origin5-bz2.c:4686)
+   by 0x........: handle_compress (origin5-bz2.c:4750)
+   by 0x........: BZ2_bzCompress (origin5-bz2.c:4822)
+   by 0x........: BZ2_bzBuffToBuffCompress (origin5-bz2.c:5630)
+   by 0x........: main (origin5-bz2.c:6484)
+ Uninitialised value was created by a client request
+   at 0x........: main (origin5-bz2.c:6479)
+
+Use of uninitialised value of size 8
+   at 0x........: copy_input_until_stop (origin5-bz2.c:4686)
+   by 0x........: handle_compress (origin5-bz2.c:4750)
+   by 0x........: BZ2_bzCompress (origin5-bz2.c:4822)
+   by 0x........: BZ2_bzBuffToBuffCompress (origin5-bz2.c:5630)
+   by 0x........: main (origin5-bz2.c:6484)
+ Uninitialised value was created by a client request
+   at 0x........: main (origin5-bz2.c:6479)
+
+Conditional jump or move depends on uninitialised value(s)
+   at 0x........: main (origin5-bz2.c:6512)
+ Uninitialised value was created by a client request
+   at 0x........: main (origin5-bz2.c:6479)
+
diff --git a/memcheck/tests/origin6-fp.stderr.exp-glibc212-tilegx b/memcheck/tests/origin6-fp.stderr.exp-glibc212-tilegx
new file mode 100644
index 0000000..fa55d0e
--- /dev/null
+++ b/memcheck/tests/origin6-fp.stderr.exp-glibc212-tilegx
@@ -0,0 +1,76 @@
+Conditional jump or move depends on uninitialised value(s)
+   at 0x........: __divdf3 (in /u/zliu/WS1/valgrind/valgrind-latest/memcheck/tests/origin6-fp)
+   by 0x........: do3x3smooth (origin6-fp.c:47)
+   by 0x........: main (origin6-fp.c:89)
+ Uninitialised value was created by a client request
+   at 0x........: setup_arr (origin6-fp.c:75)
+   by 0x........: main (origin6-fp.c:87)
+
+Conditional jump or move depends on uninitialised value(s)
+   at 0x........: __divdf3 (in /u/zliu/WS1/valgrind/valgrind-latest/memcheck/tests/origin6-fp)
+   by 0x........: do3x3smooth (origin6-fp.c:47)
+   by 0x........: main (origin6-fp.c:89)
+ Uninitialised value was created by a client request
+   at 0x........: setup_arr (origin6-fp.c:75)
+   by 0x........: main (origin6-fp.c:87)
+
+Conditional jump or move depends on uninitialised value(s)
+   at 0x........: __divdf3 (in /u/zliu/WS1/valgrind/valgrind-latest/memcheck/tests/origin6-fp)
+   by 0x........: do3x3smooth (origin6-fp.c:47)
+   by 0x........: main (origin6-fp.c:89)
+ Uninitialised value was created by a client request
+   at 0x........: setup_arr (origin6-fp.c:75)
+   by 0x........: main (origin6-fp.c:87)
+
+Conditional jump or move depends on uninitialised value(s)
+   at 0x........: __float_estimateDiv128To64 (in /u/zliu/WS1/valgrind/valgrind-latest/memcheck/tests/origin6-fp)
+   by 0x........: __divdf3 (in /u/zliu/WS1/valgrind/valgrind-latest/memcheck/tests/origin6-fp)
+   by 0x........: do3x3smooth (origin6-fp.c:47)
+   by 0x........: main (origin6-fp.c:89)
+ Uninitialised value was created by a client request
+   at 0x........: setup_arr (origin6-fp.c:75)
+   by 0x........: main (origin6-fp.c:87)
+
+Conditional jump or move depends on uninitialised value(s)
+   at 0x........: __float_estimateDiv128To64 (in /u/zliu/WS1/valgrind/valgrind-latest/memcheck/tests/origin6-fp)
+   by 0x........: __divdf3 (in /u/zliu/WS1/valgrind/valgrind-latest/memcheck/tests/origin6-fp)
+   by 0x........: do3x3smooth (origin6-fp.c:47)
+   by 0x........: main (origin6-fp.c:89)
+ Uninitialised value was created by a client request
+   at 0x........: setup_arr (origin6-fp.c:75)
+   by 0x........: main (origin6-fp.c:87)
+
+Conditional jump or move depends on uninitialised value(s)
+   at 0x........: __float_estimateDiv128To64 (in /u/zliu/WS1/valgrind/valgrind-latest/memcheck/tests/origin6-fp)
+   by 0x........: __divdf3 (in /u/zliu/WS1/valgrind/valgrind-latest/memcheck/tests/origin6-fp)
+   by 0x........: do3x3smooth (origin6-fp.c:47)
+   by 0x........: main (origin6-fp.c:89)
+ Uninitialised value was created by a client request
+   at 0x........: setup_arr (origin6-fp.c:75)
+   by 0x........: main (origin6-fp.c:87)
+
+Conditional jump or move depends on uninitialised value(s)
+   at 0x........: __float_estimateDiv128To64 (in /u/zliu/WS1/valgrind/valgrind-latest/memcheck/tests/origin6-fp)
+   by 0x........: __divdf3 (in /u/zliu/WS1/valgrind/valgrind-latest/memcheck/tests/origin6-fp)
+   by 0x........: do3x3smooth (origin6-fp.c:47)
+   by 0x........: main (origin6-fp.c:89)
+ Uninitialised value was created by a client request
+   at 0x........: setup_arr (origin6-fp.c:75)
+   by 0x........: main (origin6-fp.c:87)
+
+Conditional jump or move depends on uninitialised value(s)
+   at 0x........: __divdf3 (in /u/zliu/WS1/valgrind/valgrind-latest/memcheck/tests/origin6-fp)
+   by 0x........: do3x3smooth (origin6-fp.c:47)
+   by 0x........: main (origin6-fp.c:89)
+ Uninitialised value was created by a client request
+   at 0x........: setup_arr (origin6-fp.c:75)
+   by 0x........: main (origin6-fp.c:87)
+
+Conditional jump or move depends on uninitialised value(s)
+   at 0x........: __float_roundAndPackFloat64 (in /u/zliu/WS1/valgrind/valgrind-latest/memcheck/tests/origin6-fp)
+   by 0x........: main (origin6-fp.c:89)
+ Uninitialised value was created by a client request
+   at 0x........: setup_arr (origin6-fp.c:75)
+   by 0x........: main (origin6-fp.c:87)
+
+Test succeeded.
diff --git a/memcheck/tests/vbit-test/irops.c b/memcheck/tests/vbit-test/irops.c
index 4204899..e35b3bf 100644
--- a/memcheck/tests/vbit-test/irops.c
+++ b/memcheck/tests/vbit-test/irops.c
@@ -11,251 +11,251 @@
    That is not necessary but helpful when supporting a new architecture.
 */
 static irop_t irops[] = {
-  { DEFOP(Iop_Add8,    UNDEF_LEFT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_Add16,   UNDEF_LEFT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_Add32,   UNDEF_LEFT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_Add64,   UNDEF_LEFT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1 }, // mips asserts
-  { DEFOP(Iop_Sub8,    UNDEF_LEFT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_Sub16,   UNDEF_LEFT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_Sub32,   UNDEF_LEFT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_Sub64,   UNDEF_LEFT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 1 }, // ppc32, mips assert
-  { DEFOP(Iop_Mul8,    UNDEF_LEFT), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_Mul16,   UNDEF_LEFT), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_Mul32,   UNDEF_LEFT), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_Mul64,   UNDEF_LEFT), .s390x = 0, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 1 }, // ppc32, mips assert
-  { DEFOP(Iop_Or8,     UNDEF_OR),   .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_Or16,    UNDEF_OR),   .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_Or32,    UNDEF_OR),   .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_Or64,    UNDEF_OR),   .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1 }, // mips asserts
-  { DEFOP(Iop_And8,    UNDEF_AND),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_And16,   UNDEF_AND),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_And32,   UNDEF_AND),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_And64,   UNDEF_AND),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_Xor8,    UNDEF_SAME), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_Xor16,   UNDEF_SAME), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_Xor32,   UNDEF_SAME), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_Xor64,   UNDEF_SAME), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_Shl8,    UNDEF_SHL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_Shl16,   UNDEF_SHL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_Shl32,   UNDEF_SHL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_Shl64,   UNDEF_SHL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 1 }, // ppc32 asserts
-  { DEFOP(Iop_Shr8,    UNDEF_SHR),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 }, // ppc32/64 assert
-  { DEFOP(Iop_Shr16,   UNDEF_SHR),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 }, // ppc32/64 assert
-  { DEFOP(Iop_Shr32,   UNDEF_SHR),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_Shr64,   UNDEF_SHR),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 1 }, // ppc32 asserts
-  { DEFOP(Iop_Sar8,    UNDEF_SAR),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 }, // ppc32/64 assert
-  { DEFOP(Iop_Sar16,   UNDEF_SAR),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 }, // ppc32/64 assert
-  { DEFOP(Iop_Sar32,   UNDEF_SAR),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_Sar64,   UNDEF_SAR),  .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 1, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 1 }, // ppc32 asserts
-  { DEFOP(Iop_CmpEQ8,  UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_CmpEQ16, UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_CmpEQ32, UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_CmpEQ64, UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 1 }, // ppc32, mips assert
-  { DEFOP(Iop_CmpNE8,  UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_CmpNE16, UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_CmpNE32, UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_CmpNE64, UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 1 }, // ppc32, mips assert
-  { DEFOP(Iop_Not8,       UNDEF_SAME), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_Not16,      UNDEF_SAME), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_Not32,      UNDEF_SAME), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_Not64,      UNDEF_SAME), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_CasCmpEQ8,  UNDEF_NONE), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_CasCmpEQ16, UNDEF_NONE), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_CasCmpEQ32, UNDEF_NONE), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_CasCmpEQ64, UNDEF_NONE), .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
+  { DEFOP(Iop_Add8,    UNDEF_LEFT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_Add16,   UNDEF_LEFT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_Add32,   UNDEF_LEFT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_Add64,   UNDEF_LEFT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1, .tilegx = 1 }, // mips asserts
+  { DEFOP(Iop_Sub8,    UNDEF_LEFT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_Sub16,   UNDEF_LEFT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_Sub32,   UNDEF_LEFT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_Sub64,   UNDEF_LEFT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 1, .tilegx = 1 }, // ppc32, mips assert
+  { DEFOP(Iop_Mul8,    UNDEF_LEFT), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_Mul16,   UNDEF_LEFT), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_Mul32,   UNDEF_LEFT), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_Mul64,   UNDEF_LEFT), .s390x = 0, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 1, .tilegx = 0 }, // ppc32, mips assert
+  { DEFOP(Iop_Or8,     UNDEF_OR),   .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_Or16,    UNDEF_OR),   .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_Or32,    UNDEF_OR),   .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_Or64,    UNDEF_OR),   .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1, .tilegx = 1 }, // mips asserts
+  { DEFOP(Iop_And8,    UNDEF_AND),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_And16,   UNDEF_AND),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_And32,   UNDEF_AND),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_And64,   UNDEF_AND),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_Xor8,    UNDEF_SAME), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_Xor16,   UNDEF_SAME), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_Xor32,   UNDEF_SAME), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_Xor64,   UNDEF_SAME), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_Shl8,    UNDEF_SHL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_Shl16,   UNDEF_SHL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_Shl32,   UNDEF_SHL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_Shl64,   UNDEF_SHL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 1, .tilegx = 1 }, // ppc32 asserts
+  { DEFOP(Iop_Shr8,    UNDEF_SHR),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 }, // ppc32/64 assert
+  { DEFOP(Iop_Shr16,   UNDEF_SHR),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 }, // ppc32/64 assert
+  { DEFOP(Iop_Shr32,   UNDEF_SHR),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_Shr64,   UNDEF_SHR),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 1, .tilegx = 1 }, // ppc32 asserts
+  { DEFOP(Iop_Sar8,    UNDEF_SAR),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 }, // ppc32/64 assert
+  { DEFOP(Iop_Sar16,   UNDEF_SAR),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 }, // ppc32/64 assert
+  { DEFOP(Iop_Sar32,   UNDEF_SAR),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_Sar64,   UNDEF_SAR),  .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 1, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 1, .tilegx = 1 }, // ppc32 asserts
+  { DEFOP(Iop_CmpEQ8,  UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_CmpEQ16, UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_CmpEQ32, UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_CmpEQ64, UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 1, .tilegx = 1 }, // ppc32, mips assert
+  { DEFOP(Iop_CmpNE8,  UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_CmpNE16, UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_CmpNE32, UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_CmpNE64, UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 1, .tilegx = 1 }, // ppc32, mips assert
+  { DEFOP(Iop_Not8,       UNDEF_SAME), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_Not16,      UNDEF_SAME), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_Not32,      UNDEF_SAME), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_Not64,      UNDEF_SAME), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0, .tilegx = 1 },
+  { DEFOP(Iop_CasCmpEQ8,  UNDEF_NONE), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_CasCmpEQ16, UNDEF_NONE), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_CasCmpEQ32, UNDEF_NONE), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_CasCmpEQ64, UNDEF_NONE), .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
 
-  { DEFOP(Iop_CasCmpNE8,  UNDEF_NONE), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_CasCmpNE16, UNDEF_NONE), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_CasCmpNE32, UNDEF_NONE), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_CasCmpNE64, UNDEF_NONE), .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
+  { DEFOP(Iop_CasCmpNE8,  UNDEF_NONE), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_CasCmpNE16, UNDEF_NONE), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_CasCmpNE32, UNDEF_NONE), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_CasCmpNE64, UNDEF_NONE), .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
   { DEFOP(Iop_ExpCmpNE8,  UNDEF_UNKNOWN), }, // exact (expensive) equality
   { DEFOP(Iop_ExpCmpNE16, UNDEF_UNKNOWN), }, // exact (expensive) equality
   { DEFOP(Iop_ExpCmpNE32, UNDEF_UNKNOWN), }, // exact (expensive) equality
   { DEFOP(Iop_ExpCmpNE64, UNDEF_UNKNOWN), }, // exact (expensive) equality
-  { DEFOP(Iop_MullS8,     UNDEF_LEFT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_MullS16,    UNDEF_LEFT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_MullS32,    UNDEF_LEFT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1 }, // mips asserts
+  { DEFOP(Iop_MullS8,     UNDEF_LEFT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_MullS16,    UNDEF_LEFT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_MullS32,    UNDEF_LEFT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1, .tilegx = 1 }, // mips asserts
   // s390 has signed multiplication of 64-bit values but the result
   // is 64-bit (not 128-bit). So we cannot test this op standalone.
-  { DEFOP(Iop_MullS64,    UNDEF_LEFT), .s390x = 0, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 =0, .mips64 = 1 }, // ppc32, mips assert
-  { DEFOP(Iop_MullU8,     UNDEF_LEFT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 =0, .mips64 = 0 },
-  { DEFOP(Iop_MullU16,    UNDEF_LEFT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 =0, .mips64 = 0 },
-  { DEFOP(Iop_MullU32,    UNDEF_LEFT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 =0, .mips64 = 1 }, // mips asserts
-  { DEFOP(Iop_MullU64,    UNDEF_LEFT), .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 =0, .mips64 = 1 }, // ppc32, mips assert
-  { DEFOP(Iop_Clz64,      UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 =0, .mips64 = 1 }, // ppc32 asserts
-  { DEFOP(Iop_Clz32,      UNDEF_ALL),  .s390x = 0, .amd64 = 0, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 =1, .mips64 = 1 },
-  { DEFOP(Iop_Ctz64,      UNDEF_ALL),  .s390x = 0, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 =0, .mips64 = 0 },
-  { DEFOP(Iop_Ctz32,      UNDEF_ALL),  .s390x = 0, .amd64 = 0, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 =0, .mips64 = 0 },
-  { DEFOP(Iop_CmpLT32S,   UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 =1, .mips64 = 1 },
-  { DEFOP(Iop_CmpLT64S,   UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 =0, .mips64 = 1 }, // ppc, mips assert
-  { DEFOP(Iop_CmpLE32S,   UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 =1, .mips64 = 1 },
-  { DEFOP(Iop_CmpLE64S,   UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 =0, .mips64 = 1 }, // ppc, mips assert
-  { DEFOP(Iop_CmpLT32U,   UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 =1, .mips64 = 1 },
-  { DEFOP(Iop_CmpLT64U,   UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 =0, .mips64 = 1 }, // ppc32, mips assert
-  { DEFOP(Iop_CmpLE32U,   UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 =1, .mips64 = 1 },
-  { DEFOP(Iop_CmpLE64U,   UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 =0, .mips64 = 0 }, // ppc32 asserts
+  { DEFOP(Iop_MullS64,    UNDEF_LEFT), .s390x = 0, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 =0, .mips64 = 1, .tilegx = 0 }, // ppc32, mips assert
+  { DEFOP(Iop_MullU8,     UNDEF_LEFT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 =0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_MullU16,    UNDEF_LEFT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 =0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_MullU32,    UNDEF_LEFT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 =0, .mips64 = 1, .tilegx = 1 }, // mips asserts
+  { DEFOP(Iop_MullU64,    UNDEF_LEFT), .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 =0, .mips64 = 1, .tilegx = 0 }, // ppc32, mips assert
+  { DEFOP(Iop_Clz64,      UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 =0, .mips64 = 1, .tilegx = 1 }, // ppc32 asserts
+  { DEFOP(Iop_Clz32,      UNDEF_ALL),  .s390x = 0, .amd64 = 0, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 =1, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_Ctz64,      UNDEF_ALL),  .s390x = 0, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 =0, .mips64 = 0, .tilegx = 1 },
+  { DEFOP(Iop_Ctz32,      UNDEF_ALL),  .s390x = 0, .amd64 = 0, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 =0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_CmpLT32S,   UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 =1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_CmpLT64S,   UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 =0, .mips64 = 1, .tilegx = 1 }, // ppc, mips assert
+  { DEFOP(Iop_CmpLE32S,   UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 =1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_CmpLE64S,   UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 =0, .mips64 = 1, .tilegx = 1 }, // ppc, mips assert
+  { DEFOP(Iop_CmpLT32U,   UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 =1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_CmpLT64U,   UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 =0, .mips64 = 1, .tilegx = 1}, // ppc32, mips assert
+  { DEFOP(Iop_CmpLE32U,   UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 =1, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_CmpLE64U,   UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 =0, .mips64 = 0, .tilegx = 0 }, // ppc32 asserts
   { DEFOP(Iop_CmpNEZ8,    UNDEF_ALL), },   // not supported by mc_translate
   { DEFOP(Iop_CmpNEZ16,   UNDEF_ALL), },   // not supported by mc_translate
   { DEFOP(Iop_CmpNEZ32,   UNDEF_ALL), },   // not supported by mc_translate
   { DEFOP(Iop_CmpNEZ64,   UNDEF_ALL), },   // not supported by mc_translate
-  { DEFOP(Iop_CmpwNEZ32,  UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_CmpwNEZ64,  UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1 }, // mips asserts
+  { DEFOP(Iop_CmpwNEZ32,  UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_CmpwNEZ64,  UNDEF_ALL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1, .tilegx = 1 }, // mips asserts
   { DEFOP(Iop_Left8,      UNDEF_UNKNOWN), },  // not supported by mc_translate
   { DEFOP(Iop_Left16,     UNDEF_UNKNOWN), },  // not supported by mc_translate
   { DEFOP(Iop_Left32,     UNDEF_UNKNOWN), },  // not supported by mc_translate
   { DEFOP(Iop_Left64,     UNDEF_UNKNOWN), },  // not supported by mc_translate
   { DEFOP(Iop_Max32U,     UNDEF_UNKNOWN), },  // not supported by mc_translate
-  { DEFOP(Iop_CmpORD32U,  UNDEF_ORD), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0 }, // support added in vbit-test
-  { DEFOP(Iop_CmpORD64U,  UNDEF_ORD), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 0 }, // support added in vbit-test
-  { DEFOP(Iop_CmpORD32S,  UNDEF_ORD), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0 }, // support added in vbit-test
-  { DEFOP(Iop_CmpORD64S,  UNDEF_ORD), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 0 }, // support added in vbit-test
-  { DEFOP(Iop_DivU32,     UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_DivS32,     UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_DivU64,     UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 0 }, // ppc32 asserts
-  { DEFOP(Iop_DivS64,     UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 0 }, // ppc32 asserts
-  { DEFOP(Iop_DivU64E,    UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 0 }, // ppc32 asserts
-  { DEFOP(Iop_DivS64E,    UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 0 }, // ppc32 asserts
-  { DEFOP(Iop_DivU32E,    UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_DivS32E,    UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0 },
+  { DEFOP(Iop_CmpORD32U,  UNDEF_ORD), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0, .tilegx = 0 }, // support added in vbit-test
+  { DEFOP(Iop_CmpORD64U,  UNDEF_ORD), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 }, // support added in vbit-test
+  { DEFOP(Iop_CmpORD32S,  UNDEF_ORD), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0, .tilegx = 0 }, // support added in vbit-test
+  { DEFOP(Iop_CmpORD64S,  UNDEF_ORD), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 }, // support added in vbit-test
+  { DEFOP(Iop_DivU32,     UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_DivS32,     UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_DivU64,     UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 }, // ppc32 asserts
+  { DEFOP(Iop_DivS64,     UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 }, // ppc32 asserts
+  { DEFOP(Iop_DivU64E,    UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 }, // ppc32 asserts
+  { DEFOP(Iop_DivS64E,    UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 }, // ppc32 asserts
+  { DEFOP(Iop_DivU32E,    UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_DivS32E,    UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
   // On s390 the DivMod operations always appear in a certain context
   // So they cannot be tested in isolation on that platform.
-  { DEFOP(Iop_DivModU64to32,  UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_DivModS64to32,  UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_DivModU128to64, UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 1 }, // mips asserts
-  { DEFOP(Iop_DivModS128to64, UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 1 }, // mips asserts
-  { DEFOP(Iop_DivModS64to64,  UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 }, // mips asserts
-  { DEFOP(Iop_8Uto16,    UNDEF_ZEXT),   .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_8Uto32,    UNDEF_ZEXT),   .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_8Uto64,    UNDEF_ZEXT),   .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 1 }, // ppc32 assert
-  { DEFOP(Iop_16Uto32,   UNDEF_ZEXT),   .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_16Uto64,   UNDEF_ZEXT),   .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 1 }, // ppc32 assert
-  { DEFOP(Iop_32Uto64,   UNDEF_ZEXT),   .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1 }, // mips asserts
-  { DEFOP(Iop_8Sto16,    UNDEF_SEXT),   .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_8Sto32,    UNDEF_SEXT),   .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_8Sto64,    UNDEF_SEXT),   .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 1 }, // ppc32, mips assert
-  { DEFOP(Iop_16Sto32,   UNDEF_SEXT),   .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_16Sto64,   UNDEF_SEXT),   .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 1 }, // ppc32, mips assert
-  { DEFOP(Iop_32Sto64,   UNDEF_SEXT),   .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1 }, // mips asserts
-  { DEFOP(Iop_64to8,     UNDEF_TRUNC),  .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 1, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 1 }, // ppc32, mips assert
-  { DEFOP(Iop_32to8,     UNDEF_TRUNC),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_64to16,    UNDEF_TRUNC),  .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 1 }, // ppc32, mips assert
-  { DEFOP(Iop_16to8,     UNDEF_TRUNC),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_16HIto8,   UNDEF_UPPER),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_8HLto16,   UNDEF_CONCAT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1 },  // ppc isel
-  { DEFOP(Iop_32to16,    UNDEF_TRUNC),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_32HIto16,  UNDEF_UPPER),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_16HLto32,  UNDEF_CONCAT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1 },  // ppc isel
-  { DEFOP(Iop_64to32,    UNDEF_TRUNC),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1 }, // mips asserts
-  { DEFOP(Iop_64HIto32,  UNDEF_UPPER),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1 },
-  { DEFOP(Iop_32HLto64,  UNDEF_CONCAT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1 }, // mips asserts
-  { DEFOP(Iop_128to64,   UNDEF_TRUNC),  .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1 }, // mips asserts
-  { DEFOP(Iop_128HIto64, UNDEF_UPPER),  .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1 }, // mips asserts
-  { DEFOP(Iop_64HLto128, UNDEF_CONCAT), .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1 }, // mips asserts
-  { DEFOP(Iop_Not1,      UNDEF_ALL),    .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_32to1,     UNDEF_TRUNC),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_64to1,     UNDEF_TRUNC),  .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 1 }, // ppc32, mips assert
-  { DEFOP(Iop_1Uto8,     UNDEF_ZEXT),   .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_1Uto32,    UNDEF_ZEXT),   .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_1Uto64,    UNDEF_ZEXT),   .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 1 }, // ppc32 assert
-  { DEFOP(Iop_1Sto8,     UNDEF_ALL),    .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
+  { DEFOP(Iop_DivModU64to32,  UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_DivModS64to32,  UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_DivModU128to64, UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 1, .tilegx = 0 }, // mips asserts
+  { DEFOP(Iop_DivModS128to64, UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 1, .tilegx = 0 }, // mips asserts
+  { DEFOP(Iop_DivModS64to64,  UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 }, // mips asserts
+  { DEFOP(Iop_8Uto16,    UNDEF_ZEXT),   .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_8Uto32,    UNDEF_ZEXT),   .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_8Uto64,    UNDEF_ZEXT),   .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 1, .tilegx = 1 }, // ppc32 assert
+  { DEFOP(Iop_16Uto32,   UNDEF_ZEXT),   .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_16Uto64,   UNDEF_ZEXT),   .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 1, .tilegx = 1 }, // ppc32 assert
+  { DEFOP(Iop_32Uto64,   UNDEF_ZEXT),   .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1, .tilegx = 1 }, // mips asserts
+  { DEFOP(Iop_8Sto16,    UNDEF_SEXT),   .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_8Sto32,    UNDEF_SEXT),   .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_8Sto64,    UNDEF_SEXT),   .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 1, .tilegx = 1 }, // ppc32, mips assert
+  { DEFOP(Iop_16Sto32,   UNDEF_SEXT),   .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_16Sto64,   UNDEF_SEXT),   .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 1, .tilegx = 1 }, // ppc32, mips assert
+  { DEFOP(Iop_32Sto64,   UNDEF_SEXT),   .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1, .tilegx = 1 }, // mips asserts
+  { DEFOP(Iop_64to8,     UNDEF_TRUNC),  .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 1, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 1, .tilegx = 1 }, // ppc32, mips assert
+  { DEFOP(Iop_32to8,     UNDEF_TRUNC),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_64to16,    UNDEF_TRUNC),  .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 1, .tilegx = 1 }, // ppc32, mips assert
+  { DEFOP(Iop_16to8,     UNDEF_TRUNC),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_16HIto8,   UNDEF_UPPER),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_8HLto16,   UNDEF_CONCAT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1, .tilegx = 0 },  // ppc isel
+  { DEFOP(Iop_32to16,    UNDEF_TRUNC),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_32HIto16,  UNDEF_UPPER),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_16HLto32,  UNDEF_CONCAT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1, .tilegx = 0 },  // ppc isel
+  { DEFOP(Iop_64to32,    UNDEF_TRUNC),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1, .tilegx = 0 }, // mips asserts
+  { DEFOP(Iop_64HIto32,  UNDEF_UPPER),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_32HLto64,  UNDEF_CONCAT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1, .tilegx = 1 }, // mips asserts
+  { DEFOP(Iop_128to64,   UNDEF_TRUNC),  .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1, .tilegx = 0 }, // mips asserts
+  { DEFOP(Iop_128HIto64, UNDEF_UPPER),  .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1, .tilegx = 0 }, // mips asserts
+  { DEFOP(Iop_64HLto128, UNDEF_CONCAT), .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1, .tilegx = 0 }, // mips asserts
+  { DEFOP(Iop_Not1,      UNDEF_ALL),    .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_32to1,     UNDEF_TRUNC),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_64to1,     UNDEF_TRUNC),  .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 1, .tilegx = 1 }, // ppc32, mips assert
+  { DEFOP(Iop_1Uto8,     UNDEF_ZEXT),   .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_1Uto32,    UNDEF_ZEXT),   .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_1Uto64,    UNDEF_ZEXT),   .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 1, .tilegx = 1 }, // ppc32 assert
+  { DEFOP(Iop_1Sto8,     UNDEF_ALL),    .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 0 },
   { DEFOP(Iop_1Sto16,    UNDEF_ALL), }, // not handled by mc_translate
-  { DEFOP(Iop_1Sto32,    UNDEF_ALL), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_1Sto64,    UNDEF_ALL), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_AddF64,    UNDEF_ALL), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1 }, // mips asserts
-  { DEFOP(Iop_SubF64,    UNDEF_ALL), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1 }, // mips asserts
-  { DEFOP(Iop_MulF64,    UNDEF_ALL), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1 }, // mips asserts
-  { DEFOP(Iop_DivF64,    UNDEF_ALL), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1 }, // mips asserts
-  { DEFOP(Iop_AddF32,    UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 1, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_SubF32,    UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 1, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_MulF32,    UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 1, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_DivF32,    UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 1, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_AddF64r32, UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_SubF64r32, UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_MulF64r32, UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_DivF64r32, UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_NegF64,    UNDEF_ALL), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_AbsF64,    UNDEF_ALL), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_NegF32,    UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 1, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_AbsF32,    UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 1, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_SqrtF64,   UNDEF_ALL), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1 }, // mips asserts
-  { DEFOP(Iop_SqrtF32,   UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 1, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_CmpF64,    UNDEF_ALL), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_CmpF32,    UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 }, // mips asserts
-  { DEFOP(Iop_CmpF128,   UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_F64toI16S, UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_F64toI32S, UNDEF_ALL), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_F64toI64S, UNDEF_ALL), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_F64toI64U, UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_F64toI32U, UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_I32StoF64, UNDEF_ALL), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_I64StoF64, UNDEF_ALL), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1 },
-  { DEFOP(Iop_I64UtoF64, UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0 }, // mips asserts
-  { DEFOP(Iop_I64UtoF32, UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_I32UtoF32, UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_I32UtoF64, UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 1, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_F32toI32S, UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_F32toI64S, UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 1 },
-  { DEFOP(Iop_F32toI32U, UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_F32toI64U, UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_I32StoF32, UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_I64StoF32, UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 1 },
-  { DEFOP(Iop_F32toF64,  UNDEF_ALL), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_F64toF32,  UNDEF_ALL), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 1 }, // mips asserts
-  { DEFOP(Iop_ReinterpF64asI64, UNDEF_SAME), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1 }, // mips asserts
-  { DEFOP(Iop_ReinterpI64asF64, UNDEF_SAME), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1 }, // mips asserts
-  { DEFOP(Iop_ReinterpF32asI32, UNDEF_SAME), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
+  { DEFOP(Iop_1Sto32,    UNDEF_ALL), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_1Sto64,    UNDEF_ALL), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 1 },
+  { DEFOP(Iop_AddF64,    UNDEF_ALL), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1, .tilegx = 0 }, // mips asserts
+  { DEFOP(Iop_SubF64,    UNDEF_ALL), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1, .tilegx = 0 }, // mips asserts
+  { DEFOP(Iop_MulF64,    UNDEF_ALL), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1, .tilegx = 0 }, // mips asserts
+  { DEFOP(Iop_DivF64,    UNDEF_ALL), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1, .tilegx = 0 }, // mips asserts
+  { DEFOP(Iop_AddF32,    UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 1, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_SubF32,    UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 1, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_MulF32,    UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 1, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_DivF32,    UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 1, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_AddF64r32, UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_SubF64r32, UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_MulF64r32, UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_DivF64r32, UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_NegF64,    UNDEF_ALL), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_AbsF64,    UNDEF_ALL), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_NegF32,    UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 1, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_AbsF32,    UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 1, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_SqrtF64,   UNDEF_ALL), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1, .tilegx = 0 }, // mips asserts
+  { DEFOP(Iop_SqrtF32,   UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 1, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_CmpF64,    UNDEF_ALL), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_CmpF32,    UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 }, // mips asserts
+  { DEFOP(Iop_CmpF128,   UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_F64toI16S, UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_F64toI32S, UNDEF_ALL), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_F64toI64S, UNDEF_ALL), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_F64toI64U, UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_F64toI32U, UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_I32StoF64, UNDEF_ALL), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_I64StoF64, UNDEF_ALL), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_I64UtoF64, UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0, .tilegx = 0 }, // mips asserts
+  { DEFOP(Iop_I64UtoF32, UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_I32UtoF32, UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_I32UtoF64, UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 1, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_F32toI32S, UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_F32toI64S, UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_F32toI32U, UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_F32toI64U, UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_I32StoF32, UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_I64StoF32, UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_F32toF64,  UNDEF_ALL), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_F64toF32,  UNDEF_ALL), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 1, .tilegx = 0 }, // mips asserts
+  { DEFOP(Iop_ReinterpF64asI64, UNDEF_SAME), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1, .tilegx = 0 }, // mips asserts
+  { DEFOP(Iop_ReinterpI64asF64, UNDEF_SAME), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1, .tilegx = 0 }, // mips asserts
+  { DEFOP(Iop_ReinterpF32asI32, UNDEF_SAME), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1, .tilegx = 0 },
   // ppc requires this op to show up in a specific context. So it cannot be
   // tested standalone on that platform.
-  { DEFOP(Iop_ReinterpI32asF32, UNDEF_SAME), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_F64HLtoF128, UNDEF_CONCAT),    .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_F128HItoF64, UNDEF_UPPER),     .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_F128LOtoF64, UNDEF_TRUNC), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_AddF128,       UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_SubF128,       UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_MulF128,       UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_DivF128,       UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_NegF128,       UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_AbsF128,       UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_SqrtF128,      UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_I32StoF128,    UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_I64StoF128,    UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_I32UtoF128,    UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_I64UtoF128,    UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_F32toF128,     UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_F64toF128,     UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_F128toI32S,    UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_F128toI64S,    UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_F128toI32U,    UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_F128toI64U,    UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_F128toF64,     UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_F128toF32,     UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_AtanF64,       UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_Yl2xF64,       UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_Yl2xp1F64,     UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_PRemF64,       UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_PRemC3210F64,  UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_PRem1F64,      UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_PRem1C3210F64, UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_ScaleF64,      UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_SinF64,        UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_CosF64,        UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_TanF64,        UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_2xm1F64,       UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_RoundF64toInt, UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 1 },
-  { DEFOP(Iop_RoundF32toInt, UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1 },
-  { DEFOP(Iop_MAddF32,       UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 1 },
-  { DEFOP(Iop_MSubF32,       UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 1 },
-  { DEFOP(Iop_MAddF64,       UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1 },
-  { DEFOP(Iop_MSubF64,       UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1 },
-  { DEFOP(Iop_MAddF64r32,    UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_MSubF64r32,    UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_RSqrtEst5GoodF64,      UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0 },
-  { DEFOP(Iop_RoundF64toF64_NEAREST, UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1 },
-  { DEFOP(Iop_RoundF64toF64_NegINF,  UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1 },
-  { DEFOP(Iop_RoundF64toF64_PosINF,  UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1 },
-  { DEFOP(Iop_RoundF64toF64_ZERO,    UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1 },
-  { DEFOP(Iop_TruncF64asF32, UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1 }, // mips asserts
-  { DEFOP(Iop_RoundF64toF32, UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0 },
+  { DEFOP(Iop_ReinterpI32asF32, UNDEF_SAME), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_F64HLtoF128, UNDEF_CONCAT),    .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_F128HItoF64, UNDEF_UPPER),     .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_F128LOtoF64, UNDEF_TRUNC), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_AddF128,       UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_SubF128,       UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_MulF128,       UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_DivF128,       UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_NegF128,       UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_AbsF128,       UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_SqrtF128,      UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_I32StoF128,    UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_I64StoF128,    UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_I32UtoF128,    UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_I64UtoF128,    UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_F32toF128,     UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_F64toF128,     UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_F128toI32S,    UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_F128toI64S,    UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_F128toI32U,    UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_F128toI64U,    UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_F128toF64,     UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_F128toF32,     UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_AtanF64,       UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_Yl2xF64,       UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_Yl2xp1F64,     UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_PRemF64,       UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_PRemC3210F64,  UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_PRem1F64,      UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_PRem1C3210F64, UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_ScaleF64,      UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_SinF64,        UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_CosF64,        UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_TanF64,        UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_2xm1F64,       UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_RoundF64toInt, UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_RoundF32toInt, UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_MAddF32,       UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_MSubF32,       UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_MAddF64,       UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_MSubF64,       UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_MAddF64r32,    UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_MSubF64r32,    UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_RSqrtEst5GoodF64,      UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
+  { DEFOP(Iop_RoundF64toF64_NEAREST, UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_RoundF64toF64_NegINF,  UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_RoundF64toF64_PosINF,  UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_RoundF64toF64_ZERO,    UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1, .tilegx = 0 },
+  { DEFOP(Iop_TruncF64asF32, UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1, .tilegx = 0 }, // mips asserts
+  { DEFOP(Iop_RoundF64toF32, UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 0, .tilegx = 0 },
   { DEFOP(Iop_RecpExpF64, UNDEF_UNKNOWN), },
   { DEFOP(Iop_RecpExpF32, UNDEF_UNKNOWN), },
 
@@ -1161,6 +1161,9 @@
 #ifdef __i386__
          return p->x86 ? p : NULL;
 #endif
+#ifdef __tilegx__
+         return p->tilegx ? p : NULL;
+#endif
          return NULL;
       }
    }
diff --git a/memcheck/tests/vbit-test/vtest.h b/memcheck/tests/vbit-test/vtest.h
index 34dfb89..e73cee0 100644
--- a/memcheck/tests/vbit-test/vtest.h
+++ b/memcheck/tests/vbit-test/vtest.h
@@ -76,6 +76,7 @@
    unsigned    x86    : 1;
    unsigned    mips32 : 1;
    unsigned    mips64 : 1;
+   unsigned    tilegx : 1;
 } irop_t;
 
 
diff --git a/none/tests/Makefile.am b/none/tests/Makefile.am
index c56137e..fb1db5d 100644
--- a/none/tests/Makefile.am
+++ b/none/tests/Makefile.am
@@ -32,6 +32,9 @@
 if VGCONF_ARCHS_INCLUDE_MIPS64
 SUBDIRS += mips64
 endif
+if VGCONF_ARCHS_INCLUDE_TILEGX
+SUBDIRS += tilegx
+endif
 
 # OS-specific tests
 if VGCONF_OS_IS_LINUX
@@ -46,7 +49,7 @@
 SUBDIRS += x86-linux
 endif
 
-DIST_SUBDIRS = x86 amd64 ppc32 ppc64 arm arm64 s390x mips32 mips64 \
+DIST_SUBDIRS = x86 amd64 ppc32 ppc64 arm arm64 s390x mips32 mips64 tilegx \
                linux darwin x86-linux scripts .
 
 dist_noinst_SCRIPTS = \
@@ -66,7 +69,8 @@
 	allexec64.stdout.exp allexec64.stderr.exp allexec64.vgtest\
 	ansi.stderr.exp ansi.vgtest \
 	args.stderr.exp args.stdout.exp args.vgtest \
-	async-sigs.stderr.exp async-sigs.stderr.exp-mips32 async-sigs.vgtest \
+	async-sigs.stderr.exp async-sigs.stderr.exp-mips32 \
+	async-sigs.vgtest \
 	bigcode.vgtest bigcode.stderr.exp bigcode.stdout.exp \
 	bitfield1.stderr.exp bitfield1.vgtest \
 	bug129866.vgtest bug129866.stderr.exp bug129866.stdout.exp \
diff --git a/none/tests/allexec_prepare_prereq b/none/tests/allexec_prepare_prereq
index 09958b5..2c70a08 100755
--- a/none/tests/allexec_prepare_prereq
+++ b/none/tests/allexec_prepare_prereq
@@ -33,5 +33,6 @@
 pair s390x_unexisting_in_32bits s390x
 pair arm                        arm64
 pair mips32                     mips64
+pair tilegx_unexisting_32bits   tilegx
 
 exit 0
diff --git a/none/tests/tilegx/Makefile.am b/none/tests/tilegx/Makefile.am
new file mode 100644
index 0000000..086ff43
--- /dev/null
+++ b/none/tests/tilegx/Makefile.am
@@ -0,0 +1,13 @@
+
+include $(top_srcdir)/Makefile.tool-tests.am
+
+EXTRA_DIST =
+
+check_PROGRAMS = \
+	allexec
+
+AM_CFLAGS    += @FLAG_M64@
+AM_CXXFLAGS  += @FLAG_M64@
+AM_CCASFLAGS += @FLAG_M64@
+
+allexec_CFLAGS          = $(AM_CFLAGS) @FLAG_W_NO_NONNULL@
diff --git a/none/tests/tilegx/allexec.c b/none/tests/tilegx/allexec.c
new file mode 100644
index 0000000..130d0b0
--- /dev/null
+++ b/none/tests/tilegx/allexec.c
@@ -0,0 +1 @@
+link ../allexec.c
\ No newline at end of file
diff --git a/tests/arch_test.c b/tests/arch_test.c
index a39da6a..81a12ec 100644
--- a/tests/arch_test.c
+++ b/tests/arch_test.c
@@ -33,6 +33,7 @@
    "s390x",
    "mips32",
    "mips64",
+   "tilegx",
    NULL
 };
 
@@ -74,6 +75,9 @@
 #elif defined(VGP_mips64_linux)
    if ( 0 == strcmp( arch, "mips64" ) ) return True;
 
+#elif defined(VGP_tilegx_linux)
+   if ( 0 == strcmp( arch, "tilegx" ) ) return True;
+
 #else
 #  error Unknown platform
 #endif   // VGP_*