diff options
author | sewardj <sewardj@a5019735-40e9-0310-863c-91ae7b9d1cf9> | 2015-04-10 12:30:09 +0000 |
---|---|---|
committer | sewardj <sewardj@a5019735-40e9-0310-863c-91ae7b9d1cf9> | 2015-04-10 12:30:09 +0000 |
commit | 112711afefcfcd43680c7c4aa8d38ef180e8811e (patch) | |
tree | b773b426fcd6bdc36ef7f545ae338ec9be24dcb2 | |
parent | 5370de0069f9f5f21bf3cebb9b27dfacd86f5c89 (diff) | |
download | valgrind-112711afefcfcd43680c7c4aa8d38ef180e8811e.tar.gz |
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
87 files changed, 5924 insertions, 298 deletions
diff --git a/Makefile.all.am b/Makefile.all.am index 860ef90e5..282c791c2 100644 --- a/Makefile.all.am +++ b/Makefile.all.am @@ -234,6 +234,9 @@ AM_CFLAGS_PSO_MIPS64_LINUX = @FLAG_M64@ $(AM_CFLAGS_BASE) @FLAG_MIPS64@ \ $(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_AMD64_DARWIN = $(PRELOAD_LDFLAGS_COMMON_DARWIN) -arch x86_64 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 458d5ee98..41f5c9722 100644 --- a/Makefile.tool.am +++ b/Makefile.tool.am @@ -76,6 +76,9 @@ TOOL_LDFLAGS_MIPS64_LINUX = \ -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_MIPS32_LINUX = \ 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_LDFLAGS_MIPS64_LINUX = \ $(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 9b9b9b53e..09a8db6f1 100644 --- a/Makefile.vex.am +++ b/Makefile.vex.am @@ -26,6 +26,7 @@ pkginclude_HEADERS = \ 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 @@ noinst_HEADERS = \ 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 @@ noinst_HEADERS = \ 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_offsets.h: auxprogs/genoffsets.c \ 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 @@ LIBVEX_SOURCES_COMMON = \ 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 @@ LIBVEX_SOURCES_COMMON = \ 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 265044e23..376d79e33 100644 --- a/cachegrind/cg_arch.c +++ b/cachegrind/cg_arch.c @@ -477,6 +477,13 @@ configure_caches(cache_t *I1c, cache_t *D1c, cache_t *LLc, *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 9ee5c62d0..396bde167 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 a9d23108a..9de921755 100644 --- a/configure.ac +++ b/configure.ac @@ -268,6 +268,12 @@ case "${host_cpu}" in 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 @@ case "$ARCH_MAX-$VGCONF_OS" in 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 @@ AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_MIPS32, 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 @@ AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_MIPS32_LINUX, 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 @@ AM_CONDITIONAL(VGCONF_OS_IS_LINUX, -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 @@ AC_CONFIG_FILES([ 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 1532b538c..e62d774a1 100644 --- a/coregrind/Makefile.am +++ b/coregrind/Makefile.am @@ -343,6 +343,7 @@ COREGRIND_SOURCES_COMMON = \ 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 @@ COREGRIND_SOURCES_COMMON = \ 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 @@ COREGRIND_SOURCES_COMMON = \ 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 @@ COREGRIND_SOURCES_COMMON = \ 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 @@ COREGRIND_SOURCES_COMMON = \ 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 53c8d83e2..08f38c1ab 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 @@ static const char *select_platform(const char *clientname) (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 @@ int main(int argc, char** argv, char** envp) (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 20a178366..21f1e0e73 100644 --- a/coregrind/m_aspacemgr/aspacemgr-common.c +++ b/coregrind/m_aspacemgr/aspacemgr-common.c @@ -158,7 +158,8 @@ SysRes VG_(am_do_mmap_NO_NOTIFY)( Addr start, SizeT length, UInt prot, # 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 @@ SysRes ML_(am_open) ( const HChar* pathname, Int flags, Int mode ) /* 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 @@ Int ML_(am_readlink)(const HChar* path, HChar* buf, UInt bufsiz) # 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 d208a5389..811eb9192 100644 --- a/coregrind/m_cache.c +++ b/coregrind/m_cache.c @@ -540,8 +540,8 @@ get_cache_info(VexArchInfo *vai) #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 2c59bba94..f68cc1fa3 100644 --- a/coregrind/m_coredump/coredump-elf.c +++ b/coregrind/m_coredump/coredump-elf.c @@ -419,7 +419,17 @@ static void fill_prstatus(const ThreadState *tst, # 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 @@ static void fill_fpu(const ThreadState *tst, vki_elf_fpregset_t *fpu) 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 45f4243ec..fc7169a1d 100644 --- a/coregrind/m_debugger.c +++ b/coregrind/m_debugger.c @@ -386,6 +386,69 @@ static Int ptrace_setregs(Int pid, const VexGuestArchState* vex) regs.MIPS_r31 = vex->guest_r31; return VG_(ptrace)(VKI_PTRACE_SETREGS, pid, NULL, ®s); +#elif defined(VGP_tilegx_linux) + struct vki_user_regs_struct regs; + VG_(memset)(®s, 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, ®s); + #else # error Unknown arch #endif diff --git a/coregrind/m_debuginfo/d3basics.c b/coregrind/m_debuginfo/d3basics.c index 2f7f802ec..09d1b12a6 100644 --- a/coregrind/m_debuginfo/d3basics.c +++ b/coregrind/m_debuginfo/d3basics.c @@ -424,6 +424,9 @@ static Bool get_Dwarf_Reg( /*OUT*/Addr* a, Word regno, const RegSummary* regs ) 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 158daa7dc..1fcc6127f 100644 --- a/coregrind/m_debuginfo/debuginfo.c +++ b/coregrind/m_debuginfo/debuginfo.c @@ -955,6 +955,9 @@ ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV, Int use_fd ) # 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 @@ UWord evalCfiExpr ( const XArray* exprs, Int ix, || 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 @@ static Addr compute_cfa ( const D3UnwindRegs* uregs, 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 @@ Addr ML_(get_CFA) ( Addr ip, Addr sp, Addr fp, 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 @@ Bool VG_(use_CF_info) ( /*MOD*/D3UnwindRegs* uregsHere, # 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 @@ Bool VG_(use_CF_info) ( /*MOD*/D3UnwindRegs* uregsHere, 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 e64401c67..c7278e2ea 100644 --- a/coregrind/m_debuginfo/priv_storage.h +++ b/coregrind/m_debuginfo/priv_storage.h @@ -333,6 +333,19 @@ typedef 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 @@ typedef 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 f0b7ede84..a038a52db 100644 --- a/coregrind/m_debuginfo/readdwarf.c +++ b/coregrind/m_debuginfo/readdwarf.c @@ -1763,6 +1763,10 @@ void ML_(read_debuginfo_dwarf1) ( # 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 @@ void ML_(read_debuginfo_dwarf1) ( || 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 @@ static Bool summarise_context(/*OUT*/Addr* base, 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 @@ static Bool summarise_context(/*OUT*/Addr* base, 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 @@ static Bool summarise_context(/*OUT*/Addr* base, 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 @@ static Bool summarise_context(/*OUT*/Addr* base, *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 @@ static Int copy_convert_CfiExpr_tree ( XArray* dstxa, 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 f5c46748d..fda416122 100644 --- a/coregrind/m_debuginfo/readelf.c +++ b/coregrind/m_debuginfo/readelf.c @@ -2161,7 +2161,7 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) # 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 663d5f72f..926a13f71 100644 --- a/coregrind/m_debuginfo/storage.c +++ b/coregrind/m_debuginfo/storage.c @@ -212,6 +212,11 @@ void ML_(ppDiCfSI) ( const XArray* /* of CfiExpr */ exprs, 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 @@ static void ppCfiReg ( CfiReg reg ) 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 22941f27d..76adccce4 100644 --- a/coregrind/m_debuglog.c +++ b/coregrind/m_debuglog.c @@ -508,6 +508,51 @@ static UInt local_sys_getpid ( void ) : "$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 000000000..3451fe5d2 --- /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 c23581a48..1dc6e41a5 100644 --- a/coregrind/m_gdbserver/target.c +++ b/coregrind/m_gdbserver/target.c @@ -804,6 +804,8 @@ void valgrind_initialize_target(void) 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 000000000..81ccafeff --- /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 7b87856cf..3a3228f9a 100644 --- a/coregrind/m_gdbserver/valgrind_low.h +++ b/coregrind/m_gdbserver/valgrind_low.h @@ -107,5 +107,6 @@ extern void ppc64_init_architecture (struct valgrind_target_ops *target); 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 b198dbf2f..868325bd2 100644 --- a/coregrind/m_initimg/initimg-linux.c +++ b/coregrind/m_initimg/initimg-linux.c @@ -1173,6 +1173,21 @@ void VG_(ii_finalise_image)( IIFinaliseImageInfo iifii ) 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 80d372d32..365b50377 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 55d33f772..8506f5d61 100644 --- a/coregrind/m_libcfile.c +++ b/coregrind/m_libcfile.c @@ -131,8 +131,8 @@ Bool VG_(resolve_filename) ( Int fd, const HChar** result ) } 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_(mknod) ( const HChar* pathname, Int mode, UWord dev ) 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 @@ Int VG_(pipe) ( Int fd[2] ) } 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 @@ SysRes VG_(stat) ( const HChar* file_name, struct vg_stat* vgbuf ) # 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_(fcntl) ( Int fd, Int cmd, Addr arg ) 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 @@ const HChar *VG_(get_startup_wd) ( void ) 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 @@ SSizeT VG_(readlink) (const HChar* path, HChar* buf, SizeT bufsiz) { 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 @@ Int VG_(access) ( const HChar* path, Bool irusr, Bool iwusr, Bool ixusr ) 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 @@ SysRes VG_(pread) ( Int fd, void* buf, Int count, OffT offset ) # 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 @@ Int VG_(socket) ( Int domain, Int type, Int protocol ) # 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 @@ Int my_connect ( Int sockfd, struct vki_sockaddr_in* serv_addr, Int addrlen ) # 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 @@ Int VG_(write_socket)( Int sd, const void *msg, Int count ) # 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 @@ Int VG_(getsockname) ( Int sd, struct vki_sockaddr *name, Int *namelen) 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 @@ Int VG_(getpeername) ( Int sd, struct vki_sockaddr *name, Int *namelen) 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 @@ Int VG_(getsockopt) ( Int sd, Int level, Int optname, void *optval, # 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 @@ Int VG_(setsockopt) ( Int sd, Int level, Int optname, void *optval, # 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 f3f40704c..f25320a20 100644 --- a/coregrind/m_libcproc.c +++ b/coregrind/m_libcproc.c @@ -466,7 +466,7 @@ Int VG_(gettid)(void) * 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 @@ Int VG_(getgroups)( Int size, UInt* list ) 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_(ptrace) ( Int request, Int pid, void *addr, void *data ) 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 @@ void VG_(invalidate_icache) ( void *ptr, SizeT nbytes ) (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 3fa403b24..2551b1093 100644 --- a/coregrind/m_machine.c +++ b/coregrind/m_machine.c @@ -127,6 +127,13 @@ void VG_(get_UnwindStartRegs) ( /*OUT*/UnwindStartRegs* regs, = 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 @@ static void apply_to_GPs_of_tid(ThreadId tid, void (*f)(ThreadId, (*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 @@ Bool VG_(machine_get_hwcaps)( void ) 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 @@ Int VG_(machine_get_size_of_largest_guest_register) ( void ) # elif defined(VGA_mips64) return 8; +# elif defined(VGA_tilegx) + return 8; + # else # error "Unknown arch" # endif @@ -1762,7 +1840,8 @@ void* VG_(fnptr_to_fnentry)( void* f ) || 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 05ddc3504..52f9f9f2e 100644 --- a/coregrind/m_main.c +++ b/coregrind/m_main.c @@ -2152,7 +2152,7 @@ Int valgrind_main ( Int argc, HChar **argv, HChar **envp ) # 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 @@ asm( "\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 d87110b9a..246558260 100644 --- a/coregrind/m_redir.c +++ b/coregrind/m_redir.c @@ -1491,6 +1491,15 @@ void VG_(redir_initialise) ( void ) ); } +# 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 0207f5b57..5d3b17519 100644 --- a/coregrind/m_scheduler/scheduler.c +++ b/coregrind/m_scheduler/scheduler.c @@ -1684,6 +1684,9 @@ void VG_(nuke_all_threads_except) ( ThreadId me, VgSchedReturnCode src ) #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 000000000..e6cf4ef18 --- /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 4c34c05d4..e27a61bbf 100644 --- a/coregrind/m_signals.c +++ b/coregrind/m_signals.c @@ -567,8 +567,21 @@ typedef struct SigQueue { (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 @@ extern void my_sigreturn(void); " 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 617f26c5b..c4672e6c2 100644 --- a/coregrind/m_stacktrace.c +++ b/coregrind/m_stacktrace.c @@ -1392,6 +1392,213 @@ UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known, #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 cd3395870..0d7e1f05c 100644 --- a/coregrind/m_syscall.c +++ b/coregrind/m_syscall.c @@ -85,6 +85,18 @@ SysRes VG_(mk_SysRes_amd64_linux) ( Long val ) { 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 @@ asm ( ".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 @@ SysRes VG_(do_syscall) ( UWord sysno, UWord a1, UWord a2, UWord a3, 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 62ce78325..14f17802e 100644 --- a/coregrind/m_syswrap/priv_types_n_macros.h +++ b/coregrind/m_syswrap/priv_types_n_macros.h @@ -93,7 +93,8 @@ typedef || 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 000000000..0bd3756ab --- /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 f0c979339..a98d10a81 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -297,6 +297,15 @@ static void run_a_thread_NORETURN ( Word tidW ) : "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 @@ SysRes ML_(do_fork_clone) ( ThreadId tid, UInt flags, 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 @@ POST(sys_lookup_dcookie) } #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 d9c24a500..cf45638ee 100644 --- a/coregrind/m_syswrap/syswrap-main.c +++ b/coregrind/m_syswrap/syswrap-main.c @@ -650,6 +650,19 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs* canonical, 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 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs* canonical, 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 @@ void getSyscallStatusFromGuestState ( /*OUT*/SyscallStatus* canonical, 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 @@ void putSyscallStatusIntoGuestState ( /*IN*/ ThreadId tid, 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 @@ void getSyscallArgLayout ( /*OUT*/SyscallArgLayout* layout ) 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 @@ void ML_(fixup_guest_state_to_restart_syscall) ( ThreadArchState* arch ) # 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 000000000..28ee5df88 --- /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 3d2be09ba..027f9f6a6 100644 --- a/coregrind/m_trampoline.S +++ b/coregrind/m_trampoline.S @@ -1329,6 +1329,76 @@ VG_(trampoline_stuff_end): # 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 @@ VG_(trampoline_stuff_end): #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 a5da1c99f..28ac906c6 100644 --- a/coregrind/m_translate.c +++ b/coregrind/m_translate.c @@ -760,8 +760,8 @@ void log_bytes ( const HChar* bytes, SizeT nbytes ) 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 531a7209a..767b878bd 100644 --- a/coregrind/pub_core_aspacemgr.h +++ b/coregrind/pub_core_aspacemgr.h @@ -321,7 +321,7 @@ extern Bool VG_(am_relocate_nooverlap_client)( /*OUT*/Bool* need_discard, #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 7ac5a728e..9d7e6b451 100644 --- a/coregrind/pub_core_basics.h +++ b/coregrind/pub_core_basics.h @@ -96,6 +96,10 @@ typedef 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 761819153..ce1b199fd 100644 --- a/coregrind/pub_core_debuginfo.h +++ b/coregrind/pub_core_debuginfo.h @@ -130,6 +130,10 @@ typedef 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 14ea354f1..7fb7afeb5 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 fafe7077f..eeb4aa110 100644 --- a/coregrind/pub_core_mallocfree.h +++ b/coregrind/pub_core_mallocfree.h @@ -79,7 +79,8 @@ typedef Int ArenaId; 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 e35ff444f..8c7bdba59 100644 --- a/coregrind/pub_core_syscall.h +++ b/coregrind/pub_core_syscall.h @@ -86,6 +86,7 @@ extern SysRes VG_(mk_SysRes_mips32_linux)( UWord v0, UWord v1, 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 411a23cfd..763072915 100644 --- a/coregrind/pub_core_trampoline.h +++ b/coregrind/pub_core_trampoline.h @@ -104,6 +104,11 @@ extern void* VG_(arm_linux_REDIR_FOR_memcpy)( void*, void*, Int ); 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 b063d5411..224a9cc7b 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 df9e23218..8e7e42e5a 100644 --- a/coregrind/vgdb-invoker-ptrace.c +++ b/coregrind/vgdb-invoker-ptrace.c @@ -518,7 +518,7 @@ void detach_from_all_threads (pid_t pid) } } -# 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 @@ Bool invoker_invoke_gdbserver (pid_t pid) { 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 @@ Bool invoker_invoke_gdbserver (pid_t pid) 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 @@ Bool invoker_invoke_gdbserver (pid_t pid) /* 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 @@ Bool invoker_invoke_gdbserver (pid_t pid) 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 a57192ae1..f26cccaec 100644 --- a/docs/internals/register-uses.txt +++ b/docs/internals/register-uses.txt @@ -8,7 +8,7 @@ avoid having to endlessly re-look up this info in ABI documents. 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 @@ registers are EAX, EDX, and ECX respectively. 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 @@ fs thread ptr ppc32-linux ~~~~~~~~~~~ -Reg Callee Arg +Reg Callee Arg Name Saves? Reg? Comment Vex-uses? ------------------------------------------------------------------- r0 n n sometimes RAZ @@ -95,7 +95,7 @@ fpscr ppc64-linux ~~~~~~~~~~~ -Reg Callee Arg +Reg Callee Arg Name Saves? Reg? Comment Vex-uses? ------------------------------------------------------------------- r13 n n thread ptr @@ -142,7 +142,7 @@ Name Saves? Reg? Comment Vex-uses? --------------------------------------------------------------- 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 @@ selection when register pairs are required. ppc32-aix5 ~~~~~~~~~~ -Reg Callee Arg +Reg Callee Arg Name Saves? Reg? Comment Vex-uses? ------------------------------------------------------------------- r0 n n sometimes RAZ @@ -237,7 +237,7 @@ r30 y altivec spill temporary 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 @@ lr y return address 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 86d53f384..0b4715753 100644 --- a/drd/drd_bitmap.h +++ b/drd/drd_bitmap.h @@ -140,7 +140,8 @@ Addr make_address(const UWord a1, const UWord a0) || 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 413ed3b75..bed68aac9 100644 --- a/drd/drd_clientreq.c +++ b/drd/drd_clientreq.c @@ -68,7 +68,8 @@ void DRD_(clientreq_init)(void) * 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 95e9f42ae..88e4d44e1 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 50dd40232..19d78d49e 100644 --- a/exp-sgcheck/pc_main.c +++ b/exp-sgcheck/pc_main.c @@ -77,6 +77,10 @@ static void pc_pre_clo_init(void) 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 818cc6167..328b9b61b 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 bced1cde8..eb597e8eb 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 7cb9c2ff0..e18c46831 100644 --- a/gdbserver_tests/nlcontrolc.vgtest +++ b/gdbserver_tests/nlcontrolc.vgtest @@ -11,7 +11,7 @@ args: 1000000000 1000000000 1000000000 BSBSBSBS 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 996f01c7b..f6f869c2d 100644 --- a/gdbserver_tests/nlgone_return.vgtest +++ b/gdbserver_tests/nlgone_return.vgtest @@ -4,7 +4,7 @@ prog: gone 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 74cf9d86c..9f3636cd3 100644 --- a/helgrind/tests/annotate_hbefore.c +++ b/helgrind/tests/annotate_hbefore.c @@ -285,6 +285,16 @@ UWord do_acasW ( UWord* addr, UWord expected, UWord nyu ) 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 be62337db..c66b8ec1f 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 2b720a8f6..dde93e8a1 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 50e285309..481f91639 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 f6f192cb7..949459e0f 100644 --- a/include/pub_tool_basics.h +++ b/include/pub_tool_basics.h @@ -282,7 +282,7 @@ static inline Bool sr_EQ ( SysRes sr1, SysRes sr2 ) { #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 @@ static inline Bool sr_EQ ( SysRes sr1, SysRes sr2 ) { || 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 436afe0a3..8b38283ea 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 c80d49b29..1e3117928 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 7f7f03e79..860e8d0a4 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 7689a9f2a..4baf855f4 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 @@ typedef #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 @@ typedef #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 @@ VALGRIND_PRINTF_BACKTRACE(const char *format, ...) #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 42b24fe32..808c1d88c 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 @@ typedef unsigned int vki_uint; # 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 000000000..c95e76845 --- /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 000000000..08137d8a2 --- /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 000000000..9b0b99b9c --- /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 04f06af50..501754339 100644 --- a/massif/tests/Makefile.am +++ b/massif/tests/Makefile.am @@ -33,12 +33,18 @@ EXTRA_DIST = \ 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 e4ad60c79..60d5079d5 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 @@ static Int get_otrack_shadow_offset_wrk ( Int offset, Int szB ) # 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 @@ IRType MC_(get_otrack_reg_array_equiv_int_type) ( IRRegArray* arr ) 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 6d6b3ebf0..f17716761 100644 --- a/memcheck/tests/Makefile.am +++ b/memcheck/tests/Makefile.am @@ -187,9 +187,11 @@ EXTRA_DIST = \ 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 1fede8c8f..8f2c4645f 100644 --- a/memcheck/tests/atomic_incs.c +++ b/memcheck/tests/atomic_incs.c @@ -233,6 +233,20 @@ __attribute__((noinline)) void atomic_add_8bit ( char* p, int n ) ); } 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 @@ __attribute__((noinline)) void atomic_add_16bit ( short* p, int n ) ); } 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 @@ __attribute__((noinline)) void atomic_add_32bit ( int* p, int n ) : /*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 @@ __attribute__((noinline)) void atomic_add_64bit ( long long int* p, int n ) : /*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 3937e3eaa..428ea05b1 100644 --- a/memcheck/tests/leak-segv-jmp.c +++ b/memcheck/tests/leak-segv-jmp.c @@ -159,6 +159,30 @@ extern UWord do_syscall_WRK ( : "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 000000000..cca6411c1 --- /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 000000000..fa55d0e60 --- /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 4204899b2..e35b3bfb3 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 @@ get_irop(IROp op) #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 34dfb891d..e73cee0be 100644 --- a/memcheck/tests/vbit-test/vtest.h +++ b/memcheck/tests/vbit-test/vtest.h @@ -76,6 +76,7 @@ typedef struct { 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 c56137ef1..fb1db5d45 100644 --- a/none/tests/Makefile.am +++ b/none/tests/Makefile.am @@ -32,6 +32,9 @@ endif 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 @@ if VGCONF_PLATFORMS_INCLUDE_X86_LINUX 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 @@ EXTRA_DIST = \ 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 09958b552..2c70a08a6 100755 --- a/none/tests/allexec_prepare_prereq +++ b/none/tests/allexec_prepare_prereq @@ -33,5 +33,6 @@ pair ppc32 ppc64 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 000000000..086ff4365 --- /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 000000000..130d0b0de --- /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 a39da6a8b..81a12ec67 100644 --- a/tests/arch_test.c +++ b/tests/arch_test.c @@ -33,6 +33,7 @@ char* all_archs[] = { "s390x", "mips32", "mips64", + "tilegx", NULL }; @@ -74,6 +75,9 @@ static Bool go(char* arch) #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_* |